-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/topo/graphcreate.c
-: 0:Graph:graphcreate.gcno
-: 0:Data:graphcreate.gcda
-: 0:Runs:609
-: 0:Programs:164
-: 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_Graph_create */
-: 12:#if defined(HAVE_PRAGMA_WEAK)
-: 13:#pragma weak MPI_Graph_create = PMPI_Graph_create
-: 14:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
-: 15:#pragma _HP_SECONDARY_DEF PMPI_Graph_create MPI_Graph_create
-: 16:#elif defined(HAVE_PRAGMA_CRI_DUP)
-: 17:#pragma _CRI duplicate MPI_Graph_create as PMPI_Graph_create
-: 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_Graph_create
-: 25:#define MPI_Graph_create PMPI_Graph_create
-: 26:
-: 27:#endif
-: 28:
-: 29:/* Note on index and indx - index is an (old) function name in string.h;
-: 30: while it is valid to use it as a variable or parameter name, it can
-: 31: solicit warning messages from the compiler. To avoid those, the name
-: 32: indx is used instead of index in this file */
-: 33:
-: 34:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
-: 35: the MPI routines */
-: 36:#ifndef MPICH_MPI_FROM_PMPI
-: 37:int MPIR_Graph_create( const MPID_Comm *comm_ptr, int nnodes,
-: 38: const int indx[], const int edges[], int reorder,
-: 39: MPI_Comm *comm_graph)
92: 40:{
-: 41: static const char FCNAME[] = "MPIR_Graph_create";
92: 42: int mpi_errno = MPI_SUCCESS;
-: 43: int i, nedges;
92: 44: MPID_Comm *newcomm_ptr = NULL;
92: 45: MPIR_Topology *graph_ptr = NULL;
92: 46: MPIU_CHKPMEM_DECL(3);
-: 47:
-: 48: /* Set this to null in case there is an error */
92: 49: *comm_graph = MPI_COMM_NULL;
-: 50:
-: 51: /* Create a new communicator */
92: 52: if (reorder) {
-: 53: int nrank;
-: 54: MPI_Comm ncomm;
62: 55: MPIU_THREADPRIV_DECL;
-: 56:
62: 57: MPIU_THREADPRIV_GET;
-: 58:
-: 59: /* Allow the cart map routine to remap the assignment of ranks to
-: 60: processes */
62: 61: MPIR_Nest_incr();
62: 62: mpi_errno = NMPI_Graph_map( comm_ptr->handle, nnodes,
-: 63: (int *)indx, (int *)edges,
-: 64: &nrank );
-: 65: /* Create the new communicator with split, since we need to reorder
-: 66: the ranks (including the related internals, such as the connection
-: 67: tables */
62: 68: if (mpi_errno == 0) {
62: 69: mpi_errno = NMPI_Comm_split( comm_ptr->handle,
-: 70: nrank == MPI_UNDEFINED ? MPI_UNDEFINED : 1,
-: 71: nrank, &ncomm );
62: 72: if (!mpi_errno) {
62: 73: MPID_Comm_get_ptr( ncomm, newcomm_ptr );
-: 74: }
-: 75: }
62: 76: MPIR_Nest_decr();
-: 77: }
-: 78: else {
-: 79: /* Just use the first nnodes processes in the communicator */
30: 80: mpi_errno = MPIR_Comm_copy( (MPID_Comm *)comm_ptr, nnodes,
-: 81: &newcomm_ptr );
-: 82: }
|
92: 83: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 84:
-: 85:
-: 86: /* If this process is not in the resulting communicator, return a
-: 87: null communicator and exit */
|
92: 88: if (!newcomm_ptr) {
1: 89: *comm_graph = MPI_COMM_NULL;
1: 90: goto fn_exit;
-: 91: }
-: 92:
91: 93: nedges = indx[nnodes-1];
91: 94: MPIU_CHKPMEM_MALLOC(graph_ptr,MPIR_Topology*,sizeof(MPIR_Topology),
-: 95: mpi_errno,"graph_ptr");
-: 96:
91: 97: graph_ptr->kind = MPI_GRAPH;
91: 98: graph_ptr->topo.graph.nnodes = nnodes;
91: 99: graph_ptr->topo.graph.nedges = nedges;
182: 100: MPIU_CHKPMEM_MALLOC(graph_ptr->topo.graph.index,int*,
-: 101: nnodes*sizeof(int),mpi_errno,"graph.index");
91: 102: MPIU_CHKPMEM_MALLOC(graph_ptr->topo.graph.edges,int*,
-: 103: nedges*sizeof(int),mpi_errno,"graph.edges");
520: 104: for (i=0; i<nnodes; i++)
429: 105: graph_ptr->topo.graph.index[i] = indx[i];
873: 106: for (i=0; i<nedges; i++)
782: 107: graph_ptr->topo.graph.edges[i] = edges[i];
-: 108:
-: 109: /* Finally, place the topology onto the new communicator and return the
-: 110: handle */
91: 111: mpi_errno = MPIR_Topology_put( newcomm_ptr, graph_ptr );
|
91: 112: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 113:
|
91: 114: *comm_graph = newcomm_ptr->handle;
-: 115:
-: 116: /* ... end of body of routine ... */
-: 117:
92: 118: fn_exit:
92: 119: return mpi_errno;
-: 120:
|
-: 121: fn_fail:
-: 122: /* --BEGIN ERROR HANDLING-- */
#####: 123: MPIU_CHKPMEM_REAP();
-: 124:# ifdef HAVE_ERROR_CHECKING
-: 125: {
#####: 126: mpi_errno = MPIR_Err_create_code(
-: 127: mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
-: 128: "**mpi_graph_create",
-: 129: "**mpi_graph_create %C %d %p %p %d %p", comm_ptr->handle,
-: 130: nnodes, indx,
-: 131: edges, reorder, comm_graph);
-: 132: }
-: 133:# endif
#####: 134: mpi_errno = MPIR_Err_return_comm( (MPID_Comm*)comm_ptr, FCNAME, mpi_errno );
#####: 135: goto fn_exit;
-: 136: /* --END ERROR HANDLING-- */
-: 137:}
-: 138:#endif
-: 139:
-: 140:#undef FUNCNAME
-: 141:#define FUNCNAME MPI_Graph_create
-: 142:
-: 143:/*@
-: 144:MPI_Graph_create - Makes a new communicator to which topology information
-: 145: has been attached
-: 146:
-: 147:Input Parameters:
-: 148:+ comm_old - input communicator without topology (handle)
-: 149:. nnodes - number of nodes in graph (integer)
-: 150:. indx - array of integers describing node degrees (see below)
-: 151:. edges - array of integers describing graph edges (see below)
-: 152:- reorder - ranking may be reordered (true) or not (false) (logical)
-: 153:
-: 154:Output Parameter:
-: 155:. comm_graph - communicator with graph topology added (handle)
-: 156:
-: 157:Notes:
-: 158:Each process must provide a description of the entire graph, not just the
-: 159:neigbors of the calling process.
-: 160:
-: 161:Algorithm:
-: 162:We ignore the 'reorder' info currently.
-: 163:
-: 164:.N ThreadSafe
-: 165:
-: 166:.N Fortran
-: 167:
-: 168:.N Errors
-: 169:.N MPI_SUCCESS
-: 170:.N MPI_ERR_TOPOLOGY
-: 171:.N MPI_ERR_COMM
-: 172:.N MPI_ERR_ARG
-: 173:
-: 174:@*/
-: 175:int MPI_Graph_create(MPI_Comm comm_old, int nnodes, int *indx, int *edges,
-: 176: int reorder, MPI_Comm *comm_graph)
|
106: 177:{
-: 178: static const char FCNAME[] = "MPI_Graph_create";
106: 179: int mpi_errno = MPI_SUCCESS;
-: 180: int i;
106: 181: MPID_Comm *comm_ptr = NULL;
106: 182: MPIU_THREADPRIV_DECL;
-: 183: MPID_MPI_STATE_DECL(MPID_STATE_MPI_GRAPH_CREATE);
-: 184:
106: 185: MPIR_ERRTEST_INITIALIZED_ORDIE();
-: 186:
106: 187: MPIU_THREAD_CS_ENTER(ALLFUNC,);
-: 188: MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_GRAPH_CREATE);
-: 189:
-: 190: /* Validate parameters, especially handles needing to be converted */
|
-: 191:# ifdef HAVE_ERROR_CHECKING
-: 192: {
-: 193: MPID_BEGIN_ERROR_CHECKS;
-: 194: {
106: 195: MPIR_ERRTEST_COMM(comm_old, mpi_errno);
106: 196: if (mpi_errno != MPI_SUCCESS) goto fn_fail;
-: 197: }
-: 198: MPID_END_ERROR_CHECKS;
-: 199: }
-: 200:# endif
-: 201:
-: 202: /* Convert MPI object handles to object pointers */
|
104: 203: MPID_Comm_get_ptr( comm_old, comm_ptr );
-: 204:
-: 205: /* Validate parameters and objects (post conversion) */
|
-: 206:# ifdef HAVE_ERROR_CHECKING
-: 207: {
-: 208: MPID_BEGIN_ERROR_CHECKS;
-: 209: {
-: 210: /* Validate comm_ptr */
104: 211: MPID_Comm_valid_ptr( comm_ptr, mpi_errno );
-: 212: /* If comm_ptr is not valid, it will be reset to null */
104: 213: if (comm_ptr) {
104: 214: MPIR_ERRTEST_COMM_INTRA(comm_ptr,mpi_errno);
-: 215: }
104: 216: MPIR_ERRTEST_ARGNEG(nnodes,"nnodes",mpi_errno);
104: 217: if (nnodes > 0) {
98: 218: MPIR_ERRTEST_ARGNULL(indx,"index",mpi_errno);
98: 219: MPIR_ERRTEST_ARGNULL(edges,"edges",mpi_errno);
-: 220: }
104: 221: MPIR_ERRTEST_ARGNULL(comm_graph,"comm_graph",mpi_errno);
104: 222: if (mpi_errno) goto fn_fail;
-: 223: }
-: 224: MPID_END_ERROR_CHECKS;
-: 225: }
-: 226:# endif /* HAVE_ERROR_CHECKING */
-: 227:
-: 228:# ifdef HAVE_ERROR_CHECKING
-: 229: {
-: 230: MPID_BEGIN_ERROR_CHECKS;
-: 231: {
102: 232: int comm_size = comm_ptr->remote_size;
-: 233:
-: 234: /* Check that the communicator is large enough */
102: 235: if (nnodes > comm_size) {
2: 236: mpi_errno = MPIR_Err_create_code( MPI_SUCCESS,
-: 237: MPIR_ERR_RECOVERABLE,
-: 238: FCNAME, __LINE__,
-: 239: MPI_ERR_ARG,
-: 240: "**topotoolarge", "**topotoolarge %d %d",
-: 241: nnodes, comm_size );
-: 242: }
-: 243:
-: 244: /* Perform the remaining tests only if nnodes is valid.
-: 245: This avoids SEGVs from accessing invalid parts of the
-: 246: edges or index arrays */
102: 247: if (mpi_errno) goto fn_fail;
-: 248:
-: 249: /* Check that index is monotone nondecreasing */
-: 250: /* Use ERR_ARG instead of ERR_TOPOLOGY because there is no
-: 251: topology yet */
542: 252: for (i=0; i<nnodes; i++) {
442: 253: if (indx[i] < 0) {
#####: 254: mpi_errno = MPIR_Err_create_code( MPI_SUCCESS,
-: 255: MPIR_ERR_RECOVERABLE,
-: 256: FCNAME, __LINE__,
-: 257: MPI_ERR_ARG,
-: 258: "**indexneg", "**indexneg %d %d", i, indx[i] );
-: 259: }
442: 260: if (i+1<nnodes && indx[i] > indx[i+1]) {
#####: 261: mpi_errno = MPIR_Err_create_code( MPI_SUCCESS,
-: 262: MPIR_ERR_RECOVERABLE,
-: 263: FCNAME, __LINE__,
-: 264: MPI_ERR_ARG,
-: 265: "**indexnonmonotone", "**indexnonmonotone %d %d %d",
-: 266: i, indx[i], indx[i+1] );
-: 267: }
-: 268: }
-: 269:
-: 270: /* Check that edge number is in range. Note that the
-: 271: edges refer to a rank in the communicator, and can
-: 272: be greater than nnodes */
100: 273: if (nnodes > 0) {
896: 274: for (i=0; i<indx[nnodes-1]; i++) {
800: 275: if (edges[i] > comm_size || edges[i] < 0) {
8: 276: mpi_errno = MPIR_Err_create_code( MPI_SUCCESS,
-: 277: MPIR_ERR_RECOVERABLE,
-: 278: FCNAME, __LINE__,
-: 279: MPI_ERR_ARG,
-: 280: "**edgeoutrange", "**edgeoutrange %d %d %d",
-: 281: i, edges[i], comm_size );
-: 282: }
-: 283: }
-: 284: }
-: 285: /*
-: 286: * As of MPI 2.1, null edges are expressly permitted, so this
-: 287: * test is no longer needed.
-: 288: */
-: 289:#if 0
-: 290: /* We could also check that no edge is from a node to itself.
-: 291: This gives us an excuse to run over the entire arrays.
-: 292: This test could be combined with the above to make the code
-: 293: shorter.
-: 294: */
-: 295: if (!mpi_errno) {
-: 296: int j=0;
-: 297: for (i=0; i<nnodes && !mpi_errno; i++) {
-: 298: for (;j<indx[i]; j++) {
-: 299: if (edges[j] == i) {
-: 300: mpi_errno = MPIR_Err_create_code( MPI_SUCCESS,
-: 301: MPIR_ERR_RECOVERABLE,
-: 302: FCNAME, __LINE__,
-: 303: MPI_ERR_ARG,
-: 304: "**nulledge", "**nulledge %d %d", i, j );
-: 305: break;
-: 306: }
-: 307: }
-: 308: }
-: 309: }
-: 310:#endif
-: 311:
100: 312: if (mpi_errno) goto fn_fail;
-: 313: }
-: 314: MPID_END_ERROR_CHECKS;
-: 315: }
-: 316:# endif /* HAVE_ERROR_CHECKING */
-: 317:
-: 318: /* ... body of routine ... */
-: 319:
-: 320: /* Test for empty communicator */
|
96: 321: if (nnodes == 0) {
4: 322: *comm_graph = MPI_COMM_NULL;
4: 323: goto fn_exit;
-: 324: }
-: 325:
92: 326: if (comm_ptr->topo_fns != NULL &&
-: 327: comm_ptr->topo_fns->graphCreate != NULL) {
|
#####: 328: mpi_errno = comm_ptr->topo_fns->graphCreate( comm_ptr, nnodes,
-: 329: (const int *)indx,
-: 330: (const int *)edges,
-: 331: reorder, comm_graph );
-: 332: }
-: 333: else {
|
92: 334: mpi_errno = MPIR_Graph_create( comm_ptr, nnodes,
-: 335: (const int *)indx,
-: 336: (const int *)edges,
-: 337: reorder, comm_graph );
-: 338: }
|
92: 339: if (mpi_errno) goto fn_fail;
-: 340:
-: 341: /* ... end of body of routine ... */
-: 342:
|
106: 343: fn_exit:
|
-: 344: MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_GRAPH_CREATE);
|
106: 345: MPIU_THREAD_CS_EXIT(ALLFUNC,);
106: 346: return mpi_errno;
-: 347:
|
10: 348: fn_fail:
-: 349: /* --BEGIN ERROR HANDLING-- */
-: 350:# ifdef HAVE_ERROR_CHECKING
-: 351: {
10: 352: mpi_errno = MPIR_Err_create_code(
-: 353: mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
-: 354: "**mpi_graph_create",
-: 355: "**mpi_graph_create %C %d %p %p %d %p", comm_old, nnodes, indx,
-: 356: edges, reorder, comm_graph);
-: 357: }
-: 358:# endif
10: 359: mpi_errno = MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );
10: 360: goto fn_exit;
-: 361: /* --END ERROR HANDLING-- */
-: 362:}
|