X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2b4010b2a5fda082278a02a35a9e9eb18b58e110..2114c044f7a785c1c53c0f69d0203fd50c2175d5:/src/smpi/smpi_mpi_dt.c diff --git a/src/smpi/smpi_mpi_dt.c b/src/smpi/smpi_mpi_dt.c index 2ad759ca9a..54eecc2710 100644 --- a/src/smpi/smpi_mpi_dt.c +++ b/src/smpi/smpi_mpi_dt.c @@ -10,7 +10,7 @@ #include #include #include - +#include #include "private.h" #include "smpi_mpi_dt_private.h" #include "mc/mc.h" @@ -20,24 +20,32 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi, "Logging specific to SMPI (datatype)"); +#define INTSIZEDCHAR (sizeof(int)*CHAR_BIT-1)/3 + 3 +xbt_dict_t smpi_type_keyvals = NULL; +int type_keyval_id=0;//avoid collisions + #define CREATE_MPI_DATATYPE(name, type) \ static s_smpi_mpi_datatype_t mpi_##name = { \ + (char*) # name, \ sizeof(type), /* size */ \ 0, /*was 1 has_subtype*/ \ 0, /* lb */ \ sizeof(type), /* ub = lb + size */ \ DT_FLAG_BASIC, /* flags */ \ - NULL /* pointer on extended struct*/ \ + NULL, /* attributes */ \ + NULL, /* pointer on extended struct*/ \ }; \ MPI_Datatype name = &mpi_##name; #define CREATE_MPI_DATATYPE_NULL(name) \ static s_smpi_mpi_datatype_t mpi_##name = { \ + (char*) # name, \ 0, /* size */ \ 0, /*was 1 has_subtype*/ \ 0, /* lb */ \ 0, /* ub = lb + size */ \ DT_FLAG_BASIC, /* flags */ \ + NULL, /* attributes */ \ NULL /* pointer on extended struct*/ \ }; \ MPI_Datatype name = &mpi_##name; @@ -51,6 +59,10 @@ typedef struct { float value; float index; } float_float; +typedef struct { + long value; + long index; +} long_long; typedef struct { double value; double index; @@ -75,7 +87,10 @@ typedef struct { long double value; int index; } long_double_int; - +typedef struct { + int64_t value; + int64_t index; +} integer128_t; // Predefined data types CREATE_MPI_DATATYPE(MPI_CHAR, char); CREATE_MPI_DATATYPE(MPI_SHORT, short); @@ -93,6 +108,7 @@ CREATE_MPI_DATATYPE(MPI_DOUBLE, double); CREATE_MPI_DATATYPE(MPI_LONG_DOUBLE, long double); CREATE_MPI_DATATYPE(MPI_WCHAR, wchar_t); CREATE_MPI_DATATYPE(MPI_C_BOOL, _Bool); +CREATE_MPI_DATATYPE(MPI_BYTE, int8_t); CREATE_MPI_DATATYPE(MPI_INT8_T, int8_t); CREATE_MPI_DATATYPE(MPI_INT16_T, int16_t); CREATE_MPI_DATATYPE(MPI_INT32_T, int32_t); @@ -114,12 +130,26 @@ CREATE_MPI_DATATYPE(MPI_SHORT_INT, short_int); CREATE_MPI_DATATYPE(MPI_2INT, int_int); CREATE_MPI_DATATYPE(MPI_2FLOAT, float_float); CREATE_MPI_DATATYPE(MPI_2DOUBLE, double_double); +CREATE_MPI_DATATYPE(MPI_2LONG, long_long); + +CREATE_MPI_DATATYPE(MPI_REAL, float); +CREATE_MPI_DATATYPE(MPI_REAL4, float); +CREATE_MPI_DATATYPE(MPI_REAL8, float); +CREATE_MPI_DATATYPE(MPI_REAL16, double); +CREATE_MPI_DATATYPE_NULL(MPI_COMPLEX8); +CREATE_MPI_DATATYPE_NULL(MPI_COMPLEX16); +CREATE_MPI_DATATYPE_NULL(MPI_COMPLEX32); +CREATE_MPI_DATATYPE(MPI_INTEGER1, int); +CREATE_MPI_DATATYPE(MPI_INTEGER2, int16_t); +CREATE_MPI_DATATYPE(MPI_INTEGER4, int32_t); +CREATE_MPI_DATATYPE(MPI_INTEGER8, int64_t); +CREATE_MPI_DATATYPE(MPI_INTEGER16, integer128_t); CREATE_MPI_DATATYPE(MPI_LONG_DOUBLE_INT, long_double_int); CREATE_MPI_DATATYPE_NULL(MPI_UB); CREATE_MPI_DATATYPE_NULL(MPI_LB); -CREATE_MPI_DATATYPE_NULL(MPI_PACKED); +CREATE_MPI_DATATYPE(MPI_PACKED, char); // Internal use only CREATE_MPI_DATATYPE(MPI_PTR, void*); @@ -145,33 +175,76 @@ MPI_Aint smpi_datatype_ub(MPI_Datatype datatype) return datatype->ub; } -MPI_Datatype smpi_datatype_dup(MPI_Datatype datatype) +int smpi_datatype_dup(MPI_Datatype datatype, MPI_Datatype* new_t) { - MPI_Datatype new_t= xbt_new(s_smpi_mpi_datatype_t,1); - memcpy(new_t, datatype, sizeof(s_smpi_mpi_datatype_t)); - if (datatype->has_subtype) - memcpy(new_t->substruct, datatype->substruct, sizeof(s_smpi_subtype_t)); - return new_t; + int ret=MPI_SUCCESS; + *new_t= xbt_new(s_smpi_mpi_datatype_t,1); + memcpy(*new_t, datatype, sizeof(s_smpi_mpi_datatype_t)); + if (datatype->has_subtype){ + //FIXME: may copy too much information. + (*new_t)->substruct=xbt_malloc(sizeof(s_smpi_mpi_struct_t)); + memcpy((*new_t)->substruct, datatype->substruct, sizeof(s_smpi_mpi_struct_t)); + } + if(datatype->name) + (*new_t)->name = strdup(datatype->name); + if(datatype->attributes !=NULL){ + (*new_t)->attributes=xbt_dict_new(); + xbt_dict_cursor_t cursor = NULL; + int *key; + int flag; + void* value_in; + void* value_out; + xbt_dict_foreach(datatype->attributes, cursor, key, value_in){ + smpi_type_key_elem elem = xbt_dict_get_or_null(smpi_type_keyvals, (const char*)key); + if(elem && elem->copy_fn!=MPI_NULL_COPY_FN){ + ret = elem->copy_fn(datatype, atoi((const char*)key), NULL, value_in, &value_out, &flag ); + if(ret!=MPI_SUCCESS){ + *new_t=MPI_DATATYPE_NULL; + return ret; + } + if(flag) + xbt_dict_set((*new_t)->attributes, (const char*)key,value_out, NULL); + } + } + } + return ret; } int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent) { + if(datatype == MPI_DATATYPE_NULL){ + *lb=0; + *extent=0; + return MPI_SUCCESS; + } *lb = datatype->lb; *extent = datatype->ub - datatype->lb; return MPI_SUCCESS; } MPI_Aint smpi_datatype_get_extent(MPI_Datatype datatype){ + if(datatype == MPI_DATATYPE_NULL){ + return 0; + } return datatype->ub - datatype->lb; } +void smpi_datatype_get_name(MPI_Datatype datatype, char* name, int* length){ + *length = strlen(datatype->name); + strcpy(name, datatype->name); +} + +void smpi_datatype_set_name(MPI_Datatype datatype, char* name){ + datatype->name = strdup(name);; +} + int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype) { int count; if(smpi_privatize_global_variables){ - switch_data_segment(smpi_process_index()); + smpi_switch_data_segment(smpi_process_index()); } /* First check if we really have something to do */ if (recvcount > 0 && recvbuf != sendbuf) { @@ -181,17 +254,17 @@ int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype, count = sendcount < recvcount ? sendcount : recvcount; if(sendtype->has_subtype == 0 && recvtype->has_subtype == 0) { - if(!_xbt_replay_is_active()) memcpy(recvbuf, sendbuf, count); + if(!smpi_process_get_replaying()) memcpy(recvbuf, sendbuf, count); } else if (sendtype->has_subtype == 0) { s_smpi_subtype_t *subtype = recvtype->substruct; - subtype->unserialize( sendbuf, recvbuf,1, subtype); + subtype->unserialize( sendbuf, recvbuf, recvcount/smpi_datatype_size(recvtype), subtype, MPI_REPLACE); } else if (recvtype->has_subtype == 0) { s_smpi_subtype_t *subtype = sendtype->substruct; - subtype->serialize(sendbuf, recvbuf,1, subtype); + subtype->serialize(sendbuf, recvbuf, sendcount/smpi_datatype_size(sendtype), subtype); }else{ s_smpi_subtype_t *subtype = sendtype->substruct; @@ -200,7 +273,7 @@ int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype, subtype->serialize( sendbuf, buf_tmp,count/smpi_datatype_size(sendtype), subtype); subtype = recvtype->substruct; - subtype->unserialize( buf_tmp, recvbuf,count/smpi_datatype_size(recvtype), subtype); + subtype->unserialize( buf_tmp, recvbuf,count/smpi_datatype_size(recvtype), subtype, MPI_REPLACE); free(buf_tmp); } @@ -220,7 +293,7 @@ int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype, */ void serialize_vector( const void *noncontiguous_vector, void *contiguous_vector, - size_t count, + int count, void *type) { s_smpi_mpi_vector_t* type_c = (s_smpi_mpi_vector_t*)type; @@ -257,8 +330,9 @@ void serialize_vector( const void *noncontiguous_vector, */ void unserialize_vector( const void *contiguous_vector, void *noncontiguous_vector, - size_t count, - void *type) + int count, + void *type, + MPI_Op op) { s_smpi_mpi_vector_t* type_c = (s_smpi_mpi_vector_t*)type; int i; @@ -268,13 +342,16 @@ void unserialize_vector( const void *contiguous_vector, for (i = 0; i < type_c->block_count * count; i++) { if (type_c->old_type->has_subtype == 0) - memcpy(noncontiguous_vector_char, - contiguous_vector_char, type_c->block_length * type_c->size_oldtype); + smpi_op_apply(op, contiguous_vector_char, noncontiguous_vector_char, &type_c->block_length, + &type_c->old_type); + /* memcpy(noncontiguous_vector_char, + contiguous_vector_char, type_c->block_length * type_c->size_oldtype);*/ else ((s_smpi_subtype_t*)type_c->old_type->substruct)->unserialize( contiguous_vector_char, noncontiguous_vector_char, type_c->block_length, - type_c->old_type->substruct); + type_c->old_type->substruct, + op); contiguous_vector_char += type_c->block_length*type_c->size_oldtype; if((i+1)%type_c->block_count ==0) noncontiguous_vector_char += type_c->block_length*smpi_datatype_get_extent(type_c->old_type); @@ -310,6 +387,7 @@ s_smpi_mpi_vector_t* smpi_datatype_vector_create( int block_stride, void smpi_datatype_create(MPI_Datatype* new_type, int size,int lb, int ub, int has_subtype, void *struct_type, int flags){ MPI_Datatype new_t= xbt_new(s_smpi_mpi_datatype_t,1); + new_t->name = NULL; new_t->size = size; new_t->has_subtype = size>0? has_subtype:0; new_t->lb = lb; @@ -317,6 +395,7 @@ void smpi_datatype_create(MPI_Datatype* new_type, int size,int lb, int ub, int h new_t->flags = flags; new_t->substruct = struct_type; new_t->in_use=0; + new_t->attributes=NULL; *new_type = new_t; #ifdef HAVE_MC @@ -326,6 +405,17 @@ void smpi_datatype_create(MPI_Datatype* new_type, int size,int lb, int ub, int h } void smpi_datatype_free(MPI_Datatype* type){ + if((*type)->attributes !=NULL){ + xbt_dict_cursor_t cursor = NULL; + int* key; + void * value; + int flag; + xbt_dict_foreach((*type)->attributes, cursor, key, value){ + smpi_type_key_elem elem = xbt_dict_get_or_null(smpi_type_keyvals, (const char*)key); + if(elem && elem->delete_fn) + elem->delete_fn(*type, atoi((const char*)key), value, &flag); + } + } if((*type)->flags & DT_FLAG_PREDEFINED)return; @@ -339,6 +429,9 @@ void smpi_datatype_free(MPI_Datatype* type){ ((s_smpi_subtype_t *)(*type)->substruct)->subtype_free(type); xbt_free((*type)->substruct); } + if ((*type)->name != NULL){ + xbt_free((*type)->name); + } xbt_free(*type); *type = MPI_DATATYPE_NULL; } @@ -382,7 +475,7 @@ Contiguous Implementation */ void serialize_contiguous( const void *noncontiguous_hvector, void *contiguous_hvector, - size_t count, + int count, void *type) { s_smpi_mpi_contiguous_t* type_c = (s_smpi_mpi_contiguous_t*)type; @@ -402,15 +495,18 @@ void serialize_contiguous( const void *noncontiguous_hvector, */ void unserialize_contiguous( const void *contiguous_vector, void *noncontiguous_vector, - size_t count, - void *type) + int count, + void *type, + MPI_Op op) { s_smpi_mpi_contiguous_t* type_c = (s_smpi_mpi_contiguous_t*)type; char* contiguous_vector_char = (char*)contiguous_vector; char* noncontiguous_vector_char = (char*)noncontiguous_vector+type_c->lb; - - memcpy(noncontiguous_vector_char, - contiguous_vector_char, count* type_c->block_count * type_c->size_oldtype); + int n= count* type_c->block_count; + smpi_op_apply(op, contiguous_vector_char, noncontiguous_vector_char, &n, + &type_c->old_type); + /*memcpy(noncontiguous_vector_char, + contiguous_vector_char, count* type_c->block_count * type_c->size_oldtype);*/ } void free_contiguous(MPI_Datatype* d){ @@ -522,7 +618,7 @@ Hvector Implementation - Vector with stride in bytes */ void serialize_hvector( const void *noncontiguous_hvector, void *contiguous_hvector, - size_t count, + int count, void *type) { s_smpi_mpi_hvector_t* type_c = (s_smpi_mpi_hvector_t*)type; @@ -558,8 +654,9 @@ void serialize_hvector( const void *noncontiguous_hvector, */ void unserialize_hvector( const void *contiguous_vector, void *noncontiguous_vector, - size_t count, - void *type) + int count, + void *type, + MPI_Op op) { s_smpi_mpi_hvector_t* type_c = (s_smpi_mpi_hvector_t*)type; int i; @@ -569,13 +666,16 @@ void unserialize_hvector( const void *contiguous_vector, for (i = 0; i < type_c->block_count * count; i++) { if (type_c->old_type->has_subtype == 0) - memcpy(noncontiguous_vector_char, - contiguous_vector_char, type_c->block_length * type_c->size_oldtype); + smpi_op_apply(op, contiguous_vector_char, noncontiguous_vector_char, &type_c->block_length, + &type_c->old_type); + /*memcpy(noncontiguous_vector_char, + contiguous_vector_char, type_c->block_length * type_c->size_oldtype);*/ else ((s_smpi_subtype_t*)type_c->old_type->substruct)->unserialize( contiguous_vector_char, noncontiguous_vector_char, type_c->block_length, - type_c->old_type->substruct); + type_c->old_type->substruct, + op); contiguous_vector_char += type_c->block_length*type_c->size_oldtype; if((i+1)%type_c->block_count ==0) noncontiguous_vector_char += type_c->block_length*type_c->size_oldtype; @@ -664,7 +764,7 @@ Indexed Implementation */ void serialize_indexed( const void *noncontiguous_indexed, void *contiguous_indexed, - size_t count, + int count, void *type) { s_smpi_mpi_indexed_t* type_c = (s_smpi_mpi_indexed_t*)type; @@ -701,8 +801,9 @@ void serialize_indexed( const void *noncontiguous_indexed, */ void unserialize_indexed( const void *contiguous_indexed, void *noncontiguous_indexed, - size_t count, - void *type) + int count, + void *type, + MPI_Op op) { s_smpi_mpi_indexed_t* type_c = (s_smpi_mpi_indexed_t*)type; @@ -712,13 +813,16 @@ void unserialize_indexed( const void *contiguous_indexed, for(j=0; jblock_count; i++) { if (type_c->old_type->has_subtype == 0) - memcpy(noncontiguous_indexed_char , - contiguous_indexed_char, type_c->block_lengths[i] * type_c->size_oldtype); + smpi_op_apply(op, contiguous_indexed_char, noncontiguous_indexed_char, &type_c->block_lengths[i], + &type_c->old_type); + /*memcpy(noncontiguous_indexed_char , + contiguous_indexed_char, type_c->block_lengths[i] * type_c->size_oldtype);*/ else ((s_smpi_subtype_t*)type_c->old_type->substruct)->unserialize( contiguous_indexed_char, noncontiguous_indexed_char, type_c->block_lengths[i], - type_c->old_type->substruct); + type_c->old_type->substruct, + op); contiguous_indexed_char += type_c->block_lengths[i]*type_c->size_oldtype; if (iblock_count-1) @@ -829,7 +933,7 @@ Hindexed Implementation - Indexed with indices in bytes */ void serialize_hindexed( const void *noncontiguous_hindexed, void *contiguous_hindexed, - size_t count, + int count, void *type) { s_smpi_mpi_hindexed_t* type_c = (s_smpi_mpi_hindexed_t*)type; @@ -865,8 +969,9 @@ void serialize_hindexed( const void *noncontiguous_hindexed, */ void unserialize_hindexed( const void *contiguous_hindexed, void *noncontiguous_hindexed, - size_t count, - void *type) + int count, + void *type, + MPI_Op op) { s_smpi_mpi_hindexed_t* type_c = (s_smpi_mpi_hindexed_t*)type; int i,j; @@ -876,13 +981,16 @@ void unserialize_hindexed( const void *contiguous_hindexed, for(j=0; jblock_count; i++) { if (type_c->old_type->has_subtype == 0) - memcpy(noncontiguous_hindexed_char, - contiguous_hindexed_char, type_c->block_lengths[i] * type_c->size_oldtype); + smpi_op_apply(op, contiguous_hindexed_char, noncontiguous_hindexed_char, &type_c->block_lengths[i], + &type_c->old_type); + /*memcpy(noncontiguous_hindexed_char, + contiguous_hindexed_char, type_c->block_lengths[i] * type_c->size_oldtype);*/ else ((s_smpi_subtype_t*)type_c->old_type->substruct)->unserialize( contiguous_hindexed_char, noncontiguous_hindexed_char, type_c->block_lengths[i], - type_c->old_type->substruct); + type_c->old_type->substruct, + op); contiguous_hindexed_char += type_c->block_lengths[i]*type_c->size_oldtype; if (iblock_count-1)noncontiguous_hindexed_char = (char*)noncontiguous_hindexed + type_c->block_indices[i+1]; @@ -991,7 +1099,7 @@ struct Implementation - Indexed with indices in bytes */ void serialize_struct( const void *noncontiguous_struct, void *contiguous_struct, - size_t count, + int count, void *type) { s_smpi_mpi_struct_t* type_c = (s_smpi_mpi_struct_t*)type; @@ -1028,8 +1136,9 @@ void serialize_struct( const void *noncontiguous_struct, */ void unserialize_struct( const void *contiguous_struct, void *noncontiguous_struct, - size_t count, - void *type) + int count, + void *type, + MPI_Op op) { s_smpi_mpi_struct_t* type_c = (s_smpi_mpi_struct_t*)type; int i,j; @@ -1039,13 +1148,16 @@ void unserialize_struct( const void *contiguous_struct, for(j=0; jblock_count; i++) { if (type_c->old_types[i]->has_subtype == 0) - memcpy(noncontiguous_struct_char, - contiguous_struct_char, type_c->block_lengths[i] * smpi_datatype_size(type_c->old_types[i])); + smpi_op_apply(op, contiguous_struct_char, noncontiguous_struct_char, &type_c->block_lengths[i], + & type_c->old_types[i]); + /*memcpy(noncontiguous_struct_char, + contiguous_struct_char, type_c->block_lengths[i] * smpi_datatype_size(type_c->old_types[i]));*/ else ((s_smpi_subtype_t*)type_c->old_types[i]->substruct)->unserialize( contiguous_struct_char, noncontiguous_struct_char, type_c->block_lengths[i], - type_c->old_types[i]->substruct); + type_c->old_types[i]->substruct, + op); contiguous_struct_char += type_c->block_lengths[i]*smpi_datatype_size(type_c->old_types[i]); if (iblock_count-1)noncontiguous_struct_char = (char*)noncontiguous_struct + type_c->block_indices[i+1]; @@ -1172,7 +1284,6 @@ typedef struct s_smpi_mpi_op { #define BXOR_OP(a, b) (b) ^= (a) #define MAXLOC_OP(a, b) (b) = (a.value) < (b.value) ? (b) : (a) #define MINLOC_OP(a, b) (b) = (a.value) < (b.value) ? (a) : (b) -#define REPLACE_OP(a,b) (b) = (a) #define APPLY_FUNC(a, b, length, type, func) \ { \ @@ -1201,6 +1312,8 @@ static void max_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, MAX_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, MAX_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, MAX_OP); } else if (*datatype == MPI_FLOAT) { APPLY_FUNC(a, b, length, float, MAX_OP); } else if (*datatype == MPI_DOUBLE) { @@ -1227,6 +1340,8 @@ static void min_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, MIN_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, MIN_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, MIN_OP); } else if (*datatype == MPI_FLOAT) { APPLY_FUNC(a, b, length, float, MIN_OP); } else if (*datatype == MPI_DOUBLE) { @@ -1253,6 +1368,8 @@ static void sum_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, SUM_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, SUM_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, SUM_OP); } else if (*datatype == MPI_FLOAT) { APPLY_FUNC(a, b, length, float, SUM_OP); } else if (*datatype == MPI_DOUBLE) { @@ -1285,6 +1402,8 @@ static void prod_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, PROD_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, PROD_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, PROD_OP); } else if (*datatype == MPI_FLOAT) { APPLY_FUNC(a, b, length, float, PROD_OP); } else if (*datatype == MPI_DOUBLE) { @@ -1317,6 +1436,8 @@ static void land_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, LAND_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, LAND_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, LAND_OP); } else if (*datatype == MPI_C_BOOL) { APPLY_FUNC(a, b, length, _Bool, LAND_OP); } @@ -1339,6 +1460,8 @@ static void lor_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, LOR_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, LOR_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, LOR_OP); } else if (*datatype == MPI_C_BOOL) { APPLY_FUNC(a, b, length, _Bool, LOR_OP); } @@ -1361,6 +1484,8 @@ static void lxor_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, LXOR_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, LXOR_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, LXOR_OP); } else if (*datatype == MPI_C_BOOL) { APPLY_FUNC(a, b, length, _Bool, LXOR_OP); } @@ -1371,8 +1496,7 @@ static void band_func(void *a, void *b, int *length, { if (*datatype == MPI_CHAR) { APPLY_FUNC(a, b, length, char, BAND_OP); - } - if (*datatype == MPI_SHORT) { + }else if (*datatype == MPI_SHORT) { APPLY_FUNC(a, b, length, short, BAND_OP); } else if (*datatype == MPI_INT) { APPLY_FUNC(a, b, length, int, BAND_OP); @@ -1384,6 +1508,8 @@ static void band_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, BAND_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, BAND_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, BAND_OP); } else if (*datatype == MPI_BYTE) { APPLY_FUNC(a, b, length, uint8_t, BAND_OP); } @@ -1406,6 +1532,8 @@ static void bor_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, BOR_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, BOR_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, BOR_OP); } else if (*datatype == MPI_BYTE) { APPLY_FUNC(a, b, length, uint8_t, BOR_OP); } @@ -1428,6 +1556,8 @@ static void bxor_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, unsigned int, BXOR_OP); } else if (*datatype == MPI_UNSIGNED_LONG) { APPLY_FUNC(a, b, length, unsigned long, BXOR_OP); + } else if (*datatype == MPI_UNSIGNED_CHAR) { + APPLY_FUNC(a, b, length, unsigned char, BXOR_OP); } else if (*datatype == MPI_BYTE) { APPLY_FUNC(a, b, length, uint8_t, BXOR_OP); } @@ -1444,6 +1574,8 @@ static void minloc_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, double_int, MINLOC_OP); } else if (*datatype == MPI_SHORT_INT) { APPLY_FUNC(a, b, length, short_int, MINLOC_OP); + } else if (*datatype == MPI_2LONG) { + APPLY_FUNC(a, b, length, long_long, MINLOC_OP); } else if (*datatype == MPI_2INT) { APPLY_FUNC(a, b, length, int_int, MINLOC_OP); } else if (*datatype == MPI_LONG_DOUBLE_INT) { @@ -1466,6 +1598,8 @@ static void maxloc_func(void *a, void *b, int *length, APPLY_FUNC(a, b, length, double_int, MAXLOC_OP); } else if (*datatype == MPI_SHORT_INT) { APPLY_FUNC(a, b, length, short_int, MAXLOC_OP); + } else if (*datatype == MPI_2LONG) { + APPLY_FUNC(a, b, length, long_long, MAXLOC_OP); } else if (*datatype == MPI_2INT) { APPLY_FUNC(a, b, length, int_int, MAXLOC_OP); } else if (*datatype == MPI_LONG_DOUBLE_INT) { @@ -1480,23 +1614,7 @@ static void maxloc_func(void *a, void *b, int *length, static void replace_func(void *a, void *b, int *length, MPI_Datatype * datatype) { - if (*datatype == MPI_CHAR) { - APPLY_FUNC(a, b, length, char, REPLACE_OP); - } else if (*datatype == MPI_SHORT) { - APPLY_FUNC(a, b, length, short, REPLACE_OP); - } else if (*datatype == MPI_INT) { - APPLY_FUNC(a, b, length, int, REPLACE_OP); - } else if (*datatype == MPI_LONG) { - APPLY_FUNC(a, b, length, long, REPLACE_OP); - } else if (*datatype == MPI_UNSIGNED_SHORT) { - APPLY_FUNC(a, b, length, unsigned short, REPLACE_OP); - } else if (*datatype == MPI_UNSIGNED) { - APPLY_FUNC(a, b, length, unsigned int, REPLACE_OP); - } else if (*datatype == MPI_UNSIGNED_LONG) { - APPLY_FUNC(a, b, length, unsigned long, REPLACE_OP); - } else if (*datatype == MPI_BYTE) { - APPLY_FUNC(a, b, length, uint8_t, REPLACE_OP); - } + memcpy(b, a, *length * smpi_datatype_size(*datatype)); } #define CREATE_MPI_OP(name, func) \ @@ -1540,11 +1658,136 @@ void smpi_op_destroy(MPI_Op op) void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len, MPI_Datatype * datatype) { + if(op==MPI_OP_NULL) + return; + if(smpi_privatize_global_variables){ //we need to switch here, as the called function may silently touch global variables - XBT_VERB("Applying operation, switch to the right data frame "); - switch_data_segment(smpi_process_index()); + XBT_DEBUG("Applying operation, switch to the right data frame "); + smpi_switch_data_segment(smpi_process_index()); } - if(!_xbt_replay_is_active()) + if(!smpi_process_get_replaying()) op->func(invec, inoutvec, len, datatype); } + +int smpi_type_attr_delete(MPI_Datatype type, int keyval){ + char* tmpkey=xbt_malloc(INTSIZEDCHAR); + sprintf(tmpkey, "%d", keyval); + smpi_type_key_elem elem = xbt_dict_get_or_null(smpi_type_keyvals, (const char*)tmpkey); + if(!elem) + return MPI_ERR_ARG; + if(elem->delete_fn!=MPI_NULL_DELETE_FN){ + void * value; + int flag; + if(smpi_type_attr_get(type, keyval, &value, &flag)==MPI_SUCCESS){ + int ret = elem->delete_fn(type, keyval, value, &flag); + if(ret!=MPI_SUCCESS) return ret; + } + } + if(type->attributes==NULL) + return MPI_ERR_ARG; + + xbt_dict_remove(type->attributes, (const char*)tmpkey); + xbt_free(tmpkey); + return MPI_SUCCESS; +} + +int smpi_type_attr_get(MPI_Datatype type, int keyval, void* attr_value, int* flag){ + char* tmpkey=xbt_malloc(INTSIZEDCHAR); + sprintf(tmpkey, "%d", keyval); + smpi_type_key_elem elem = xbt_dict_get_or_null(smpi_type_keyvals, (const char*)tmpkey); + if(!elem) + return MPI_ERR_ARG; + xbt_ex_t ex; + if(type->attributes==NULL){ + *flag=0; + return MPI_SUCCESS; + } + TRY { + *(void**)attr_value = xbt_dict_get(type->attributes, (const char*)tmpkey); + *flag=1; + } + CATCH(ex) { + *flag=0; + xbt_ex_free(ex); + } + xbt_free(tmpkey); + return MPI_SUCCESS; +} + +int smpi_type_attr_put(MPI_Datatype type, int keyval, void* attr_value){ + if(!smpi_type_keyvals) + smpi_type_keyvals = xbt_dict_new(); + char* tmpkey=xbt_malloc(INTSIZEDCHAR); + sprintf(tmpkey, "%d", keyval); + smpi_type_key_elem elem = xbt_dict_get_or_null(smpi_type_keyvals, (const char*)tmpkey); + if(!elem ) + return MPI_ERR_ARG; + int flag; + void* value; + smpi_type_attr_get(type, keyval, &value, &flag); + if(flag && elem->delete_fn!=MPI_NULL_DELETE_FN){ + int ret = elem->delete_fn(type, keyval, value, &flag); + if(ret!=MPI_SUCCESS) return ret; + } + if(type->attributes==NULL) + type->attributes=xbt_dict_new(); + + xbt_dict_set(type->attributes, (const char*)tmpkey, attr_value, NULL); + xbt_free(tmpkey); + return MPI_SUCCESS; +} + +int smpi_type_keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state){ + + if(!smpi_type_keyvals) + smpi_type_keyvals = xbt_dict_new(); + + smpi_type_key_elem value = (smpi_type_key_elem) xbt_new0(s_smpi_mpi_type_key_elem_t,1); + + value->copy_fn=copy_fn; + value->delete_fn=delete_fn; + + *keyval = type_keyval_id; + char* tmpkey=xbt_malloc(INTSIZEDCHAR); + sprintf(tmpkey, "%d", *keyval); + xbt_dict_set(smpi_type_keyvals,(const char*)tmpkey,(void*)value, NULL); + type_keyval_id++; + xbt_free(tmpkey); + return MPI_SUCCESS; +} + +int smpi_type_keyval_free(int* keyval){ + char* tmpkey=xbt_malloc(INTSIZEDCHAR); + sprintf(tmpkey, "%d", *keyval); + smpi_type_key_elem elem = xbt_dict_get_or_null(smpi_type_keyvals, (const char*)tmpkey); + if(!elem){ + xbt_free(tmpkey); + return MPI_ERR_ARG; + } + xbt_dict_remove(smpi_type_keyvals, (const char*)tmpkey); + xbt_free(elem); + xbt_free(tmpkey); + return MPI_SUCCESS; +} + +int smpi_mpi_pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm){ + size_t size = smpi_datatype_size(type); + if (outcount - *position < incount*size) + return MPI_ERR_BUFFER; + smpi_datatype_copy(inbuf, incount, type, + (char*)outbuf + *position, outcount, MPI_CHAR); + *position += incount * size; + return MPI_SUCCESS; +} + +int smpi_mpi_unpack(void* inbuf, int insize, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm){ + size_t size = smpi_datatype_size(type); + if (outcount*size> insize) + return MPI_ERR_BUFFER; + smpi_datatype_copy((char*)inbuf + *position, insize, MPI_CHAR, + outbuf, outcount, type); + *position += outcount * size; + return MPI_SUCCESS; +} +