From f7bfc7f9646c3f1c3b350a78b2fae5a35ea939f7 Mon Sep 17 00:00:00 2001 From: Augustin Degomme Date: Tue, 11 Jun 2013 16:14:10 +0200 Subject: [PATCH] Fix bug happening with MPI_Datatypes Provide better support for contiguous datatypes --- src/smpi/private.h | 2 +- src/smpi/smpi_mpi_dt.c | 124 +++++++++++++++++++++++++++++---- src/smpi/smpi_mpi_dt_private.h | 24 +++++++ src/smpi/smpi_pmpi.c | 2 +- 4 files changed, 135 insertions(+), 17 deletions(-) diff --git a/src/smpi/private.h b/src/smpi/private.h index 1f7d45d14a..cf468565ca 100644 --- a/src/smpi/private.h +++ b/src/smpi/private.h @@ -114,7 +114,7 @@ void smpi_datatype_use(MPI_Datatype type); void smpi_datatype_unuse(MPI_Datatype type); int smpi_datatype_contiguous(int count, MPI_Datatype old_type, - MPI_Datatype* new_type); + MPI_Datatype* new_type, MPI_Aint lb); int smpi_datatype_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type); diff --git a/src/smpi/smpi_mpi_dt.c b/src/smpi/smpi_mpi_dt.c index 6041b85688..e42513b15f 100644 --- a/src/smpi/smpi_mpi_dt.c +++ b/src/smpi/smpi_mpi_dt.c @@ -323,17 +323,100 @@ void smpi_datatype_unuse(MPI_Datatype type){ smpi_datatype_free(&type); } -int smpi_datatype_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) + + + +/* +Contiguous Implementation +*/ + + +/* + * Copies noncontiguous data into contiguous memory. + * @param contiguous_hvector - output hvector + * @param noncontiguous_hvector - input hvector + * @param type - pointer contening : + * - stride - stride of between noncontiguous data, in bytes + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void serialize_contiguous( const void *noncontiguous_hvector, + void *contiguous_hvector, + size_t count, + void *type) +{ + s_smpi_mpi_contiguous_t* type_c = (s_smpi_mpi_contiguous_t*)type; + char* contiguous_vector_char = (char*)contiguous_hvector; + char* noncontiguous_vector_char = (char*)noncontiguous_hvector+type_c->lb; + memcpy(contiguous_vector_char, + noncontiguous_vector_char, count* type_c->block_count * type_c->size_oldtype); +} +/* + * Copies contiguous data into noncontiguous memory. + * @param noncontiguous_vector - output hvector + * @param contiguous_vector - input hvector + * @param type - pointer contening : + * - stride - stride of between noncontiguous data, in bytes + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void unserialize_contiguous( const void *contiguous_vector, + void *noncontiguous_vector, + size_t count, + void *type) +{ + 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); +} + +void free_contiguous(MPI_Datatype* d){ +} + +/* + * Create a Sub type contiguous to be able to serialize and unserialize it + * the structure s_smpi_mpi_contiguous_t is derived from s_smpi_subtype which + * required the functions unserialize and serialize + * + */ +s_smpi_mpi_contiguous_t* smpi_datatype_contiguous_create( MPI_Aint lb, + int block_count, + MPI_Datatype old_type, + int size_oldtype){ + s_smpi_mpi_contiguous_t *new_t= xbt_new(s_smpi_mpi_contiguous_t,1); + new_t->base.serialize = &serialize_contiguous; + new_t->base.unserialize = &unserialize_contiguous; + new_t->base.subtype_free = &free_contiguous; + new_t->lb = lb; + new_t->block_count = block_count; + new_t->old_type = old_type; + new_t->size_oldtype = size_oldtype; + return new_t; +} + + + + +int smpi_datatype_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type, MPI_Aint lb) { int retval; if(old_type->has_subtype){ //handle this case as a hvector with stride equals to the extent of the datatype return smpi_datatype_hvector(count, 1, smpi_datatype_get_extent(old_type), old_type, new_type); } + + s_smpi_mpi_contiguous_t* subtype = smpi_datatype_contiguous_create( lb, + count, + old_type, + smpi_datatype_size(old_type)); + smpi_datatype_create(new_type, count * smpi_datatype_size(old_type), - 0,count * smpi_datatype_size(old_type), - 0,NULL, DT_FLAG_CONTIGUOUS); + lb,lb + count * smpi_datatype_size(old_type), + 1,subtype, DT_FLAG_CONTIGUOUS); retval=MPI_SUCCESS; return retval; } @@ -536,7 +619,7 @@ void serialize_indexed( const void *noncontiguous_indexed, s_smpi_mpi_indexed_t* type_c = (s_smpi_mpi_indexed_t*)type; int i,j; char* contiguous_indexed_char = (char*)contiguous_indexed; - char* noncontiguous_indexed_char = (char*)noncontiguous_indexed; + char* noncontiguous_indexed_char = (char*)noncontiguous_indexed+type_c->block_indices[0] * type_c->size_oldtype; for(j=0; jblock_count; i++) { if (type_c->old_type->has_subtype == 0) @@ -570,15 +653,15 @@ void unserialize_indexed( const void *contiguous_indexed, size_t count, void *type) { + s_smpi_mpi_indexed_t* type_c = (s_smpi_mpi_indexed_t*)type; int i,j; - char* contiguous_indexed_char = (char*)contiguous_indexed; - char* noncontiguous_indexed_char = (char*)noncontiguous_indexed; + char* noncontiguous_indexed_char = (char*)noncontiguous_indexed+type_c->block_indices[0]*smpi_datatype_get_extent(type_c->old_type); for(j=0; jblock_count; i++) { if (type_c->old_type->has_subtype == 0) - memcpy(noncontiguous_indexed_char, + 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, @@ -666,9 +749,12 @@ int smpi_datatype_indexed(int count, int* blocklens, int* indices, MPI_Datatype smpi_datatype_create(new_type, size * smpi_datatype_size(old_type),lb,ub,1, subtype, DT_FLAG_DATA); }else{ + s_smpi_mpi_contiguous_t* subtype = smpi_datatype_contiguous_create( lb, + size, + old_type, + smpi_datatype_size(old_type)); smpi_datatype_create(new_type, size * - smpi_datatype_size(old_type),0,size * - smpi_datatype_size(old_type),0, NULL, DT_FLAG_DATA|DT_FLAG_CONTIGUOUS); + smpi_datatype_size(old_type),lb,ub,1, subtype, DT_FLAG_DATA|DT_FLAG_CONTIGUOUS); } retval=MPI_SUCCESS; return retval; @@ -696,7 +782,7 @@ void serialize_hindexed( const void *noncontiguous_hindexed, s_smpi_mpi_hindexed_t* type_c = (s_smpi_mpi_hindexed_t*)type; int i,j; char* contiguous_hindexed_char = (char*)contiguous_hindexed; - char* noncontiguous_hindexed_char = (char*)noncontiguous_hindexed; + char* noncontiguous_hindexed_char = (char*)noncontiguous_hindexed+ type_c->block_indices[0]; for(j=0; jblock_count; i++) { if (type_c->old_type->has_subtype == 0) @@ -733,7 +819,7 @@ void unserialize_hindexed( const void *contiguous_hindexed, int i,j; char* contiguous_hindexed_char = (char*)contiguous_hindexed; - char* noncontiguous_hindexed_char = (char*)noncontiguous_hindexed; + char* noncontiguous_hindexed_char = (char*)noncontiguous_hindexed+ type_c->block_indices[0]; for(j=0; jblock_count; i++) { if (type_c->old_type->has_subtype == 0) @@ -823,9 +909,13 @@ int smpi_datatype_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Dat ub ,1, subtype, DT_FLAG_DATA); }else{ + s_smpi_mpi_contiguous_t* subtype = smpi_datatype_contiguous_create( lb, + size, + old_type, + smpi_datatype_size(old_type)); smpi_datatype_create(new_type, size * smpi_datatype_size(old_type), 0,size * smpi_datatype_size(old_type), - 0, NULL, DT_FLAG_DATA|DT_FLAG_CONTIGUOUS); + 1, subtype, DT_FLAG_DATA|DT_FLAG_CONTIGUOUS); } retval=MPI_SUCCESS; return retval; @@ -853,7 +943,7 @@ void serialize_struct( const void *noncontiguous_struct, s_smpi_mpi_struct_t* type_c = (s_smpi_mpi_struct_t*)type; int i,j; char* contiguous_struct_char = (char*)contiguous_struct; - char* noncontiguous_struct_char = (char*)noncontiguous_struct; + char* noncontiguous_struct_char = (char*)noncontiguous_struct+ type_c->block_indices[0]; for(j=0; jblock_count; i++) { if (type_c->old_types[i]->has_subtype == 0) @@ -891,7 +981,7 @@ void unserialize_struct( const void *contiguous_struct, int i,j; char* contiguous_struct_char = (char*)contiguous_struct; - char* noncontiguous_struct_char = (char*)noncontiguous_struct; + char* noncontiguous_struct_char = (char*)noncontiguous_struct+ type_c->block_indices[0]; for(j=0; jblock_count; i++) { if (type_c->old_types[i]->has_subtype == 0) @@ -993,7 +1083,11 @@ int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datat smpi_datatype_create(new_type, size, lb, ub,1, subtype, DT_FLAG_DATA); }else{ - smpi_datatype_create(new_type, size, lb, ub,0, NULL, DT_FLAG_DATA|DT_FLAG_CONTIGUOUS); + s_smpi_mpi_contiguous_t* subtype = smpi_datatype_contiguous_create( lb, + size, + MPI_CHAR, + 1); + smpi_datatype_create(new_type, size, lb, ub,1, subtype, DT_FLAG_DATA|DT_FLAG_CONTIGUOUS); } return MPI_SUCCESS; } diff --git a/src/smpi/smpi_mpi_dt_private.h b/src/smpi/smpi_mpi_dt_private.h index 656754d8c8..23af198871 100644 --- a/src/smpi/smpi_mpi_dt_private.h +++ b/src/smpi/smpi_mpi_dt_private.h @@ -40,6 +40,14 @@ extern MPI_Datatype MPI_PTR; used for serialization/unserialization of messages */ +typedef struct s_smpi_mpi_contiguous{ + s_smpi_subtype_t base; + MPI_Datatype old_type; + MPI_Aint lb; + size_t size_oldtype; + size_t block_count; +} s_smpi_mpi_contiguous_t; + typedef struct s_smpi_mpi_vector{ s_smpi_subtype_t base; MPI_Datatype old_type; @@ -90,7 +98,23 @@ typedef struct s_smpi_mpi_struct{ Functions to handle serialization/unserialization of messages, 3 for each type of MPI_Type One for creating the substructure to handle, one for serialization, one for unserialization */ +void unserialize_contiguous( const void *contiguous_vector, + void *noncontiguous_vector, + size_t count, + void *type); +void serialize_contiguous( const void *noncontiguous_vector, + void *contiguous_vector, + size_t count, + void *type); + +void free_contiguous(MPI_Datatype* type); + +s_smpi_mpi_contiguous_t* smpi_datatype_contiguous_create( MPI_Aint lb, + int block_count, + MPI_Datatype old_type, + int size_oldtype); + void unserialize_vector( const void *contiguous_vector, void *noncontiguous_vector, size_t count, diff --git a/src/smpi/smpi_pmpi.c b/src/smpi/smpi_pmpi.c index 42d62948d4..988f0ad59c 100644 --- a/src/smpi/smpi_pmpi.c +++ b/src/smpi/smpi_pmpi.c @@ -2023,7 +2023,7 @@ int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_typ } else if (count<0){ retval = MPI_ERR_COUNT; } else { - retval = smpi_datatype_contiguous(count, old_type, new_type); + retval = smpi_datatype_contiguous(count, old_type, new_type, 0); } smpi_bench_begin(); return retval; -- 2.20.1