/*@ MPI_Group_incl - Produces a group by reordering an existing group and taking only listed members Input Parameters: + group - group (handle) . n - number of elements in array 'ranks' (and size of newgroup) (integer) - ranks - ranks of processes in 'group' to appear in 'newgroup' (array of integers) Output Parameters: . newgroup - new group derived from above, in the order defined by 'ranks' (handle) .N ThreadSafe .N Fortran .N Errors .N MPI_SUCCESS .N MPI_ERR_GROUP .N MPI_ERR_ARG .N MPI_ERR_EXHAUSTED .N MPI_ERR_RANK .seealso: MPI_Group_free @*/ int MPI_Group_incl(MPI_Group group, int n, const int ranks[], MPI_Group * newgroup) { int mpi_errno = MPI_SUCCESS; MPIR_Group *group_ptr = NULL, *new_group_ptr = NULL; MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPI_GROUP_INCL); MPIR_ERRTEST_INITIALIZED_ORDIE(); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPI_GROUP_INCL); /* Validate parameters, especially handles needing to be converted */ #ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { MPIR_ERRTEST_GROUP(group, mpi_errno); MPIR_ERRTEST_ARGNEG(n, "n", mpi_errno); } MPID_END_ERROR_CHECKS; } #endif /* Convert MPI object handles to object pointers */ MPIR_Group_get_ptr(group, group_ptr); /* Validate parameters and objects (post conversion) */ #ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { /* Validate group_ptr */ MPIR_Group_valid_ptr(group_ptr, mpi_errno); /* If group_ptr is not valid, it will be reset to null */ if (group_ptr) { mpi_errno = MPIR_Group_check_valid_ranks(group_ptr, ranks, n); } if (mpi_errno) goto fn_fail; } MPID_END_ERROR_CHECKS; } #endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ if (n == 0) { *newgroup = MPI_GROUP_EMPTY; goto fn_exit; } mpi_errno = MPIR_Group_incl_impl(group_ptr, n, ranks, &new_group_ptr); if (mpi_errno) goto fn_fail; MPIR_OBJ_PUBLISH_HANDLE(*newgroup, new_group_ptr->handle); /* ... end of body of routine ... */ fn_exit: MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_GROUP_INCL); MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ #ifdef HAVE_ERROR_CHECKING { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, "**mpi_group_incl", "**mpi_group_incl %G %d %p %p", group, n, ranks, newgroup); } #endif mpi_errno = MPIR_Err_return_comm(NULL, __func__, mpi_errno); goto fn_exit; /* --END ERROR HANDLING-- */ }
pami_result_t MPIDI_Comm_create_from_pami_geom(pami_geometry_range_t *task_slices, size_t slice_count, pami_geometry_t *geometry, void **cookie) { int mpi_errno = MPI_SUCCESS; int num_tasks = 0; int *ranks = NULL; MPID_Comm *comm_ptr = NULL, *new_comm_ptr = NULL; MPID_Group *group_ptr = NULL, *new_group_ptr = NULL; int i = 0, j = 0; /* Get comm_ptr for MPI_COMM_WORLD and get the group_ptr for it */ MPID_Comm_get_ptr( MPI_COMM_WORLD, comm_ptr ); mpi_errno = MPIR_Comm_group_impl(comm_ptr, &group_ptr); if (mpi_errno) { TRACE_ERR("Error while creating group_ptr from MPI_COMM_WORLD in MPIDI_Comm_create_from_pami_geom\n"); return PAMI_ERROR; } /* Create the ranks list from the pami_geometry_range_t array */ for(i = 0; i < slice_count; i++) { num_tasks += (task_slices[i].hi - task_slices[i].lo) + 1; } ranks = MPIU_Calloc0(num_tasks, int); for(i = 0; i < slice_count; i++) { int slice_sz = (task_slices[i].hi - task_slices[i].lo) + 1; int k = 0; for(k = 0; k < slice_sz; k++) { ranks[j] = task_slices[i].lo + k; j++; } } /* Now we have all we need to create the new group. Create it */ mpi_errno = MPIR_Group_incl_impl(group_ptr, num_tasks, ranks, &new_group_ptr); if (mpi_errno) { TRACE_ERR("Error while creating new_group_ptr from group_ptr in MPIDI_Comm_create_from_pami_geom\n"); return PAMI_ERROR; } /* Now create the communicator using the new_group_ptr */ mpi_errno = MPIR_Comm_create_intra(comm_ptr, new_group_ptr, &new_comm_ptr); if (mpi_errno) { TRACE_ERR("Error while creating new_comm_ptr from group_ptr in MPIDI_Comm_create_from_pami_geom\n"); return PAMI_ERROR; } if(new_comm_ptr) { /* Get the geometry from the communicator and set the out parameters */ *geometry = new_comm_ptr->mpid.geometry; *cookie = new_comm_ptr; } else { *geometry = PAMI_GEOMETRY_NULL; *cookie = NULL; } /* Cleanup */ MPIU_TestFree(&ranks); return PAMI_SUCCESS; }
int MPIDI_CH3U_Get_failed_group(int last_rank, MPIR_Group **failed_group) { char *c; int i, mpi_errno = MPI_SUCCESS, rank; UT_array *failed_procs = NULL; MPIR_Group *world_group; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_GET_FAILED_GROUP); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_GET_FAILED_GROUP); MPL_DBG_MSG_D(MPIDI_CH3_DBG_OTHER, VERBOSE, "Getting failed group with %d as last acknowledged\n", last_rank); if (-1 == last_rank) { MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER, VERBOSE, "No failure acknowledged"); *failed_group = MPIR_Group_empty; goto fn_exit; } if (*MPIDI_failed_procs_string == '\0') { MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER, VERBOSE, "Found no failed ranks"); *failed_group = MPIR_Group_empty; goto fn_exit; } utarray_new(failed_procs, &ut_int_icd); /* parse list of failed processes. This is a comma separated list of ranks or ranges of ranks (e.g., "1, 3-5, 11") */ i = 0; c = MPIDI_failed_procs_string; while(1) { parse_rank(&rank); ++i; MPL_DBG_MSG_D(MPIDI_CH3_DBG_OTHER, VERBOSE, "Found failed rank: %d", rank); utarray_push_back(failed_procs, &rank); MPIDI_last_known_failed = rank; MPIR_ERR_CHKINTERNAL(*c != ',' && *c != '\0', mpi_errno, "error parsing failed process list"); if (*c == '\0' || last_rank == rank) break; ++c; /* skip ',' */ } /* Create group of failed processes for comm_world. Failed groups for other communicators can be created from this one using group_intersection. */ mpi_errno = MPIR_Comm_group_impl(MPIR_Process.comm_world, &world_group); if (mpi_errno) MPIR_ERR_POP(mpi_errno); mpi_errno = MPIR_Group_incl_impl(world_group, i, ut_int_array(failed_procs), failed_group); if (mpi_errno) MPIR_ERR_POP(mpi_errno); mpi_errno = MPIR_Group_release(world_group); if (mpi_errno) MPIR_ERR_POP(mpi_errno); fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_GET_FAILED_GROUP); if (failed_procs) utarray_free(failed_procs); return mpi_errno; fn_oom: MPIR_ERR_SET1(mpi_errno, MPI_ERR_OTHER, "**nomem", "**nomem %s", "utarray"); fn_fail: goto fn_exit; }