-/* Copyright (c) 2014, 2017. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2014-2017. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "xbt/sysdep.h"
#include "smpi/smpi.h"
-#include "src/smpi/smpi_group.hpp"
#include "private.h"
#include <vector>
#include <math.h>
-typedef struct s_smpi_mpi_cart_topology {
- int nnodes;
- int ndims;
- int *dims;
- int *periodic;
- int *position;
-} s_smpi_mpi_cart_topology_t;
-
-typedef struct s_smpi_mpi_graph_topology {
- int nnodes;
- int nedges;
- int *index;
- int *edges;
-} s_smpi_mpi_graph_topology_t;
-
-typedef struct s_smpi_dist_graph_topology {
- int indegree;
- int *in;
- int *in_weights;
- int outdegree;
- int *out;
- int *out_weights;
- int is_weighted;
-} s_smpi_mpi_dist_graph_topology_t;
-
-typedef struct s_smpi_mpi_topology {
- MPIR_Topo_type kind;
- union topo {
- MPIR_Graph_Topology graph;
- MPIR_Cart_Topology cart;
- MPIR_Dist_Graph_Topology dist_graph;
- } topo;
-} s_smpi_mpi_topology_t;
-
-void smpi_topo_destroy(MPI_Topology topo) {
- if(topo == nullptr) {
- return;
- }
- switch (topo->kind) {
- case MPI_CART:
- smpi_cart_topo_destroy(topo->topo.cart);
- break;
- case MPI_GRAPH:
- // This topology is not supported by SMPI yet
- smpi_graph_topo_destroy(topo->topo.graph);
- break;
- case MPI_DIST_GRAPH:
- // This topology is not supported by SMPI yet
- smpi_dist_graph_topo_destroy(topo->topo.dist_graph);
- break;
- default:
- return;
- }
- xbt_free(topo);
-}
+/* static functions */
+static int assignnodes(int ndim, int nfactor, int *pfacts,int **pdims);
+static int getfactors(int num, int *nfators, int **factors);
-MPI_Topology smpi_topo_create(MPIR_Topo_type kind) {
- MPI_Topology newTopo = static_cast<MPI_Topology>(xbt_malloc(sizeof(*newTopo)));
- newTopo->kind = kind;
- // Allocate and initialize the right topo should be done by the caller
- return newTopo;
-}
-void smpi_graph_topo_destroy(MPIR_Graph_Topology graph) {
- if (graph) {
- delete[] graph->index;
- delete[] graph->edges;
- xbt_free(graph);
- }
+namespace simgrid{
+namespace smpi{
+
+
+Topo_Graph::~Topo_Graph()
+{
+ delete[] index_;
+ delete[] edges_;
}
-void smpi_dist_graph_topo_destroy(MPIR_Dist_Graph_Topology dist_graph) {
- if (dist_graph) {
- delete[] dist_graph->in;
- delete[] dist_graph->in_weights;
- delete[] dist_graph->out;
- delete[] dist_graph->out_weights;
- xbt_free(dist_graph);
- }
+Topo_Dist_Graph::~Topo_Dist_Graph()
+{
+ delete[] in_;
+ delete[] in_weights_;
+ delete[] out_;
+ delete[] out_weights_;
}
/*******************************************************************************
* Cartesian topologies
******************************************************************************/
-void smpi_cart_topo_destroy(MPIR_Cart_Topology cart) {
- if (cart) {
- delete[] cart->dims;
- delete[] cart->periodic;
- delete[] cart->position;
- xbt_free(cart);
- }
+Topo_Cart::~Topo_Cart()
+{
+ delete[] dims_;
+ delete[] periodic_;
+ delete[] position_;
}
-MPI_Topology smpi_cart_topo_create(int ndims) {
- MPI_Topology newTopo = smpi_topo_create(MPI_CART);
- MPIR_Cart_Topology newCart = static_cast<MPIR_Cart_Topology>(xbt_malloc(sizeof(*newCart)));
- newCart->nnodes = 0;
- newCart->ndims = ndims;
- newCart->dims = new int[ndims];
- newCart->periodic = new int[ndims];
- newCart->position = new int[ndims];
- newTopo->topo.cart = newCart;
- return newTopo;
+Topo_Cart::Topo_Cart(int ndims) : ndims_(ndims)
+{
+ dims_ = new int[ndims];
+ periodic_ = new int[ndims];
+ position_ = new int[ndims];
}
/* reorder is ignored, don't know what would be the consequences of a dumb reordering but neither do I see the point of
* reordering*/
-int smpi_mpi_cart_create(MPI_Comm comm_old, int ndims, int dims[], int periods[], int reorder, MPI_Comm *comm_cart) {
- int retval = MPI_SUCCESS;
- MPI_Topology newCart;
+Topo_Cart::Topo_Cart(MPI_Comm comm_old, int ndims, int dims[], int periods[], int reorder, MPI_Comm *comm_cart) : Topo_Cart(ndims) {
MPI_Group newGroup;
MPI_Group oldGroup;
int nranks;
- int rank = smpi_comm_rank(comm_old);
+ int rank = comm_old->rank();
int newSize = 1;
if(ndims != 0) {
}
if(rank >= newSize) {
*comm_cart = MPI_COMM_NULL;
- return retval;
+ return;
}
- newCart = smpi_cart_topo_create(ndims);
- oldGroup = smpi_comm_group(comm_old);
- newGroup = new simgrid::SMPI::Group(newSize);
+ oldGroup = comm_old->group();
+ newGroup = new Group(newSize);
for (int i = 0 ; i < newSize ; i++) {
newGroup->set_mapping(oldGroup->index(i), i);
}
- newCart->topo.cart->nnodes = newSize;
+ nnodes_ = newSize;
- // FIXME : code duplication... See smpi_mpi_cart_coords
+ // FIXME : code duplication... See coords
nranks = newSize;
for (int i=0; i<ndims; i++) {
- newCart->topo.cart->dims[i] = dims[i];
- newCart->topo.cart->periodic[i] = periods[i];
+ dims_[i] = dims[i];
+ periodic_[i] = periods[i];
nranks = nranks / dims[i];
/* FIXME: nranks could be zero (?) */
- newCart->topo.cart->position[i] = rank / nranks;
+ position_[i] = rank / nranks;
rank = rank % nranks;
}
- *comm_cart = smpi_comm_new(newGroup, newCart);
+ *comm_cart = new Comm(newGroup, this);
} else {
if (rank == 0) {
- newCart = smpi_cart_topo_create(ndims);
- *comm_cart = smpi_comm_new(new simgrid::SMPI::Group(smpi_comm_group(MPI_COMM_SELF)), newCart);
+ *comm_cart = new Comm(new Group(MPI_COMM_SELF->group()), this);
} else {
*comm_cart = MPI_COMM_NULL;
}
}
- return retval;
+ comm_=*comm_cart;
}
-int smpi_mpi_cart_sub(MPI_Comm comm, const int remain_dims[], MPI_Comm *newcomm) {
- MPI_Topology oldTopo = smpi_comm_topo(comm);
- int oldNDims = oldTopo->topo.cart->ndims;
+Topo_Cart* Topo_Cart::sub(const int remain_dims[], MPI_Comm *newcomm) {
+ int oldNDims = ndims_;
int j = 0;
int *newDims = nullptr;
int *newPeriodic = nullptr;
if (remain_dims == nullptr && oldNDims != 0) {
- return MPI_ERR_ARG;
+ return nullptr;
}
int newNDims = 0;
for (int i = 0 ; i < oldNDims ; i++) {
// that should not segfault
for (int i = 0 ; j < newNDims ; i++) {
if(remain_dims[i]) {
- newDims[j] = oldTopo->topo.cart->dims[i];
- newPeriodic[j] = oldTopo->topo.cart->periodic[i];
+ newDims[j] =dims_[i];
+ newPeriodic[j] =periodic_[i];
j++;
}
}
}
- return smpi_mpi_cart_create(comm, newNDims, newDims, newPeriodic, 0, newcomm);
+ return new Topo_Cart(comm_, newNDims, newDims, newPeriodic, 0, newcomm);
}
-int smpi_mpi_cart_coords(MPI_Comm comm, int rank, int maxdims, int coords[]) {
- MPI_Topology topo = smpi_comm_topo(comm);
- int nnodes = topo->topo.cart->nnodes;
- for (int i = 0; i< topo->topo.cart->ndims; i++ ) {
- nnodes = nnodes / topo->topo.cart->dims[i];
+int Topo_Cart::coords(int rank, int maxdims, int coords[]) {
+ int nnodes = nnodes_;
+ for (int i = 0; i< ndims_; i++ ) {
+ nnodes = nnodes /dims_[i];
coords[i] = rank / nnodes;
rank = rank % nnodes;
}
return MPI_SUCCESS;
}
-int smpi_mpi_cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
- MPI_Topology topo = smpi_comm_topo(comm);
- int ndims=topo->topo.cart->ndims < maxdims ? topo->topo.cart->ndims : maxdims;
+int Topo_Cart::get(int maxdims, int* dims, int* periods, int* coords) {
+ int ndims=ndims_ < maxdims ?ndims_ : maxdims;
for(int i = 0 ; i < ndims ; i++) {
- dims[i] = topo->topo.cart->dims[i];
- periods[i] = topo->topo.cart->periodic[i];
- coords[i] = topo->topo.cart->position[i];
+ dims[i] =dims_[i];
+ periods[i] =periodic_[i];
+ coords[i] =position_[i];
}
return MPI_SUCCESS;
}
-int smpi_mpi_cart_rank(MPI_Comm comm, int* coords, int* rank) {
- MPI_Topology topo = smpi_comm_topo(comm);
- int ndims = topo->topo.cart->ndims;
+int Topo_Cart::rank(int* coords, int* rank) {
+ int ndims =ndims_;
int coord;
*rank = 0;
int multiplier = 1;
/* The user can give us whatever coordinates he wants. If one of them is out of range, either this dimension is
* periodic, and we consider the equivalent coordinate inside the bounds, or it's not and then it's an error
*/
- if (coord >= topo->topo.cart->dims[i]) {
- if ( topo->topo.cart->periodic[i] ) {
- coord = coord % topo->topo.cart->dims[i];
+ if (coord >=dims_[i]) {
+ if (periodic_[i] ) {
+ coord = coord %dims_[i];
} else {
// Should I do that ?
*rank = -1;
return MPI_ERR_ARG;
}
} else if (coord < 0) {
- if(topo->topo.cart->periodic[i]) {
- coord = coord % topo->topo.cart->dims[i];
+ if(periodic_[i]) {
+ coord = coord %dims_[i];
if (coord)
- coord = topo->topo.cart->dims[i] + coord;
+ coord =dims_[i] + coord;
} else {
*rank = -1;
return MPI_ERR_ARG;
}
*rank += multiplier * coord;
- multiplier *= topo->topo.cart->dims[i];
+ multiplier *=dims_[i];
}
return MPI_SUCCESS;
}
-int smpi_mpi_cart_shift(MPI_Comm comm, int direction, int disp, int *rank_source, int *rank_dest) {
- MPI_Topology topo = smpi_comm_topo(comm);
- int position[topo->topo.cart->ndims];
+int Topo_Cart::shift(int direction, int disp, int *rank_source, int *rank_dest) {
- if(topo->topo.cart->ndims == 0) {
+ int position[ndims_];
+
+ if(ndims_ == 0) {
return MPI_ERR_ARG;
}
- if (topo->topo.cart->ndims < direction) {
+ if (ndims_ < direction) {
return MPI_ERR_DIMS;
}
- smpi_mpi_cart_coords(comm, smpi_comm_rank(comm), topo->topo.cart->ndims, position);
+ this->coords(comm_->rank(),ndims_, position);
position[direction] += disp;
if(position[direction] < 0 ||
- position[direction] >= topo->topo.cart->dims[direction]) {
- if(topo->topo.cart->periodic[direction]) {
- position[direction] %= topo->topo.cart->dims[direction];
- smpi_mpi_cart_rank(comm, position, rank_dest);
+ position[direction] >=dims_[direction]) {
+ if(periodic_[direction]) {
+ position[direction] %=dims_[direction];
+ this->rank(position, rank_dest);
} else {
*rank_dest = MPI_PROC_NULL;
}
} else {
- smpi_mpi_cart_rank(comm, position, rank_dest);
+ this->rank(position, rank_dest);
}
- position[direction] = topo->topo.cart->position[direction] - disp;
- if(position[direction] < 0 || position[direction] >= topo->topo.cart->dims[direction]) {
- if(topo->topo.cart->periodic[direction]) {
- position[direction] %= topo->topo.cart->dims[direction];
- smpi_mpi_cart_rank(comm, position, rank_source);
+ position[direction] = position_[direction] - disp;
+ if(position[direction] < 0 || position[direction] >=dims_[direction]) {
+ if(periodic_[direction]) {
+ position[direction] %=dims_[direction];
+ this->rank(position, rank_source);
} else {
*rank_source = MPI_PROC_NULL;
}
} else {
- smpi_mpi_cart_rank(comm, position, rank_source);
+ this->rank(position, rank_source);
}
return MPI_SUCCESS;
}
-int smpi_mpi_cartdim_get(MPI_Comm comm, int *ndims) {
- MPI_Topology topo = smpi_comm_topo(comm);
-
- *ndims = topo->topo.cart->ndims;
+int Topo_Cart::dim_get(int *ndims) {
+ *ndims =ndims_;
return MPI_SUCCESS;
}
* $HEADER$
*/
-/* static functions */
-static int assignnodes(int ndim, int nfactor, int *pfacts,int **pdims);
-static int getfactors(int num, int *nfators, int **factors);
/*
* This is a utility function, no need to have anything in the lower layer for this at all
*/
-int smpi_mpi_dims_create(int nnodes, int ndims, int dims[])
+int Topo_Cart::Dims_create(int nnodes, int ndims, int dims[])
{
/* Get # of free-to-be-assigned processes and # of free dimensions */
int freeprocs = nnodes;
return MPI_SUCCESS;
}
+}
+}
+
/*
* assignnodes
*
(*nfactors) = i;
return MPI_SUCCESS;
}
+