diff --git a/ompi/attribute/attribute.c b/ompi/attribute/attribute.c index 01549ec372..b73528ec74 100644 --- a/ompi/attribute/attribute.c +++ b/ompi/attribute/attribute.c @@ -241,7 +241,7 @@ Ick. */ -#define DELETE_ATTR_CALLBACKS(type, attribute, keyval_obj) \ +#define DELETE_ATTR_CALLBACKS(type, attribute, keyval_obj, object) \ if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77)) { \ MPI_Fint f_key = OMPI_INT_2_FINT(key); \ MPI_Fint f_err; \ @@ -289,7 +289,7 @@ /* See the big, long comment above from DELETE_ATTR_CALLBACKS -- most of that text applies here, too. */ -#define COPY_ATTR_CALLBACKS(type, old_object, keyval_obj, in_attr, out_attr) \ +#define COPY_ATTR_CALLBACKS(type, old_object, keyval_obj, in_attr, new_object, out_attr) \ if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77)) { \ MPI_Fint f_key = OMPI_INT_2_FINT(key); \ MPI_Fint f_err; \ @@ -332,7 +332,7 @@ in = translate_to_c(in_attr); \ if ((err = (*((keyval_obj->copy_attr_fn).attr_##type##_copy_fn)) \ ((ompi_##type##_t *)old_object, key, keyval_obj->extra_state, \ - in, &out, &flag)) != MPI_SUCCESS) { \ + in, &out, &flag, (ompi_##type##_t *)(new_object))) != MPI_SUCCESS) { \ OPAL_THREAD_UNLOCK(&alock); \ return err; \ } \ @@ -645,15 +645,15 @@ int ompi_attr_delete(ompi_attribute_type_t type, void *object, if (OMPI_SUCCESS == ret) { switch (type) { case COMM_ATTR: - DELETE_ATTR_CALLBACKS(communicator, attr, key_item); + DELETE_ATTR_CALLBACKS(communicator, attr, key_item, object); break; case WIN_ATTR: - DELETE_ATTR_CALLBACKS(win, attr, key_item); + DELETE_ATTR_CALLBACKS(win, attr, key_item, object); break; case TYPE_ATTR: - DELETE_ATTR_CALLBACKS(datatype, attr, key_item); + DELETE_ATTR_CALLBACKS(datatype, attr, key_item, object); break; default: @@ -857,19 +857,19 @@ int ompi_attr_copy_all(ompi_attribute_type_t type, void *old_object, case COMM_ATTR: /* Now call the copy_attr_fn */ COPY_ATTR_CALLBACKS(communicator, old_object, hash_value, - old_attr, new_attr); + old_attr, new_object, new_attr); break; case TYPE_ATTR: /* Now call the copy_attr_fn */ COPY_ATTR_CALLBACKS(datatype, old_object, hash_value, - old_attr, new_attr); + old_attr, new_object, new_attr); break; case WIN_ATTR: /* Now call the copy_attr_fn */ COPY_ATTR_CALLBACKS(win, old_object, hash_value, - old_attr, new_attr); + old_attr, new_object, new_attr); break; } @@ -1024,15 +1024,15 @@ static int set_value(ompi_attribute_type_t type, void *object, if (OMPI_SUCCESS == ret) { switch (type) { case COMM_ATTR: - DELETE_ATTR_CALLBACKS(communicator, old_attr, key_item); + DELETE_ATTR_CALLBACKS(communicator, old_attr, key_item, object); break; case WIN_ATTR: - DELETE_ATTR_CALLBACKS(win, old_attr, key_item); + DELETE_ATTR_CALLBACKS(win, old_attr, key_item, object); break; case TYPE_ATTR: - DELETE_ATTR_CALLBACKS(datatype, old_attr, key_item); + DELETE_ATTR_CALLBACKS(datatype, old_attr, key_item, object); break; default: diff --git a/ompi/attribute/attribute.h b/ompi/attribute/attribute.h index 87db226be6..7ed8152f60 100644 --- a/ompi/attribute/attribute.h +++ b/ompi/attribute/attribute.h @@ -36,7 +36,6 @@ #define ATTR_HASH_SIZE 10 - /* * Flags for keyvals */ @@ -91,29 +90,41 @@ typedef void (ompi_mpi2_fortran_delete_attr_function)(MPI_Fint *obj, void *attr_in, void *extra_state, MPI_Fint *ierr); +/* + * Internally the copy function for all kinds of MPI objects has one more + * argument, the pointer to the new object. Therefore, we can do on the + * flight modifications of the new communicator based on attributes stored + * on the main communicator. + */ +typedef int (MPI_Comm_internal_copy_attr_function)(MPI_Comm, int, void *, + void *, void *, int *, MPI_Comm); +typedef int (MPI_Type_internal_copy_attr_function)(MPI_Datatype, int, void *, + void *, void *, int *, MPI_Datatype); +typedef int (MPI_Win_internal_copy_attr_function)(MPI_Win, int, void *, + void *, void *, int *, MPI_Win); /* Union to take care of proper casting of the function pointers passed from the front end functions depending on the type. This will avoid casting function pointers to void* */ union ompi_attribute_fn_ptr_union_t { - MPI_Comm_delete_attr_function *attr_communicator_delete_fn; - MPI_Type_delete_attr_function *attr_datatype_delete_fn; - MPI_Win_delete_attr_function *attr_win_delete_fn; + MPI_Comm_delete_attr_function *attr_communicator_delete_fn; + MPI_Type_delete_attr_function *attr_datatype_delete_fn; + MPI_Win_delete_attr_function *attr_win_delete_fn; - MPI_Comm_copy_attr_function *attr_communicator_copy_fn; - MPI_Type_copy_attr_function *attr_datatype_copy_fn; - MPI_Win_copy_attr_function *attr_win_copy_fn; + MPI_Comm_internal_copy_attr_function *attr_communicator_copy_fn; + MPI_Type_internal_copy_attr_function *attr_datatype_copy_fn; + MPI_Win_internal_copy_attr_function *attr_win_copy_fn; /* For Fortran old MPI-1 callback functions */ ompi_mpi1_fortran_delete_attr_function *attr_mpi1_fortran_delete_fn; - ompi_mpi1_fortran_copy_attr_function *attr_mpi1_fortran_copy_fn; + ompi_mpi1_fortran_copy_attr_function *attr_mpi1_fortran_copy_fn; /* For Fortran new MPI-2 callback functions */ ompi_mpi2_fortran_delete_attr_function *attr_mpi2_fortran_delete_fn; - ompi_mpi2_fortran_copy_attr_function *attr_mpi2_fortran_copy_fn; + ompi_mpi2_fortran_copy_attr_function *attr_mpi2_fortran_copy_fn; }; typedef union ompi_attribute_fn_ptr_union_t ompi_attribute_fn_ptr_union_t; diff --git a/ompi/attribute/attribute_predefined.c b/ompi/attribute/attribute_predefined.c index bcb2b6328d..615a34108e 100644 --- a/ompi/attribute/attribute_predefined.c +++ b/ompi/attribute/attribute_predefined.c @@ -331,8 +331,8 @@ static int create_comm(int target_keyval, bool want_inherit) ompi_attribute_fn_ptr_union_t del; keyval = -1; - copy.attr_communicator_copy_fn = - want_inherit ? MPI_COMM_DUP_FN : MPI_COMM_NULL_COPY_FN; + copy.attr_communicator_copy_fn = (MPI_Comm_internal_copy_attr_function*) + (want_inherit ? MPI_COMM_DUP_FN : MPI_COMM_NULL_COPY_FN); del.attr_communicator_delete_fn = MPI_COMM_NULL_DELETE_FN; err = ompi_attr_create_keyval(COMM_ATTR, copy, del, &keyval, NULL, OMPI_KEYVAL_PREDEFINED); @@ -361,7 +361,7 @@ static int create_win(int target_keyval) ompi_attribute_fn_ptr_union_t del; keyval = -1; - copy.attr_win_copy_fn = MPI_WIN_NULL_COPY_FN; + copy.attr_win_copy_fn = (MPI_Win_internal_copy_attr_function*)MPI_WIN_NULL_COPY_FN; del.attr_win_delete_fn = MPI_WIN_NULL_DELETE_FN; err = ompi_attr_create_keyval(WIN_ATTR, copy, del, &keyval, NULL, OMPI_KEYVAL_PREDEFINED); diff --git a/ompi/mpi/c/comm_create_keyval.c b/ompi/mpi/c/comm_create_keyval.c index 4dd95ce5f8..9befeaedb2 100644 --- a/ompi/mpi/c/comm_create_keyval.c +++ b/ompi/mpi/c/comm_create_keyval.c @@ -45,15 +45,15 @@ int MPI_Comm_create_keyval(MPI_Comm_copy_attr_function *comm_copy_attr_fn, if ((NULL == comm_copy_attr_fn) || (NULL == comm_delete_attr_fn) || (NULL == comm_keyval)) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, - FUNC_NAME); + FUNC_NAME); } } - copy_fn.attr_communicator_copy_fn = comm_copy_attr_fn; + copy_fn.attr_communicator_copy_fn = (MPI_Comm_internal_copy_attr_function*)comm_copy_attr_fn; del_fn.attr_communicator_delete_fn = comm_delete_attr_fn; ret = ompi_attr_create_keyval(COMM_ATTR, copy_fn, - del_fn, comm_keyval, extra_state, 0); + del_fn, comm_keyval, extra_state, 0); OMPI_ERRHANDLER_RETURN(ret, MPI_COMM_WORLD, MPI_ERR_OTHER, FUNC_NAME); } diff --git a/ompi/mpi/c/keyval_create.c b/ompi/mpi/c/keyval_create.c index 2f5a1b2a92..5fbca66869 100644 --- a/ompi/mpi/c/keyval_create.c +++ b/ompi/mpi/c/keyval_create.c @@ -42,19 +42,19 @@ int MPI_Keyval_create(MPI_Copy_function *copy_attr_fn, ompi_attribute_fn_ptr_union_t del_fn; if (MPI_PARAM_CHECK) { - OMPI_ERR_INIT_FINALIZE(FUNC_NAME); - if (NULL == keyval) { - return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_KEYVAL, - FUNC_NAME); - } else if ((NULL == copy_attr_fn) || (NULL == delete_attr_fn)) { + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + if (NULL == keyval) { + return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_KEYVAL, + FUNC_NAME); + } else if ((NULL == copy_attr_fn) || (NULL == delete_attr_fn)) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, - FUNC_NAME); - } + FUNC_NAME); + } } - copy_fn.attr_communicator_copy_fn = copy_attr_fn; + copy_fn.attr_communicator_copy_fn = (MPI_Comm_internal_copy_attr_function*)copy_attr_fn; del_fn.attr_communicator_delete_fn = delete_attr_fn; ret = ompi_attr_create_keyval(COMM_ATTR, copy_fn, - del_fn, keyval, extra_state, 0); + del_fn, keyval, extra_state, 0); OMPI_ERRHANDLER_RETURN(ret, MPI_COMM_WORLD, MPI_ERR_OTHER, FUNC_NAME); } diff --git a/ompi/mpi/c/type_create_keyval.c b/ompi/mpi/c/type_create_keyval.c index 00a8fed21f..95d2e356e0 100644 --- a/ompi/mpi/c/type_create_keyval.c +++ b/ompi/mpi/c/type_create_keyval.c @@ -46,16 +46,16 @@ int MPI_Type_create_keyval(MPI_Type_copy_attr_function *type_copy_attr_fn, if ((NULL == type_copy_attr_fn) || (NULL == type_delete_attr_fn) || (NULL == type_keyval)) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, - MPI_ERR_ARG, - FUNC_NAME); + MPI_ERR_ARG, + FUNC_NAME); } } - copy_fn.attr_datatype_copy_fn = type_copy_attr_fn; + copy_fn.attr_datatype_copy_fn = (MPI_Type_internal_copy_attr_function*)type_copy_attr_fn; del_fn.attr_datatype_delete_fn = type_delete_attr_fn; ret = ompi_attr_create_keyval(TYPE_ATTR, copy_fn, del_fn, - type_keyval, extra_state, 0); + type_keyval, extra_state, 0); OMPI_ERRHANDLER_RETURN(ret, MPI_COMM_WORLD, ret, FUNC_NAME); } diff --git a/ompi/mpi/c/win_create_keyval.c b/ompi/mpi/c/win_create_keyval.c index 27106df19e..5a4974b13d 100644 --- a/ompi/mpi/c/win_create_keyval.c +++ b/ompi/mpi/c/win_create_keyval.c @@ -48,7 +48,7 @@ int MPI_Win_create_keyval(MPI_Win_copy_attr_function *win_copy_attr_fn, FUNC_NAME); } } - copy_fn.attr_win_copy_fn = win_copy_attr_fn; + copy_fn.attr_win_copy_fn = (MPI_Win_internal_copy_attr_function*)win_copy_attr_fn; del_fn.attr_win_delete_fn = win_delete_attr_fn; ret = ompi_attr_create_keyval(WIN_ATTR, copy_fn, del_fn,