-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/topo/cart_create.c
        -:    0:Graph:cart_create.gcno
        -:    0:Data:cart_create.gcda
        -:    0:Runs:689
        -:    0:Programs:184
        -:    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_create */
        -:   12:#if defined(HAVE_PRAGMA_WEAK)
        -:   13:#pragma weak MPI_Cart_create = PMPI_Cart_create
        -:   14:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
        -:   15:#pragma _HP_SECONDARY_DEF PMPI_Cart_create  MPI_Cart_create
        -:   16:#elif defined(HAVE_PRAGMA_CRI_DUP)
        -:   17:#pragma _CRI duplicate MPI_Cart_create as PMPI_Cart_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_Cart_create
        -:   25:#define MPI_Cart_create PMPI_Cart_create
        -:   26:
        -:   27:#endif
        -:   28:
        -:   29:#undef FUNCNAME
        -:   30:#define FUNCNAME MPI_Cart_create
        -:   31:
        -:   32:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
        -:   33:   the MPI routines */
        -:   34:#ifndef MPICH_MPI_FROM_PMPI
        -:   35:int MPIR_Cart_create( const MPID_Comm *comm_ptr, int ndims, const int dims[], 
        -:   36:		      const int periods[], int reorder, MPI_Comm *comm_cart )
      305:   37:{
        -:   38:#ifdef HAVE_ERROR_CHECKING
        -:   39:    static const char FCNAME[] = "MPIR_Cart_create";
        -:   40:#endif
      305:   41:    int       i, newsize, rank, nranks, mpi_errno = MPI_SUCCESS;
      305:   42:    MPID_Comm *newcomm_ptr = NULL;
      305:   43:    MPIR_Topology *cart_ptr = NULL;
        -:   44:    MPI_Comm ncomm;
      305:   45:    MPIU_CHKPMEM_DECL(4);
        -:   46:    
        -:   47:    /* Set this as null incase we exit with an error */
      305:   48:    *comm_cart = MPI_COMM_NULL;
        -:   49:
        -:   50:    /* Check for invalid arguments */
      305:   51:    newsize = 1;
     1101:   52:    for (i=0; i<ndims; i++) 
      796:   53:	newsize *= dims[i];
        -:   54:
        -:   55:    /* Use ERR_ARG instead of ERR_TOPOLOGY because there is no topology yet */
      305:   56:    MPIU_ERR_CHKANDJUMP2((newsize > comm_ptr->remote_size), mpi_errno, 
        -:   57:			 MPI_ERR_ARG, "**cartdim",
        -:   58:			 "**cartdim %d %d", comm_ptr->remote_size, newsize);
        -:   59:
      299:   60:    if (ndims == 0) {
        -:   61:	/* specified as a 0D Cartesian topology in MPI 2.1. 
        -:   62:	   Rank 0 returns a dup of COMM_SELF with the topology info attached.
        -:   63:           Others return MPI_COMM_NULL. */
        -:   64:
        9:   65:	rank = comm_ptr->rank;
        -:   66:
        9:   67:	if (rank == 0) {
        3:   68:            MPIU_THREADPRIV_DECL;
        -:   69:
        3:   70:            MPIU_THREADPRIV_GET;
        3:   71:            MPIR_Nest_incr();
        3:   72:	    mpi_errno = NMPI_Comm_dup(MPI_COMM_SELF, &ncomm);
        3:   73:            MPIR_Nest_decr();
        3:   74:	    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:   75:	    
        3:   76:	    MPID_Comm_get_ptr( ncomm, newcomm_ptr );
        -:   77:	
        -:   78:	    /* Create the topology structure */
        3:   79:	    MPIU_CHKPMEM_MALLOC(cart_ptr,MPIR_Topology*,sizeof(MPIR_Topology),
        -:   80:				mpi_errno, "cart_ptr" );
        -:   81:	    
        3:   82:	    cart_ptr->kind               = MPI_CART;
        3:   83:	    cart_ptr->topo.cart.nnodes   = 1;
        3:   84:	    cart_ptr->topo.cart.ndims    = 0;
        -:   85:	    
        -:   86:	    /* make mallocs of size 1 int so that they get freed as part of the 
        -:   87:	       normal free mechanism */
        -:   88:	    
        6:   89:	    MPIU_CHKPMEM_MALLOC(cart_ptr->topo.cart.dims,int*,sizeof(int),
        -:   90:				mpi_errno, "cart.dims");
        6:   91:	    MPIU_CHKPMEM_MALLOC(cart_ptr->topo.cart.periodic,int*,sizeof(int),
        -:   92:				mpi_errno, "cart.periodic");
        6:   93:	    MPIU_CHKPMEM_MALLOC(cart_ptr->topo.cart.position,int*,sizeof(int),
        -:   94:				mpi_errno, "cart.position");
        -:   95:	}
        -:   96:	else {
        6:   97:	    *comm_cart = MPI_COMM_NULL;
        6:   98:	    return MPI_SUCCESS;
        -:   99:	}
        -:  100:    }
        -:  101:
        -:  102:    else {
        -:  103:
        -:  104:	/* Create a new communicator as a duplicate of the input communicator
        -:  105:	   (but do not duplicate the attributes) */
      290:  106:	if (reorder) {
       96:  107:	    MPIU_THREADPRIV_DECL;
        -:  108:	    
        -:  109:	    /* Allow the cart map routine to remap the assignment of ranks to 
        -:  110:	       processes */
       96:  111:	    MPIU_THREADPRIV_GET;
       96:  112:	    MPIR_Nest_incr();
       96:  113:	    mpi_errno = NMPI_Cart_map( comm_ptr->handle, ndims, (int *)dims, 
        -:  114:				       (int *)periods, &rank );
        -:  115:	    /* Create the new communicator with split, since we need to reorder
        -:  116:	       the ranks (including the related internals, such as the connection
        -:  117:	       tables */
       96:  118:	    if (mpi_errno == 0) {
       96:  119:		mpi_errno = NMPI_Comm_split( comm_ptr->handle, 
        -:  120:					     rank == MPI_UNDEFINED ? MPI_UNDEFINED : 1,
        -:  121:					     rank, &ncomm );
       96:  122:		if (!mpi_errno) {
       96:  123:		    MPID_Comm_get_ptr( ncomm, newcomm_ptr );
        -:  124:		}
        -:  125:	    }
       96:  126:	    MPIR_Nest_decr();
        -:  127:	}
        -:  128:	else {
      194:  129:	    mpi_errno = MPIR_Comm_copy( (MPID_Comm *)comm_ptr, newsize, 
        -:  130:					&newcomm_ptr );
      194:  131:	    rank   = comm_ptr->rank;
        -:  132:	}
      290:  133:	if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:  134:
        -:  135:	/* If this process is not in the resulting communicator, return a 
        -:  136:	   null communicator and exit */
      290:  137:	if (rank >= newsize || rank == MPI_UNDEFINED) {
        2:  138:	    *comm_cart = MPI_COMM_NULL;
        2:  139:	    return MPI_SUCCESS;
        -:  140:	}
        -:  141:	
        -:  142:	/* Create the topololgy structure */
      288:  143:	MPIU_CHKPMEM_MALLOC(cart_ptr,MPIR_Topology*,sizeof(MPIR_Topology),
        -:  144:			    mpi_errno, "cart_ptr" );
        -:  145:	
      288:  146:	cart_ptr->kind               = MPI_CART;
      288:  147:	cart_ptr->topo.cart.nnodes   = newsize;
      288:  148:	cart_ptr->topo.cart.ndims    = ndims;
      576:  149:	MPIU_CHKPMEM_MALLOC(cart_ptr->topo.cart.dims,int*,ndims*sizeof(int),
        -:  150:			    mpi_errno, "cart.dims");
      288:  151:	MPIU_CHKPMEM_MALLOC(cart_ptr->topo.cart.periodic,int*,ndims*sizeof(int),
        -:  152:			    mpi_errno, "cart.periodic");
      288:  153:	MPIU_CHKPMEM_MALLOC(cart_ptr->topo.cart.position,int*,ndims*sizeof(int),
        -:  154:			    mpi_errno, "cart.position");
      288:  155:	nranks = newsize;
     1072:  156:	for (i=0; i<ndims; i++)
        -:  157:	{
      784:  158:	    cart_ptr->topo.cart.dims[i]     = dims[i];
      784:  159:	    cart_ptr->topo.cart.periodic[i] = periods[i];
      784:  160:	    nranks = nranks / dims[i];
        -:  161:	    /* FIXME: nranks could be zero (?) */
      784:  162:	    cart_ptr->topo.cart.position[i] = rank / nranks;
      784:  163:	    rank = rank % nranks;
        -:  164:	}
        -:  165:    } 
        -:  166:
        -:  167:
        -:  168:    /* Place this topology onto the communicator */
      291:  169:    mpi_errno = MPIR_Topology_put( newcomm_ptr, cart_ptr );
      291:  170:    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:  171:
      291:  172:    *comm_cart = newcomm_ptr->handle;
        -:  173:
      291:  174:    return mpi_errno;
        -:  175:
        -:  176:  fn_fail:
        -:  177:    /* --BEGIN ERROR HANDLING-- */
    #####:  178:    MPIU_CHKPMEM_REAP();
        -:  179:#   ifdef HAVE_ERROR_CHECKING
        -:  180:    {
        6:  181:	mpi_errno = MPIR_Err_create_code(
        -:  182:	    mpi_errno, MPIR_ERR_RECOVERABLE, "MPIR_Cart_create", __LINE__, 
        -:  183:	    MPI_ERR_OTHER, 
        -:  184:	    "**mpi_cart_create",
        -:  185:	    "**mpi_cart_create %C %d %p %p %d %p", comm_ptr, ndims, dims, 
        -:  186:	    periods, reorder, comm_cart);
        -:  187:    }
        -:  188:#   endif
        6:  189:    return mpi_errno;
        -:  190:    /* --END ERROR HANDLING-- */
        -:  191:}
        -:  192:#endif
        -:  193:
        -:  194:/*@
        -:  195:
        -:  196:MPI_Cart_create - Makes a new communicator to which topology information
        -:  197:                  has been attached
        -:  198:
        -:  199:Input Parameters:
        -:  200:+ comm_old - input communicator (handle) 
        -:  201:. ndims - number of dimensions of cartesian grid (integer) 
        -:  202:. dims - integer array of size ndims specifying the number of processes in 
        -:  203:  each dimension 
        -:  204:. periods - logical array of size ndims specifying whether the grid is 
        -:  205:  periodic (true) or not (false) in each dimension 
        -:  206:- reorder - ranking may be reordered (true) or not (false) (logical) 
        -:  207:
        -:  208:Output Parameter:
        -:  209:. comm_cart - communicator with new cartesian topology (handle) 
        -:  210:
        -:  211:Algorithm:
        -:  212:We ignore 'reorder' info currently.
        -:  213:
        -:  214:.N ThreadSafe
        -:  215:
        -:  216:.N Fortran
        -:  217:
        -:  218:.N Errors
        -:  219:.N MPI_SUCCESS
        -:  220:.N MPI_ERR_TOPOLOGY
        -:  221:.N MPI_ERR_DIMS
        -:  222:.N MPI_ERR_ARG
        -:  223:@*/
        -:  224:int MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods, 
        -:  225:		    int reorder, MPI_Comm *comm_cart)
      307:  226:{
        -:  227:#ifdef HAVE_ERROR_CHECKING
        -:  228:    static const char FCNAME[] = "MPI_Cart_create";
        -:  229:#endif
      307:  230:    int       mpi_errno = MPI_SUCCESS;
      307:  231:    MPID_Comm *comm_ptr = NULL;
      307:  232:    MPIU_THREADPRIV_DECL;
        -:  233:    MPID_MPI_STATE_DECL(MPID_STATE_MPI_CART_CREATE);
        -:  234:
      307:  235:    MPIR_ERRTEST_INITIALIZED_ORDIE();
        -:  236:    
      307:  237:    MPIU_THREAD_CS_ENTER(ALLFUNC,);
        -:  238:    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_CART_CREATE);
        -:  239:
        -:  240:    /* Validate parameters, especially handles needing to be converted */
        -:  241:#   ifdef HAVE_ERROR_CHECKING
        -:  242:    {
        -:  243:        MPID_BEGIN_ERROR_CHECKS;
        -:  244:        {
      307:  245:	    MPIR_ERRTEST_COMM(comm_old, mpi_errno);
      307:  246:            if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:  247:        }
        -:  248:        MPID_END_ERROR_CHECKS;
        -:  249:    }
        -:  250:#   endif
        -:  251:    
        -:  252:    /* Convert MPI object handles to object pointers */
      305:  253:    MPID_Comm_get_ptr( comm_old, comm_ptr );
        -:  254:
        -:  255:    /* Validate parameters and objects (post conversion) */
        -:  256:#   ifdef HAVE_ERROR_CHECKING
        -:  257:    {
        -:  258:        MPID_BEGIN_ERROR_CHECKS;
        -:  259:        {
        -:  260:            /* Validate comm_ptr */
      305:  261:            MPID_Comm_valid_ptr( comm_ptr, mpi_errno );
        -:  262:	    /* If comm_ptr is not valid, it will be reset to null */
      305:  263:	    if (comm_ptr) {
      305:  264:		MPIR_ERRTEST_COMM_INTRA(comm_ptr,mpi_errno);
        -:  265:	    }
        -:  266:
      305:  267:	    if (ndims > 0) {
      296:  268:		MPIR_ERRTEST_ARGNULL( dims, "dims", mpi_errno );
      296:  269:		MPIR_ERRTEST_ARGNULL( periods, "periods", mpi_errno );
        -:  270:	    }
      305:  271:	    MPIR_ERRTEST_ARGNULL( comm_cart, "comm_cart", mpi_errno );
      305:  272:	    if (ndims < 0) {
        -:  273:		/* Must have a non-negative number of dimensions */
    #####:  274:		mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, 
        -:  275:			  MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_DIMS,
        -:  276:						  "**dims",  "**dims %d", 0 );
        -:  277:	    }
      305:  278:	    MPIR_ERRTEST_ARGNEG( ndims, "ndims", mpi_errno );
      305:  279:	    if (comm_ptr) {
      305:  280:		MPIR_ERRTEST_COMM_INTRA( comm_ptr, mpi_errno );
        -:  281:	    }
      305:  282:            if (mpi_errno) goto fn_fail;
        -:  283:        }
        -:  284:        MPID_END_ERROR_CHECKS;
        -:  285:    }
        -:  286:#   endif /* HAVE_ERROR_CHECKING */
        -:  287:
        -:  288:    /* ... body of routine ...  */
        -:  289:
      305:  290:    if (comm_ptr->topo_fns != NULL && comm_ptr->topo_fns->cartCreate != NULL) {
    #####:  291:	mpi_errno = comm_ptr->topo_fns->cartCreate( comm_ptr, ndims, 
        -:  292:						    (const int*) dims,
        -:  293:						    (const int*) periods, 
        -:  294:						    reorder,
        -:  295:						    comm_cart );
        -:  296:    }
        -:  297:    else {
      305:  298:	mpi_errno = MPIR_Cart_create( comm_ptr, ndims, 
        -:  299:				      (const int*) dims,
        -:  300:				      (const int*) periods, reorder, 
        -:  301:				      comm_cart );
        -:  302:    }
        -:  303:#ifdef HAVE_ERROR_CHECKING
      305:  304:    if (mpi_errno) goto fn_fail;
        -:  305:#endif
        -:  306:    /* ... end of body of routine ... */
        -:  307:
        -:  308:#ifdef HAVE_ERROR_CHECKING
      307:  309:  fn_exit:
        -:  310:#endif
        -:  311:    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_CART_CREATE);
      307:  312:    MPIU_THREAD_CS_EXIT(ALLFUNC,);
      307:  313:    return mpi_errno;
        -:  314:
        -:  315:    /* --BEGIN ERROR HANDLING-- */
        -:  316:#   ifdef HAVE_ERROR_CHECKING
        8:  317:  fn_fail:
        -:  318:    {
        8:  319:	mpi_errno = MPIR_Err_create_code(
        -:  320:	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, 
        -:  321:	    "**mpi_cart_create",
        -:  322:	    "**mpi_cart_create %C %d %p %p %d %p", comm_old, ndims, dims, 
        -:  323:	    periods, reorder, comm_cart);
        -:  324:    }
        8:  325:    mpi_errno = MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );
        8:  326:    goto fn_exit;
        -:  327:#   endif
        -:  328:    /* --END ERROR HANDLING-- */
        -:  329:}