-:    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:}