-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/topo/cart_sub.c
-: 0:Graph:cart_sub.gcno
-: 0:Data:cart_sub.gcda
-: 0:Runs:547
-: 0:Programs:146
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: *
-: 4: * (C) 2001 by Argonne National Laboratory.
-: 5: * See COPYRIGHT in top-level directory.
-: 6: */
-: 7:
-: 8:#include "mpiimpl.h"
-: 9:#include "topo.h"
-: 10:
-: 11:/* -- Begin Profiling Symbol Block for routine MPI_Cart_sub */
-: 12:#if defined(HAVE_PRAGMA_WEAK)
-: 13:#pragma weak MPI_Cart_sub = PMPI_Cart_sub
-: 14:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
-: 15:#pragma _HP_SECONDARY_DEF PMPI_Cart_sub MPI_Cart_sub
-: 16:#elif defined(HAVE_PRAGMA_CRI_DUP)
-: 17:#pragma _CRI duplicate MPI_Cart_sub as PMPI_Cart_sub
-: 18:#endif
-: 19:/* -- End Profiling Symbol Block */
-: 20:
-: 21:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
-: 22: the MPI routines */
-: 23:#ifndef MPICH_MPI_FROM_PMPI
-: 24:#undef MPI_Cart_sub
-: 25:#define MPI_Cart_sub PMPI_Cart_sub
-: 26:
-: 27:#endif
-: 28:
-: 29:#undef FUNCNAME
-: 30:#define FUNCNAME MPI_Cart_sub
-: 31:
-: 32:/*@
-: 33:
-: 34:MPI_Cart_sub - Partitions a communicator into subgroups which
-: 35: form lower-dimensional cartesian subgrids
-: 36:
-: 37:Input Parameters:
-: 38:+ comm - communicator with cartesian structure (handle)
-: 39:- remain_dims - the 'i'th entry of remain_dims specifies whether the 'i'th
-: 40:dimension is kept in the subgrid (true) or is dropped (false) (logical
-: 41:vector)
-: 42:
-: 43:Output Parameter:
-: 44:. newcomm - communicator containing the subgrid that includes the calling
-: 45:process (handle)
-: 46:
-: 47:.N ThreadSafe
-: 48:
-: 49:.N Fortran
-: 50:
-: 51:.N Errors
-: 52:.N MPI_SUCCESS
-: 53:.N MPI_ERR_TOPOLOGY
-: 54:.N MPI_ERR_COMM
-: 55:.N MPI_ERR_ARG
-: 56:@*/
-: 57:int MPI_Cart_sub(MPI_Comm comm, int *remain_dims, MPI_Comm *comm_new)
53: 58:{
-: 59: static const char FCNAME[] = "MPI_Cart_sub";
53: 60: int mpi_errno = MPI_SUCCESS, all_false;
-: 61: int ndims, key, color, ndims_in_subcomm, nnodes_in_subcomm, i, j, rank;
53: 62: MPID_Comm *comm_ptr = NULL, *newcomm_ptr;
-: 63: MPIR_Topology *topo_ptr, *toponew_ptr;
53: 64: MPIU_THREADPRIV_DECL;
53: 65: MPIU_CHKPMEM_DECL(4);
-: 66: MPID_MPI_STATE_DECL(MPID_STATE_MPI_CART_SUB);
-: 67:
53: 68: MPIR_ERRTEST_INITIALIZED_ORDIE();
-: 69:
53: 70: MPIU_THREAD_CS_ENTER(ALLFUNC,);
-: 71: MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_CART_SUB);
-: 72:
53: 73: MPIU_THREADPRIV_GET;
-: 74:
-: 75: /* Validate parameters, especially handles needing to be converted */
|
-: 76:# ifdef HAVE_ERROR_CHECKING
-: 77: {
-: 78: MPID_BEGIN_ERROR_CHECKS;
-: 79: {
53: 80: MPIR_ERRTEST_COMM(comm, mpi_errno);
53: 81: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 82: }
-: 83: MPID_END_ERROR_CHECKS;
-: 84: }
-: 85:# endif
-: 86:
-: 87: /* Convert MPI object handles to object pointers */
|
52: 88: MPID_Comm_get_ptr( comm, comm_ptr );
-: 89:
-: 90: /* Validate parameters and objects (post conversion) */
|
-: 91:# ifdef HAVE_ERROR_CHECKING
-: 92: {
-: 93: MPID_BEGIN_ERROR_CHECKS;
-: 94: {
-: 95: /* Validate comm_ptr */
52: 96: MPID_Comm_valid_ptr( comm_ptr, mpi_errno );
-: 97: /* If comm_ptr is not valid, it will be reset to null */
52: 98: if (mpi_errno) goto fn_fail;
-: 99: }
-: 100: MPID_END_ERROR_CHECKS;
-: 101: }
-: 102:# endif /* HAVE_ERROR_CHECKING */
-: 103:
-: 104: /* ... body of routine ... */
-: 105:
-: 106: /* Check that the communicator already has a Cartesian topology */
|
52: 107: topo_ptr = MPIR_Topology_get( comm_ptr );
-: 108:
52: 109: MPIU_ERR_CHKANDJUMP(!topo_ptr,mpi_errno,MPI_ERR_TOPOLOGY,"**notopology");
51: 110: MPIU_ERR_CHKANDJUMP(topo_ptr->kind != MPI_CART,mpi_errno,MPI_ERR_TOPOLOGY,
-: 111: "**notcarttopo");
-: 112:
47: 113: ndims = topo_ptr->topo.cart.ndims;
-: 114:
47: 115: all_false = 1; /* all entries in remain_dims are false */
73: 116: for (i=0; i<ndims; i++) {
68: 117: if (remain_dims[i]) {
-: 118: /* any 1 is true, set flag to 0 and break */
42: 119: all_false = 0;
42: 120: break;
-: 121: }
-: 122: }
-: 123:
47: 124: if (all_false) {
-: 125: /* ndims=0, or all entries in remain_dims are false.
-: 126: MPI 2.1 says return a 0D Cartesian topology. */
5: 127: MPIR_Nest_incr();
5: 128: mpi_errno = NMPI_Cart_create(comm, 0, NULL, NULL, 0, comm_new);
5: 129: MPIR_Nest_decr();
|
5: 130: if (mpi_errno) goto fn_fail;
-: 131: }
-: 132:
-: 133: else {
-: 134: /* Determine the number of remaining dimensions */
|
42: 135: ndims_in_subcomm = 0;
42: 136: nnodes_in_subcomm = 1;
126: 137: for (i=0; i<ndims; i++) {
84: 138: if (remain_dims[i]) {
48: 139: ndims_in_subcomm ++;
48: 140: nnodes_in_subcomm *= topo_ptr->topo.cart.dims[i];
-: 141: }
-: 142: }
-: 143:
-: 144: /* Split this communicator. Do this even if there are no remaining
-: 145: dimensions so that the topology information is attached */
42: 146: key = 0;
42: 147: color = 0;
126: 148: for (i=0; i<ndims; i++) {
84: 149: if (remain_dims[i]) {
48: 150: key = (key * topo_ptr->topo.cart.dims[i]) +
-: 151: topo_ptr->topo.cart.position[i];
-: 152: }
-: 153: else {
36: 154: color = (color * topo_ptr->topo.cart.dims[i]) +
-: 155: topo_ptr->topo.cart.position[i];
-: 156: }
-: 157: }
42: 158: MPIR_Nest_incr();
42: 159: mpi_errno = NMPI_Comm_split( comm, color, key, comm_new );
42: 160: MPIR_Nest_decr();
|
42: 161: if (mpi_errno) goto fn_fail;
-: 162:
-: 163: /* Save the topology of this new communicator */
|
42: 164: MPIU_CHKPMEM_MALLOC(toponew_ptr,MPIR_Topology*,sizeof(MPIR_Topology),
-: 165: mpi_errno,"toponew_ptr");
-: 166:
42: 167: toponew_ptr->kind = MPI_CART;
42: 168: toponew_ptr->topo.cart.ndims = ndims_in_subcomm;
42: 169: toponew_ptr->topo.cart.nnodes = nnodes_in_subcomm;
42: 170: if (ndims_in_subcomm) {
42: 171: MPIU_CHKPMEM_MALLOC(toponew_ptr->topo.cart.dims,int*,
-: 172: ndims_in_subcomm*sizeof(int),mpi_errno,"cart.dims");
42: 173: MPIU_CHKPMEM_MALLOC(toponew_ptr->topo.cart.periodic,int*,
-: 174: ndims_in_subcomm*sizeof(int),mpi_errno,"cart.periodic");
42: 175: MPIU_CHKPMEM_MALLOC(toponew_ptr->topo.cart.position,int*,
-: 176: ndims_in_subcomm*sizeof(int),mpi_errno,"cart.position");
-: 177: }
-: 178: else {
|
#####: 179: toponew_ptr->topo.cart.dims = 0;
#####: 180: toponew_ptr->topo.cart.periodic = 0;
#####: 181: toponew_ptr->topo.cart.position = 0;
-: 182: }
-: 183:
|
42: 184: j = 0;
126: 185: for (i=0; i<ndims; i++) {
84: 186: if (remain_dims[i]) {
48: 187: toponew_ptr->topo.cart.dims[j] = topo_ptr->topo.cart.dims[i];
48: 188: toponew_ptr->topo.cart.periodic[j] = topo_ptr->topo.cart.periodic[i];
48: 189: j++;
-: 190: }
-: 191: }
-: 192:
42: 193: MPID_Comm_get_ptr( *comm_new, newcomm_ptr );
-: 194: /* Compute the position of this process in the new communicator */
42: 195: rank = newcomm_ptr->rank;
90: 196: for (i=0; i<ndims_in_subcomm; i++) {
48: 197: nnodes_in_subcomm /= toponew_ptr->topo.cart.dims[i];
48: 198: toponew_ptr->topo.cart.position[i] = rank / nnodes_in_subcomm;
48: 199: rank = rank % nnodes_in_subcomm;
-: 200: }
-: 201:
42: 202: mpi_errno = MPIR_Topology_put( newcomm_ptr, toponew_ptr );
|
42: 203: if (mpi_errno) goto fn_fail;
-: 204: }
-: 205: /* ... end of body of routine ... */
-: 206:
|
53: 207: fn_exit:
|
-: 208: MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_CART_SUB);
|
53: 209: MPIU_THREAD_CS_EXIT(ALLFUNC,);
53: 210: return mpi_errno;
-: 211:
|
-: 212: fn_fail:
-: 213: /* --BEGIN ERROR HANDLING-- */
#####: 214: MPIU_CHKPMEM_REAP();
-: 215:# ifdef HAVE_ERROR_CHECKING
-: 216: {
6: 217: mpi_errno = MPIR_Err_create_code(
-: 218: mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_cart_sub",
-: 219: "**mpi_cart_sub %C %p %p", comm, remain_dims, comm_new);
-: 220: }
-: 221:# endif
6: 222: mpi_errno = MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );
6: 223: goto fn_exit;
-: 224: /* --END ERROR HANDLING-- */
-: 225:}
|