From 447691d4daf70a0d086309bd91bae1cfc5ba6af5 Mon Sep 17 00:00:00 2001 From: degomme Date: Sun, 5 Oct 2014 20:17:05 +0200 Subject: [PATCH] Add MPI_Type*keyval and MPI_Type*attr functions --- src/smpi/private.h | 16 +- src/smpi/smpi_comm.c | 1 - src/smpi/smpi_mpi_dt.c | 153 +++++++++++++++++- src/smpi/smpi_pmpi.c | 62 +++---- .../smpi/mpich3-test/attr/CMakeLists.txt | 12 +- teshsuite/smpi/mpich3-test/attr/testlist | 11 +- 6 files changed, 203 insertions(+), 52 deletions(-) diff --git a/src/smpi/private.h b/src/smpi/private.h index d6b87e070d..d799e81f55 100644 --- a/src/smpi/private.h +++ b/src/smpi/private.h @@ -58,6 +58,7 @@ typedef struct s_smpi_mpi_datatype{ MPI_Aint lb; MPI_Aint ub; int flags; + xbt_dict_t attributes; /* this let us know how to serialize and unserialize*/ void *substruct; int in_use; @@ -119,6 +120,12 @@ typedef struct s_smpi_mpi_key_elem { } s_smpi_mpi_key_elem_t; typedef struct s_smpi_mpi_key_elem *smpi_key_elem; +typedef struct s_smpi_mpi_type_key_elem { + MPI_Type_copy_attr_function* copy_fn; + MPI_Type_delete_attr_function* delete_fn; +} s_smpi_mpi_type_key_elem_t; +typedef struct s_smpi_mpi_type_key_elem *smpi_type_key_elem; + void smpi_process_destroy(void); void smpi_process_finalize(void); int smpi_process_finalized(void); @@ -196,7 +203,7 @@ int is_datatype_valid(MPI_Datatype datatype); size_t smpi_datatype_size(MPI_Datatype datatype); MPI_Aint smpi_datatype_lb(MPI_Datatype datatype); MPI_Aint smpi_datatype_ub(MPI_Datatype datatype); -MPI_Datatype smpi_datatype_dup(MPI_Datatype datatype); +int smpi_datatype_dup(MPI_Datatype datatype, MPI_Datatype* new_t); int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent); MPI_Aint smpi_datatype_get_extent(MPI_Datatype datatype); @@ -415,8 +422,11 @@ int smpi_keyval_free(int* keyval); int smpi_attr_delete(MPI_Comm comm, int keyval); int smpi_attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag); int smpi_attr_put(MPI_Comm comm, int keyval, void* attr_value); - - +int smpi_type_attr_delete(MPI_Datatype type, int keyval); +int smpi_type_attr_get(MPI_Datatype type, int keyval, void* attr_value, int* flag); +int smpi_type_attr_put(MPI_Datatype type, int keyval, void* attr_value); +int smpi_type_keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state); +int smpi_type_keyval_free(int* keyval); // utilities extern double smpi_cpu_threshold; extern double smpi_running_power; diff --git a/src/smpi/smpi_comm.c b/src/smpi/smpi_comm.c index ee2a7c32dc..b1fb5b2fd5 100644 --- a/src/smpi/smpi_comm.c +++ b/src/smpi/smpi_comm.c @@ -556,7 +556,6 @@ int smpi_comm_attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag){ *flag=0; xbt_ex_free(ex); } - return MPI_SUCCESS; } diff --git a/src/smpi/smpi_mpi_dt.c b/src/smpi/smpi_mpi_dt.c index e943324a7c..2a9a464b10 100644 --- a/src/smpi/smpi_mpi_dt.c +++ b/src/smpi/smpi_mpi_dt.c @@ -20,6 +20,9 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi, "Logging specific to SMPI (datatype)"); +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, \ @@ -28,7 +31,8 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi, 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; @@ -40,6 +44,7 @@ MPI_Datatype name = &mpi_##name; 0, /* lb */ \ 0, /* ub = lb + size */ \ DT_FLAG_BASIC, /* flags */ \ + NULL, /* attributes */ \ NULL /* pointer on extended struct*/ \ }; \ MPI_Datatype name = &mpi_##name; @@ -168,15 +173,39 @@ 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)); + 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); - return new_t; + (*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, @@ -364,6 +393,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 @@ -373,6 +403,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(*type, atoi((const char*)key), &value, &flag); + } + } if((*type)->flags & DT_FLAG_PREDEFINED)return; @@ -1626,3 +1667,99 @@ void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len, 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(sizeof(int)); + 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); + return MPI_SUCCESS; +} + +int smpi_type_attr_get(MPI_Datatype type, int keyval, void* attr_value, int* flag){ + char* tmpkey=xbt_malloc(sizeof(int)); + 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 { + char* tmpkey=xbt_malloc(sizeof(int)); + sprintf(tmpkey, "%d", keyval); + *(void**)attr_value = xbt_dict_get(type->attributes, (const char*)tmpkey); + *flag=1; + } + CATCH(ex) { + *flag=0; + xbt_ex_free(ex); + } + 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(sizeof(int)); + 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); + 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(sizeof(int)); + sprintf(tmpkey, "%d", *keyval); + xbt_dict_set(smpi_type_keyvals,(const char*)tmpkey,(void*)value, NULL); + type_keyval_id++; + return MPI_SUCCESS; +} + +int smpi_type_keyval_free(int* keyval){ + smpi_type_key_elem elem = xbt_dict_get_or_null(smpi_type_keyvals, (const char*)keyval); + if(!elem) + return MPI_ERR_ARG; + char* tmpkey=xbt_malloc(sizeof(int)); + sprintf(tmpkey, "%d", *keyval); + xbt_dict_remove(smpi_type_keyvals, (const char*)tmpkey); + xbt_free(elem); + return MPI_SUCCESS; +} diff --git a/src/smpi/smpi_pmpi.c b/src/smpi/smpi_pmpi.c index a40bccb707..6d6f958cfd 100644 --- a/src/smpi/smpi_pmpi.c +++ b/src/smpi/smpi_pmpi.c @@ -253,8 +253,7 @@ int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){ if (datatype == MPI_DATATYPE_NULL) { retval = MPI_ERR_TYPE; } else { - *newtype = smpi_datatype_dup(datatype); - retval = MPI_SUCCESS; + retval = smpi_datatype_dup(datatype, newtype); } return retval; } @@ -3001,7 +3000,6 @@ int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) { return smpi_attr_put(comm, keyval, attr_value); } - int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag) { return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag); @@ -3026,6 +3024,40 @@ int PMPI_Comm_free_keyval(int* keyval) { return PMPI_Keyval_free(keyval); } + +int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag) +{ + if (type==MPI_DATATYPE_NULL) + return MPI_ERR_TYPE; + else + return smpi_type_attr_get(type, type_keyval, attribute_val, flag); +} + +int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val) +{ + if (type==MPI_DATATYPE_NULL) + return MPI_ERR_TYPE; + else + return smpi_type_attr_put(type, type_keyval, attribute_val); +} + +int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval) +{ + if (type==MPI_DATATYPE_NULL) + return MPI_ERR_TYPE; + else + return smpi_type_attr_delete(type, type_keyval); +} + +int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state) +{ + return smpi_type_keyval_create(copy_fn, delete_fn, keyval, extra_state); +} + +int PMPI_Type_free_keyval(int* keyval) { + return smpi_type_keyval_free(keyval); +} + /* The following calls are not yet implemented and will fail at runtime. */ /* Once implemented, please move them above this notice. */ @@ -3146,30 +3178,6 @@ int PMPI_Unpack(void* inbuf, int insize, int* position, void* outbuf, int outcou NOT_YET_IMPLEMENTED } -int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag) -{ - NOT_YET_IMPLEMENTED -} - -int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val) -{ - NOT_YET_IMPLEMENTED -} - -int PMPI_Type_delete_attr (MPI_Datatype type, int comm_keyval) -{ - NOT_YET_IMPLEMENTED -} - -int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state) -{ - NOT_YET_IMPLEMENTED -} - -int PMPI_Type_free_keyval(int* keyval) { - NOT_YET_IMPLEMENTED -} - int PMPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* comm_out) { NOT_YET_IMPLEMENTED } diff --git a/teshsuite/smpi/mpich3-test/attr/CMakeLists.txt b/teshsuite/smpi/mpich3-test/attr/CMakeLists.txt index c4772079bd..3d71bdf407 100644 --- a/teshsuite/smpi/mpich3-test/attr/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/attr/CMakeLists.txt @@ -13,16 +13,16 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) include_directories("${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") -# add_executable(attr2type attr2type.c) + add_executable(attr2type attr2type.c) add_executable(attrend2 attrend2.c) add_executable(attrend attrend.c) add_executable(attrerr attrerr.c) add_executable(attrerrcomm attrerrcomm.c) -# add_executable(attrerrtype attrerrtype.c) + add_executable(attrerrtype attrerrtype.c) # add_executable(attric attric.c) add_executable(attrorder attrorder.c) add_executable(attrordercomm attrordercomm.c) -# add_executable(attrordertype attrordertype.c) + add_executable(attrordertype attrordertype.c) add_executable(attrt attrt.c) add_executable(baseattr2 baseattr2.c) add_executable(baseattrcomm baseattrcomm.c) @@ -31,16 +31,16 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) # add_executable(fkeyvaltype fkeyvaltype.c) # add_executable(keyval_double_free keyval_double_free.c) -# target_link_libraries(attr2type simgrid mtest_c) + target_link_libraries(attr2type simgrid mtest_c) target_link_libraries(attrend2 simgrid mtest_c) target_link_libraries(attrend simgrid mtest_c) target_link_libraries(attrerr simgrid mtest_c) target_link_libraries(attrerrcomm simgrid mtest_c) -# target_link_libraries(attrerrtype simgrid mtest_c) + target_link_libraries(attrerrtype simgrid mtest_c) # target_link_libraries(attric simgrid mtest_c) target_link_libraries(attrorder simgrid mtest_c) target_link_libraries(attrordercomm simgrid mtest_c) -# target_link_libraries(attrordertype simgrid mtest_c) + target_link_libraries(attrordertype simgrid mtest_c) target_link_libraries(attrt simgrid mtest_c) target_link_libraries(baseattr2 simgrid mtest_c) target_link_libraries(baseattrcomm simgrid mtest_c) diff --git a/teshsuite/smpi/mpich3-test/attr/testlist b/teshsuite/smpi/mpich3-test/attr/testlist index c687935157..b18c61964c 100644 --- a/teshsuite/smpi/mpich3-test/attr/testlist +++ b/teshsuite/smpi/mpich3-test/attr/testlist @@ -12,17 +12,14 @@ attrerr 1 attrend2 1 attrend2 5 attrerrcomm 1 -#needs MPI_Errhandler_set, MPI_Type_create_keyval, MPI_Type_dup, MPI_Type_set_attr, MPI_Type_delete_attr -#attrerrtype 1 -#needs MPI_Type_create_keyval, MPI_Type_dup, MPI_Type_set_attr -#attr2type 1 +attrerrtype 1 +attr2type 1 attrorder 1 attrordercomm 1 -#needs MPI_Type_create_keyval, MPI_Type_delete_keyval, MPI_Type_set_attr, MPI_Type_delete_attr -#attrordertype 1 +attrordertype 1 baseattr2 1 baseattrcomm 1 -#MPI_Keyval_create, MPI_Keyval_free for type and comm also +#would need a refcount in keyval and attr #fkeyval 1 #fkeyvalcomm 1 #fkeyvaltype 1 -- 2.20.1