int MPIDI_CH3U_Win_allocate_shared(MPI_Aint size, int disp_unit, MPID_Info *info, MPID_Comm *comm_ptr, void **base_ptr, MPID_Win **win_ptr) { int mpi_errno = MPI_SUCCESS; MPID_Comm *comm_self_ptr = NULL; MPID_Group *group_comm, *group_self; int result; MPIU_CHKPMEM_DECL(1); MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_WIN_ALLOCATE_SHARED); MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_WIN_ALLOCATE_SHARED); #ifdef HAVE_ERROR_CHECKING /* The baseline CH3 implementation only works with MPI_COMM_SELF */ MPID_Comm_get_ptr( MPI_COMM_SELF, comm_self_ptr ); mpi_errno = MPIR_Comm_group_impl(comm_ptr, &group_comm); if (mpi_errno) MPIU_ERR_POP(mpi_errno); mpi_errno = MPIR_Comm_group_impl(comm_self_ptr, &group_self); if (mpi_errno) MPIU_ERR_POP(mpi_errno); mpi_errno = MPIR_Group_compare_impl(group_comm, group_self, &result); if (mpi_errno) MPIU_ERR_POP(mpi_errno); mpi_errno = MPIR_Group_free_impl(group_comm); if (mpi_errno) MPIU_ERR_POP(mpi_errno); mpi_errno = MPIR_Group_free_impl(group_self); if (mpi_errno) MPIU_ERR_POP(mpi_errno); if (result != MPI_IDENT) { MPIU_ERR_SETANDJUMP(mpi_errno, MPI_ERR_RMA_SHARED, "**ch3|win_shared_comm"); } #endif mpi_errno = MPIDI_CH3U_Win_allocate(size, disp_unit, info, comm_ptr, base_ptr, win_ptr); if (mpi_errno) MPIU_ERR_POP(mpi_errno); MPIU_CHKPMEM_MALLOC((*win_ptr)->shm_base_addrs, void **, 1 /* comm_size */ * sizeof(void *), mpi_errno, "(*win_ptr)->shm_base_addrs"); (*win_ptr)->shm_base_addrs[0] = *base_ptr; /* Register the shared memory window free function, which will free the memory allocated here. */ (*win_ptr)->RMAFns.Win_free = MPIDI_SHM_Win_free; fn_exit: MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_WIN_ALLOCATE_SHARED); return mpi_errno; /* --BEGIN ERROR HANDLING-- */ fn_fail: MPIU_CHKPMEM_REAP(); goto fn_exit; /* --END ERROR HANDLING-- */ }
/*@ MPI_Group_compare - Compares two groups Input Parameters: + group1 - group1 (handle) - group2 - group2 (handle) Output Parameters: . result - integer which is 'MPI_IDENT' if the order and members of the two groups are the same, 'MPI_SIMILAR' if only the members are the same, and 'MPI_UNEQUAL' otherwise .N ThreadSafe .N Fortran .N Errors .N MPI_SUCCESS .N MPI_ERR_GROUP .N MPI_ERR_ARG @*/ int MPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result) { int mpi_errno = MPI_SUCCESS; MPID_Group *group_ptr1 = NULL; MPID_Group *group_ptr2 = NULL; MPID_MPI_STATE_DECL(MPID_STATE_MPI_GROUP_COMPARE); MPIR_ERRTEST_INITIALIZED_ORDIE(); /* The routines that setup the group data structures must be executed within a mutex. As most of the group routines are not performance critical, we simple run these routines within the SINGLE_CS */ MPIU_THREAD_CS_ENTER(ALLFUNC,); MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_GROUP_COMPARE); /* Validate parameters, especially handles needing to be converted */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { MPIR_ERRTEST_ARGNULL( result, "result", mpi_errno ); MPIR_ERRTEST_GROUP(group1, mpi_errno); MPIR_ERRTEST_GROUP(group2, mpi_errno); } MPID_END_ERROR_CHECKS; } # endif /* Convert MPI object handles to object pointers */ MPID_Group_get_ptr( group1, group_ptr1 ); MPID_Group_get_ptr( group2, group_ptr2 ); /* Validate parameters and objects (post conversion) */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { /* Validate group_ptr */ MPID_Group_valid_ptr( group_ptr1, mpi_errno ); MPID_Group_valid_ptr( group_ptr2, mpi_errno ); /* If group_ptr is not valid, it will be reset to null */ if (mpi_errno) goto fn_fail; } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ mpi_errno = MPIR_Group_compare_impl(group_ptr1, group_ptr2, result); if (mpi_errno) MPIU_ERR_POP(mpi_errno); /* ... end of body of routine ... */ fn_exit: MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_GROUP_COMPARE); MPIU_THREAD_CS_EXIT(ALLFUNC,); return mpi_errno; /* --BEGIN ERROR HANDLING-- */ fn_fail: { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_group_compare", "**mpi_group_compare %G %G %p", group1, group2, result); } mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno ); goto fn_exit; /* --END ERROR HANDLING-- */ }
int MPIR_Comm_agree(MPIR_Comm *comm_ptr, int *flag) { int mpi_errno = MPI_SUCCESS, mpi_errno_tmp = MPI_SUCCESS; MPIR_Group *comm_grp, *failed_grp, *new_group_ptr, *global_failed; int result, success = 1; MPIR_Errflag_t errflag = MPIR_ERR_NONE; int values[2]; MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPIR_COMM_AGREE); MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPIR_COMM_AGREE); MPIR_Comm_group_impl(comm_ptr, &comm_grp); /* Get the locally known (not acknowledged) group of failed procs */ mpi_errno = MPID_Comm_failure_get_acked(comm_ptr, &failed_grp); if (mpi_errno) MPIR_ERR_POP(mpi_errno); /* First decide on the group of failed procs. */ mpi_errno = MPID_Comm_get_all_failed_procs(comm_ptr, &global_failed, MPIR_AGREE_TAG); if (mpi_errno) errflag = MPIR_ERR_PROC_FAILED; mpi_errno = MPIR_Group_compare_impl(failed_grp, global_failed, &result); if (mpi_errno) MPIR_ERR_POP(mpi_errno); /* Create a subgroup without the failed procs */ mpi_errno = MPIR_Group_difference_impl(comm_grp, global_failed, &new_group_ptr); if (mpi_errno) MPIR_ERR_POP(mpi_errno); /* If that group isn't the same as what we think is failed locally, then * mark it as such. */ if (result == MPI_UNEQUAL || errflag) success = 0; /* Do an allreduce to decide whether or not anyone thinks the group * has changed */ mpi_errno_tmp = MPIR_Allreduce_group(MPI_IN_PLACE, &success, 1, MPI_INT, MPI_MIN, comm_ptr, new_group_ptr, MPIR_AGREE_TAG, &errflag); if (!success || errflag || mpi_errno_tmp) success = 0; values[0] = success; values[1] = *flag; /* Determine both the result of this function (mpi_errno) and the result * of flag that will be returned to the user. */ MPIR_Allreduce_group(MPI_IN_PLACE, values, 2, MPI_INT, MPI_BAND, comm_ptr, new_group_ptr, MPIR_AGREE_TAG, &errflag); /* Ignore the result of the operation this time. Everyone will either * return a failure because of !success earlier or they will return * something useful for flag because of this operation. If there was a new * failure in between the first allreduce and the second one, it's ignored * here. */ if (failed_grp != MPIR_Group_empty) MPIR_Group_release(failed_grp); MPIR_Group_release(new_group_ptr); MPIR_Group_release(comm_grp); if (global_failed != MPIR_Group_empty) MPIR_Group_release(global_failed); success = values[0]; *flag = values[1]; if (!success) { MPIR_ERR_SET(mpi_errno_tmp, MPIX_ERR_PROC_FAILED, "**mpix_comm_agree"); MPIR_ERR_ADD(mpi_errno, mpi_errno_tmp); } fn_exit: MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_COMM_AGREE); return mpi_errno; fn_fail: goto fn_exit; }