these are the topo/base functions which are always present. topo module authors need not implement these functions at all if they so choose. this is teh first version. i require that lam_comm_ functions be implemented so that i can test some of them out. obviously, not all of them depend on lam_comm or lam_group functions
This commit was SVN r839.
Этот коммит содержится в:
родитель
c798be5b1e
Коммит
4faa12e156
@ -8,6 +8,8 @@
|
||||
#include "lam_config.h"
|
||||
#include "mpi.h"
|
||||
|
||||
#include "mca/mpi/topo/topo.h"
|
||||
|
||||
/*
|
||||
* All stuff goes in here
|
||||
*/
|
||||
@ -21,8 +23,8 @@ extern "C" {
|
||||
bool *have_hidden_threads);
|
||||
|
||||
|
||||
int mca_topo_base_init_comm (lam_comm_t *comm);
|
||||
int mca_topo_base_get_param (lam_comm_t *comm, int keyval);
|
||||
int mca_topo_base_init_comm (lam_communicator_t *comm);
|
||||
int mca_topo_base_get_param (lam_communicator_t *comm, int keyval);
|
||||
|
||||
const mca_topo_1_0_0_t *
|
||||
mca_topo_unity_query(int *priority,
|
||||
@ -34,63 +36,64 @@ extern "C" {
|
||||
* for graph_map() and cart_map() for their topology modules.
|
||||
* But they can implement these glue functions if they want.
|
||||
*/
|
||||
int topo_base_cart_coords (lam_comm_t *comm,
|
||||
int topo_base_cart_coords (lam_communicator_t *comm,
|
||||
int rank,
|
||||
int maxdims,
|
||||
int *coords);
|
||||
|
||||
int topo_base_cart_create (lam_comm_t *old_comm,
|
||||
int topo_base_cart_create (lam_communicator_t *old_comm,
|
||||
int ndims,
|
||||
int *dims,
|
||||
int *peroids,
|
||||
int *periods,
|
||||
int reorder,
|
||||
lam_comm_t *comm_cart);
|
||||
lam_communicator_t *comm_cart);
|
||||
|
||||
int topo_base_cartdim_get (lam_comm_t *comm,
|
||||
int topo_base_cartdim_get (lam_communicator_t *comm,
|
||||
int *ndims);
|
||||
|
||||
int topo_base_cart_get (lam_comm_t *comm,
|
||||
int topo_base_cart_get (lam_communicator_t *comm,
|
||||
int maxdims,
|
||||
int *dims,
|
||||
int *periods,
|
||||
int *coords);
|
||||
|
||||
int topo_base_cart_rank (lam_comm_t *comm,
|
||||
int topo_base_cart_rank (lam_communicator_t *comm,
|
||||
int *coords,
|
||||
int *rank);
|
||||
|
||||
int topo_base_cart_shift (lam_comm_t *comm,
|
||||
int topo_base_cart_shift (lam_communicator_t *comm,
|
||||
int direction,
|
||||
int disp,
|
||||
int *rank_source,
|
||||
int *rank_dest);
|
||||
|
||||
int topo_base_cart_sub (lam_comm_t *comm,
|
||||
int topo_base_cart_sub (lam_communicator_t *comm,
|
||||
int *remain_dims,
|
||||
lam_comm_t **new_comm);
|
||||
lam_communicator_t **new_comm);
|
||||
|
||||
int topo_base_graph_create (lam_comm_t *comm_old,
|
||||
int topo_base_graph_create (lam_communicator_t *comm_old,
|
||||
int nnodes,
|
||||
int *index,
|
||||
int *edges,
|
||||
int reorder,
|
||||
lam_comm_t **comm_graph);
|
||||
lam_communicator_t **comm_graph);
|
||||
|
||||
int topo_base_graph_dims_get (lam_comm_t *comm,
|
||||
int topo_base_graph_dims_get (lam_communicator_t *comm,
|
||||
int *nodes,
|
||||
int *nedges);
|
||||
|
||||
int topo_base_graph_get (lam_comm_t *comm,
|
||||
int topo_base_graph_get (lam_communicator_t *comm,
|
||||
int maxindex,
|
||||
int maxedges,
|
||||
int *index,
|
||||
int *edges);
|
||||
|
||||
int topo_base_graph_neighbors (lam_comm_t *comm,
|
||||
int topo_base_graph_neighbors (lam_communicator_t *comm,
|
||||
int rank,
|
||||
int maxneighbors,
|
||||
int *neighbors);
|
||||
|
||||
int topo_base_graph_neighbors_count (lam_comm_t *comm,
|
||||
int topo_base_graph_neighbors_count (lam_communicator_t *comm,
|
||||
int rank,
|
||||
int *nneighbors);
|
||||
|
||||
|
@ -3,3 +3,44 @@
|
||||
*/
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - determines process coords in cartesian topology given
|
||||
* rank in group
|
||||
*
|
||||
* @param comm - communicator with cartesian structure (handle)
|
||||
* @param rank - rank of a process within group of 'comm' (integer)
|
||||
* @param maxdims - length of vector 'coords' in the calling program (integer)
|
||||
* @param coords - integer array (of size 'ndims') containing the cartesian
|
||||
* coordinates of specified process (integer)
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
* @retval MPI_ERR_COMM
|
||||
* @retval MPI_ERR_TOPOLOGY
|
||||
* @retval MPI_ERR_RANK
|
||||
* @retval MPI_ERR_DIMS
|
||||
* @retval MPI_ERR_ARG
|
||||
*/
|
||||
|
||||
int topo_base_cart_coords (lam_communicator_t *comm,
|
||||
int rank,
|
||||
int maxdims,
|
||||
int *coords){
|
||||
int dim;
|
||||
int remprocs;
|
||||
int i;
|
||||
int *d;
|
||||
|
||||
/*
|
||||
* loop computing the co-ordinates
|
||||
*/
|
||||
d = comm->c_topo_dims;
|
||||
remprocs = comm->c_topo_nprocs;
|
||||
for (i = 0; (i < comm->c_topo_ndims) && (i < maxdims); ++i, ++d) {
|
||||
dim = (*d > 0) ? *d : -(*d);
|
||||
remprocs /= dim;
|
||||
*coords++ = rank / remprocs;
|
||||
rank %= remprocs;
|
||||
}
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
@ -4,3 +4,120 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - makes a new communicator to which topology information
|
||||
* has been attached
|
||||
*
|
||||
* @param comm input communicator (handle)
|
||||
* @param ndims number of dimensions of cartesian grid (integer)
|
||||
* @param dims integer array of size ndims specifying the number of processes in
|
||||
* each dimension
|
||||
* @param periods logical array of size ndims specifying whether the grid is
|
||||
* periodic (true) or not (false) in each dimension
|
||||
* @param reorder ranking may be reordered (true) or not (false) (logical)
|
||||
* @param comm_cart communicator with new cartesian topology (handle)
|
||||
*
|
||||
* LAM/MPI currently ignores the 'reorder' flag.
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
*/
|
||||
|
||||
int topo_base_cart_create (lam_communicator_t *old_comm,
|
||||
int ndims,
|
||||
int *dims,
|
||||
int *periods,
|
||||
int reorder,
|
||||
lam_communicator_t *comm_cart){
|
||||
lam_groupt_t *newcomm;
|
||||
lam_group_t *newgroup;
|
||||
int size;
|
||||
int nprocs;
|
||||
int rank;
|
||||
int err;
|
||||
int range[1][3];
|
||||
int i;
|
||||
int *p;
|
||||
|
||||
/*
|
||||
* Compute the # of processes in the grid.
|
||||
*/
|
||||
nprocs = 1;
|
||||
for (i = 0, p = dims; i < ndims; ++i, ++p) {
|
||||
if (*p <= 0) {
|
||||
return MPI_ERR_DIMS;
|
||||
}
|
||||
nprocs *= *p;
|
||||
}
|
||||
/*
|
||||
* Create the group for the new communicator.
|
||||
*/
|
||||
err = lam_comm_size (comm, &size);
|
||||
if (err != MPI_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (nprocs > size) {
|
||||
return MPI_ERR_DIMS;
|
||||
}
|
||||
|
||||
if (nprocs == size) {
|
||||
err = lam_comm_group (comm, &newgroup);
|
||||
} else {
|
||||
range[0][0] = 0;
|
||||
range[0][1] = nprocs - 1;
|
||||
range[0][2] = 1;
|
||||
err = lam_group_range_incl (comm->c_group, 1, range, &newgroup);
|
||||
}
|
||||
|
||||
if (err != MPI_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
/*
|
||||
* Create the new communicator.
|
||||
*/
|
||||
err = lam_comm_create (comm, newgroup, comm_cart);
|
||||
if (err != MPI_SUCCESS) {
|
||||
lam_group_free (&newgroup);
|
||||
return err;
|
||||
}
|
||||
/*
|
||||
* Fill the communicator with topology information.
|
||||
*/
|
||||
newcomm = *comm_cart;
|
||||
if (newcomm != MPI_COMM_NULL) {
|
||||
newcomm->c_topo_type = MPI_CART;
|
||||
newcomm->c_topo_nprocs = nprocs;
|
||||
newcomm->c_topo_ndims = ndims;
|
||||
newcomm->c_topo_dims = (int *)
|
||||
malloc((unsigned) 2 * ndims * sizeof(int));
|
||||
if (newcomm->c_topo_dims == 0) {
|
||||
return MPI_ERR_OTHER;
|
||||
}
|
||||
newcomm->c_topo_coords = newcomm->c_topo_dims + ndims;
|
||||
for (i = 0, p = newcomm->c_topo_dims; i < ndims; ++i, ++p) {
|
||||
*p = (*periods) ? -(*dims) : *dims;
|
||||
++dims;
|
||||
++periods;
|
||||
}
|
||||
/*
|
||||
* Compute the caller's coordinates.
|
||||
*/
|
||||
err = lam_comm_rank (newcomm, &rank);
|
||||
if (err != MPI_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = lam_cart_coors (newcomm, rank,
|
||||
ndims, newcomm->c_topo_coords);
|
||||
if (err != MPI_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = lam_group_free (&newgroup);
|
||||
if (err != MPI_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
@ -4,3 +4,42 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - retrieves Cartesian topology information associated with a
|
||||
* communicator
|
||||
*
|
||||
* @param comm communicator with cartesian structure (handle)
|
||||
* @param maxdims length of vectors 'dims', 'periods', and 'coords'
|
||||
* in the calling program (integer)
|
||||
* @param dims number of processes for each cartesian dimension (array of integer)
|
||||
* @param periods periodicity (true/false) for each cartesian dimension
|
||||
* (array of logical)
|
||||
* @param coords coordinates of calling process in cartesian structure
|
||||
* (array of integer)
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
*/
|
||||
int topo_base_cart_get (lam_communicator_t *comm,
|
||||
int maxdims,
|
||||
int *dims,
|
||||
int *periods,
|
||||
int *coords){
|
||||
int i;
|
||||
int *d;
|
||||
int *c;
|
||||
|
||||
d = comm->c_topo_dims;
|
||||
c = comm->c_topo_coords;
|
||||
for (i = 0; (i < comm->c_topo_ndims) && (i < maxdims); ++i) {
|
||||
if (*d > 0) {
|
||||
*dims++ = *d++;
|
||||
*periods++ = 0;
|
||||
} else {
|
||||
*dims++ = -(*d++);
|
||||
*periods++ = 1;
|
||||
}
|
||||
*coords++ = *c++;
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
@ -4,3 +4,57 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - Determines process rank in communicator given Cartesian
|
||||
* location
|
||||
*
|
||||
* @param comm communicator with cartesian structure (handle)
|
||||
* @param coords integer array (of size 'ndims') specifying the cartesian
|
||||
* coordinates of a process
|
||||
* @param rank rank of specified process (integer)
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
* @retval MPI_ERR_COMM
|
||||
* @retval MPI_ERR_TOPOLOGY
|
||||
* @retval MPI_ERR_ARG
|
||||
*/
|
||||
|
||||
int topo_base_cart_rank (lam_communicator_t *comm,
|
||||
int *coords,
|
||||
int *rank){
|
||||
int prank;
|
||||
int dim;
|
||||
int ord;
|
||||
int factor;
|
||||
int i;
|
||||
int *d;
|
||||
int *c;
|
||||
|
||||
/*
|
||||
* Loop over coordinates computing the rank.
|
||||
*/
|
||||
factor = 1;
|
||||
prank = 0;
|
||||
i = comm->c_topo_ndims - 1;
|
||||
d = comm->c_topo_dims + i;
|
||||
c = coords + i;
|
||||
|
||||
for (; i >= 0; --i, --c, --d) {
|
||||
dim = (*d > 0) ? *d : -(*d);
|
||||
ord = *c;
|
||||
if ((ord < 0) || (ord >= dim)) {
|
||||
if (*d > 0) {
|
||||
return MPI_ERR_ARG;
|
||||
}
|
||||
ord %= dim;
|
||||
if (ord < 0) {
|
||||
ord += dim;
|
||||
}
|
||||
}
|
||||
prank += factor * ord;
|
||||
factor *= dim;
|
||||
}
|
||||
*rank = prank;
|
||||
|
||||
return(MPI_SUCCESS);
|
||||
}
|
||||
|
@ -4,3 +4,86 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - Returns the shifted source and destination ranks, given a
|
||||
* shift direction and amount
|
||||
*
|
||||
* @param comm communicator with cartesian structure (handle)
|
||||
* @param direction coordinate directionension of shift (integer)
|
||||
* @param disp displacement (> 0: upwards shift, < 0: downwards shift) (integer)
|
||||
* @param rank_source rank of source process (integer)
|
||||
* @param rank_dest rank of destination process (integer)
|
||||
*
|
||||
* The 'direction' argument is in the range '[0,n-1]' for an n-directionensional
|
||||
* Cartesian mesh.
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
* @retval MPI_ERR_TOPOLOGY
|
||||
* @retval MPI_ERR_DIMS
|
||||
* @retval MPI_ERR_COMM
|
||||
* @retval MPI_ERR_ARG
|
||||
*/
|
||||
int topo_base_cart_shift (lam_communicator_t *comm,
|
||||
int direction,
|
||||
int disp,
|
||||
int *rank_source,
|
||||
int *rank_dest){
|
||||
int factor;
|
||||
int thisdirection = 0;
|
||||
int thisperiod = 0;
|
||||
int ord;
|
||||
int srcord;
|
||||
int destord;
|
||||
int i;
|
||||
int *p;
|
||||
|
||||
/*
|
||||
* Handle the trivial case.
|
||||
*/
|
||||
ord = comm->c_group->g_myrank;
|
||||
if (disp == 0) {
|
||||
*rank_dest = *rank_source = ord;
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
/*
|
||||
* Compute the rank factor and ordinate.
|
||||
*/
|
||||
factor = comm->c_topo_nprocs;
|
||||
p = comm->c_topo_dims;
|
||||
for (i = 0; (i < comm->c_topo_ndims) && (i <= direction); ++i, ++p) {
|
||||
if ((thisdirection = *p) > 0) {
|
||||
thisperiod = 0;
|
||||
} else {
|
||||
thisperiod = 1;
|
||||
thisdirection = -thisdirection;
|
||||
}
|
||||
|
||||
ord %= factor;
|
||||
factor /= thisdirection;
|
||||
}
|
||||
|
||||
ord /= factor;
|
||||
/*
|
||||
* Check the displacement value and compute the new ranks.
|
||||
*/
|
||||
*rank_source = *rank_dest = MPI_UNDEFINED;
|
||||
|
||||
srcord = ord - disp;
|
||||
destord = ord + disp;
|
||||
if ( ((destord < 0) || (destord >= thisdirection)) && (!thisperiod) ) {
|
||||
*rank_dest = MPI_PROC_NULL;
|
||||
} else {
|
||||
destord %= thisdirection;
|
||||
if (destord < 0) destord += thisdirection;
|
||||
*rank_dest = comm->c_group->g_myrank + ((destord - ord) * factor);
|
||||
}
|
||||
if ( ((srcord < 0) || (srcord >= thisdirection)) && (!thisperiod) ) {
|
||||
*rank_source = MPI_PROC_NULL;
|
||||
} else {
|
||||
srcord %= thisdirection;
|
||||
if (srcord < 0) srcord += thisdirection;
|
||||
*rank_source = comm->c_group->g_myrank + ((srcord - ord) * factor);
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
@ -4,3 +4,120 @@
|
||||
|
||||
#include "mca/topo/base/base.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 topo_base_cart_sub (lam_communicator_t *comm,
|
||||
int *remain_dims,
|
||||
lam_communicator_t **new_comm){
|
||||
lam_communicator_t *newcomm;
|
||||
int errcode;
|
||||
int colour;
|
||||
int key;
|
||||
int colfactor;
|
||||
int keyfactor;
|
||||
int rank;
|
||||
int ndim;
|
||||
int dim;
|
||||
int allfalse;
|
||||
int i;
|
||||
int *d;
|
||||
int *c;
|
||||
int *r;
|
||||
int *p;
|
||||
|
||||
/*
|
||||
* Compute colour and key used in splitting the communicator.
|
||||
*/
|
||||
colour = key = 0;
|
||||
colfactor = keyfactor = 1;
|
||||
ndim = 0;
|
||||
allfalse = 0;
|
||||
|
||||
i = comm->c_topo_ndims - 1;
|
||||
d = comm->c_topo_dims + i;
|
||||
c = comm->c_topo_coords + i;
|
||||
r = remain_dims + i;
|
||||
|
||||
for (; i >= 0; --i, --d, --c, --r) {
|
||||
dim = (*d > 0) ? *d : -(*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 cartesian communicator with just ourselves in it (you can't
|
||||
* have a communicator unless you're in it).
|
||||
*/
|
||||
if (ndim == 0) {
|
||||
lam_comm_rank (comm, &colour);
|
||||
ndim = 1;
|
||||
allfalse = 1;
|
||||
}
|
||||
/*
|
||||
* Split the communicator.
|
||||
*/
|
||||
errcode = lam_comm_split (comm, colour, key, new_comm);
|
||||
if (errcode != MPI_SUCCESS) {
|
||||
return errcode;
|
||||
}
|
||||
/*
|
||||
* Fill the communicator with topology information.
|
||||
*/
|
||||
newcomm = *new_comm;
|
||||
if (newcomm != MPI_COMM_NULL) {
|
||||
newcomm->c_topo_type = MPI_CART;
|
||||
newcomm->c_topo_nprocs = keyfactor;
|
||||
newcomm->c_topo_ndims = ndim;
|
||||
newcomm->c_topo_dims = (int *)
|
||||
malloc((unsigned) 2 * ndim * sizeof(int));
|
||||
if (newcomm->c_topo_dims == 0) {
|
||||
return MPI_ERR_OTHER;
|
||||
}
|
||||
newcomm->c_topo_coords = newcomm->c_topo_dims + ndim;
|
||||
if (!allfalse) {
|
||||
p = newcomm->c_topo_dims;
|
||||
d = comm->c_topo_dims;
|
||||
r = remain_dims;
|
||||
for (i = 0; i < comm->c_topo_ndims; ++i, ++d, ++r) {
|
||||
if (*r) {
|
||||
*p++ = *d;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newcomm->c_topo_dims[0] = 1;
|
||||
}
|
||||
/*
|
||||
* Compute the caller's coordinates.
|
||||
*/
|
||||
errcode = lam_comm_rank (newcomm, &rank);
|
||||
if (errcode != MPI_SUCCESS) {
|
||||
return errcode;
|
||||
}
|
||||
errcode = lam_cart_coords (newcomm, rank,
|
||||
ndim, newcomm->c_topo_coords);
|
||||
if (errcode != MPI_SUCCESS) {
|
||||
return errcode;
|
||||
}
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
@ -4,3 +4,21 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - retrieves Cartesian topology information associated with a
|
||||
* communicator
|
||||
*
|
||||
* @param comm communicator with cartesian structure (handle)
|
||||
* @param ndims number of dimensions of the cartesian structure (integer)
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
* @retval MPI_ERR_COMM
|
||||
*/
|
||||
int topo_base_cartdim_get (lam_communicator_t *comm,
|
||||
int *ndims){
|
||||
|
||||
*ndims = comm->c_topo_ndims;
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,3 +4,109 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
*
|
||||
* function - makes a new communicator to which topology information
|
||||
* has been attached
|
||||
*
|
||||
* @param comm_old input communicator without topology (handle)
|
||||
* @param nnodes number of nodes in graph (integer)
|
||||
* @param index array of integers describing node degrees (see below)
|
||||
* @param edges array of integers describing graph edges (see below)
|
||||
* @param reorder ranking may be reordered (true) or not (false) (logical)
|
||||
* @param comm_graph communicator with graph topology added (handle)
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
* @retval MPI_ERR_OUT_OF_RESOURCE
|
||||
*/
|
||||
|
||||
int topo_base_graph_create (lam_communicator_t *comm_old,
|
||||
int nnodes,
|
||||
int *index,
|
||||
int *edges,
|
||||
int reorder,
|
||||
lam_communicator_t **comm_graph) {
|
||||
|
||||
lam_group_t *newgroup;
|
||||
int nedges;
|
||||
int size;
|
||||
int err;
|
||||
int range[1][3];
|
||||
int i;
|
||||
int *topo;
|
||||
int *p;
|
||||
|
||||
/*
|
||||
* Create and error check the topology information.
|
||||
*/
|
||||
nedges = index[nnodes - 1];
|
||||
topo = (int *) malloc((unsigned) (nnodes + nedges) * sizeof(int));
|
||||
if (topo == 0) {
|
||||
printf ("Out of resources\n");
|
||||
return MPI_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
for (i = 0, p = topo; i < nnodes; ++i, ++p) {
|
||||
*p = *index++;
|
||||
}
|
||||
|
||||
for (i = 0; i < nedges; ++i, ++p) {
|
||||
*p = *edges++;
|
||||
if (*p < 0 || *p >= nnodes) {
|
||||
free((char *) topo);
|
||||
return MPI_ERR_TOPOLOGY;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Create the group for the new communicator.
|
||||
*/
|
||||
err = lam_comm_size (comm_old, &size);
|
||||
if (err != MPI_SUCCESS) {
|
||||
free((char *) topo);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (nnodes > size) {
|
||||
free((char *) topo);
|
||||
return MPI_ERR_ARG;
|
||||
}
|
||||
|
||||
if (nnodes == size) {
|
||||
err = lam_comm_group (comm_old, &newgroup);
|
||||
} else {
|
||||
range[0][0] = 0;
|
||||
range[0][1] = nnodes - 1;
|
||||
range[0][2] = 1;
|
||||
err = lam_group_range_incl(comm_old->c_group, 1, range, &newgroup);
|
||||
}
|
||||
if (err != MPI_SUCCESS) {
|
||||
free((char *) topo);
|
||||
return err;
|
||||
}
|
||||
/*
|
||||
* Create the new communicator.
|
||||
*/
|
||||
err = lam_comm_create (comm_old, newgroup, comm_graph);
|
||||
if (err != MPI_SUCCESS) {
|
||||
free((char *) topo);
|
||||
lam_group_free (&newgroup);
|
||||
return err;
|
||||
}
|
||||
/*
|
||||
* Set the communicator topology information.
|
||||
*/
|
||||
if (*comm_graph != MPI_COMM_NULL) {
|
||||
(*comm_graph)->c_topo_type = MPI_GRAPH;
|
||||
(*comm_graph)->c_topo_nprocs = nnodes;
|
||||
(*comm_graph)->c_topo_nedges = nedges;
|
||||
(*comm_graph)->c_topo_index = topo;
|
||||
(*comm_graph)->c_topo_edges = topo + nnodes;
|
||||
}
|
||||
|
||||
err = lam_group_free (&newgroup);
|
||||
if (err != MPI_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return(MPI_SUCCESS);
|
||||
}
|
||||
|
@ -4,3 +4,29 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - Retrieves graph topology information associated with a
|
||||
* communicator
|
||||
*
|
||||
* @param comm - communicator for group with graph structure (handle)
|
||||
* @param nodes - number of nodes in graph (integer)
|
||||
* @param nedges - number of edges in graph (integer)
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
* @retval MPI_ERR_TOPOLOGY
|
||||
* @retval MPI_ERR_COMM
|
||||
* @retval MPI_ERR_ARG
|
||||
*/
|
||||
int topo_base_graph_dims_get (lam_communicator_t *comm,
|
||||
int *nodes,
|
||||
int *nedges){
|
||||
|
||||
*nodes = comm->c_topo_nprocs;
|
||||
*nedges = comm->c_topo_nedges;
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -4,3 +4,39 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - retrieves graph topology information associated with a
|
||||
* communicator
|
||||
*
|
||||
* @param comm communicator with graph structure (handle)
|
||||
* @param maxindex length of vector 'index' in the calling program (integer)
|
||||
* @param maxedges length of vector 'edges' in the calling program (integer)
|
||||
* @param nodes array of integers containing the graph structure (for details see
|
||||
* @param edges array of integers containing the graph structure
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
*/
|
||||
|
||||
int topo_base_graph_get (lam_communicator_t *comm,
|
||||
int maxindex,
|
||||
int maxedges,
|
||||
int *index,
|
||||
int *edges){
|
||||
int i;
|
||||
int *p;
|
||||
|
||||
/*
|
||||
* Fill the nodes and edges arrays.
|
||||
*/
|
||||
p = comm->c_topo_index;
|
||||
for (i = 0; (i < comm->c_topo_nprocs) && (i < maxindex); ++i, ++p) {
|
||||
*nodes++ = *p;
|
||||
}
|
||||
|
||||
p = comm->c_topo_edges;
|
||||
for (i = 0; (i < comm->c_topo_nedges) && (i < maxedges); ++i, ++p) {
|
||||
*edges++ = *p;
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
@ -4,3 +4,42 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - returns the neighbors of a node associated
|
||||
* with a graph topology
|
||||
*
|
||||
* @param comm communicator with graph topology (handle)
|
||||
* @param rank rank of process in group of comm (integer)
|
||||
* @param maxneighbors size of array neighbors (integer)
|
||||
* @param neighbors ranks of processes that are neighbors to specified process
|
||||
* (array of integer)
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
*/
|
||||
|
||||
int topo_base_graph_neighbors (lam_communicator_t *comm,
|
||||
int rank,
|
||||
int maxneighbors,
|
||||
int *neighbors){
|
||||
int nnbrs;
|
||||
int i;
|
||||
int *p;
|
||||
|
||||
/*
|
||||
* Fill the neighbours.
|
||||
*/
|
||||
nnbrs = comm->c_topo_index[rank];
|
||||
p = comm->c_topo_edges;
|
||||
|
||||
if (rank > 0) {
|
||||
i = comm->c_topo_index[rank - 1];
|
||||
nnbrs -= i;
|
||||
p += i;
|
||||
}
|
||||
|
||||
for (i = 0; (i < maxneighbors) && (i < nnbrs); ++i, ++p) {
|
||||
*neighbors++ = *p;
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
@ -4,3 +4,24 @@
|
||||
|
||||
#include "mca/topo/base/base.h"
|
||||
|
||||
/*
|
||||
* function - returns the number of neighbors of a node
|
||||
* associated with a graph topology
|
||||
*
|
||||
* @param comm communicator with graph topology (handle)
|
||||
* @param rank rank of process in group of 'comm' (integer)
|
||||
* @param nneighbors number of neighbors of specified process (integer)
|
||||
*
|
||||
* @retval MPI_SUCCESS
|
||||
*/
|
||||
|
||||
int topo_base_graph_neighbors_count (lam_communicator_t *comm,
|
||||
int rank,
|
||||
int *nneighbors){
|
||||
*nneighbors = comm->c_topo_index[rank];
|
||||
if (rank > 0) {
|
||||
*nneighbors -= comm->c_topo_index[rank - 1];
|
||||
}
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user