Files
onefileheader_tensor/onetensor/y_tensor_h.h
T

3179 lines
105 KiB
C

#ifndef __TOOLS_T_C_H__
#define __TOOLS_T_C_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <sys/ioctl.h>
/* 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, size, function)\
for(size_t _ind = 0; _ind < 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 size);\
type MAX_ARRAY_##type(const type *array, size_t size);\
size_t ARG_MAX_ARRAY_##type(const type *array, size_t size);\
type MIN_ARRAY_##type(const type *array, size_t size);\
size_t ARG_MIN_ARRAY_##type(const type *array, size_t 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 size)\
{\
for(size_t i = 0; i < 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 rank;
size_t *shape;
size_t size;
};
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 size);
dimension * create_reverse_dim(size_t size);
dimension* init_dim(size_t *t, size_t sz);
dimension* init_copy_dim(size_t *t, size_t sz);
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_size);
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 sz){\
dimension *d = malloc(sizeof(dimension));\
d->size=sz;\
d->shape=t;\
updateRankDim(d);\
return d;\
}\
\
dimension* init_copy_dim(size_t *t, size_t sz){\
if (sz==0) return NULL;\
dimension *d = malloc(sizeof(dimension));\
d->shape=malloc(sz * sizeof(size_t));\
d->size = sz;\
for(size_t i=0; i<sz; ++i) d->shape[i]=t[i];\
updateRankDim(d);\
return d;\
}\
dimension *\
create_dim(size_t sz){\
if (sz==0) return NULL;\
dimension *d = malloc(sizeof(dimension));\
d->shape=malloc(sz * sizeof(size_t));\
d->size = sz;\
return d;\
}\
\
dimension* clone_dim(dimension *dim){\
return init_copy_dim(dim->shape,dim->size);\
}\
\
dimension *\
create_reverse_dim(size_t sz){\
dimension *dim = create_dim(sz);\
for(size_t i=0;i<sz;++i) dim->shape[i]=sz-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->size != d1->size) return false;\
if(d0->rank != d1->rank) return false;\
for(size_t i=0;i<d0->size; ++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->size)){\
dimension *d = init_copy_dim(root->shape, (root->size)-minusSubdim);\
updateRankDim(d);\
return d;\
}\
return NULL;\
}\
\
dimension* sub_copy_minus_dim_tail(dimension *root, size_t minusSubdim){\
if(minusSubdim < (root->size)){\
dimension *d = init_copy_dim((root->shape)+minusSubdim, (root->size)-minusSubdim);\
updateRankDim(d);\
return d;\
}\
return NULL;\
}\
\
dimension* sub_copy_dim_head(dimension *root, size_t subdim){\
if(subdim < (root->size)){\
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->size)){\
dimension *d = init_copy_dim((root->shape)+(root->size - subdim), subdim);\
updateRankDim(d);\
return d;\
}\
return NULL;\
}\
\
void add_copy_dimension(dimension **d, dimension *d0, dimension *d1) {\
(*d) = create_dim(d0->size + d1->size);\
for (size_t i = 0; i < d0->size; i++) (*d)->shape[i] = d0->shape[i];\
for (size_t i = 0; i < d1->size; i++) (*d)->shape[d0->size + i] = d1->shape[i];\
updateRankDim(*d);\
}\
\
void min_copy_dimension(dimension **d, dimension *d0, dimension *d1) {\
size_t mindim = min(d0->size,d1->size) ;\
(*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->size)){\
dimension *d = init_dim(root->shape, (root->size)-minusSubdim);\
updateRankDim(d);\
return d;\
}\
return NULL;\
}\
dimension* sub_minus_dim_tail(dimension *root, size_t minusSubdim){\
if(minusSubdim < (root->size)){\
dimension *d = init_dim((root->shape)+minusSubdim, (root->size)-minusSubdim);\
updateRankDim(d);\
return d;\
}\
return NULL;\
}\
dimension* sub_dim_head(dimension *root, size_t subdim){\
if(subdim < (root->size)){\
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->size)){\
dimension *d = init_dim((root->shape)+(root->size - subdim), subdim);\
updateRankDim(d);\
return d;\
}\
return NULL;\
}\
\
/*\
void split_dim_part(dimension *root, dimension **part_1, dimension **part_2, size_t sz_nb_minus_part ) */\
void split_dim_part(dimension *root, dimension **part_1, dimension **part_2, size_t pivotSplit, size_t rangeInPivot ) {\
if(pivotSplit < root->size){\
if(rangeInPivot < root->shape[pivotSplit]){\
/*size_t sz_part1= (root->rank * sz_nb_minus_part)/(root->shape[(root->size)-1]);*/\
/*printf("sz_part1 :%ld \n",sz_part1);*/\
*part_1 = init_copy_dim(root->shape, root->size);\
((*part_1)->shape[pivotSplit]) -= rangeInPivot;\
updateRankDim(*part_1);\
/*if(sz_nb_minus_part <2)\
*part_2 = init_copy_dim((root->shape), root->size-1 );\
else{*/\
*part_2 = init_copy_dim((root->shape), root->size );\
(*part_2)->shape[pivotSplit] = rangeInPivot ;\
/*}*/\
updateRankDim(*part_2);\
}\
}\
}\
\
void increment_dim_var(dimension *d){\
if(littleEndian){\
(d->shape[0])++;\
}\
else{\
(d->shape[d->size - 1])++;\
}\
}\
\
\
void decrement_dim_var(dimension *d){\
if(littleEndian){\
(d->shape[0])--;\
}\
else{\
(d->shape[d->size - 1])--;\
}\
}\
\
void add_dimension(dimension **d, dimension *d0, dimension *d1) {\
(*d) = create_dim(d0->size + d1->size);\
for (size_t i = 0; i < d0->size; i++) (*d)->shape[i] = d0->shape[i];\
for (size_t i = 0; i < d1->size; i++) (*d)->shape[d0->size + i] = d1->shape[i];\
updateRankDim(*d);\
}\
\
void min_dimension(dimension **d, dimension *d0, dimension *d1) {\
if (d0->size > d1->size) {\
*d = d1;\
}\
else if (d0->size < d1->size) {\
*d = d0;\
}\
else { /* d0->size = d1->size*/\
*d = d0;\
for (size_t i = 0; i < d0->size; 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)->size = %ld | (%s)->rank = %ld \n[",d,msg,d->size,msg,d->rank);\
for(size_t i=0; i<d->size; ++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->size+40;\
*dimContent = malloc(nbch);\
/*printf("nbCh=%ld\n",nbch);*/\
char *val=NULL;\
size_t cur=0;\
char *dimSzCh="dim->size";\
for(size_t i=0; i<strlen(dimSzCh);++i)\
(*dimContent)[cur++]=dimSzCh[i];\
(*dimContent)[cur++]='=';\
val=TYPE_SIZE_T_TO_STR(d->size);\
for(size_t c=0;c<strlen(val);++c)\
(*dimContent)[cur++]=val[c];\
free(val); val = NULL;\
(*dimContent)[cur++]=' ';\
(*dimContent)[cur++]='/';\
(*dimContent)[cur++]=' ';\
char *dimRkCh="dim->rank";\
for(size_t i=0; i<strlen(dimRkCh);++i)\
(*dimContent)[cur++]=dimRkCh[i];\
(*dimContent)[cur++]='=';\
val=TYPE_SIZE_T_TO_STR(d->rank);\
for(size_t c=0;c<strlen(val);++c)\
(*dimContent)[cur++]=val[c];\
free(val); val = NULL;\
(*dimContent)[cur++]=' ';\
(*dimContent)[cur++]='\n';\
(*dimContent)[cur++]='[';\
for(size_t i=0; i<d->size;++i){\
(*dimContent)[cur++]=' ';\
val=TYPE_SIZE_T_TO_STR(d->shape[i]);\
for(size_t c=0;c<strlen(val);++c)\
(*dimContent)[cur++]=val[c];\
free(val); val = NULL;\
(*dimContent)[cur++]=',';\
\
}\
(*dimContent)[cur++]=']';\
\
(*dimContent)[cur++]='\n';\
(*dimContent)[cur++]='\0';\
\
return cur;\
}\
\
void updateRankDim(dimension *dim){\
dim->rank=1;\
for(size_t i=0; i<dim->size; ++i)\
dim->rank *=dim->shape[i];\
}\
\
/* signed */\
long int signedLineFromCoord(long int *coo, dimension *dim){\
long int begin = 0;\
long int end = dim->size - 1;\
long int (*iter)(long int); iter = &incr;\
bool (*cond)(long int, long int); cond = &isLessEqThan;\
\
if (littleEndian) {\
begin = dim->size - 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->size - 1;\
long int (*iter)(long int) = incr;\
bool (*cond)(long int, long int) = isLessThan;\
if (littleEndian == false) {\
/*if (littleEndian) {*/\
begin = dim->size - 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->rank;\
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->size*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)->size = 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_size){\
dimension * dim = create_dim(dimension_size);\
for(size_t i=0; i<dimension_size; ++i)\
dim->shape[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 <stdlib.h>
#include <time.h>
#include <pthread.h>
//#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 rankInDim); \
tensor_##type * sub_minus_tensor_tail_##type(tensor_##type *rootens, size_t minuSubdim, size_t rankInDim); \
tensor_##type * sub_tensor_head_##type(tensor_##type *rootens, size_t subdim, size_t rankInDim); \
tensor_##type * sub_tensor_tail_##type(tensor_##type *rootens, size_t subdim, size_t rankInDim); \
tensor_##type * sub_copy_minus_tensor_head_##type(tensor_##type *rootens, size_t minuSubdim, size_t rankInDim); \
tensor_##type * sub_copy_minus_tensor_tail_##type(tensor_##type *rootens, size_t minuSubdim, size_t rankInDim); \
tensor_##type * sub_copy_tensor_head_##type(tensor_##type *rootens, size_t sub_copydim, size_t rankInDim); \
tensor_##type * sub_copy_tensor_tail_##type(tensor_##type *rootens, size_t sub_copydim, size_t rankInDim); \
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 sz,char *msg){
printf("======== %s ======= size: %ld\n",msg,sz);
for(size_t i=0; i< sz; ++i)
printf("[%ld : %ld ] ",i,a[i]);
printf("\n");
}
int checkContractProdTensorDim(dimension *d0, dimension *d1, ssize_t contractionNumber){
if((d0->size-contractionNumber <0)||(d1->size-contractionNumber <0)) return 0;
if(littleEndian){
ssize_t beginCommonM0=d0->size-contractionNumber;
for(ssize_t i=0; i<contractionNumber; ++i){
if(d0->shape[beginCommonM0+i] != d1->shape[i]) return 0;
}
}else{
ssize_t beginCommonM1=d1->size-contractionNumber;
for(ssize_t i=0; i<contractionNumber; ++i){
if(d0->shape[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->rank);\
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)->rank - dim->rank);\
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; i<dim->rank;++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)->rank - dim->rank);*/\
r_tens->x = malloc(sizeof(type)*dim->rank);\
size_t dRank=(troot->dim)->rank - dim->rank;\
for(size_t i=0; i<dim->rank;++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->size);\
r_tens->x = malloc(sizeof(type)*dim->rank);\
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)->rank);\
for(size_t i=0; i<(tens->dim)->rank;++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->rank - src->dim->rank;\
if(diff == 0) \
for(size_t i=0; i<(src->dim)->rank;++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)->rank;++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 rankInDim){\
dimension *rdim= rootens->dim;\
dimension *dS_t = sub_minus_dim_tail(rdim,rdim->size - minuSubdim);\
if(rankInDim < dS_t->rank){\
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->rank);\
if(littleEndian){\
for(size_t i=0; i<dS_h->rank; ++i){\
ret_ens->x[i]=rootens->x[i*dS_t->rank + rankInDim];\
\
}\
}else{\
for(size_t i=0; i<dS_h->rank; ++i){\
ret_ens->x[i]=rootens->x[i + dS_h->rank * rankInDim];\
}\
}\
return ret_ens;\
}\
return NULL;\
}\
\
tensor_##type * sub_minus_tensor_tail_##type(tensor_##type *rootens, size_t minuSubdim, size_t rankInDim){\
dimension *rdim= rootens->dim;\
dimension *dS_h = sub_minus_dim_head(rdim,rdim->size - minuSubdim);\
if(rankInDim < dS_h->rank){\
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->rank);\
if(littleEndian==false){\
for(size_t i=0; i<dS_t->rank; ++i){\
ret_ens->x[i]=rootens->x[i*dS_h->rank + rankInDim];\
}\
}else{\
for(size_t i=0; i<dS_t->rank; ++i){\
ret_ens->x[i]=rootens->x[i + dS_t->rank * rankInDim];\
}\
\
}\
return ret_ens;\
}\
return NULL;\
}\
\
tensor_##type * sub_tensor_head_##type(tensor_##type *rootens, size_t subdim, size_t rankInDim){\
dimension *rdim= rootens->dim;\
dimension *dS_t = sub_dim_tail(rdim,rdim->size - subdim);\
if(rankInDim < dS_t->rank){\
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->rank);\
if(littleEndian){\
for(size_t i=0; i<dS_h->rank; ++i){\
ret_ens->x[i]=rootens->x[i*dS_t->rank + rankInDim];\
}\
}else{\
for(size_t i=0; i<dS_h->rank; ++i){\
ret_ens->x[i]=rootens->x[i + dS_h->rank * rankInDim];\
}\
\
}\
return ret_ens;\
}\
return NULL;\
}\
tensor_##type * sub_tensor_tail_##type(tensor_##type *rootens, size_t subdim, size_t rankInDim){ \
dimension *rdim= rootens->dim;\
dimension *dS_h = sub_dim_head(rdim,rdim->size - subdim);\
if(rankInDim < dS_h->rank){\
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->rank);\
if(littleEndian==false){\
for(size_t i=0; i<dS_t->rank; ++i){\
ret_ens->x[i]=rootens->x[i*dS_h->rank + rankInDim];\
}\
}else{\
for(size_t i=0; i<dS_t->rank; ++i){\
ret_ens->x[i]=rootens->x[i + dS_t->rank * rankInDim];\
}\
\
}\
return ret_ens;\
}\
return NULL;\
}\
\
tensor_##type * sub_copy_minus_tensor_head_##type(tensor_##type *rootens, size_t minuSubdim, size_t rankInDim){\
dimension *rdim= rootens->dim;\
dimension *dS_t = sub_copy_minus_dim_tail(rdim,rdim->size - minuSubdim);\
if(rankInDim < dS_t->rank){\
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->rank);*/\
if(littleEndian){\
/*ret_ens->x = malloc(sizeof(type)*dS_h->rank);\
*/for(size_t i=0; i<dS_h->rank; ++i){\
ret_ens->x[i]=rootens->x[i*dS_t->rank + rankInDim];\
/*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->rank, i,dS_h->rank,i*dS_h->rank + rankInDim);*/\
\
}\
}else{\
/*ret_ens->x = (rootens->x)+rankInDim*dS_h->rank;*/\
for(size_t i=0; i<dS_h->rank; ++i){\
ret_ens->x[i]=rootens->x[i + dS_h->rank * rankInDim];\
}\
}\
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 rankInDim){\
dimension *rdim= rootens->dim;\
dimension *dS_h = sub_copy_minus_dim_head(rdim,rdim->size - minuSubdim);\
if(rankInDim < dS_h->rank){\
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->rank);\
*/if(littleEndian==false){\
for(size_t i=0; i<dS_t->rank; ++i){\
ret_ens->x[i]=rootens->x[i*dS_h->rank + rankInDim];\
}\
}else{\
/*ret_ens->x = (rootens->x)+rankInDim*dS_t->rank;*/\
for(size_t i=0; i<dS_t->rank; ++i){\
ret_ens->x[i]=rootens->x[i + dS_t->rank * rankInDim];\
}\
\
}\
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 rankInDim){\
/*return sub_copy_minus_tensor_head_##type(rootens,rootens->dim->size - sub_copydim, rankInDim);*/\
dimension *rdim= rootens->dim;\
dimension *dS_t = sub_copy_dim_tail(rdim,rdim->size - sub_copydim);\
if(rankInDim < dS_t->rank){\
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->rank);\
*/if(littleEndian){\
for(size_t i=0; i<dS_h->rank; ++i){\
ret_ens->x[i]=rootens->x[i*dS_t->rank + rankInDim];\
/*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->rank, i,dS_h->rank,i*dS_h->rank + rankInDim);*/\
}\
}else{\
/*ret_ens->x = (rootens->x)+rankInDim*dS_h->rank;*/\
for(size_t i=0; i<dS_h->rank; ++i){\
ret_ens->x[i]=rootens->x[i + dS_h->rank * rankInDim];\
/*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->rank, i,dS_h->rank,i*dS_h->rank + rankInDim);*/\
}\
\
}\
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 rankInDim){ \
/*return sub_copy_minus_tensor_tail_##type(rootens,rootens->dim->size - sub_copydim, rankInDim);*/\
dimension *rdim= rootens->dim;\
dimension *dS_h = sub_copy_dim_head(rdim,rdim->size - sub_copydim);\
if(rankInDim < dS_h->rank){\
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->rank);\
*/if(littleEndian==false){\
for(size_t i=0; i<dS_t->rank; ++i){\
ret_ens->x[i]=rootens->x[i*dS_h->rank + rankInDim];\
/*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->rank, i,dS_h->rank,i*dS_h->rank + rankInDim);*/\
}\
}else{\
/*ret_ens->x = (rootens->x)+rankInDim*dS_t->rank;*/\
for(size_t i=0; i<dS_t->rank; ++i){\
ret_ens->x[i]=rootens->x[i + dS_t->rank * rankInDim];\
/*printf("%ld: [i:%ld] | %ld : [%ld ]\n",dS_t->rank, i,dS_h->rank,i*dS_h->rank + rankInDim);*/\
}\
\
}\
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)->size); \
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->size) - 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->size) - 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)->rank;++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)->size;++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)->size-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)->size); \
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->size) - 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->size) - 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)->size; ++i)\
fprintf(fileWrite," %ld,", (T->dim)->shape[i]);\
fprintf(fileWrite,"] \n");\
\
for(long int i=0;i<(T->dim)->rank;++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)->size;++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)->size-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 sz = ((T->dim)->rank)*(32+ withIndex * 5*(T->dim)->size + 129 );\
/*printf("malloc %ld char\n",sz);*/\
*tensorContent = malloc(sz ) ;\
size_t cur=0;\
size_t *coord = malloc(sizeof(long int)*(T->dim)->size); \
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->size) - 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;c<strlen(val);++c)\
(*tensorContent)[cur++]=val[c];\
free(val); val = NULL;\
}else{\
begin = 0 ; end = (T->dim->size) - 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;c<strlen(val);++c)\
(*tensorContent)[cur++]=val[c];\
free(val); val = NULL;\
}\
for(long int i=0;i<(T->dim)->rank;++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)->size;++k) {\
/*printf(" %ld,",coord[k]);*/\
val=TYPE_SIZE_T_TO_STR(coord[k]);\
for(size_t c=0;c<strlen(val);++c){\
(*tensorContent)[cur++]=' ';\
(*tensorContent)[cur++]=val[c];\
}\
free(val); val = NULL;\
(*tensorContent)[cur++]=',';\
}\
(*tensorContent)[cur++]='}';\
(*tensorContent)[cur++]='#';\
val=TYPE_SIZE_T_TO_STR(i);\
for(size_t c=0;c<strlen(val);++c)\
(*tensorContent)[cur++]=val[c];\
free(val); val = NULL;\
(*tensorContent)[cur++]=']';\
(*tensorContent)[cur++]=' ';\
}\
if(T->x[i] != T->x[i]){\
/*char *nanStr="ALERT NAN";\
for(size_t c=0;c<strlen(nanStr);++c)\
(*tensorContent)[cur++]=nanStr[c];*/\
printf(" ALERT NAN ");\
;\
/*return strlen(nanStr)*/;\
}\
val=type##_TO_STR(T->x[i]);\
/*printf(" {%ld} %s [",i,val);*/\
(*tensorContent)[cur++]=' ';\
for(size_t c=0;c<strlen(val);++c)\
(*tensorContent)[cur++]=val[c];\
free(val); val = NULL;\
(*tensorContent)[cur++]=',';\
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(")"); */ (*tensorContent)[cur++]=')'; ++count;}\
else break;\
}\
if(count == (T->dim)->size-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 sz = (Troot->dim)->size;\
if(pivotSplit < sz){\
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 sz = (Troot->dim)->size;\
if(pivotSplit < sz){\
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->size)); \
size_t* coord0 , lin0; \
coord0 = malloc(sizeof(size_t)* M0->dim->size); \
size_t* coord1 , lin1; \
coord1 = malloc(sizeof(size_t)* M1->dim->size); \
for (size_t i = 0; i < dd->rank; i++) { \
vCoordFromLin(coord, i, M->dim); \
subArray(coord0, coord, 0, M0->dim->size, 0); \
subArray(coord1, coord, 0, M1->dim->size, M0->dim->size); \
\
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; i<M0->dim->rank; ++i){\
for(size_t j=0; j<M1->dim->rank; ++j){\
if(littleEndian)\
m_idx= i*M1->dim->rank + j ;\
else\
m_idx= i+M0->dim->rank * 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<...<l=n / xl = y0,x{l+1}=y1, x{n}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=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->size - contractionNumber;\
size_t len1 = M1->dim->size - 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->rank; i++) {\
if(littleEndian){\
a0_id=i/dSub1->rank;\
a1_id=i%dSub1->rank;\
}\
else{\
a0_id=i%dSub0->rank;\
a1_id=i/dSub0->rank;\
}\
M->x[i] = 0;\
for (size_t k = 0; k < dM->rank; k++) {\
if(littleEndian){\
n0_id= a0_id*dM->rank + k;\
n1_id= a1_id + dSub1->rank * k;\
}\
else{\
n0_id= a0_id + dSub0->rank * k;\
n1_id= a1_id*dM->rank + 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<...<l=n / xl = y0,x{l+1}=y1, x{n}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=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->size - contractionNumber;\
size_t len1 = M1->dim->size - 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->rank; i++) {\
if(littleEndian){\
a0_id=i/dSub1->rank;\
a1_id=i%dSub1->rank;\
n0_id=a0_id*dM->rank ;\
n1_id= a1_id ;\
}\
else{\
a0_id=i%dSub0->rank;\
a1_id=i/dSub0->rank;\
n1_id= a1_id*dM->rank ;\
n0_id= a0_id ;\
}\
M->x[i] = 0;\
for (size_t k = 0; k < dM->rank; k++) {\
if(littleEndian){\
/*n0_id= a0_id*dM->rank + k;*/\
/*n1_id= a1_id + dSub1->rank * 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->rank ;\
}\
else{\
/*n0_id= a0_id + dSub0->rank * k;*/\
/*n1_id= a1_id*dM->rank + 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->rank ;\
}\
\
}\
}\
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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(M->dim->rank)/nbthread ;\
/*if(i < nbthread - 1 ) arg_th[i]->endRange = (i+1)*(M->dim->rank)/nbthread ;\
else arg_th[i]->endRange = M->dim->rank ;\
*/if(littleEndian){\
arg_th[i]->MRank = M1->dim->rank;\
}\
else{\
arg_th[i]->MRank = M0->dim->rank;\
}\
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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(M0->dim->rank)/nbthread ;\
/*if(i < nbthread - 1 ) arg_th[i]->endRange = (i+1)*(M0->dim->rank)/nbthread ;\
else arg_th[i]->endRange = M0->dim->rank ;\
*/arg_th[i]->M1Rank = M1->dim->rank;\
arg_th[i]->M0Rank = M0->dim->rank;\
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<...<l=n / xl = y0,x{l+1}=y1, x{n}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=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->size - contractionNumber;\
size_t len1 = M1->dim->size - 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->rank)/nbthread ;\
if(i < nbthread - 1 ) arg_th[i]->endRange = (i+1)*(M->dim->rank)/nbthread ;\
else arg_th[i]->endRange = M->dim->rank ;\
if(littleEndian){\
arg_th[i]->dSubRank = dSub1->rank;\
}\
else{\
arg_th[i]->dSubRank = dSub0->rank;\
}\
arg_th[i]->dMRank = dM->rank;\
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->size - contractionNumber;\
size_t len1 = M1->dim->size - 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->rank)/nbthread ;\
if(i < nbthread - 1 ) arg_th[i]->endRange = (i+1)*(M->dim->rank)/nbthread ;\
else arg_th[i]->endRange = M->dim->rank ;\
if(littleEndian){\
arg_th[i]->dSubRank = dSub1->rank;\
}\
else{\
arg_th[i]->dSubRank = dSub0->rank;\
}\
arg_th[i]->dMRank = dM->rank;\
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<...<l=n / xl = y0,x{l+1}=y1, x{n}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=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->size - contractionNumber;\
size_t len1 = M1->dim->size - 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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(dSub0->rank)/nbthread ;\
arg_th[i]->dSub1Rank = dSub1->rank;\
arg_th[i]->dSub0Rank = dSub0->rank;\
arg_th[i]->dMRank = dM->rank;\
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<...<l=n / xl = y0,x{l+1}=y1, x{n}=yl et zi=xi i<n-l et zj=y{j-(n-l)} j>=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->size - contractionNumber;\
size_t len1 = M1->dim->size - 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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(dSub0->rank)/nbthread ;\
arg_th[i]->dSub1Rank = dSub1->rank;\
arg_th[i]->dSub0Rank = dSub0->rank;\
arg_th[i]->dMRank = dM->rank;\
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->size - contractionNumber;\
size_t len1 = M1->dim->size - 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->size);\
\
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->size);\
size_t* coordM1 ;\
coordM1 = malloc(sizeof(size_t)* M1->dim->size);\
\
size_t* Koord ;\
Koord = malloc(sizeof(size_t)* contractionNumber);\
\
for (size_t i = 0; i < M->dim->rank; 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->rank; 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 size) 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->size + 1);\
dimension * d1 = create_dim(M1->dim->size + 1);\
size_t i;\
d0->shape[0] = 1;\
for(i=0; i<M0->dim->size; ++i) d0->shape[i+1] = M0->dim->shape[i];\
for(i=0; i<M1->dim->size; ++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->size,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 size_unknown=false; \
for(size_t i=0; i<len ; ++i){\
if(input[i]==']') break;\
if((input[i]=='*') ||(input[i]=='_')){ size_unknown =true; break;}\
}\
while(ppEnd && (ppEnd[0] !=']') ){\
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);\
/*printf("ss: %ld\n",ss);*/\
ttmp=ppEnd;\
}\
dimension *dim=create_dim_from_list_shape(l_p);\
/*printf("ppEnd = %s\n",ppEnd);*/\
\
ttmp++; ppEnd++;\
\
if(size_unknown == false){\
tens = create_tensor_##type(dim);\
\
size_t i=0;\
type x;\
while(ppEnd && (ppEnd[0] !='\0') && i<dim->rank){\
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 size_unknown=false; \
for(size_t i=0; i<len ; ++i){\
if(input[i]==']') break;\
if((input[i]=='*') ||(input[i]=='_')){ size_unknown =true; break;}\
}\
while(ppEnd && (ppEnd[0] !=']') ){\
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);\
/*printf("ss: %ld\n",ss);*/\
ttmp=ppEnd;\
}\
dimension *dim=create_dim_from_list_shape(l_p);\
/*printf("ppEnd = %s\n",ppEnd);*/\
\
ttmp++; ppEnd++;\
\
if(size_unknown == false){\
/*dimension *dim1 = create_dim(dim->size-1);\
dimension *ddim1 = create_dim(dim->size-2);\
dimension *ddim2 = create_dim(dim->size-2);\
dimension *dim2 = create_dim(2);\
*/dimension *dim1 = create_dim(dim->size-pivotSplit);\
dimension *ddim1 = create_dim(dim->size-pivotSplit-1);\
dimension *ddim2 = create_dim(pivotSplit);\
dimension *dim2 = create_dim(pivotSplit+1);\
for(size_t i=0;i<dim1->size;++i) dim1->shape[i] = dim->shape[i];\
for(size_t i=0;i<ddim1->size;++i) ddim1->shape[i] = dim->shape[i+1];\
for(size_t i=0;i<ddim2->size;++i) ddim2->shape[i] = dim->shape[ dim->size - pivotSplit + i];\
dim2->shape[0] = dim->shape[0];\
for(size_t i=1;i<dim2->size;++i) dim2->shape[i] = ddim2->shape[i-1];\
/*dim2->shape[1] = dim->shape[dim->size - 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') && j<dim2->rank){\
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->rank);\
*/if(i1 == ddim1->rank){\
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->rank);\
*/if(i2 == ddim2->rank){\
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->size-1);\
dimension *ddim2 = create_dim(1);\
for(size_t i=0;i<ddim1->size;++i) ddim1->shape[i] = dim->shape[i];\
ddim2->shape[0] = dim->shape[dim->size - 1];\
*/dimension *ddim1 = create_dim(dim->size-pivotSplit);\
dimension *ddim2 = create_dim(pivotSplit);\
for(size_t i=0;i<ddim1->size;++i) ddim1->shape[i] = dim->shape[i];\
for(size_t i=0;i<ddim2->size;++i) ddim2->shape[i] = dim->shape[dim->size - 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->rank){\
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->rank){\
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 size_unknown=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<retfread*block_size; ++curIn) iinput[curIn]=input[curIn];\
while(!Done && ( ((iinput[curIn-1] >='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<len ; ++i){\
if(iinput[i]==']') {broken = true; break;}\
if((iinput[i]=='*') ||(iinput[i]=='_')){ \
broken=true; size_unknown =true;\
break;\
}\
}\
Done = broken;\
}\
rewind(f_input);\
list_shape_in_dim *l_p=NULL;\
dimension *dim=NULL;\
size_t ss;\
char *ttmp;\
char *ppEnd="[";\
bool bracketsDown=false;\
size_t i1=0,i=0,j=0,i2=0;\
bool filled1=false,filled2=false;\
array_chainlist_##type *l_a1=NULL;\
array_chainlist_##type *l_a2=NULL;\
bool initDim=false;\
dimension *dim1 =NULL ;\
dimension *ddim1=NULL;\
dimension *ddim2=NULL;\
dimension *dim2=NULL ;\
Done=false;\
while(!Done){\
retfread = fread(input, block_size, block_count, f_input) ;\
Done = (retfread != block_count);\
/*input[retfread*block_size]='\0';\
*/for(curIn=0; curIn<retfread*block_size; ++curIn) iinput[curIn]=input[curIn];\
while(!Done && (((iinput[curIn-1] >='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(size_unknown == false){\
\
if(!initDim){\
dim1 = create_dim(dim->size-pivotSplit);\
ddim1 = create_dim(dim->size-pivotSplit-1);\
ddim2 = create_dim(pivotSplit);\
dim2 = create_dim(pivotSplit+1);\
for(size_t i=0;i<dim1->size;++i) dim1->shape[i] = dim->shape[i];\
for(size_t i=0;i<ddim1->size;++i) ddim1->shape[i] = dim->shape[i+1];\
for(size_t i=0;i<ddim2->size;++i) ddim2->shape[i] = dim->shape[ dim->size - pivotSplit + i];\
dim2->shape[0] = dim->shape[0];\
for(size_t i=1;i<dim2->size;++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) && j<dim2->rank){ \
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->rank){\
filled1=true;\
i1=0;\
filled2=false;\
}\
}else{\
if(!filled2){\
++i2;\
(*Tpart2)->x[j++] = x;\
if(i2 == ddim2->rank){\
filled2=true;\
i2=0;\
filled1=false;\
}\
}\
\
}\
}\
ttmp=ppEnd;\
}\
if(Done){\
free_dimension(ddim1);\
free_dimension(ddim2);\
}\
}\
else{\
\
if(!initDim){\
ddim1 = create_dim(dim->size-pivotSplit);\
ddim2 = create_dim(pivotSplit);\
for(size_t i=0;i<ddim1->size;++i) ddim1->shape[i] = dim->shape[i];\
for(size_t i=0;i<ddim2->size;++i) ddim2->shape[i] = dim->shape[dim->size - 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->rank){\
filled1=true;\
i1=0;\
filled2=false;\
}\
}else{\
if(!filled2){\
++i2;\
append_array_chainlist_##type(&l_a2, x);\
if(i2 == ddim2->rank){\
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)->size - 1);\
for(size_t i=0; i<dim->size; ++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; j<dim->rank; ++j) (re_tens[i])->x[j] = tens->x[i*(dim->rank) + 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->rank;\
dimension *dim=create_dim(part_dim->size + 1);\
if(littleEndian){\
dim->shape[0]=miss_part_d;\
for(size_t i=0; i<part_dim->size;++i) dim->shape[i+1]=part_dim->shape[i];\
}else{\
size_t i=0;\
for(i=0; i<part_dim->size;++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 dimsz = (org->dim)->size; \
dimension *dim_tr=create_dim(dimsz);\
for(size_t i=0; i<dimsz; ++i) dim_tr->shape[i]=(org->dim)->shape[(dimsz-1)-i];\
updateRankDim(dim_tr);\
printDebug_dimension(dim_tr,"dim_tr");\
tensor_##type *tens_tr = create_tensor_##type(dim_tr);\
size_t *coord = malloc((dimsz)*sizeof(size_t));\
size_t *coord_tr = malloc((dimsz)*sizeof(size_t));\
for(size_t i=0; i<dim_tr->rank; ++i){\
vCoordFromLin(coord,i,org->dim);\
for(size_t j=0; j<dimsz;++j) coord_tr[j]=coord[dimsz-1-j]; \
tens_tr->x[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 dimsz = (org->dim)->size; \
dimension *dim_tr=create_dim(dimsz);\
for(size_t i=0; i<dimsz; ++i) dim_tr->shape[i]=(org->dim)->shape[(dimsz-1)-i];\
updateRankDim(dim_tr);\
printDebug_dimension(dim_tr,"dim_tr");\
tensor_##type *tens_tr = create_tensor_##type(dim_tr);\
size_t *coord = malloc((dimsz)*sizeof(size_t));\
size_t *coord_tr = malloc((dimsz)*sizeof(size_t));\
for(size_t i=0; i<dim_tr->rank; ++i){\
vCoordFromLin(coord,i,org->dim);\
for(size_t j=0; j<dimsz;++j) coord_tr[j]=coord[dshape->shape[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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(M0->dim->rank)/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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(M0->dim->rank)/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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(M0->dim->rank)/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(" rankM0=%ld , rank M2:%ld ; iseq :%d \n",(M0->dim)->rank,(M2->dim)->rank,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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(M0->dim->rank)/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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(M0->dim->rank)/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(" rankM0=%ld , rank M2:%ld ; iseq :%d \n",(M0->dim)->rank,(M2->dim)->rank,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->rank)/nbthread ;\
arg_th[i]->endRange = (i+1)*(M0->dim->rank)/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 */