1
1

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.
Этот коммит содержится в:
Prabhanjan Kambadur 2004-03-08 06:48:24 +00:00
родитель c798be5b1e
Коммит 4faa12e156
13 изменённых файлов: 718 добавлений и 18 удалений

Просмотреть файл

@ -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;
}