#ifndef __TOOLS_T_C_H__ #define __TOOLS_T_C_H__ #include #include #include #include #include #include /* to define DEBUG in gcc cli do: gcc -D DEBUG=1 or 0 if need!*/ #ifndef DEBUG #define DEBUG 0 #endif /* F_OUT file (stream) to log*/ #ifndef F_OUT #define F_OUT stdout #endif /* F_ERR file (stream) to log*/ #ifndef F_ERR #define F_ERR stderr #endif /* #ifndef SECOND #define SECOND 0 #endif #ifndef NANOSECOND #define NANOSECOND 0 #endif double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start); double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start); long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start); */ #if 1 extern long int PRECISION_TYPE_FLOAT ; extern long int PRECISION_TYPE_DOUBLE ; extern long int PRECISION_TYPE_L_DOUBLE ; #endif /*void get_cursor_position(int *col, int *rows);*/ #if DEBUG #define debug_print(fmt, ...) \ do { /*if (DEBUG)*/ fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ __LINE__, __func__, __VA_ARGS__); } while (0) #define PRINT_DEBUG_(fmt, ...) \ do { /*if (DEBUG)*/ fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \ __LINE__, __func__, __VA_ARGS__); } while (0) #else #define debug_print(fmt, ...) {} #define PRINT_DEBUG_(fmt, ...) {} #endif #define error_print(fmt, ...) \ fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ __LINE__, __func__, __VA_ARGS__); #define PRINT_ERROR(fmt, ...) \ fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \ __LINE__, __func__, __VA_ARGS__); #define PRINT_LOC_T(fmt, ...) \ fprintf(F_OUT, "%s:%d:%s(): " fmt, __FILE__, \ __LINE__, __func__, __VA_ARGS__); #define TYPE_CHAR char #define TYPE_U_CHAR unsigned char #define TYPE_INT int #define TYPE_U_INT unsigned int #define TYPE_L_INT long int #define TYPE_U_L_INT unsigned long int #define TYPE_SIZE_T size_t #define TYPE_FLOAT float #define TYPE_DOUBLE double #define TYPE_L_DOUBLE long double #define TYPE_STRING char* #define FREE(x) { free((x)); (x) = NULL;} #define FOREACH(array, array_size, function)\ for(size_t _ind = 0; _ind < array_size; ++_ind) function(array[_ind]); #define MIN(X, Y) (((Y) < (X)) ? (Y) : (X)) #define MAX(X, Y) (((Y) > (X)) ? (Y) : (X)) #define GENERATE_ALL(type)\ int COMPARE_N_##type(const void *,const void*);\ void COPY_ARRAY_##type(type* dst, const type* src, size_t array_size);\ type MAX_ARRAY_##type(const type *array, size_t array_size);\ size_t ARG_MAX_ARRAY_##type(const type *array, size_t array_size);\ type MIN_ARRAY_##type(const type *array, size_t array_size);\ size_t ARG_MIN_ARRAY_##type(const type *array, size_t array_size);\ TYPE_STRING type##_TO_STR(type var);\ GENERATE_ALL(TYPE_CHAR) GENERATE_ALL(TYPE_U_CHAR) GENERATE_ALL(TYPE_INT) GENERATE_ALL(TYPE_U_INT) GENERATE_ALL(TYPE_L_INT) GENERATE_ALL(TYPE_U_L_INT) GENERATE_ALL(TYPE_SIZE_T) GENERATE_ALL(TYPE_FLOAT) GENERATE_ALL(TYPE_DOUBLE) GENERATE_ALL(TYPE_L_DOUBLE) GENERATE_ALL(TYPE_STRING) /* strto_type */ int strto_TYPE_INT(char *str, char **endptr); unsigned int strto_TYPE_U_INT(char *str, char **endptr); long int strto_TYPE_L_INT(char *str, char **endptr); unsigned long int strto_TYPE_U_L_INT(char *str, char **endptr); size_t strto_TYPE_SIZE_T(char *str, char **endptr); float strto_TYPE_FLOAT(char *str, char **endptr); double strto_TYPE_DOUBLE(char *str, char **endptr); long double strto_TYPE_L_DOUBLE(char *str, char **endptr); /* * time calucl */ double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start); double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start); long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start); #endif /*__TOOLS_T_C_H__*/ #ifndef IMPLEMENTATION_TOOLS #define IMPLEMENTATION_TOOLS()\ \ GEN_TO_STR_N(TYPE_CHAR,2,"%c")\ GEN_TO_STR_N(TYPE_U_CHAR,2,"%c")\ GEN_TO_STR_N(TYPE_INT,22,"%d")\ GEN_TO_STR_N(TYPE_U_INT,22,"%u")\ GEN_TO_STR_N(TYPE_L_INT,22,"%ld")\ GEN_TO_STR_N(TYPE_U_L_INT,22,"%lu")\ GEN_TO_STR_N(TYPE_SIZE_T,22,"%lu")\ GEN_TO_STR_N(TYPE_FLOAT,128,"%.10f")\ GEN_TO_STR_N(TYPE_DOUBLE,256,"%.30lf")\ GEN_TO_STR_N(TYPE_L_DOUBLE,256,"%.30Lf")\ \ TYPE_STRING TYPE_STRING_TO_STR(TYPE_STRING var){\ return var;\ }\ \ \ long int PRECISION_TYPE_CHAR = 1;\ long int PRECISION_TYPE_U_CHAR = 1;\ long int PRECISION_TYPE_INT = 1;\ long int PRECISION_TYPE_U_INT = 1;\ long int PRECISION_TYPE_L_INT = 1;\ long int PRECISION_TYPE_U_L_INT = 1;\ long int PRECISION_TYPE_SIZE_T = 1;\ \ long int PRECISION_TYPE_FLOAT = 100000000;\ long int PRECISION_TYPE_DOUBLE = 100000000000;\ long int PRECISION_TYPE_L_DOUBLE = 100000000000000;\ \ \ \ \ int \ COMPARE_N_TYPE_STRING(const void *a,const void* b)\ {\ char **aa=(char**)a;\ char **bb=(char**)b;\ PRINT_DEBUG_("a=%s, b=%s\n",*aa, *bb);\ return strcmp(*aa,*bb);\ }\ \ void COPY_ARRAY_TYPE_STRING(char** dst, const char** src, size_t array_size)\ {\ for(size_t i = 0; i < array_size; ++i) strcpy(dst[i],src[i]);\ }\ \ \ GENERATE_FUNCTION_NUMERIC(TYPE_CHAR)\ GENERATE_FUNCTION_NUMERIC(TYPE_U_CHAR)\ GENERATE_FUNCTION_NUMERIC(TYPE_INT)\ GENERATE_FUNCTION_NUMERIC(TYPE_U_INT)\ GENERATE_FUNCTION_NUMERIC(TYPE_L_INT)\ GENERATE_FUNCTION_NUMERIC(TYPE_U_L_INT)\ GENERATE_FUNCTION_NUMERIC(TYPE_SIZE_T)\ GENERATE_FUNCTION_NUMERIC(TYPE_FLOAT)\ GENERATE_FUNCTION_NUMERIC(TYPE_DOUBLE)\ GENERATE_FUNCTION_NUMERIC(TYPE_L_DOUBLE)\ \ GENERATE_FUNCTION_ALL(TYPE_CHAR)\ GENERATE_FUNCTION_ALL(TYPE_U_CHAR)\ GENERATE_FUNCTION_ALL(TYPE_INT)\ GENERATE_FUNCTION_ALL(TYPE_U_INT)\ GENERATE_FUNCTION_ALL(TYPE_L_INT)\ GENERATE_FUNCTION_ALL(TYPE_U_L_INT)\ GENERATE_FUNCTION_ALL(TYPE_SIZE_T)\ GENERATE_FUNCTION_ALL(TYPE_FLOAT)\ GENERATE_FUNCTION_ALL(TYPE_DOUBLE)\ GENERATE_FUNCTION_ALL(TYPE_L_DOUBLE)\ GENERATE_FUNCTION_ALL(TYPE_STRING)\ \ /* strto_type */\ \ int strto_TYPE_INT(char *str, char **endptr){ \ return (int)strtol(str,endptr,10);\ }\ unsigned int strto_TYPE_U_INT(char *str, char **endptr){ \ return (unsigned int)strtoul(str,endptr,10);\ }\ long int strto_TYPE_L_INT(char *str, char **endptr){\ return strtol(str,endptr,10);\ }\ unsigned long int strto_TYPE_U_L_INT(char *str, char **endptr){\ return strtoul(str,endptr,10);\ }\ size_t strto_TYPE_SIZE_T(char *str, char **endptr){\ return strtoul(str,endptr,10);\ }\ float strto_TYPE_FLOAT(char *str, char **endptr){\ return strtof(str,endptr);\ }\ double strto_TYPE_DOUBLE(char *str, char **endptr){\ return strtod(str,endptr);\ }\ long double strto_TYPE_L_DOUBLE(char *str, char **endptr){\ return strtold(str,endptr);\ }\ \ \ /*\ * time section\ */\ \ double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start){\ /*PRINT_DEBUG_("\n\nstop.sec:%ld, start.sec:%ld, stop.nsec:%ld, start.nsec:%ld\n\n", time_stop.tv_sec , time_start.tv_sec, time_stop.tv_nsec , time_start.tv_nsec);*/\ return (time_stop.tv_sec - time_start.tv_sec) + 1.0e-9 * (time_stop.tv_nsec - time_start.tv_nsec);\ }\ \ double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start){\ /*PRINT_DEBUG_("\n\nstop.sec:%ld, start.sec:%ld, stop.nsec:%ld, start.nsec:%ld\n\n", time_stop.tv_sec , time_start.tv_sec, time_stop.tv_nsec , time_start.tv_nsec);*/\ return 1.0e3 * (time_stop.tv_sec - time_start.tv_sec) + 1.0e-6 * (time_stop.tv_nsec - time_start.tv_nsec);\ }\ \ long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start){\ /*PRINT_DEBUG_("\n\nstop.sec:%ld, start.sec:%ld, stop.nsec:%ld, start.nsec:%ld\n\n", time_stop.tv_sec , time_start.tv_sec, time_stop.tv_nsec , time_start.tv_nsec);*/\ return 1.0e9 * (time_stop.tv_sec - time_start.tv_sec) + (time_stop.tv_nsec - time_start.tv_nsec);\ }\ \ #endif /* IMPLEMENTATION_TOOLS */ #ifndef __DIMENSION_T_H__ #define __DIMENSION_T_H__ #include "../list_t/list_t.h" struct dimension{ size_t size; size_t *shape; size_t rank; }; bool littleEndian=true; bool isLessEqThan(long int a, long int b) ; bool isLessThan(long int a, long int b) ; bool isGreatEqThan(long int a, long int b) ; bool isGreatThan(long int a, long int b) ; long int incr(long int i) ; long int decr(long int i) ; typedef struct dimension dimension ; dimension * create_dim(size_t rank); dimension * create_reverse_dim(size_t rank); dimension* init_dim(size_t *t, size_t rnk); dimension* init_copy_dim(size_t *t, size_t rnk); dimension* clone_dim(dimension *dim); void free_dimension(dimension *d); bool is_equal_dim(dimension *d0, dimension *d1); dimension* sub_minus_dim_head(dimension *t, size_t minusSubdim); dimension* sub_minus_dim_tail(dimension *t, size_t minusSubdim); dimension* sub_dim_head(dimension *t, size_t subdim); dimension* sub_dim_tail(dimension *t, size_t subdim); dimension* sub_copy_minus_dim_head(dimension *t, size_t minusSubdim); dimension* sub_copy_minus_dim_tail(dimension *t, size_t minusSubdim); dimension* sub_copy_dim_head(dimension *t, size_t sub_copydim); dimension* sub_copy_dim_tail(dimension *t, size_t sub_copydim); void split_dim_part(dimension *root, dimension **part_1, dimension **part_2, size_t pivotSplit, size_t rangeInPivot ); void add_copy_dimension(dimension **d, dimension *d0, dimension *d1); void min_copy_dimension(dimension **d, dimension *d0, dimension *d1); void add_dimension(dimension **d, dimension *d0, dimension *d1); void min_dimension(dimension **d, dimension *d0, dimension *d1); void printDebug_dimension(dimension *d, char *msg); size_t sprint_dimension(char **dimContent, dimension *d); void updateRankDim(dimension *dim); size_t LineFromCoord(size_t *coo, dimension *dim); size_t* CoordFromLin(size_t line, dimension *dim); void vCoordFromLin(size_t *ret, size_t line, dimension *dim ); long int signedLineFromCoord(long *coo, dimension *dim); long int* signedCoordFromLin(long line, dimension *dim); void signedvCoordFromLin(long *ret, long int line, dimension *dim ); void increment_dim_var(dimension *d); void decrement_dim_var(dimension *d); struct list_shape_in_dim{ size_t index; size_t shape; struct list_shape_in_dim *next; }; typedef struct list_shape_in_dim list_shape_in_dim; void append_in_list_shape(list_shape_in_dim **list_p, size_t shape); dimension * create_dim_from_list_shape( list_shape_in_dim *l_p); dimension * create_binary_dim(size_t dimension_rank); void free_list_shape_in_dim(list_shape_in_dim *l_p); CREATE_HEADER_LIST(dimension) typedef dimension * ptr_DIMENSION; CREATE_HEADER_LIST(ptr_DIMENSION) GEN_HEAD_PTR_LIST(ptr_DIMENSION) /*int compare_dimension(dimension *d1, dimension *d2);*/ #endif /* __DIMENSION_T_H__*/ #ifndef min #define min(x,y) (((x)<(y))?(x):(y)) #endif //#ifndef IMPLEMENTATION_DIMENSION #define IMPLEMENTATION_DIMENSION()\ \ /*littleEndian=true;*/\ \ bool isLessEqThan(long int a, long int b) { return a <= b; }\ bool isLessThan(long int a, long int b) { return a < b; }\ bool isGreatEqThan(long int a, long int b) { return a >= b; }\ bool isGreatThan(long int a, long int b) { return a > b; }\ long int incr(long int i) { return i + 1; }\ long int decr(long int i) { return i - 1; }\ \ dimension* init_dim(size_t *t, size_t rnk){\ dimension *d = malloc(sizeof(dimension));\ d->rank=rnk;\ d->shape=t;\ updateRankDim(d);\ return d;\ }\ \ dimension* init_copy_dim(size_t *t, size_t rnk){\ if (rnk==0) return NULL;\ dimension *d = malloc(sizeof(dimension));\ d->shape=malloc(rnk * sizeof(size_t));\ d->rank = rnk;\ for(size_t i=0; ishape[i]=t[i];\ updateRankDim(d);\ return d;\ }\ dimension *\ create_dim(size_t rnk){\ if (rnk==0) return NULL;\ dimension *d = malloc(sizeof(dimension));\ d->shape=malloc(rnk * sizeof(size_t));\ d->rank = rnk;\ return d;\ }\ \ dimension* clone_dim(dimension *dim){\ return init_copy_dim(dim->shape,dim->rank);\ }\ \ dimension *\ create_reverse_dim(size_t rnk){\ dimension *dim = create_dim(rnk);\ for(size_t i=0;ishape[i]=rnk-1-i;\ updateRankDim(dim);\ return dim;\ }\ \ void free_dimension(dimension *d){\ if(d){\ free(d->shape);\ free(d);\ }\ }\ \ bool is_equal_dim(dimension *d0, dimension *d1){\ if(d0->rank != d1->rank) return false;\ if(d0->size != d1->size) return false;\ for(size_t i=0;irank; ++i)\ if(d0->shape[i] != d1->shape[i]) return false;\ \ return true;\ }\ \ dimension* sub_copy_minus_dim_head(dimension *root, size_t minusSubdim){\ if(minusSubdim < (root->rank)){\ dimension *d = init_copy_dim(root->shape, (root->rank)-minusSubdim);\ updateRankDim(d);\ return d;\ }\ return NULL;\ }\ \ dimension* sub_copy_minus_dim_tail(dimension *root, size_t minusSubdim){\ if(minusSubdim < (root->rank)){\ dimension *d = init_copy_dim((root->shape)+minusSubdim, (root->rank)-minusSubdim);\ updateRankDim(d);\ return d;\ }\ return NULL;\ }\ \ dimension* sub_copy_dim_head(dimension *root, size_t subdim){\ if(subdim < (root->rank)){\ dimension *d = init_copy_dim(root->shape, subdim);\ updateRankDim(d);\ return d;\ }\ return NULL;\ }\ \ dimension* sub_copy_dim_tail(dimension *root, size_t subdim){\ if(subdim < (root->rank)){\ dimension *d = init_copy_dim((root->shape)+(root->rank - subdim), subdim);\ updateRankDim(d);\ return d;\ }\ return NULL;\ }\ \ void add_copy_dimension(dimension **d, dimension *d0, dimension *d1) {\ (*d) = create_dim(d0->rank + d1->rank);\ for (size_t i = 0; i < d0->rank; i++) (*d)->shape[i] = d0->shape[i];\ for (size_t i = 0; i < d1->rank; i++) (*d)->shape[d0->rank + i] = d1->shape[i];\ updateRankDim(*d);\ }\ \ void min_copy_dimension(dimension **d, dimension *d0, dimension *d1) {\ size_t mindim = min(d0->rank,d1->rank) ;\ (*d)=create_dim(mindim);\ \ for (size_t i = 0; i < mindim; i++) {\ if (d0->shape[i] > d1->shape[i]) (*d)->shape[i] = d1->shape[i];\ else (*d)->shape[i] = d0->shape[i];\ }\ updateRankDim(*d);\ }\ \ \ \ \ dimension* sub_minus_dim_head(dimension *root, size_t minusSubdim){\ if(minusSubdim < (root->rank)){\ dimension *d = init_dim(root->shape, (root->rank)-minusSubdim);\ updateRankDim(d);\ return d;\ }\ return NULL;\ }\ dimension* sub_minus_dim_tail(dimension *root, size_t minusSubdim){\ if(minusSubdim < (root->rank)){\ dimension *d = init_dim((root->shape)+minusSubdim, (root->rank)-minusSubdim);\ updateRankDim(d);\ return d;\ }\ return NULL;\ }\ dimension* sub_dim_head(dimension *root, size_t subdim){\ if(subdim < (root->rank)){\ dimension *d = init_dim(root->shape, subdim);\ updateRankDim(d);\ return d;\ }\ return NULL;\ }\ dimension* sub_dim_tail(dimension *root, size_t subdim){\ if(subdim < (root->rank)){\ dimension *d = init_dim((root->shape)+(root->rank - subdim), subdim);\ updateRankDim(d);\ return d;\ }\ return NULL;\ }\ \ /*\ void split_dim_part(dimension *root, dimension **part_1, dimension **part_2, size_t rnk_nb_minus_part ) */\ void split_dim_part(dimension *root, dimension **part_1, dimension **part_2, size_t pivotSplit, size_t rangeInPivot ) {\ if(pivotSplit < root->rank){\ if(rangeInPivot < root->shape[pivotSplit]){\ /*size_t rnk_part1= (root->size * rnk_nb_minus_part)/(root->shape[(root->rank)-1]);*/\ /*printf("rnk_part1 :%ld \n",rnk_part1);*/\ *part_1 = init_copy_dim(root->shape, root->rank);\ ((*part_1)->shape[pivotSplit]) -= rangeInPivot;\ updateRankDim(*part_1);\ /*if(rnk_nb_minus_part <2)\ *part_2 = init_copy_dim((root->shape), root->rank-1 );\ else{*/\ *part_2 = init_copy_dim((root->shape), root->rank );\ (*part_2)->shape[pivotSplit] = rangeInPivot ;\ /*}*/\ updateRankDim(*part_2);\ }\ }\ }\ \ void increment_dim_var(dimension *d){\ if(littleEndian){\ (d->shape[0])++;\ }\ else{\ (d->shape[d->rank - 1])++;\ }\ }\ \ \ void decrement_dim_var(dimension *d){\ if(littleEndian){\ (d->shape[0])--;\ }\ else{\ (d->shape[d->rank - 1])--;\ }\ }\ \ void add_dimension(dimension **d, dimension *d0, dimension *d1) {\ (*d) = create_dim(d0->rank + d1->rank);\ for (size_t i = 0; i < d0->rank; i++) (*d)->shape[i] = d0->shape[i];\ for (size_t i = 0; i < d1->rank; i++) (*d)->shape[d0->rank + i] = d1->shape[i];\ updateRankDim(*d);\ }\ \ void min_dimension(dimension **d, dimension *d0, dimension *d1) {\ if (d0->rank > d1->rank) {\ *d = d1;\ }\ else if (d0->rank < d1->rank) {\ *d = d0;\ }\ else { /* d0->rank = d1->rank*/\ *d = d0;\ for (size_t i = 0; i < d0->rank; i++) {\ if (d0->shape[i] > d1->shape[i]) (*d)->shape[i] = d1->shape[i];\ }\ }\ updateRankDim(*d);\ }\ \ void printDebug_dimension(dimension *d,char *msg){\ \ printf("<%p>(%s)->rank = %ld | (%s)->size = %ld \n[",d,msg,d->rank,msg,d->size);\ for(size_t i=0; irank; ++i)\ printf(" %ld,", d->shape[i]);\ printf("] \n");\ /*printf("[%ld: %ld] |", i,d->shape[i]);*/\ /* if(littleEndian)\ printf("\nlittleEndian (true): the bigest index varies first, e.g: [x0,x1,x2,...,xn] xn is the bigest index\n");\ else\ printf("\nlittleEndian (false): the lowest index varies first, e.g: [x0,x1,x2,...,xn] x0 is the lowest index\n");\ */\ }\ \ size_t sprint_dimension(char **dimContent, dimension *d){\ if(*dimContent != NULL){\ free(*dimContent);\ *dimContent=NULL;\ }\ size_t nbch=6*d->rank+40;\ *dimContent = malloc(nbch);\ /*printf("nbCh=%ld\n",nbch);*/\ char *val=NULL;\ size_t cur=0;\ char *dimSzCh="dim->rank";\ for(size_t i=0; irank);\ for(size_t c=0;csize);\ for(size_t c=0;crank;++i){\ (*dimContent)[cur++]=' ';\ val=TYPE_SIZE_T_TO_STR(d->shape[i]);\ for(size_t c=0;csize=1;\ for(size_t i=0; irank; ++i)\ dim->size *=dim->shape[i];\ }\ \ /* signed */\ long int signedLineFromCoord(long int *coo, dimension *dim){\ long int begin = 0;\ long int end = dim->rank - 1;\ long int (*iter)(long int); iter = &incr;\ bool (*cond)(long int, long int); cond = &isLessEqThan;\ \ if (littleEndian) {\ begin = dim->rank - 1; end = 0;\ iter = &decr; cond = &isGreatEqThan;\ }\ \ long int pp = 1;\ long int sm = 0;\ for (long int i = begin; cond(i, end); i = iter(i)) {\ sm += (coo[i] * pp);\ pp *= dim->shape[i];\ }\ return sm;\ \ }\ \ void signedvCoordFromLin(long int *ret, long int line, dimension *dim ){\ \ long int begin = 0, end = dim->rank - 1;\ long int (*iter)(long int) = incr;\ bool (*cond)(long int, long int) = isLessThan;\ if (littleEndian == false) {\ /*if (littleEndian) {*/\ begin = dim->rank - 1; end = 0;\ iter = decr; cond = isGreatThan;\ }\ /*prlong intf("to coor begin = %d end = %d \n", begin, end);*/\ \ long int sm = line;\ long int pp = dim->size;\ for (long int i = begin; cond(i, end); i = iter(i)) {\ /*prlong intf(" i: %d ", i);*/\ pp /= dim->shape[i];\ ret[i] = sm / pp;\ sm %= pp;\ /*prlong intf("sm[%d] = %d , pp=%d ; ", i, sm, pp);*/\ }\ ret[end] = sm;\ }\ \ long int* signedCoordFromLin(long int line, dimension *dim){\ long int *ret;\ ret=malloc(dim->rank*sizeof(long int));\ signedvCoordFromLin(ret,line,dim);\ return ret;\ }\ \ /* */\ /* unsigned */\ size_t LineFromCoord(size_t *coo, dimension *dim) {\ return (long)signedLineFromCoord((long*)coo,dim);\ }\ \ void vCoordFromLin(size_t *ret, size_t line, dimension *dim ){\ signedvCoordFromLin((long*)ret, (long)line, dim);\ }\ \ size_t* CoordFromLin(size_t line, dimension *dim){\ return (size_t*)signedCoordFromLin((long)line, dim);\ }\ \ \ /* */\ \ void append_in_list_shape(list_shape_in_dim **list_p, size_t shape){\ list_shape_in_dim *lis=malloc(sizeof(list_shape_in_dim));\ lis->shape=shape;\ lis->next=NULL;\ if(*list_p == NULL){\ lis->index=0;\ *list_p = lis;\ }\ else{\ list_shape_in_dim *tmp =*list_p;\ while(tmp->next) tmp=tmp->next;\ lis->index = tmp->index +1;\ tmp->next=lis;\ }\ }\ \ dimension * create_dim_from_list_shape( list_shape_in_dim *l_p){\ \ if(l_p){\ list_shape_in_dim *tmp =l_p;\ while(tmp->next) tmp=tmp->next;\ dimension *dim=create_dim(tmp->index + 1);\ (dim)->rank = tmp->index + 1;\ tmp=l_p;\ while(tmp){\ (dim)->shape[tmp->index]=tmp->shape;\ tmp=tmp->next;\ }\ updateRankDim(dim);\ return dim;\ }\ return NULL;\ }\ \ dimension * create_binary_dim(size_t dimension_rank){\ dimension * dim = create_dim(dimension_rank);\ for(size_t i=0; ishape[i]=2;\ updateRankDim(dim);\ return dim;\ }\ \ \ void free_list_shape_in_dim(list_shape_in_dim *l_p){\ list_shape_in_dim *tmp=l_p, *ttmp;\ while(tmp){\ ttmp = tmp;\ tmp = ttmp->next;\ free(ttmp);\ }\ }\ \ IMPLEMENTATION_LIST(dimension)\ \ IMPLEMENTATION_LIST(ptr_DIMENSION)\ GEN_FUNC_PTR_LIST_FREE(ptr_DIMENSION){\ dimension *pdim=(dimension*)arg;\ free_dimension(pdim);\ /*free(pdim);*/\ }\ \ //#endif /* IMPLEMENTATION_DIMENSION */ #ifndef __TENSOR_T__H__ #define __TENSOR_T__H__ #include #include #include //#include "dimension_t/dimension_t.h" void subArray(size_t* dst, size_t* src, size_t debDst, size_t finDst, size_t debSrc); #define GENERATE_TENSOR_TYPE(type) \ struct tensor_##type{\ dimension *dim;\ type *x;\ };\ typedef struct tensor_##type tensor_##type;\ tensor_##type * create_tensor_##type(dimension *dim); \ tensor_##type* create_tensor_from_cpy_dim_##type(dimension *dim);\ void _recreate_tensor_if_not_the_same_dim_or_null_##type(tensor_##type **M, dimension *dd);\ tensor_##type* clone_tensor_##type(tensor_##type *tens);\ void free_tensor_##type(tensor_##type * tens); \ int copy_tensor_##type(tensor_##type * dst, tensor_##type * src);\ tensor_##type * sub_minus_tensor_head_##type(tensor_##type *rootens, size_t minuSubdim, size_t sizeInDim); \ tensor_##type * sub_minus_tensor_tail_##type(tensor_##type *rootens, size_t minuSubdim, size_t sizeInDim); \ tensor_##type * sub_tensor_head_##type(tensor_##type *rootens, size_t subdim, size_t sizeInDim); \ tensor_##type * sub_tensor_tail_##type(tensor_##type *rootens, size_t subdim, size_t sizeInDim); \ tensor_##type * sub_copy_minus_tensor_head_##type(tensor_##type *rootens, size_t minuSubdim, size_t sizeInDim); \ tensor_##type * sub_copy_minus_tensor_tail_##type(tensor_##type *rootens, size_t minuSubdim, size_t sizeInDim); \ tensor_##type * sub_copy_tensor_head_##type(tensor_##type *rootens, size_t sub_copydim, size_t sizeInDim); \ tensor_##type * sub_copy_tensor_tail_##type(tensor_##type *rootens, size_t sub_copydim, size_t sizeInDim); \ void print_tensor_msg_##type(tensor_##type *T, char *msg);\ void fprint_tensor_##type(char *file_name, tensor_##type *T);\ size_t sprint_tensor_##type(char **tensorContent,tensor_##type *T, bool withIndex);\ void split_tensor_##type(tensor_##type *Troot, tensor_##type **Tpart1, tensor_##type **Tpart2, size_t pivotSplit, size_t rangeInPivot);\ void split_copy_tensor_##type(tensor_##type *Troot, tensor_##type **Tpart1, tensor_##type **Tpart2, size_t pivotSplit, size_t rangeInPivot);\ void tensorProdNotOpt_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1); \ void tensorProd_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1); \ void tensorContractnProd_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber); \ void tensorProdThread_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1,size_t nbthread); \ void tensorProdThrea2d_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1,size_t nbthread); \ void tensorContractnProdThread_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread); \ void tensorContractnProdThreadOpt0_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread); \ void tensorContractnPro2dThread_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread); \ void tensorContractnPro2dThreadOpt0_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread); \ void tensorContractnProdNotOpt_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber); \ void tensorContractnProdOpt0_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber); \ type scalarProduct_dep_contractProd_##type(tensor_##type *M0, tensor_##type *M1, size_t nbthreads ,void (*tensorContractVar)(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread ));\ type scalarProduct_0_##type(tensor_##type *M0, tensor_##type *M1);\ void init_random_x_##type(tensor_##type *M, type minR, type maxR, int randomRange);\ tensor_##type * parseInput_withDim_to_tensor_##type(char *input);\ void parseInputOutput_withDim_to_tensors_##type(tensor_##type **Tpart1, tensor_##type **Tpart2, char *input, size_t pivotSplit);\ void parse_file_InputOutput_withDim_to_tensors_##type(tensor_##type **Tpart1, tensor_##type **Tpart2, char *file_name_input, size_t pivotSplit);\ tensor_##type ** fromInput_to_array_tensor_##type(tensor_##type *tens);\ struct array_chainlist_##type{\ size_t index;\ type x;\ struct array_chainlist_##type *next;\ };\ typedef struct array_chainlist_##type array_chainlist_##type;\ void append_array_chainlist_##type(array_chainlist_##type **list_a, type x);\ tensor_##type * create_tensor_from_list_array_##type( array_chainlist_##type *l_a, dimension *part_dim);\ void free_array_chainlist_##type(array_chainlist_##type *l_a);\ tensor_##type * transpose_notOpt_tensor_##type(tensor_##type *org);\ tensor_##type * shapeute_notOpt_tensor_##type(tensor_##type *org, dimension *dshape);\ void update_1tensor_func_##type(tensor_##type *M0, \ type (*func)(type), size_t nbthread);\ void update_2tensor_func_##type(tensor_##type *M0, tensor_##type *M1, \ type (*func)(type), size_t nbthread);\ void update_3tensor_func_##type(tensor_##type *M0, tensor_##type *M1, tensor_##type *M2, \ type (*func)(type, type), size_t nbthread);\ void update_4tensor_func_##type(tensor_##type *M0, tensor_##type *M1, tensor_##type *M2, \ type (*func)(type, type, type(*f1)(type)),\ type(*f1)(type),\ size_t nbthread);\ void update_5tensor_func_##type(tensor_##type *M0, tensor_##type *M1, tensor_##type *M2, tensor_##type *M3 , \ type (*func) (type, type, type, type(*f1)(type), type (*f2)(type,type)), \ type(*f1)(type), \ type (*f2)(type,type), \ size_t nbthread);\ void update_6tensor_func_##type(tensor_##type *M0, tensor_##type *M1, \ type (*func)(type, type, type),\ type scalar,\ size_t nbthread);\ GENERATE_TENSOR_TYPE(TYPE_FLOAT); GENERATE_TENSOR_TYPE(TYPE_DOUBLE); GENERATE_TENSOR_TYPE(TYPE_L_DOUBLE); #endif /* __TENSOR_T__H__ */ void subArray(size_t* dst, size_t* src, size_t debDst, size_t finDst, size_t debSrc) { for (size_t i = debDst; i < finDst; i++) { dst[i] = src[i + debSrc]; } } void concatArray(size_t* dst, size_t* src0, size_t* src1, size_t debDst, size_t debSrc0, size_t finSrc0, size_t debSrc1, size_t finSrc1) { size_t i = debDst; for (size_t j = debSrc0; j < finSrc0; j++) { dst[i++] = src0[j]; } for (size_t j = debSrc1; j < finSrc1; j++) { dst[i++] = src1[j]; } } void printArraySzt(size_t *a, size_t rnk,char *msg){ printf("======== %s ======= rank: %ld\n",msg,rnk); for(size_t i=0; i< rnk; ++i) printf("[%ld : %ld ] ",i,a[i]); printf("\n"); } int checkContractProdTensorDim(dimension *d0, dimension *d1, ssize_t contractionNumber){ if((d0->rank-contractionNumber <0)||(d1->rank-contractionNumber <0)) return 0; if(littleEndian){ ssize_t beginCommonM0=d0->rank-contractionNumber; for(ssize_t i=0; ishape[beginCommonM0+i] != d1->shape[i]) return 0; } }else{ ssize_t beginCommonM1=d1->rank-contractionNumber; for(ssize_t i=0; ishape[i] != d1->shape[beginCommonM1+i]) return 0; } } return 1; } /* bool isLessEqThan(long int a, long int b) { return a <= b; } bool isLessThan(long int a, long int b) { return a < b; } bool isGreatEqThan(long int a, long int b) { return a >= b; } bool isGreatThan(long int a, long int b) { return a > b; } long int incr(long int i) { return i + 1; } long int decr(long int i) { return i - 1; } */ #define FREE_COORD_\ free(coord0);\ free(coord1);\ free(coord);\ #define FREE_t \ free( tsub0 );\ free( tsub1 );\ free( tDk1 );\ free( tDk0 ); #define FREE_dM_S_\ free_dimension(dM0);\ free_dimension(dM1);\ free_dimension(dM);\ free_dimension(dSub0);\ free_dimension(dSub1);\ #define xrand() rand() #define GEN_FUNC_TENSOR(type)\ tensor_##type* create_tensor_##type(dimension *dim){\ tensor_##type *r_tens=malloc(sizeof(tensor_##type));\ updateRankDim(dim);\ r_tens->dim = dim;\ r_tens->x = malloc(sizeof(type)*dim->size);\ return r_tens;\ }\ \ void _recreate_tensor_if_not_the_same_dim_or_null_##type(tensor_##type **M, dimension *dd){\ if(*M){ \ if(!is_equal_dim((*M)->dim, dd)){\ free_tensor_##type(*M);\ (*M)=create_tensor_##type(dd);\ }else free_dimension(dd); /* because it is not used */\ }else{\ (*M)=create_tensor_##type(dd);\ }\ }\ tensor_##type* init_tensor_head_##type(tensor_##type *troot ,dimension *dim){\ tensor_##type *r_tens=malloc(sizeof(tensor_##type));\ updateRankDim(dim);\ r_tens->dim = dim;\ r_tens->x = troot->x;\ return r_tens;\ }\ \ tensor_##type* init_tensor_tail_##type(tensor_##type *troot ,dimension *dim){\ tensor_##type *r_tens=malloc(sizeof(tensor_##type));\ updateRankDim(dim);\ r_tens->dim = dim;\ r_tens->x = troot->x + ((troot->dim)->size - dim->size);\ return r_tens;\ }\ \ \ tensor_##type* init_copy_tensor_head_##type(tensor_##type *troot ,dimension *dim){\ tensor_##type *r_tens=malloc(sizeof(tensor_##type));\ updateRankDim(dim);\ r_tens->dim = dim;\ /*r_tens->x = troot->x;*/\ for(size_t i=0; isize;++i)\ r_tens->x[i]=troot->x[i];\ return r_tens;\ }\ \ tensor_##type* init_copy_tensor_tail_##type(tensor_##type *troot ,dimension *dim){\ tensor_##type *r_tens=malloc(sizeof(tensor_##type));\ updateRankDim(dim);\ r_tens->dim = dim;\ /*r_tens->x = troot->x + ((troot->dim)->size - dim->size);*/\ r_tens->x = malloc(sizeof(type)*dim->size);\ size_t dRank=(troot->dim)->size - dim->size;\ for(size_t i=0; isize;++i)\ r_tens->x[i]=troot->x[i+dRank];\ return r_tens;\ }\ \ \ tensor_##type* create_tensor_from_cpy_dim_##type(dimension *dim){\ tensor_##type *r_tens=malloc(sizeof(tensor_##type));\ r_tens->dim = init_copy_dim(dim->shape,dim->rank);\ r_tens->x = malloc(sizeof(type)*dim->size);\ return r_tens;\ }\ \ tensor_##type* clone_tensor_##type(tensor_##type *tens){\ if(tens){\ tensor_##type *r_tens=malloc(sizeof(tensor_##type));\ r_tens->dim = clone_dim(tens->dim);\ r_tens->x = malloc(sizeof(type) * (tens->dim)->size);\ for(size_t i=0; i<(tens->dim)->size;++i)\ r_tens->x[i]=tens->x[i];\ return r_tens;\ }\ return NULL;\ }\ \ int copy_tensor_##type(tensor_##type * dst, tensor_##type * src){\ if(dst!=NULL && src!=NULL){ \ int diff = dst->dim->size - src->dim->size;\ if(diff == 0) \ for(size_t i=0; i<(src->dim)->size;++i)\ dst->x[i]=src->x[i];\ return diff;\ \ }\ return -1;\ }\ \ void free_tensor_##type(tensor_##type * tens){\ if(tens){\ free_dimension(tens->dim);\ free(tens->x);\ free(tens);\ }\ }\ void init_random_x_##type(tensor_##type *M, type minR, type maxR, int randomRange){\ /*static bool initRandomFirst = true;\ if(initRandomFirst){ srand(time(NULL)); initRandomFirst = false;}*/\ int randVal;\ for(size_t i =0; i<(M->dim)->size;++i){\ randVal = xrand() % randomRange;\ M->x[i]=minR + (maxR-minR)*randVal / randomRange ;\ \ }\ }\ tensor_##type * sub_minus_tensor_head_##type(tensor_##type *rootens, size_t minuSubdim, size_t sizeInDim){\ dimension *rdim= rootens->dim;\ dimension *dS_t = sub_minus_dim_tail(rdim,rdim->rank - minuSubdim);\ if(sizeInDim < dS_t->size){\ dimension *dS_h = sub_minus_dim_head(rdim,minuSubdim);\ tensor_##type *ret_ens = malloc(sizeof(tensor_##type));\ ret_ens->dim = dS_h;\ ret_ens->x = malloc(sizeof(type)*dS_h->size);\ if(littleEndian){\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i*dS_t->size + sizeInDim];\ \ }\ }else{\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i + dS_h->size * sizeInDim];\ }\ }\ return ret_ens;\ }\ return NULL;\ }\ \ tensor_##type * sub_minus_tensor_tail_##type(tensor_##type *rootens, size_t minuSubdim, size_t sizeInDim){\ dimension *rdim= rootens->dim;\ dimension *dS_h = sub_minus_dim_head(rdim,rdim->rank - minuSubdim);\ if(sizeInDim < dS_h->size){\ dimension *dS_t = sub_minus_dim_tail(rdim,minuSubdim);\ tensor_##type *ret_ens = malloc(sizeof(tensor_##type));\ ret_ens->dim = dS_t;\ ret_ens->x = malloc(sizeof(type)*dS_t->size);\ if(littleEndian==false){\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i*dS_h->size + sizeInDim];\ }\ }else{\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i + dS_t->size * sizeInDim];\ }\ \ }\ return ret_ens;\ }\ return NULL;\ }\ \ tensor_##type * sub_tensor_head_##type(tensor_##type *rootens, size_t subdim, size_t sizeInDim){\ dimension *rdim= rootens->dim;\ dimension *dS_t = sub_dim_tail(rdim,rdim->rank - subdim);\ if(sizeInDim < dS_t->size){\ dimension *dS_h = sub_dim_head(rdim,subdim);\ tensor_##type *ret_ens = malloc(sizeof(tensor_##type));\ ret_ens->dim = dS_h;\ ret_ens->x = malloc(sizeof(type)*dS_h->size);\ if(littleEndian){\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i*dS_t->size + sizeInDim];\ }\ }else{\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i + dS_h->size * sizeInDim];\ }\ \ }\ return ret_ens;\ }\ return NULL;\ }\ tensor_##type * sub_tensor_tail_##type(tensor_##type *rootens, size_t subdim, size_t sizeInDim){ \ dimension *rdim= rootens->dim;\ dimension *dS_h = sub_dim_head(rdim,rdim->rank - subdim);\ if(sizeInDim < dS_h->size){\ dimension *dS_t = sub_dim_tail(rdim,subdim);\ tensor_##type *ret_ens = malloc(sizeof(tensor_##type));\ ret_ens->dim = dS_t;\ ret_ens->x = malloc(sizeof(type)*dS_t->size);\ if(littleEndian==false){\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i*dS_h->size + sizeInDim];\ }\ }else{\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i + dS_t->size * sizeInDim];\ }\ \ }\ return ret_ens;\ }\ return NULL;\ }\ \ tensor_##type * sub_copy_minus_tensor_head_##type(tensor_##type *rootens, size_t minuSubdim, size_t sizeInDim){\ dimension *rdim= rootens->dim;\ dimension *dS_t = sub_copy_minus_dim_tail(rdim,rdim->rank - minuSubdim);\ if(sizeInDim < dS_t->size){\ dimension *dS_h = sub_copy_minus_dim_head(rdim,minuSubdim);\ tensor_##type *ret_ens = create_tensor_##type(dS_h);\ /*malloc(sizeof(tensor_##type));\ ret_ens->dim = dS_h;\ ret_ens->x = malloc(sizeof(type)*dS_h->size);*/\ if(littleEndian){\ /*ret_ens->x = malloc(sizeof(type)*dS_h->size);\ */for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i*dS_t->size + sizeInDim];\ /*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->size, i,dS_h->size,i*dS_h->size + sizeInDim);*/\ \ }\ }else{\ /*ret_ens->x = (rootens->x)+sizeInDim*dS_h->size;*/\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i + dS_h->size * sizeInDim];\ }\ }\ free_dimension(dS_t);\ return ret_ens;\ }\ free_dimension(dS_t);\ return NULL;\ }\ \ tensor_##type * sub_copy_minus_tensor_tail_##type(tensor_##type *rootens, size_t minuSubdim, size_t sizeInDim){\ dimension *rdim= rootens->dim;\ dimension *dS_h = sub_copy_minus_dim_head(rdim,rdim->rank - minuSubdim);\ if(sizeInDim < dS_h->size){\ dimension *dS_t = sub_copy_minus_dim_tail(rdim,minuSubdim);\ tensor_##type *ret_ens = create_tensor_##type(dS_t);\ /*tensor_##type *ret_ens = malloc(sizeof(tensor_##type));\ ret_ens->dim = dS_t;\ ret_ens->x = malloc(sizeof(type)*dS_t->size);\ */if(littleEndian==false){\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i*dS_h->size + sizeInDim];\ }\ }else{\ /*ret_ens->x = (rootens->x)+sizeInDim*dS_t->size;*/\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i + dS_t->size * sizeInDim];\ }\ \ }\ free_dimension(dS_h);\ return ret_ens;\ }\ free_dimension(dS_h);\ return NULL;\ }\ \ tensor_##type * sub_copy_tensor_head_##type(tensor_##type *rootens, size_t sub_copydim, size_t sizeInDim){\ /*return sub_copy_minus_tensor_head_##type(rootens,rootens->dim->rank - sub_copydim, sizeInDim);*/\ dimension *rdim= rootens->dim;\ dimension *dS_t = sub_copy_dim_tail(rdim,rdim->rank - sub_copydim);\ if(sizeInDim < dS_t->size){\ dimension *dS_h = sub_copy_dim_head(rdim,sub_copydim);\ tensor_##type *ret_ens = create_tensor_##type(dS_h);\ /*tensor_##type *ret_ens = malloc(sizeof(tensor_##type));\ ret_ens->dim = dS_h;\ ret_ens->x = malloc(sizeof(type)*dS_h->size);\ */if(littleEndian){\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i*dS_t->size + sizeInDim];\ /*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->size, i,dS_h->size,i*dS_h->size + sizeInDim);*/\ }\ }else{\ /*ret_ens->x = (rootens->x)+sizeInDim*dS_h->size;*/\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i + dS_h->size * sizeInDim];\ /*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->size, i,dS_h->size,i*dS_h->size + sizeInDim);*/\ }\ \ }\ free_dimension(dS_t);\ return ret_ens;\ }\ free_dimension(dS_t);\ return NULL;\ }\ tensor_##type * sub_copy_tensor_tail_##type(tensor_##type *rootens, size_t sub_copydim, size_t sizeInDim){ \ /*return sub_copy_minus_tensor_tail_##type(rootens,rootens->dim->rank - sub_copydim, sizeInDim);*/\ dimension *rdim= rootens->dim;\ dimension *dS_h = sub_copy_dim_head(rdim,rdim->rank - sub_copydim);\ if(sizeInDim < dS_h->size){\ dimension *dS_t = sub_copy_dim_tail(rdim,sub_copydim);\ tensor_##type *ret_ens = create_tensor_##type(dS_t);\ /*tensor_##type *ret_ens = malloc(sizeof(tensor_##type));\ ret_ens->dim = dS_t;\ ret_ens->x = malloc(sizeof(type)*dS_t->size);\ */if(littleEndian==false){\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i*dS_h->size + sizeInDim];\ /*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->size, i,dS_h->size,i*dS_h->size + sizeInDim);*/\ }\ }else{\ /*ret_ens->x = (rootens->x)+sizeInDim*dS_t->size;*/\ for(size_t i=0; isize; ++i){\ ret_ens->x[i]=rootens->x[i + dS_t->size * sizeInDim];\ /*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->size, i,dS_h->size,i*dS_h->size + sizeInDim);*/\ }\ \ }\ free_dimension(dS_h);\ return ret_ens;\ }\ free_dimension(dS_h);\ return NULL;\ }\ \ void print_tensor_msg_##type(tensor_##type *T,char *msg) {\ /*size_t j=0 ,k=0*/;\ size_t *coord = malloc(sizeof(long int)*(T->dim)->rank); \ char *val=NULL;\ /*char *dimsg=malloc(512);\ sprintf(dimsg,"(%s)->dim",msg);\ printDebug_dimension(T->dim,dimsg);\ */printf("%s\n",msg);\ long int begin , end /*, beginIter , endIter*/ ;\ long int (*iter)(long int) ;\ bool (*cond)(long int, long int) ; \ if (littleEndian ) {\ begin = (T->dim->rank) - 1; end = 0;\ iter = decr; cond = isGreatEqThan; \ /*printf("littleEndian(=true): the bigest index varies first, e.g: [x0,x1,x2,...,xn] xn is the bigest index \n");*/\ }else{\ begin = 0 ; end = (T->dim->rank) - 1; \ iter = incr; cond = isLessEqThan; \ /*printf("littleEndian(=false): the lowest index varies first, e.g: [x0,x1,x2,...,xn] x0 is the lowest index \n");*/\ }\ for(long int i=0;i<(T->dim)->size;++i){\ vCoordFromLin(coord,i,T->dim);\ if(coord[begin]==0){\ for(long int j=begin; cond(j,end); j= iter(j) ){\ if(coord[j]==0) printf("(");\ else break;\ }\ }\ /*printf(" [");\ for(size_t k=0; k<(T->dim)->rank;++k) printf(" %ld",coord[k]);\ */val=type##_TO_STR(T->x[i]);\ printf(" |#%ld]: %s, ",i,val);\ /*printf(" %s, ",val);*/\ free(val); val=NULL;\ /*if(T->x[i] != T->x[i]){\ printf("\nALERT NAN\n");\ char c;\ scanf("%c",&c);\ }*/\ if(coord[begin]==(T->dim)->shape[begin]-1){\ size_t count=0;\ for(long int j=begin; cond(j,end); j = iter(j)){\ if(coord[j]==(T->dim)->shape[j]-1) {\ printf(")"); ++count;\ }\ else break;\ }\ if(count == (T->dim)->rank-1) printf("\n ");\ }\ }\ \ free(coord);\ printf("\n");\ /*free(dimsg);*/\ }\ \ \ void fprint_tensor_##type(char *file_name, tensor_##type *T) {\ /*size_t j=0,k=0;*/\ size_t *coord = malloc(sizeof(long int)*(T->dim)->rank); \ char *val=NULL;\ FILE *fileWrite = fopen(file_name, "w");\ if(fileWrite == NULL) {\ printf("error while opening %s\n",file_name);\ exit(1);\ }\ long int begin , end /*, beginIter, endIter*/ ;\ long int (*iter)(long int) ;\ bool (*cond)(long int, long int) ; \ if (littleEndian ) {\ begin = (T->dim->rank) - 1; end = 0;\ iter = decr; cond = isGreatEqThan; \ /*fprintf(fileWrite,"littleEndian(=true): the bigest index varies first, e.g: [x0,x1,x2,...,xn] xn is the bigest index \n");*/\ }else{\ begin = 0 ; end = (T->dim->rank) - 1; \ iter = incr; cond = isLessEqThan; \ /*fprintf(fileWrite,"littleEndian(=false): the lowest index varies first, e.g: [x0,x1,x2,...,xn] x0 is the lowest index \n");*/\ }\ fprintf(fileWrite,"[");\ for(size_t i=0; i<(T->dim)->rank; ++i)\ fprintf(fileWrite," %ld,", (T->dim)->shape[i]);\ fprintf(fileWrite,"] \n");\ \ for(long int i=0;i<(T->dim)->size;++i){\ vCoordFromLin(coord,i,T->dim);\ if(coord[begin]==0){\ for(long int j=begin; cond(j,end); j= iter(j) ){\ if(coord[j]==0) fprintf(fileWrite,"(");\ else break;\ }\ }\ if(T->x[i] != T->x[i]){\ printf("\nALERT NAN\n");\ ;\ return;\ }\ /*fprintf(fileWrite," [");\ for(size_t k=0; k<(T->dim)->rank;++k) fprintf(fileWrite," %ld,",coord[k]);\ */val=type##_TO_STR(T->x[i]);\ fprintf(fileWrite," %s, ",val);\ free(val); val=NULL;\ if(coord[begin]==(T->dim)->shape[begin]-1){\ size_t count=0;\ for(long int j=begin; cond(j,end); j = iter(j)){\ if(coord[j]==(T->dim)->shape[j]-1) {\ fprintf(fileWrite,")"); ++count;\ }\ else break;\ }\ if(count == (T->dim)->rank-1) fprintf(fileWrite,"\n ");\ }\ }\ \ free(coord);\ fprintf(fileWrite,"\n");\ fclose(fileWrite);\ }\ \ size_t sprint_tensor_##type(char **tensorContent,tensor_##type *T, bool withIndex) {\ if(*tensorContent != NULL) {\ free(*tensorContent);\ *tensorContent = NULL; \ }\ size_t rnk = ((T->dim)->size)*(32+ withIndex * 5*(T->dim)->rank + 129 );\ /*printf("malloc %ld char\n",rnk);*/\ *tensorContent = malloc(rnk ) ;\ size_t cur=0;\ size_t *coord = malloc(sizeof(long int)*(T->dim)->rank); \ char *val=NULL;\ long int begin , end /*, beginIter, endIter*/ ;\ long int (*iter)(long int) ;\ bool (*cond)(long int, long int) ; \ if (littleEndian ) {\ begin = (T->dim->rank) - 1; end = 0;\ iter = decr; cond = isGreatEqThan; \ val=malloc(128);\ sprintf(val,"littleEndian(=true): the bigest index varies first, e.g: [x0,x1,x2,...,xn] xn is the bigest index \n");\ for(size_t c=0;cdim->rank) - 1; \ iter = incr; cond = isLessEqThan; \ val=malloc(128);\ sprintf(val,"littleEndian(=false): the lowest index varies first, e.g: [x0,x1,x2,...,xn] x0 is the lowest index \n");\ for(size_t c=0;cdim)->size;++i){\ vCoordFromLin(coord,i,T->dim);\ if(coord[begin]==0){\ for(long int j=begin; cond(j,end); j= iter(j) ){\ if(coord[j]==0) /*printf("(")*/(*tensorContent)[cur++]='(';\ else break;\ }\ }\ if(withIndex){\ (*tensorContent)[cur++]=' ';\ (*tensorContent)[cur++]='[';\ (*tensorContent)[cur++]='{';\ for(size_t k=0; k<(T->dim)->rank;++k) {\ /*printf(" %ld,",coord[k]);*/\ val=TYPE_SIZE_T_TO_STR(coord[k]);\ for(size_t c=0;cx[i] != T->x[i]){\ /*char *nanStr="ALERT NAN";\ for(size_t c=0;cx[i]);\ /*printf(" {%ld} %s [",i,val);*/\ (*tensorContent)[cur++]=' ';\ for(size_t c=0;cdim)->shape[begin]-1){\ size_t count=0;\ for(long int j=begin; cond(j,end); j = iter(j)){\ if(coord[j]==(T->dim)->shape[j]-1) {/*printf(")"); */ (*tensorContent)[cur++]=')'; ++count;}\ else break;\ }\ if(count == (T->dim)->rank-1) {(*tensorContent)[cur++]='\n'; (*tensorContent)[cur++]=' ';}\ }\ }\ \ free(coord);\ /*printf("\n");*/(*tensorContent)[cur++]='\n';\ (*tensorContent)[cur++]='\0';\ return cur;\ }\ \ \ void split_tensor_##type(tensor_##type *Troot, tensor_##type **Tpart1, tensor_##type **Tpart2, size_t pivotSplit, size_t rangeInPivot){\ size_t rnk = (Troot->dim)->rank;\ if(pivotSplit < rnk){\ if( rangeInPivot < (Troot->dim)->shape[pivotSplit]){\ dimension *dpart1, *dpart2;\ split_dim_part(Troot->dim, &dpart1, &dpart2, pivotSplit, rangeInPivot);\ *Tpart1 = init_tensor_head_##type(Troot, dpart1);\ *Tpart2 = init_tensor_tail_##type(Troot, dpart2);\ }\ }\ } \ void split_copy_tensor_##type(tensor_##type *Troot, tensor_##type **Tpart1, tensor_##type **Tpart2, size_t pivotSplit, size_t rangeInPivot){\ size_t rnk = (Troot->dim)->rank;\ if(pivotSplit < rnk){\ if( rangeInPivot < (Troot->dim)->shape[pivotSplit]){\ dimension *dpart1, *dpart2;\ split_dim_part(Troot->dim, &dpart1, &dpart2, pivotSplit, rangeInPivot);\ *Tpart1 = init_copy_tensor_head_##type(Troot, dpart1);\ *Tpart2 = init_copy_tensor_tail_##type(Troot, dpart2);\ }\ }\ }\ \ void tensorProdNotOpt_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1) { \ dimension *dd; \ add_dimension(&dd, M0->dim, M1->dim); \ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd); \ tensor_##type *M = *MM; \ size_t* coord; \ coord = malloc(sizeof(size_t)*(dd->rank)); \ size_t* coord0 , lin0; \ coord0 = malloc(sizeof(size_t)* M0->dim->rank); \ size_t* coord1 , lin1; \ coord1 = malloc(sizeof(size_t)* M1->dim->rank); \ for (size_t i = 0; i < dd->size; i++) { \ vCoordFromLin(coord, i, M->dim); \ subArray(coord0, coord, 0, M0->dim->rank, 0); \ subArray(coord1, coord, 0, M1->dim->rank, M0->dim->rank); \ \ lin0=LineFromCoord(coord0, M0->dim); \ lin1=LineFromCoord(coord1, M1->dim); \ \ M->x[i] = M0->x[lin0] * M1->x[lin1]; \ /*printf(" M->x[%ld] = M0->x[%ld] * M1->x[%ld] ::: %f = %f * %f \n",i,lin0,lin1, M->x[i] , M0->x[lin0] , M1->x[lin1]);*/\ } \ FREE_COORD_ ; \ } \ \ \ void tensorProd_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1) { \ dimension *dd; \ add_dimension(&dd, M0->dim, M1->dim); \ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd); \ tensor_##type *M = *MM; \ size_t m_idx;\ for(size_t i=0; idim->size; ++i){\ for(size_t j=0; jdim->size; ++j){\ if(littleEndian)\ m_idx= i*M1->dim->size + j ;\ else\ m_idx= i+M0->dim->size * j ;\ M->x[m_idx]=M0->x[i]*M1->x[j];\ /*printf("[%ld|%ld:(%ld,%ld)]",x_idx++,m_idx,i,j);*/\ }\ }\ } \ \ /* M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...=n-l alor p=n+m-2l\ M[x0,x1,x3..xl x{l+1}...xn] X M[xn,x{n-1},x{n-2}...xl y{l+1} ..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)\ M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]*/\ \ void tensorContractnProd_##type(tensor_##type** MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber) {\ /* if (!checkMatchProdtensor(M0->dim, M1->dim, contractionNumber)) {\ prsize_tf("Deep = %d\n", contractionNumber);\ }*/\ if(checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)==0){\ printf("checkContractProdTensorDim %ld contractionNumber\n", contractionNumber);\ printDebug_dimension(M0->dim, "M0 dim");\ printDebug_dimension(M1->dim, "M1 dim");\ getchar();\ }\ \ size_t len0 = M0->dim->rank - contractionNumber;\ size_t len1 = M1->dim->rank - contractionNumber;\ \ size_t* tsub0 = malloc(sizeof(size_t) *len0);\ size_t* tsub1 = malloc(sizeof(size_t) *len1);\ size_t* tDk1 = malloc(sizeof(size_t) *contractionNumber);\ size_t* tDk0 = malloc(sizeof(size_t) *contractionNumber);\ subArray(tsub0, M0->dim->shape, 0, len0, 0);\ subArray(tsub1, M1->dim->shape, 0, len1, contractionNumber);\ subArray(tDk1, M1->dim->shape, 0, contractionNumber, 0);\ subArray(tDk0, M0->dim->shape, 0, contractionNumber, len0);\ /*printArraySzt(tsub0,len0,"tsub0");\ printArraySzt(tsub1,len1,"tsub1");\ printArraySzt(tDk0,contractionNumber,"tDk0");\ printArraySzt(tDk1,contractionNumber,"tDk1");*/\ dimension *dSub0 = init_dim(tsub0, len0);\ dimension *dSub1 = init_dim(tsub1, len1);\ dimension *dM1 = init_dim(tDk1, contractionNumber);\ dimension *dM0 = init_dim(tDk0, contractionNumber);\ /*printDebug_dimension(dSub0,"dSub0");\ printDebug_dimension(dSub1,"dSub1");\ printDebug_dimension(dM0,"dM0");\ printDebug_dimension(dM1,"dM1");*/\ dimension *dM;\ min_copy_dimension(&dM, dM0, dM1);\ /*printDebug_dimension(dM,"dM");*/\ \ dimension *dd;\ add_dimension(&dd, dSub0, dSub1);\ /*printDebug_dimension(dd,"dd");*/\ updateRankDim(dd);\ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd);\ tensor_##type *M= *MM;\ \ \ \ size_t a0_id, a1_id, n0_id, n1_id;\ for (size_t i = 0; i < M->dim->size; i++) {\ if(littleEndian){\ a0_id=i/dSub1->size;\ a1_id=i%dSub1->size;\ }\ else{\ a0_id=i%dSub0->size;\ a1_id=i/dSub0->size;\ }\ M->x[i] = 0;\ for (size_t k = 0; k < dM->size; k++) {\ if(littleEndian){\ n0_id= a0_id*dM->size + k;\ n1_id= a1_id + dSub1->size * k;\ }\ else{\ n0_id= a0_id + dSub0->size * k;\ n1_id= a1_id*dM->size + k;\ }\ M->x[i] += M0->x[n0_id] * M1->x[n1_id];\ \ }\ }\ FREE_dM_S_ \ }\ \ /* M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...=n-l alor p=n+m-2l\ M[x0,x1,x3..xl x{l+1}...xn] X M[xn,x{n-1},x{n-2}...xl y{l+1} ..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)\ M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]*/\ \ void tensorContractnProdOpt0_##type(tensor_##type** MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber) {\ /* if (!checkMatchProdtensor(M0->dim, M1->dim, contractionNumber)) {\ prsize_tf("Deep = %d\n", contractionNumber);\ }*/\ if(checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)==0){\ printf("checkContractProdTensorDim %ld contractionNumber\n", contractionNumber);\ printDebug_dimension(M0->dim, "M0 dim");\ printDebug_dimension(M1->dim, "M1 dim");\ getchar();\ }\ \ size_t len0 = M0->dim->rank - contractionNumber;\ size_t len1 = M1->dim->rank - contractionNumber;\ \ size_t* tsub0 = malloc(sizeof(size_t) *len0);\ size_t* tsub1 = malloc(sizeof(size_t) *len1);\ size_t* tDk1 = malloc(sizeof(size_t) *contractionNumber);\ size_t* tDk0 = malloc(sizeof(size_t) *contractionNumber);\ subArray(tsub0, M0->dim->shape, 0, len0, 0);\ subArray(tsub1, M1->dim->shape, 0, len1, contractionNumber);\ subArray(tDk1, M1->dim->shape, 0, contractionNumber, 0);\ subArray(tDk0, M0->dim->shape, 0, contractionNumber, len0);\ /*printArraySzt(tsub0,len0,"tsub0");\ printArraySzt(tsub1,len1,"tsub1");\ printArraySzt(tDk0,contractionNumber,"tDk0");\ printArraySzt(tDk1,contractionNumber,"tDk1");*/\ dimension *dSub0 = init_dim(tsub0, len0);\ dimension *dSub1 = init_dim(tsub1, len1);\ dimension *dM1 = init_dim(tDk1, contractionNumber);\ dimension *dM0 = init_dim(tDk0, contractionNumber);\ /*printDebug_dimension(dSub0,"dSub0");\ printDebug_dimension(dSub1,"dSub1");\ printDebug_dimension(dM0,"dM0");\ printDebug_dimension(dM1,"dM1");*/\ dimension *dM;\ min_copy_dimension(&dM, dM0, dM1);\ /*printDebug_dimension(dM,"dM");*/\ \ dimension *dd;\ add_dimension(&dd, dSub0, dSub1);\ /*printDebug_dimension(dd,"dd");*/\ updateRankDim(dd);\ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd);\ tensor_##type *M= *MM;\ \ \ \ size_t a0_id, a1_id, n0_id, n1_id;\ for (size_t i = 0; i < M->dim->size; i++) {\ if(littleEndian){\ a0_id=i/dSub1->size;\ a1_id=i%dSub1->size;\ n0_id=a0_id*dM->size ;\ n1_id= a1_id ;\ }\ else{\ a0_id=i%dSub0->size;\ a1_id=i/dSub0->size;\ n1_id= a1_id*dM->size ;\ n0_id= a0_id ;\ }\ M->x[i] = 0;\ for (size_t k = 0; k < dM->size; k++) {\ if(littleEndian){\ /*n0_id= a0_id*dM->size + k;*/\ /*n1_id= a1_id + dSub1->size * k;*/\ /*M->x[i] += M0->x[begin0++] * M1->x[n1_id];*/\ M->x[i] += M0->x[n0_id++] * M1->x[n1_id];\ n1_id +=dSub1->size ;\ }\ else{\ /*n0_id= a0_id + dSub0->size * k;*/\ /*n1_id= a1_id*dM->size + k;*/\ /*M->x[i] += M0->x[n0_id] * M1->x[begin1++];*/\ M->x[i] += M0->x[n0_id] * M1->x[n1_id++];\ n0_id += dSub0->size ;\ }\ \ }\ }\ FREE_dM_S_ \ }\ \ struct arg_Prod_##type{\ type *M0x;\ type *M1x;\ type *Mx;\ size_t beginRange;\ size_t endRange;\ size_t MRank;\ };\ void* runProd_thread_##type(void *arg){\ struct arg_Prod_##type *arg_t = arg;\ size_t a0_id, a1_id;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ if(littleEndian){\ a0_id=i / arg_t->MRank;\ a1_id=i % arg_t->MRank;\ }\ else{\ a0_id=i % arg_t->MRank;\ a1_id=i / arg_t->MRank;\ }\ arg_t->Mx[i] = arg_t->M0x[a0_id] * arg_t->M1x[a1_id];\ }\ return 0;\ }\ \ \ void tensorProdThread_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t nbthread) { \ dimension *dd; \ add_dimension(&dd, M0->dim, M1->dim); \ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd); \ tensor_##type *M = *MM; \ \ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_Prod_##type **arg_th = malloc( nbthread * sizeof(struct arg_Prod_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_Prod_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->Mx=M->x;\ arg_th[i]->beginRange = i*(M->dim->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(M->dim->size)/nbthread ;\ /*if(i < nbthread - 1 ) arg_th[i]->endRange = (i+1)*(M->dim->size)/nbthread ;\ else arg_th[i]->endRange = M->dim->size ;\ */if(littleEndian){\ arg_th[i]->MRank = M1->dim->size;\ }\ else{\ arg_th[i]->MRank = M0->dim->size;\ }\ pthread_create(&thrd[i], NULL, runProd_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ } \ \ struct arg_Pro2d_##type{\ type *M0x;\ type *M1x;\ type *Mx;\ size_t beginRange;\ size_t endRange;\ size_t M0Rank;\ size_t M1Rank;\ };\ void* runProd_thread2d_##type(void *arg){\ struct arg_Pro2d_##type *arg_t = arg;\ size_t k;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ for (size_t j = 0; j < arg_t->M1Rank; j++) {\ if(littleEndian){\ k = i * arg_t->M1Rank + j;\ }\ else{\ k =i + arg_t->M0Rank * j ;\ }\ arg_t->Mx[k] = arg_t->M0x[i] * arg_t->M1x[j];\ }\ }\ return 0;\ }\ \ void tensorProdThrea2d_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t nbthread) { \ dimension *dd; \ add_dimension(&dd, M0->dim, M1->dim); \ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd); \ tensor_##type *M = *MM; \ \ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_Pro2d_##type **arg_th = malloc( nbthread * sizeof(struct arg_Pro2d_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_Pro2d_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->Mx=M->x;\ arg_th[i]->beginRange = i*(M0->dim->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(M0->dim->size)/nbthread ;\ /*if(i < nbthread - 1 ) arg_th[i]->endRange = (i+1)*(M0->dim->size)/nbthread ;\ else arg_th[i]->endRange = M0->dim->size ;\ */arg_th[i]->M1Rank = M1->dim->size;\ arg_th[i]->M0Rank = M0->dim->size;\ pthread_create(&thrd[i], NULL, runProd_thread2d_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ } \ \ struct arg_ProdContract_##type{\ type *M0x;\ type *M1x;\ type *Mx;\ size_t beginRange;\ size_t endRange;\ size_t dSubRank;\ size_t dMRank;\ };\ void* runProdContract_thread_##type(void *arg){\ struct arg_ProdContract_##type *arg_t = arg;\ size_t a0_id, a1_id, n0_id, n1_id;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ if(littleEndian){\ a0_id=i/ arg_t->dSubRank;\ a1_id=i% arg_t->dSubRank;\ }\ else{\ a0_id=i% arg_t->dSubRank;\ a1_id=i/ arg_t->dSubRank;\ }\ arg_t->Mx[i] = 0;\ for (size_t k = 0; k < arg_t->dMRank; k++) {\ if(littleEndian){\ n0_id= a0_id * arg_t->dMRank + k;\ n1_id= a1_id + arg_t->dSubRank * k;\ }\ else{\ n0_id= a0_id + arg_t->dSubRank * k;\ n1_id= a1_id * arg_t->dMRank + k;\ }\ arg_t->Mx[i] += arg_t->M0x[n0_id] * arg_t->M1x[n1_id];\ }\ }\ return 0;\ }\ /* M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...=n-l alor p=n+m-2l\ M[x0,x1,x3..xl x{l+1}...xn] X M[xn,x{n-1},x{n-2}...xl y{l+1} ..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)\ M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]*/\ \ \ void tensorContractnProdThread_##type(tensor_##type** MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread) {\ if(checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)==0){\ printf("checkContractProdTensorDim %ld contractionNumber\n", contractionNumber);\ printDebug_dimension(M0->dim, "M0 dim");\ printDebug_dimension(M1->dim, "M1 dim");\ getchar();\ }\ size_t len0 = M0->dim->rank - contractionNumber;\ size_t len1 = M1->dim->rank - contractionNumber;\ \ size_t* tsub0 = malloc(sizeof(size_t) *len0);\ size_t* tsub1 = malloc(sizeof(size_t) *len1);\ size_t* tDk1 = malloc(sizeof(size_t) *contractionNumber);\ size_t* tDk0 = malloc(sizeof(size_t) *contractionNumber);\ subArray(tsub0, M0->dim->shape, 0, len0, 0);\ subArray(tsub1, M1->dim->shape, 0, len1, contractionNumber);\ subArray(tDk1, M1->dim->shape, 0, contractionNumber, 0);\ subArray(tDk0, M0->dim->shape, 0, contractionNumber, len0);\ dimension *dSub0 = init_dim(tsub0, len0);\ dimension *dSub1 = init_dim(tsub1, len1);\ dimension *dM1 = init_dim(tDk1, contractionNumber);\ dimension *dM0 = init_dim(tDk0, contractionNumber);\ dimension *dM;\ min_copy_dimension(&dM, dM0, dM1);\ \ dimension *dd;\ add_dimension(&dd, dSub0, dSub1);\ updateRankDim(dd);\ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd);\ tensor_##type *M= *MM;\ \ \ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_ProdContract_##type **arg_th = malloc( nbthread * sizeof(struct arg_ProdContract_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_ProdContract_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->Mx=M->x;\ arg_th[i]->beginRange = i*(M->dim->size)/nbthread ;\ if(i < nbthread - 1 ) arg_th[i]->endRange = (i+1)*(M->dim->size)/nbthread ;\ else arg_th[i]->endRange = M->dim->size ;\ if(littleEndian){\ arg_th[i]->dSubRank = dSub1->size;\ }\ else{\ arg_th[i]->dSubRank = dSub0->size;\ }\ arg_th[i]->dMRank = dM->size;\ pthread_create(&thrd[i], NULL, runProdContract_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ FREE_dM_S_ ; \ }\ \ \ void* runProdContractOpt0_thread_##type(void *arg){\ struct arg_ProdContract_##type *arg_t = arg;\ size_t a0_id, a1_id, n0_id, n1_id;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ if(littleEndian){\ a0_id=i/ arg_t->dSubRank;\ a1_id=i% arg_t->dSubRank;\ n0_id= a0_id * arg_t->dMRank ;\ n1_id= a1_id ;\ }\ else{\ a0_id=i% arg_t->dSubRank;\ a1_id=i/ arg_t->dSubRank;\ n0_id= a0_id ;\ n1_id= a1_id * arg_t->dMRank ;\ }\ arg_t->Mx[i] = 0;\ for (size_t k = 0; k < arg_t->dMRank; k++) {\ if(littleEndian){\ arg_t->Mx[i] += arg_t->M0x[n0_id++] * arg_t->M1x[n1_id];\ n1_id += arg_t->dSubRank ;\ }\ else{\ arg_t->Mx[i] += arg_t->M0x[n0_id] * arg_t->M1x[n1_id];\ n0_id += arg_t->dSubRank ;\ }\ }\ }\ return 0;\ }\ \ \ void tensorContractnProdThreadOpt0_##type(tensor_##type** MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread) {\ if(checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)==0){\ printf("checkContractProdTensorDim %ld contractionNumber\n", contractionNumber);\ printDebug_dimension(M0->dim, "M0 dim");\ printDebug_dimension(M1->dim, "M1 dim");\ getchar();\ }\ size_t len0 = M0->dim->rank - contractionNumber;\ size_t len1 = M1->dim->rank - contractionNumber;\ \ size_t* tsub0 = malloc(sizeof(size_t) *len0);\ size_t* tsub1 = malloc(sizeof(size_t) *len1);\ size_t* tDk1 = malloc(sizeof(size_t) *contractionNumber);\ size_t* tDk0 = malloc(sizeof(size_t) *contractionNumber);\ subArray(tsub0, M0->dim->shape, 0, len0, 0);\ subArray(tsub1, M1->dim->shape, 0, len1, contractionNumber);\ subArray(tDk1, M1->dim->shape, 0, contractionNumber, 0);\ subArray(tDk0, M0->dim->shape, 0, contractionNumber, len0);\ dimension *dSub0 = init_dim(tsub0, len0);\ dimension *dSub1 = init_dim(tsub1, len1);\ dimension *dM1 = init_dim(tDk1, contractionNumber);\ dimension *dM0 = init_dim(tDk0, contractionNumber);\ dimension *dM;\ min_copy_dimension(&dM, dM0, dM1);\ \ dimension *dd;\ add_dimension(&dd, dSub0, dSub1);\ updateRankDim(dd);\ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd);\ tensor_##type *M= *MM;\ \ \ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_ProdContract_##type **arg_th = malloc( nbthread * sizeof(struct arg_ProdContract_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_ProdContract_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->Mx=M->x;\ arg_th[i]->beginRange = i*(M->dim->size)/nbthread ;\ if(i < nbthread - 1 ) arg_th[i]->endRange = (i+1)*(M->dim->size)/nbthread ;\ else arg_th[i]->endRange = M->dim->size ;\ if(littleEndian){\ arg_th[i]->dSubRank = dSub1->size;\ }\ else{\ arg_th[i]->dSubRank = dSub0->size;\ }\ arg_th[i]->dMRank = dM->size;\ pthread_create(&thrd[i], NULL, runProdContractOpt0_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ FREE_dM_S_ ; \ }\ \ struct arg_Pro2dContract_##type{\ type *M0x;\ type *M1x;\ type *Mx;\ size_t beginRange;\ size_t endRange;\ size_t dMRank;\ size_t dSub0Rank;\ size_t dSub1Rank;\ };\ \ void* runPro2dContract_thread_##type(void *arg){\ struct arg_Pro2dContract_##type *arg_t = arg;\ size_t n0_id, n1_id, l;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ for (size_t j = 0; j < arg_t->dSub1Rank; j++) {\ if(littleEndian)\ l = j + arg_t->dSub1Rank * i;\ else\ l = j * arg_t->dSub0Rank + i;\ arg_t->Mx[l] = 0;\ for (size_t k = 0; k < arg_t->dMRank; k++) {\ if(littleEndian){\ n0_id= i * arg_t->dMRank + k;\ n1_id= j + arg_t->dSub1Rank * k;\ }\ else{\ n0_id= i + arg_t->dSub0Rank * k;\ n1_id= j * arg_t->dMRank + k;\ }\ arg_t->Mx[l] += arg_t->M0x[n0_id] * arg_t->M1x[n1_id];\ }\ }\ }\ return 0;\ }\ /* M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...=n-l alor p=n+m-2l\ M[x0,x1,x3..xl x{l+1}...xn] X M[xn,x{n-1},x{n-2}...xl y{l+1} ..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)\ M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]*/\ \ void tensorContractnPro2dThread_##type(tensor_##type** MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread) {\ /*if(checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)==0){\ printf("checkContractProdTensorDim %ld contractionNumber\n", contractionNumber);\ }*/\ if(checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)==0){\ printf("checkContractProdTensorDim %ld contractionNumber\n", contractionNumber);\ printDebug_dimension(M0->dim, "M0 dim");\ printDebug_dimension(M1->dim, "M1 dim");\ getchar();\ }\ \ size_t len0 = M0->dim->rank - contractionNumber;\ size_t len1 = M1->dim->rank - contractionNumber;\ \ size_t* tsub0 = malloc(sizeof(size_t) *len0);\ size_t* tsub1 = malloc(sizeof(size_t) *len1);\ size_t* tDk1 = malloc(sizeof(size_t) *contractionNumber);\ size_t* tDk0 = malloc(sizeof(size_t) *contractionNumber);\ subArray(tsub0, M0->dim->shape, 0, len0, 0);\ subArray(tsub1, M1->dim->shape, 0, len1, contractionNumber);\ subArray(tDk1, M1->dim->shape, 0, contractionNumber, 0);\ subArray(tDk0, M0->dim->shape, 0, contractionNumber, len0);\ dimension *dSub0 = init_dim(tsub0, len0);\ dimension *dSub1 = init_dim(tsub1, len1);\ dimension *dM1 = init_dim(tDk1, contractionNumber);\ dimension *dM0 = init_dim(tDk0, contractionNumber);\ dimension *dM;\ min_copy_dimension(&dM, dM0, dM1);\ \ dimension *dd;\ add_dimension(&dd, dSub0, dSub1);\ updateRankDim(dd);\ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd);\ tensor_##type *M= *MM;\ \ \ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_Pro2dContract_##type **arg_th = malloc( nbthread * sizeof(struct arg_Pro2dContract_##type *));\ \ for(size_t i = 0; i < nbthread; ++i) {\ arg_th[i] = malloc(sizeof(struct arg_Pro2dContract_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->Mx=M->x;\ arg_th[i]->beginRange = i*(dSub0->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(dSub0->size)/nbthread ;\ arg_th[i]->dSub1Rank = dSub1->size;\ arg_th[i]->dSub0Rank = dSub0->size;\ arg_th[i]->dMRank = dM->size;\ pthread_create(&thrd[i], NULL, runPro2dContract_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ FREE_dM_S_ ; \ }\ \ void* runPro2dContractOpt0_thread_##type(void *arg){\ struct arg_Pro2dContract_##type *arg_t = arg;\ size_t n0_id, n1_id, l;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ for (size_t j = 0; j < arg_t->dSub1Rank; j++) {\ if(littleEndian){\ l = j + arg_t->dSub1Rank * i;\ n0_id= i * arg_t->dMRank ;\ n1_id= j ;\ }else{\ l = j * arg_t->dSub0Rank + i;\ n0_id= i ;\ n1_id= j * arg_t->dMRank ;\ }\ arg_t->Mx[l] = 0;\ for (size_t k = 0; k < arg_t->dMRank; k++) {\ if(littleEndian){\ /*n0_id= i * arg_t->dMRank + k;\ n1_id= j + arg_t->dSub1Rank * k;*/\ arg_t->Mx[l] += arg_t->M0x[n0_id++] * arg_t->M1x[n1_id];\ n1_id += arg_t->dSub1Rank ;\ }\ else{\ /*n0_id= i + arg_t->dSub0Rank * k;\ n1_id= j * arg_t->dMRank + k;*/\ arg_t->Mx[l] += arg_t->M0x[n0_id] * arg_t->M1x[n1_id];\ n0_id += arg_t->dSub0Rank ;\ }\ }\ }\ }\ return 0;\ }\ /* M[x0,x1,x3..xn] X M[y0,y1,y3..ym] = M[z0,z1...zp] (deep = l > 0) /exists 1<= l<...=n-l alor p=n+m-2l\ M[x0,x1,x3..xl x{l+1}...xn] X M[xn,x{n-1},x{n-2}...xl y{l+1} ..ym] = M[x0,x1..xly{l+1}...y{n+m-2l}] (deep = l > 0)\ M[[i][j]]=sum_{[k]}M0[[i][k]]*M[[k][j]]*/\ \ void tensorContractnPro2dThreadOpt0_##type(tensor_##type** MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread) {\ /*if(checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)==0){\ printf("checkContractProdTensorDim %ld contractionNumber\n", contractionNumber);\ }*/\ if(checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)==0){\ printf("checkContractProdTensorDim %ld contractionNumber\n", contractionNumber);\ printDebug_dimension(M0->dim, "M0 dim");\ printDebug_dimension(M1->dim, "M1 dim");\ getchar();\ }\ \ size_t len0 = M0->dim->rank - contractionNumber;\ size_t len1 = M1->dim->rank - contractionNumber;\ \ size_t* tsub0 = malloc(sizeof(size_t) *len0);\ size_t* tsub1 = malloc(sizeof(size_t) *len1);\ size_t* tDk1 = malloc(sizeof(size_t) *contractionNumber);\ size_t* tDk0 = malloc(sizeof(size_t) *contractionNumber);\ subArray(tsub0, M0->dim->shape, 0, len0, 0);\ subArray(tsub1, M1->dim->shape, 0, len1, contractionNumber);\ subArray(tDk1, M1->dim->shape, 0, contractionNumber, 0);\ subArray(tDk0, M0->dim->shape, 0, contractionNumber, len0);\ dimension *dSub0 = init_dim(tsub0, len0);\ dimension *dSub1 = init_dim(tsub1, len1);\ dimension *dM1 = init_dim(tDk1, contractionNumber);\ dimension *dM0 = init_dim(tDk0, contractionNumber);\ dimension *dM;\ min_copy_dimension(&dM, dM0, dM1);\ \ dimension *dd;\ add_dimension(&dd, dSub0, dSub1);\ updateRankDim(dd);\ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd);\ tensor_##type *M= *MM;\ \ \ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_Pro2dContract_##type **arg_th = malloc( nbthread * sizeof(struct arg_Pro2dContract_##type *));\ \ for(size_t i = 0; i < nbthread; ++i) {\ arg_th[i] = malloc(sizeof(struct arg_Pro2dContract_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->Mx=M->x;\ arg_th[i]->beginRange = i*(dSub0->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(dSub0->size)/nbthread ;\ arg_th[i]->dSub1Rank = dSub1->size;\ arg_th[i]->dSub0Rank = dSub0->size;\ arg_th[i]->dMRank = dM->size;\ pthread_create(&thrd[i], NULL, runPro2dContractOpt0_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ FREE_dM_S_ ; \ }\ void tensorContractnProdNotOpt_##type(tensor_##type** MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber) {\ if (!checkContractProdTensorDim(M0->dim, M1->dim, contractionNumber)) {\ printf("error Deep = %ld\n", contractionNumber);\ printDebug_dimension(M0->dim, "M0 dim");\ printDebug_dimension(M1->dim, "M1 dim");\ getchar();\ }\ size_t len0 = M0->dim->rank - contractionNumber;\ size_t len1 = M1->dim->rank - contractionNumber;\ \ size_t* tsub0 = malloc(sizeof(size_t) *len0);\ size_t* tsub1 = malloc(sizeof(size_t) *len1);\ size_t* tDk1 = malloc(sizeof(size_t) *contractionNumber);\ size_t* tDk0 = malloc(sizeof(size_t) *contractionNumber);\ subArray(tsub0, M0->dim->shape, 0, len0, 0);\ subArray(tsub1, M1->dim->shape, 0, len1, contractionNumber);\ subArray(tDk1, M1->dim->shape, 0, contractionNumber, 0);\ subArray(tDk0, M0->dim->shape, 0, contractionNumber, len0);\ /*printArraySzt(tsub0,len0,"tsub0");\ printArraySzt(tsub1,len1,"tsub1");\ printArraySzt(tDk0,contractionNumber,"tDk0");\ printArraySzt(tDk1,contractionNumber,"tDk1");*/\ dimension *dSub0 = init_dim(tsub0, len0);\ dimension *dSub1 = init_dim(tsub1, len1);\ dimension *dM1 = init_dim(tDk1, contractionNumber);\ dimension *dM0 = init_dim(tDk0, contractionNumber);\ /*printDebug_dimension(dSub0,"dSub0");\ printDebug_dimension(dSub1,"dSub1");\ printDebug_dimension(dM0,"dM0");\ printDebug_dimension(dM1,"dM1");*/\ dimension *dM;\ min_copy_dimension(&dM, dM0, dM1);\ /*printDebug_dimension(dM,"dM");*/\ \ dimension *dd;\ add_dimension(&dd, dSub0, dSub1);\ /*printDebug_dimension(dd,"dd");*/\ updateRankDim(dd);\ _recreate_tensor_if_not_the_same_dim_or_null_##type(MM,dd);\ tensor_##type *M= *MM;\ \ size_t* coord;\ coord = malloc(sizeof(size_t)* M->dim->rank);\ \ size_t* coord0 , lin0;\ coord0 = malloc(sizeof(size_t)* len0);\ size_t* coord1, lin1;\ coord1 = malloc(sizeof(size_t)* len1);\ \ size_t* coordM0 ;\ coordM0 = malloc(sizeof(size_t)* M0->dim->rank);\ size_t* coordM1 ;\ coordM1 = malloc(sizeof(size_t)* M1->dim->rank);\ \ size_t* Koord ;\ Koord = malloc(sizeof(size_t)* contractionNumber);\ \ for (size_t i = 0; i < M->dim->size; i++) {\ vCoordFromLin(coord, i, M->dim);\ subArray(coord0, coord, 0, len0, 0);\ subArray(coord1, coord, 0, len1, len0);\ M->x[i] = 0;\ for (size_t k = 0; k < dM->size; k++) {\ vCoordFromLin(Koord, k, dM);\ concatArray(coordM0, coord0, Koord, 0, 0, len0, 0, contractionNumber);\ concatArray(coordM1, Koord, coord1, 0, 0, contractionNumber, 0, len1);\ lin0 = LineFromCoord(coordM0, M0->dim);\ lin1 = LineFromCoord(coordM1, M1->dim);\ M->x[i] += M0->x[lin0] * M1->x[lin1];\ /*printf("M[%ld]:%f += M0[%ld]:%f * M1[%ld]:%f | ",i,M->x[i],lin0,M0->x[lin0],lin1,M1->x[lin1]);*/\ /*printf("k:%ld |i:%ld |lin0:%ld | lin1:%ld | ",k,i,lin0,lin1);*/\ }\ /*printf("\n");*/\ }\ FREE_COORD_ ; \ free(coordM0);\ free(coordM1);\ free(Koord); \ FREE_dM_S_ ; \ }\ \ /* dot product = of 2 tensors same dimensions M0, M1, dim0, dim1 == contract (dim0 rank) product of M0' M1' of dim0' and dim1' / dim0->shape = [1, dim0-> shape] and dim1'->shape = [dim1->shape, 1] */ \ type scalarProduct_dep_contractProd_##type(tensor_##type *M0, tensor_##type *M1, size_t nbthreads ,void (*tensorContractVar)(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread )){\ type ret = 0;\ if(is_equal_dim(M0->dim, M1->dim)){/* */\ dimension * d0 = create_dim(M0->dim->rank + 1);\ dimension * d1 = create_dim(M1->dim->rank + 1);\ size_t i;\ d0->shape[0] = 1;\ for(i=0; idim->rank; ++i) d0->shape[i+1] = M0->dim->shape[i];\ for(i=0; idim->rank; ++i) d1->shape[i] = M1->dim->shape[i];\ d1->shape[i] = 1;\ tensor_##type *M_0=create_tensor_##type(d0);\ tensor_##type *M_1=create_tensor_##type(d1);\ copy_tensor_##type(M_0,M0);\ copy_tensor_##type(M_1,M1);\ tensor_##type *M_=NULL;\ tensorContractVar(&M_,M_0,M_1,M0->dim->rank,nbthreads);\ ret = M_->x[0];\ free_tensor_##type(M_0);\ free_tensor_##type(M_1);\ free_tensor_##type(M_);\ }\ return ret;\ }\ \ type scalarProduct_0_##type(tensor_##type *M0, tensor_##type *M1){\ return scalarProduct_dep_contractProd_##type(M0,M1,4,tensorContractnProdThread_##type);\ \ }\ \ /*format_file: [dim]((x,x,a)(a,x,a)) | example:[2,3,4](((a0,b0,c0,d0)(a1,b1,c1,d1)(a2,b2,c2,d2))((e0,f0,g0,h0)(e1,f1,g1,h1)(e2,f2,g2,h2)))*/\ tensor_##type * parseInput_withDim_to_tensor_##type(char *input){\ tensor_##type *tens ;\ size_t len = strlen(input);\ list_shape_in_dim *l_p=NULL;\ size_t ss;\ char *ttmp=input;\ char *ppEnd="[";\ bool unknown_shape=false; \ for(size_t i=0; isize){\ x = strto_##type(ttmp, &ppEnd);\ while(ttmp == ppEnd && ppEnd[0] !='\0'){\ ttmp++;\ x = strto_##type(ttmp, &ppEnd);\ }\ if(ppEnd[0]!='\0')\ (tens)->x[i] = x;\ /*printf("d: %lf\n",d);*/\ ttmp=ppEnd;\ ++i;\ }\ }\ else{\ array_chainlist_##type *l_a=NULL;\ type x;\ while(ppEnd && (ppEnd[0] !='\0')){\ x = strto_##type(ttmp, &ppEnd);\ while(ttmp == ppEnd && ppEnd[0] !='\0'){\ ttmp++;\ x = strto_##type(ttmp, &ppEnd);\ }\ /*if(ppEnd[0]!='\0')*/ \ if(ppEnd != ttmp)\ append_array_chainlist_##type(&l_a, x);\ /*printf("-- x: %f\n",x);*/\ ttmp=ppEnd;\ }\ \ tens = create_tensor_from_list_array_##type(l_a,dim);\ free_dimension(dim);\ free_array_chainlist_##type(l_a);\ }\ free_list_shape_in_dim(l_p);\ return tens;\ }\ \ \ /*format_file: [*,dim1,dim2]((x,x,a)(x,a))... | example:[2,(2,3),4](((a0,b0,c0,)((a1,b1,c1))((a2,b2,c2,d2))((e0,f0,g0)(e1,f1,g1)(e2,f2,g2,h2))) ==[2,2,3][2,4]*/\ void parseInputOutput_withDim_to_tensors_##type(tensor_##type **Tpart1, tensor_##type **Tpart2, char *input, size_t pivotSplit){\ /*tensor_##type *tens ;*/\ size_t len = strlen(input);\ list_shape_in_dim *l_p=NULL;\ size_t ss;\ char *ttmp=input;\ char *ppEnd="[";\ bool unknown_shape=false; \ for(size_t i=0; irank-1);\ dimension *ddim1 = create_dim(dim->rank-2);\ dimension *ddim2 = create_dim(dim->rank-2);\ dimension *dim2 = create_dim(2);\ */dimension *dim1 = create_dim(dim->rank-pivotSplit);\ dimension *ddim1 = create_dim(dim->rank-pivotSplit-1);\ dimension *ddim2 = create_dim(pivotSplit);\ dimension *dim2 = create_dim(pivotSplit+1);\ for(size_t i=0;irank;++i) dim1->shape[i] = dim->shape[i];\ for(size_t i=0;irank;++i) ddim1->shape[i] = dim->shape[i+1];\ for(size_t i=0;irank;++i) ddim2->shape[i] = dim->shape[ dim->rank - pivotSplit + i];\ dim2->shape[0] = dim->shape[0];\ for(size_t i=1;irank;++i) dim2->shape[i] = ddim2->shape[i-1];\ /*dim2->shape[1] = dim->shape[dim->rank - 1];*/\ updateRankDim(dim1);\ updateRankDim(ddim1);\ updateRankDim(ddim2);\ updateRankDim(dim2);\ *Tpart1 = create_tensor_##type(dim1);\ *Tpart2 = create_tensor_##type(dim2);\ \ size_t i1=0,i=0,j=0,i2=0;\ bool filled1=false,filled2=false;\ type x;\ while(ppEnd && (ppEnd[0] !='\0') && jsize){\ x = strto_##type(ttmp, &ppEnd);\ while(ttmp == ppEnd && ppEnd[0] !='\0'){\ ttmp++;\ x = strto_##type(ttmp, &ppEnd);\ }\ if(ppEnd[0]!='\0'){\ if(!filled1){\ ++i1;\ (*Tpart1)->x[i++] = x;\ /*printf("++ x: %f, i1:%ld , rkn1: %ld\n",x,i1,ddim1->size);\ */if(i1 == ddim1->size){\ filled1=true;\ i1=0;\ filled2=false;\ }\ }else{\ if(!filled2){\ ++i2;\ (*Tpart2)->x[j++] = x;\ /*printf("-----++ x: %f, i2:%ld , rknr: %ld\n",x,i2,ddim2->size);\ */if(i2 == ddim2->size){\ filled2=true;\ i2=0;\ filled1=false;\ }\ }\ \ }\ /*printf("d: %lf\n",d);*/\ }\ ttmp=ppEnd;\ }\ free_dimension(ddim1);\ free_dimension(ddim2);\ }\ else{\ /*dimension *ddim1 = create_dim(dim->rank-1);\ dimension *ddim2 = create_dim(1);\ for(size_t i=0;irank;++i) ddim1->shape[i] = dim->shape[i];\ ddim2->shape[0] = dim->shape[dim->rank - 1];\ */dimension *ddim1 = create_dim(dim->rank-pivotSplit);\ dimension *ddim2 = create_dim(pivotSplit);\ for(size_t i=0;irank;++i) ddim1->shape[i] = dim->shape[i];\ for(size_t i=0;irank;++i) ddim2->shape[i] = dim->shape[dim->rank - pivotSplit + i];\ updateRankDim(ddim1);\ updateRankDim(ddim2);\ array_chainlist_##type *l_a1=NULL;\ array_chainlist_##type *l_a2=NULL;\ size_t i1=0, /*i=0,j=0, */ i2=0;\ bool filled1=false,filled2=false;\ type x;\ while(ppEnd && (ppEnd[0] !='\0')){\ x = strto_##type(ttmp, &ppEnd);\ while(ttmp == ppEnd && ppEnd[0] !='\0'){\ ttmp++;\ x = strto_##type(ttmp, &ppEnd);\ }\ /*if(ppEnd[0]!='\0')*/ \ if(ppEnd != ttmp){\ if(!filled1){\ ++i1;\ append_array_chainlist_##type(&l_a1, x);\ /*printf("++ x: %f, i1:%ld\n",x,i1);*/\ /*(*Tpart1)->x[i++] = x;*/\ if(i1 == ddim1->size){\ filled1=true;\ i1=0;\ filled2=false;\ }\ }else{\ if(!filled2){\ ++i2;\ /*(*Tpart2)->x[j++] = x;*/\ append_array_chainlist_##type(&l_a2, x);\ /*printf("++ x: %f, i2:%ld\n",x,i2);*/\ if(i2 == ddim2->size){\ filled2 = true;\ i2=0;\ filled1 = false;\ }\ }\ \ }\ /*printf("d: %lf\n",d);*/\ }\ /*printf("-- x: %f\n",x);*/\ ttmp=ppEnd;\ }\ \ *Tpart1 = create_tensor_from_list_array_##type(l_a1,ddim1);\ *Tpart2 = create_tensor_from_list_array_##type(l_a2,ddim2);\ free_array_chainlist_##type(l_a1);\ free_array_chainlist_##type(l_a2);\ free_dimension(ddim1);\ free_dimension(ddim2);\ }\ free_dimension(dim);\ free_list_shape_in_dim(l_p);\ }\ \ \ /*format_file: [*,dim1,dim2]((x,x,a)(x,a))... | example:[2,(2,3),4](((a0,b0,c0,)((a1,b1,c1))((a2,b2,c2,d2))((e0,f0,g0)(e1,f1,g1)(e2,f2,g2,h2))) == with pivot 1 => [2,2,3][2,4]*/\ void parse_file_InputOutput_withDim_to_tensors_##type(tensor_##type **Tpart1, tensor_##type **Tpart2, char *file_name_input, size_t pivotSplit){\ size_t block_size=2;\ size_t block_count=4;\ char *input=malloc(block_size*block_count + 1);\ char *iinput=malloc(block_size*block_count + 256);\ FILE *f_input;\ f_input=fopen(file_name_input,"r");\ if ( f_input == NULL ) {\ fprintf( stderr, "Cannot open file: %s for reading\n",file_name_input );\ exit( -1 );\ }\ bool unknown_shape=false, broken=false; \ bool Done=false;\ int retfread = 0, curIn=0;\ while(!Done){\ retfread = fread(input, block_size, block_count, f_input) ;\ Done = (retfread != block_count);\ /*input[retfread*block_size]='\0';\ */for(curIn=0; curIn='0') && (iinput[curIn-1] <='9'))||(iinput[curIn-1] =='.')||(iinput[curIn-1] =='E')||(iinput[curIn-1] =='e'))){\ retfread = fread(input, 1, 1, f_input) ;\ Done = (retfread != 1);\ iinput[curIn++]=input[0];\ }\ iinput[curIn]='\0';\ size_t len = strlen(iinput);\ for(size_t i=0; i='0') && (iinput[curIn-1] <='9'))||(iinput[curIn-1] =='.')||(iinput[curIn-1] =='E')||(iinput[curIn-1] =='e'))){\ retfread = fread(input, 1, 1, f_input) ;\ Done = (retfread != 1);\ iinput[curIn++] = *input;\ }\ iinput[curIn]='\0';\ ttmp=iinput;\ if( !bracketsDown){\ while(strlen(ttmp) && strlen(ppEnd) && (*ppEnd !=']') ){\ ss = strtoul(ttmp, &ppEnd, 10);\ while(ttmp == ppEnd && ppEnd[0] !=']'){\ ttmp++;\ ss = strtoul(ttmp, &ppEnd, 10);\ }\ if(ppEnd !=ttmp )\ append_in_list_shape(&l_p,ss);\ ttmp=ppEnd;\ }\ if( *ppEnd ==']'){\ dim=create_dim_from_list_shape(l_p);\ bracketsDown = true;\ ttmp++; ppEnd++;\ }\ \ }\ if(bracketsDown){\ \ if(unknown_shape == false){\ \ if(!initDim){\ dim1 = create_dim(dim->rank-pivotSplit);\ ddim1 = create_dim(dim->rank-pivotSplit-1);\ ddim2 = create_dim(pivotSplit);\ dim2 = create_dim(pivotSplit+1);\ for(size_t i=0;irank;++i) dim1->shape[i] = dim->shape[i];\ for(size_t i=0;irank;++i) ddim1->shape[i] = dim->shape[i+1];\ for(size_t i=0;irank;++i) ddim2->shape[i] = dim->shape[ dim->rank - pivotSplit + i];\ dim2->shape[0] = dim->shape[0];\ for(size_t i=1;irank;++i) dim2->shape[i] = ddim2->shape[i-1];\ updateRankDim(dim1);\ updateRankDim(ddim1);\ updateRankDim(ddim2);\ updateRankDim(dim2);\ *Tpart1 = create_tensor_##type(dim1);\ *Tpart2 = create_tensor_##type(dim2);\ initDim=true;\ }\ \ type x;\ while(strlen(ttmp) && jsize){ \ x = strto_##type(ttmp, &ppEnd);\ while(ttmp == ppEnd && strlen(ttmp)){\ ttmp++;\ x = strto_##type(ttmp, &ppEnd);\ }\ if(ttmp != ppEnd){\ if(!filled1){\ ++i1;\ (*Tpart1)->x[i++] = x;\ if(i1 == ddim1->size){\ filled1=true;\ i1=0;\ filled2=false;\ }\ }else{\ if(!filled2){\ ++i2;\ (*Tpart2)->x[j++] = x;\ if(i2 == ddim2->size){\ filled2=true;\ i2=0;\ filled1=false;\ }\ }\ \ }\ }\ ttmp=ppEnd;\ }\ if(Done){\ free_dimension(ddim1);\ free_dimension(ddim2);\ }\ }\ else{\ \ if(!initDim){\ ddim1 = create_dim(dim->rank-pivotSplit);\ ddim2 = create_dim(pivotSplit);\ for(size_t i=0;irank;++i) ddim1->shape[i] = dim->shape[i];\ for(size_t i=0;irank;++i) ddim2->shape[i] = dim->shape[dim->rank - pivotSplit + i];\ updateRankDim(ddim1);\ updateRankDim(ddim2);\ initDim=true;\ }\ type x= 0;\ while(ttmp && strlen(ttmp) ){ \ x = strto_##type(ttmp, &ppEnd);\ while(ttmp == ppEnd && strlen(ttmp)){\ ttmp++;\ x = strto_##type(ttmp, &ppEnd);\ }\ if(ppEnd != ttmp){\ if(!filled1){\ ++i1;\ append_array_chainlist_##type(&l_a1, x);\ if(i1 == ddim1->size){\ filled1=true;\ i1=0;\ filled2=false;\ }\ }else{\ if(!filled2){\ ++i2;\ append_array_chainlist_##type(&l_a2, x);\ if(i2 == ddim2->size){\ filled2 = true;\ i2=0;\ filled1 = false;\ }\ }\ \ }\ }\ ttmp=ppEnd;\ }\ \ if(Done){\ *Tpart1 = create_tensor_from_list_array_##type(l_a1,ddim1);\ *Tpart2 = create_tensor_from_list_array_##type(l_a2,ddim2);\ free_array_chainlist_##type(l_a1);\ free_array_chainlist_##type(l_a2);\ free_dimension(ddim1);\ free_dimension(ddim2);\ \ }\ }\ }\ }\ free_dimension(dim);\ free_list_shape_in_dim(l_p);\ free(input);\ free(iinput);\ fclose(f_input);\ }\ \ tensor_##type ** fromInput_to_array_tensor_##type(tensor_##type *tens){\ tensor_##type **re_tens=malloc((tens->dim)->shape[0]*sizeof(tensor_##type *));\ dimension *dim=create_dim((tens->dim)->rank - 1);\ for(size_t i=0; irank; ++i) dim->shape[i]=(tens->dim)->shape[i+1];\ updateRankDim(dim);\ for(size_t i=0; i < (tens->dim)->shape[0];++i){\ re_tens[i]=create_tensor_from_cpy_dim_##type(dim);\ for(size_t j=0; jsize; ++j) (re_tens[i])->x[j] = tens->x[i*(dim->size) + j ] ;\ }\ free_dimension(dim);\ return re_tens;\ }\ \ void append_array_chainlist_##type(array_chainlist_##type **list_a, type x){\ array_chainlist_##type *lis=malloc(sizeof(array_chainlist_##type));\ lis->x=x;\ lis->next=NULL;\ if(*list_a == NULL){\ lis->index=0;\ *list_a = lis;\ }\ else{\ array_chainlist_##type *tmp =*list_a;\ while(tmp->next) tmp=tmp->next;\ lis->index = tmp->index +1;\ tmp->next=lis;\ }\ }\ \ tensor_##type * create_tensor_from_list_array_##type( array_chainlist_##type *l_a, dimension *part_dim){\ if(l_a){\ array_chainlist_##type *tmp =l_a;\ while(tmp->next) tmp=tmp->next;\ size_t miss_part_d=(tmp->index + 1)/part_dim->size;\ dimension *dim=create_dim(part_dim->rank + 1);\ if(littleEndian){\ dim->shape[0]=miss_part_d;\ for(size_t i=0; irank;++i) dim->shape[i+1]=part_dim->shape[i];\ }else{\ size_t i=0;\ for(i=0; irank;++i) dim->shape[i]=part_dim->shape[i];\ dim->shape[i]=miss_part_d;\ \ }\ updateRankDim(dim);\ tensor_##type *tens= create_tensor_##type(dim);\ tmp=l_a;\ while(tmp){\ (tens)->x[tmp->index]=tmp->x;\ tmp=tmp->next;\ }\ return tens;\ }\ return NULL;\ }\ \ void free_array_chainlist_##type(array_chainlist_##type *l_a){\ array_chainlist_##type *tmp=l_a, *ttmp;\ while(tmp){\ ttmp = tmp;\ tmp = ttmp->next;\ free(ttmp);\ }\ }\ \ tensor_##type * transpose_notOpt_tensor_##type(tensor_##type *org){\ size_t dimrnk = (org->dim)->rank; \ dimension *dim_tr=create_dim(dimrnk);\ for(size_t i=0; ishape[i]=(org->dim)->shape[(dimrnk-1)-i];\ updateRankDim(dim_tr);\ printDebug_dimension(dim_tr,"dim_tr");\ tensor_##type *tens_tr = create_tensor_##type(dim_tr);\ size_t *coord = malloc((dimrnk)*sizeof(size_t));\ size_t *coord_tr = malloc((dimrnk)*sizeof(size_t));\ for(size_t i=0; isize; ++i){\ vCoordFromLin(coord,i,org->dim);\ for(size_t j=0; jx[LineFromCoord(coord_tr, dim_tr)] = org->x[i];\ }\ free(coord);\ free(coord_tr);\ return tens_tr;\ }\ \ tensor_##type * shapeute_notOpt_tensor_##type(tensor_##type *org, dimension *dshape){\ size_t dimrnk = (org->dim)->rank; \ dimension *dim_tr=create_dim(dimrnk);\ for(size_t i=0; ishape[i]=(org->dim)->shape[(dimrnk-1)-i];\ updateRankDim(dim_tr);\ printDebug_dimension(dim_tr,"dim_tr");\ tensor_##type *tens_tr = create_tensor_##type(dim_tr);\ size_t *coord = malloc((dimrnk)*sizeof(size_t));\ size_t *coord_tr = malloc((dimrnk)*sizeof(size_t));\ for(size_t i=0; isize; ++i){\ vCoordFromLin(coord,i,org->dim);\ for(size_t j=0; jshape[j]]; \ tens_tr->x[LineFromCoord(coord_tr, dim_tr)] = org->x[i];\ }\ free(coord);\ free(coord_tr);\ return tens_tr;\ }\ struct arg_1Update_##type{\ type *M0x;\ size_t beginRange;\ size_t endRange;\ type (*func)(type);\ };\ void* run1UpdatCalcfunc_thread_##type(void *arg){\ struct arg_1Update_##type *arg_t = arg;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ arg_t->M0x[i] = arg_t->func(arg_t->M0x[i]);\ }\ return 0;\ }\ \ void update_1tensor_func_##type(tensor_##type *M0, type (*func)(type), size_t nbthread){\ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_1Update_##type **arg_th = malloc( nbthread * sizeof(struct arg_1Update_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_1Update_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->func=func;\ arg_th[i]->beginRange = i*(M0->dim->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(M0->dim->size)/nbthread ;\ \ pthread_create(&thrd[i], NULL, run1UpdatCalcfunc_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ } \ \ struct arg_2Update_##type{\ type *M0x;\ type *M1x;\ size_t beginRange;\ size_t endRange;\ type (*func)(type);\ };\ void* run2UpdatCalcfunc_thread_##type(void *arg){\ struct arg_2Update_##type *arg_t = arg;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ arg_t->M0x[i] = arg_t->func(arg_t->M1x[i]);\ }\ return 0;\ }\ \ void update_2tensor_func_##type(tensor_##type *M0, tensor_##type *M1, type (*func)(type), size_t nbthread){\ if ( is_equal_dim(M0->dim,M1->dim)){ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_2Update_##type **arg_th = malloc( nbthread * sizeof(struct arg_2Update_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_2Update_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->func=func;\ arg_th[i]->beginRange = i*(M0->dim->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(M0->dim->size)/nbthread ;\ \ pthread_create(&thrd[i], NULL, run2UpdatCalcfunc_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ }\ } \ \ struct arg_3Update_##type{\ type *M0x;\ type *M1x;\ type *M2x;\ size_t beginRange;\ size_t endRange;\ type (*func)(type, type);\ };\ void* run3UpdatCalcfunc_thread_##type(void *arg){\ struct arg_3Update_##type *arg_t = arg;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ arg_t->M0x[i] = arg_t->func(arg_t->M1x[i], arg_t->M2x[i]);\ }\ return 0;\ }\ \ void update_3tensor_func_##type(tensor_##type *M0, tensor_##type *M1, tensor_##type *M2, type (*func)(type,type), size_t nbthread){\ if ( is_equal_dim(M0->dim,M1->dim) && (is_equal_dim(M0->dim, M2->dim))){ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_3Update_##type **arg_th = malloc( nbthread * sizeof(struct arg_3Update_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_3Update_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->M2x=M2->x;\ arg_th[i]->func=func;\ arg_th[i]->beginRange = i*(M0->dim->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(M0->dim->size)/nbthread ;\ \ pthread_create(&thrd[i], NULL, run3UpdatCalcfunc_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ }\ } \ \ \ struct arg_4Update_##type{\ type *M0x;\ type *M1x;\ type *M2x;\ size_t beginRange;\ size_t endRange;\ type (*func)(type, type, type(*f1)(type));\ type(*f1)(type);\ };\ void* run4UpdatCalcfunc_thread_##type(void *arg){\ struct arg_4Update_##type *arg_t = arg;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ arg_t->M0x[i] = arg_t->func(arg_t->M1x[i], arg_t->M2x[i], arg_t->f1);\ }\ return 0;\ }\ \ void update_4tensor_func_##type(tensor_##type *M0, tensor_##type *M1, tensor_##type *M2, \ type (*func)(type, type, type(*f1)(type)),\ type(*f1)(type),\ size_t nbthread){\ /*printf(" sizeM0=%ld , size M2:%ld ; iseq :%d \n",(M0->dim)->size,(M2->dim)->size,is_equal_dim(M0->dim,M2->dim) );\ */\ /* printDebug_dimension(M0->dim," dim M0 in update4 "); \ printDebug_dimension(M2->dim," dim M2 in update4 "); \ */if ( is_equal_dim(M0->dim, M1->dim) /*&& (is_equal_dim(M0->dim, M2->dim))*/){ \ /*printDebug_dimension(M0->dim," dim M0 in update4 "); \ */pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_4Update_##type **arg_th = malloc( nbthread * sizeof(struct arg_4Update_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_4Update_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->M2x=M2->x;\ arg_th[i]->func=func;\ arg_th[i]->f1=f1;\ arg_th[i]->beginRange = i*(M0->dim->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(M0->dim->size)/nbthread ;\ \ pthread_create(&thrd[i], NULL, run4UpdatCalcfunc_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ }\ } \ \ struct arg_5Update_##type{\ type *M0x;\ type *M1x;\ type *M2x;\ type *M3x;\ size_t beginRange;\ size_t endRange;\ type (*func)(type, type, type, type(*f1)(type), type (*f2)(type,type) );\ type(*f1)(type);\ type (*f2)(type,type);\ };\ void* run5UpdatCalcfunc_thread_##type(void *arg){\ struct arg_5Update_##type *arg_t = arg;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ arg_t->M0x[i] = arg_t->func(arg_t->M1x[i], arg_t->M2x[i], arg_t->M3x[i], arg_t->f1, arg_t->f2);\ }\ return 0;\ }\ \ void update_5tensor_func_##type(tensor_##type *M0, tensor_##type *M1, tensor_##type *M2, tensor_##type *M3 , \ type (*func) (type, type, type, type(*f1)(type), type (*f2)(type,type)), \ type(*f1)(type), \ type (*f2)(type,type), \ size_t nbthread){\ if ( is_equal_dim(M0->dim,M1->dim) && (is_equal_dim(M0->dim, M2->dim))&& (is_equal_dim(M0->dim, M3->dim))){ \ pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_5Update_##type **arg_th = malloc( nbthread * sizeof(struct arg_5Update_##type *));\ /*printDebug_dimension(M0->dim," dim M0 in update5 "); */ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_5Update_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->M2x=M2->x;\ arg_th[i]->M3x=M3->x;\ arg_th[i]->func=func;\ arg_th[i]->f1=f1;\ arg_th[i]->f2=f2;\ arg_th[i]->beginRange = i*(M0->dim->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(M0->dim->size)/nbthread ;\ \ pthread_create(&thrd[i], NULL, run5UpdatCalcfunc_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ }\ } \ \ \ struct arg_6Update_##type{\ type *M0x;\ type *M1x;\ size_t beginRange;\ size_t endRange;\ type (*func)(type, type, type);\ type scalar;\ };\ void* run6UpdatCalcfunc_thread_##type(void *arg){\ struct arg_6Update_##type *arg_t = arg;\ for (size_t i = arg_t->beginRange; i < arg_t->endRange; i++) {\ arg_t->M0x[i] = arg_t->func(arg_t->M0x[i], arg_t->M1x[i], arg_t->scalar);\ }\ return 0;\ }\ \ void update_6tensor_func_##type(tensor_##type *M0, tensor_##type *M1, \ type (*func)(type, type, type),\ type scalar,\ size_t nbthread){\ /*printf(" sizeM0=%ld , size M2:%ld ; iseq :%d \n",(M0->dim)->size,(M2->dim)->size,is_equal_dim(M0->dim,M2->dim) );\ */\ /* printDebug_dimension(M0->dim," dim M0 in update6 "); \ printDebug_dimension(M2->dim," dim M2 in update6 "); \ */if ( is_equal_dim(M0->dim, M1->dim) /*&& (is_equal_dim(M0->dim, M2->dim))*/){ \ /*printDebug_dimension(M0->dim," dim M0 in update6 "); \ */pthread_t *thrd = malloc(nbthread * sizeof(pthread_t));\ struct arg_6Update_##type **arg_th = malloc( nbthread * sizeof(struct arg_6Update_##type *));\ \ for(size_t i = 0; i < nbthread; ++i){\ arg_th[i]=malloc(sizeof(struct arg_6Update_##type));\ arg_th[i]->M0x=M0->x;\ arg_th[i]->M1x=M1->x;\ arg_th[i]->func=func;\ arg_th[i]->scalar=scalar;\ arg_th[i]->beginRange = i*(M0->dim->size)/nbthread ;\ arg_th[i]->endRange = (i+1)*(M0->dim->size)/nbthread ;\ \ pthread_create(&thrd[i], NULL, run6UpdatCalcfunc_thread_##type, (void*)arg_th[i]);\ }\ \ for(size_t i=0; i< nbthread; ++i){\ pthread_join(thrd[i], NULL);\ free(arg_th[i]);\ }\ \ free(thrd);\ free(arg_th);\ }\ } \ \ //#ifdef IMPLEMENTATION_TENSOR #define IMPLEMENTATION_TENSOR()\ \ /*IMPLEMENTATION_DIMENSION()*/\ \ \ GEN_FUNC_TENSOR(TYPE_FLOAT);\ GEN_FUNC_TENSOR(TYPE_DOUBLE);\ GEN_FUNC_TENSOR(TYPE_L_DOUBLE);\ //#endif /* IMPLEMENTATION_TENSOR */