1
1
openmpi/ompi/mca/topo/base/topo_base_cart_sub.c
Rainer Keller 6fca443a71 - No, we don't want to have a notion of an MPI_Comm in this layer
We want ompi_communicator_t instead, rrrrrr.

This commit was SVN r20770.
2009-03-12 22:38:14 +00:00

135 строки
4.1 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include "ompi/mca/topo/base/base.h"
#include "ompi/communicator/communicator.h"
#include "ompi/mca/topo/topo.h"
/*
* function - partitions a communicator into subgroups which
* form lower-dimensional cartesian subgrids
*
* @param comm communicator with cartesian structure (handle)
* @param remain_dims the 'i'th entry of 'remain_dims' specifies whether
* the 'i'th dimension is kept in the subgrid (true)
* or is dropped (false) (logical vector)
* @param new_comm communicator containing the subgrid that includes the
* calling process (handle)
*
* @retval MPI_SUCCESS
* @retval MPI_ERR_TOPOLOGY
* @retval MPI_ERR_COMM
*/
int mca_topo_base_cart_sub (ompi_communicator_t* comm,
int *remain_dims,
ompi_communicator_t** new_comm){
struct ompi_communicator_t *temp_comm;
int errcode;
int colour;
int key;
int colfactor;
int keyfactor;
int rank;
int ndim;
int dim;
int i;
int *d;
int *c;
int *r;
int *p;
*new_comm = MPI_COMM_NULL;
/*
* Compute colour and key used in splitting the communicator.
*/
colour = key = 0;
colfactor = keyfactor = 1;
ndim = 0;
i = comm->c_topo_comm->mtc_ndims_or_nnodes - 1;
d = comm->c_topo_comm->mtc_dims_or_index + i;
c = comm->c_topo_comm->mtc_coords + i;
r = remain_dims + i;
for (; i >= 0; --i, --d, --c, --r) {
dim = *d;
if (*r == 0) {
colour += colfactor * (*c);
colfactor *= dim;
} else {
++ndim;
key += keyfactor * (*c);
keyfactor *= dim;
}
}
/* Special case: if all of remain_dims were false, we need to make
a 0-dimension cartesian communicator with just ourselves in it
(you can't have a communicator unless you're in it). */
if (0 == ndim) {
colour = ompi_comm_rank (comm);
}
/*
* Split the communicator.
*/
errcode = ompi_comm_split (comm, colour, key, &temp_comm, true);
if (errcode != MPI_SUCCESS) {
return errcode;
}
/*
* Fill the communicator with topology information.
*/
if (temp_comm != MPI_COMM_NULL) {
temp_comm->c_topo_comm->mtc_ndims_or_nnodes = ndim;
if (ndim >= 1) {
p = temp_comm->c_topo_comm->mtc_dims_or_index;
d = comm->c_topo_comm->mtc_dims_or_index;
r = remain_dims;
for (i = 0; i < comm->c_topo_comm->mtc_ndims_or_nnodes;
++i, ++d, ++r) {
if (*r) {
*p++ = *d;
}
}
/*
* Compute the caller's coordinates, if ndims>0
*/
rank = ompi_comm_rank (temp_comm);
if (MPI_SUCCESS != errcode) {
OBJ_RELEASE(temp_comm);
return errcode;
}
errcode = temp_comm->c_topo->topo_cart_coords (temp_comm, rank,
ndim, temp_comm->c_topo_comm->mtc_coords);
if (MPI_SUCCESS != errcode) {
OBJ_RELEASE(temp_comm);
return errcode;
}
}
}
*new_comm = temp_comm;
return MPI_SUCCESS;
}