#include <boost/intrusive_ptr.hpp>
namespace simgrid {
-namespace SMPI {
+namespace smpi {
class Group;
class Comm;
+class Topo;
+class Cart;
+class Graph;
+class Dist_Graph;
}
}
-typedef simgrid::SMPI::Group SMPI_Group;
-typedef simgrid::SMPI::Comm SMPI_Comm;
+typedef simgrid::smpi::Group SMPI_Group;
+typedef simgrid::smpi::Comm SMPI_Comm;
+typedef simgrid::smpi::Topo SMPI_Topology;
+typedef simgrid::smpi::Graph SMPI_Graph_topology;
+typedef simgrid::smpi::Cart SMPI_Cart_topology;
+typedef simgrid::smpi::Dist_Graph SMPI_Dist_Graph_topology;
#else
typedef struct SMPI_Group SMPI_Group;
typedef struct SMPI_Comm SMPI_Comm;
+typedef struct SMPI_Topology SMPI_Topology;
+typedef struct SMPI_Graph_topology SMPI_Graph_topology;
+typedef struct SMPI_Cart_topology SMPI_Cart_topology;
+typedef struct SMPI_Dist_Graph_topology SMPI_Dist_Graph_topology;
#endif
//For accumulate
XBT_PUBLIC_DATA( MPI_Op ) MPI_REPLACE;
-struct s_smpi_mpi_topology;
-typedef struct s_smpi_mpi_topology *MPI_Topology;
+typedef SMPI_Topology *MPI_Topology;
typedef SMPI_Group* MPI_Group;
#include "smpi/smpi.h"
#include "src/smpi/smpi_group.hpp"
#include "src/smpi/smpi_comm.hpp"
+#include "src/smpi/smpi_topo.hpp"
#include "src/include/smpi/smpi_interface.h"
#include "src/instr/instr_private.h"
#include "src/internal_config.h"
#define COLL_TAG_ALLREDUCE -4445
#define SMPI_RMA_TAG -1234
-#define MPI_COMM_UNINITIALIZED ((MPI_Comm)-1)
+extern XBT_PRIVATE MPI_Comm MPI_COMM_UNINITIALIZED;
typedef struct s_smpi_mpi_request {
void *buf;
XBT_PRIVATE int smpi_process_initialized();
XBT_PRIVATE void smpi_process_mark_as_initialized();
-struct s_smpi_mpi_cart_topology;
-typedef struct s_smpi_mpi_cart_topology *MPIR_Cart_Topology;
-
-struct s_smpi_mpi_graph_topology;
-typedef struct s_smpi_mpi_graph_topology *MPIR_Graph_Topology;
-
-struct s_smpi_dist_graph_topology;
-typedef struct s_smpi_dist_graph_topology *MPIR_Dist_Graph_Topology;
-
-// MPI_Topology defined in smpi.h, as it is public
-
-XBT_PRIVATE void smpi_topo_destroy(MPI_Topology topo);
-XBT_PRIVATE MPI_Topology smpi_topo_create(MPIR_Topo_type kind);
-XBT_PRIVATE void smpi_cart_topo_destroy(MPIR_Cart_Topology cart);
-XBT_PRIVATE MPI_Topology smpi_cart_topo_create(int ndims);
-XBT_PRIVATE int smpi_mpi_cart_create(MPI_Comm comm_old, int ndims, int dims[], int periods[], int reorder,
- MPI_Comm *comm_cart);
-XBT_PRIVATE int smpi_mpi_cart_sub(MPI_Comm comm, const int remain_dims[], MPI_Comm *newcomm);
-XBT_PRIVATE int smpi_mpi_cart_coords(MPI_Comm comm, int rank, int maxdims, int coords[]);
-XBT_PRIVATE int smpi_mpi_cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords);
-XBT_PRIVATE int smpi_mpi_cart_rank(MPI_Comm comm, int* coords, int* rank);
-XBT_PRIVATE int smpi_mpi_cart_shift(MPI_Comm comm, int direction, int disp, int *rank_source, int *rank_dest);
-XBT_PRIVATE int smpi_mpi_cartdim_get(MPI_Comm comm, int *ndims);
-XBT_PRIVATE int smpi_mpi_dims_create(int nnodes, int ndims, int dims[]);
-XBT_PRIVATE void smpi_graph_topo_destroy(MPIR_Graph_Topology cart);
-XBT_PRIVATE void smpi_dist_graph_topo_destroy(MPIR_Dist_Graph_Topology cart);
+typedef SMPI_Cart_topology *MPIR_Cart_Topology;
+
+typedef SMPI_Graph_topology *MPIR_Graph_Topology;
+
+typedef SMPI_Dist_Graph_topology *MPIR_Dist_Graph_Topology;
XBT_PRIVATE smpi_process_data_t smpi_process_data();
XBT_PRIVATE smpi_process_data_t smpi_process_remote_data(int index);
xbt_dict_t smpi_comm_keyvals = nullptr;
int comm_keyval_id = 0;//avoid collisions
+
+simgrid::smpi::Comm mpi_MPI_COMM_UNINITIALIZED;
+MPI_Comm MPI_COMM_UNINITIALIZED=&mpi_MPI_COMM_UNINITIALIZED;
+
/* Support for cartesian topology was added, but there are 2 other types of topology, graph et dist graph. In order to
* support them, we have to add a field MPIR_Topo_type, and replace the MPI_Topology field by an union. */
}
namespace simgrid{
-namespace SMPI{
+namespace smpi{
+
+Comm::Comm(){}
-Comm::Comm(MPI_Group group, MPI_Topology topo)
+Comm::Comm(MPI_Group group, MPI_Topology topo) : m_group(group), m_topo(topo)
{
- m_group = group;
m_refcount=1;
m_topoType = MPI_INVALID_TOPO;
- m_topo = topo;
m_intra_comm = MPI_COMM_NULL;
m_leaders_comm = MPI_COMM_NULL;
m_is_uniform=1;
void Comm::destroy()
{
if (this == MPI_COMM_UNINITIALIZED)
- return smpi_process_comm_world()->destroy();
- smpi_topo_destroy(m_topo); // there's no use count on topos
+ smpi_process_comm_world()->destroy();
+ delete m_topo; // there's no use count on topos
this->unuse();
}
if(smpi_privatize_global_variables){ //we need to switch as the called function may silently touch global variables
smpi_switch_data_segment(smpi_process_index());
}
- MPI_Group cp = new simgrid::SMPI::Group(this->group());
- (*newcomm) = new simgrid::SMPI::Comm(cp, this->topo());
+ MPI_Group cp = new simgrid::smpi::Group(this->group());
+ (*newcomm) = new simgrid::smpi::Comm(cp, this->topo());
int ret = MPI_SUCCESS;
if(m_attributes !=nullptr){
void Comm::get_name (char* name, int* len)
{
if (this == MPI_COMM_UNINITIALIZED)
- return smpi_process_comm_world()->get_name(name, len);
+ smpi_process_comm_world()->get_name(name, len);
if(this == MPI_COMM_WORLD) {
strncpy(name, "WORLD",5);
*len = 5;
void Comm::set_leaders_comm(MPI_Comm leaders){
if (this == MPI_COMM_UNINITIALIZED)
- return smpi_process_comm_world()->set_leaders_comm(leaders);
+ smpi_process_comm_world()->set_leaders_comm(leaders);
m_leaders_comm=leaders;
}
rankmap[2 * count + 1] = recvbuf[2 * i + 1];
count++;
qsort(rankmap, count, 2 * sizeof(int), &smpi_compare_rankmap);
- group_out = new simgrid::SMPI::Group(count);
+ group_out = new simgrid::smpi::Group(count);
if (i == 0) {
group_root = group_out; /* Save root's group */
}
int reqs = 0;
for (int j = 0; j < count; j++) {
if(rankmap[2 * j] != 0) {
- group_snd[reqs]=new simgrid::SMPI::Group(group_out);
+ group_snd[reqs]=new simgrid::smpi::Group(group_out);
requests[reqs] = smpi_mpi_isend(&(group_snd[reqs]), 1, MPI_PTR, rankmap[2 * j], system_tag, this);
reqs++;
}
smpi_mpi_recv(&group_out, 1, MPI_PTR, 0, system_tag, this, MPI_STATUS_IGNORE);
} /* otherwise, exit with group_out == nullptr */
}
- return group_out!=nullptr ? new simgrid::SMPI::Comm(group_out, nullptr) : MPI_COMM_NULL;
+ return group_out!=nullptr ? new simgrid::smpi::Comm(group_out, nullptr) : MPI_COMM_NULL;
}
void Comm::use(){
if (this == MPI_COMM_UNINITIALIZED)
- return smpi_process_comm_world()->use();
+ smpi_process_comm_world()->use();
m_group->use();
m_refcount++;
}
void Comm::unuse(){
if (this == MPI_COMM_UNINITIALIZED)
- return smpi_process_comm_world()->unuse();
+ smpi_process_comm_world()->unuse();
m_refcount--;
m_group->unuse();
int leader = -1;
if (this == MPI_COMM_UNINITIALIZED)
- return smpi_process_comm_world()->init_smp();
+ smpi_process_comm_world()->init_smp();
int comm_size = this->size();
}
}
XBT_DEBUG("number of processes deployed on my node : %d", intra_comm_size);
- MPI_Group group_intra = new simgrid::SMPI::Group(intra_comm_size);
+ MPI_Group group_intra = new simgrid::smpi::Group(intra_comm_size);
i=0;
process = nullptr;
xbt_swag_foreach(process, process_list) {
}
}
- MPI_Comm comm_intra = new simgrid::SMPI::Comm(group_intra, nullptr);
+ MPI_Comm comm_intra = new simgrid::smpi::Comm(group_intra, nullptr);
leader=min_index;
int * leaders_map= static_cast<int*>(xbt_malloc0(sizeof(int)*comm_size));
}
qsort(leader_list, leader_group_size, sizeof(int),compare_ints);
- MPI_Group leaders_group = new simgrid::SMPI::Group(leader_group_size);
+ MPI_Group leaders_group = new simgrid::smpi::Group(leader_group_size);
MPI_Comm leader_comm = MPI_COMM_NULL;
if(MPI_COMM_WORLD!=MPI_COMM_UNINITIALIZED && this!=MPI_COMM_WORLD){
//create leader_communicator
for (i=0; i< leader_group_size;i++)
leaders_group->set_mapping(leader_list[i], i);
- leader_comm = new simgrid::SMPI::Comm(leaders_group, nullptr);
+ leader_comm = new simgrid::smpi::Comm(leaders_group, nullptr);
this->set_leaders_comm(leader_comm);
this->set_intra_comm(comm_intra);
leaders_group->set_mapping(leader_list[i], i);
if(this->get_leaders_comm()==MPI_COMM_NULL){
- leader_comm = new simgrid::SMPI::Comm(leaders_group, nullptr);
+ leader_comm = new simgrid::smpi::Comm(leaders_group, nullptr);
this->set_leaders_comm(leader_comm);
}else{
leader_comm=this->get_leaders_comm();
#include "private.h"
namespace simgrid{
-namespace SMPI{
+namespace smpi{
class Comm {
xbt_dict_t m_attributes;
public:
-
+ Comm();
Comm(MPI_Group group, MPI_Topology topo);
void destroy();
xbt_assert(instance, "Error, unknown instance %s", instance_id);
if(instance->comm_world == MPI_COMM_NULL){
- MPI_Group group = new simgrid::SMPI::Group(instance->size);
- instance->comm_world = new simgrid::SMPI::Comm(group, nullptr);
+ MPI_Group group = new simgrid::smpi::Group(instance->size);
+ instance->comm_world = new simgrid::smpi::Comm(group, nullptr);
}
instance->present_processes++;
index_to_process_data[index]=instance->index+rank;
{
smpi_process_data_t data = smpi_process_data();
if(data->comm_self==MPI_COMM_NULL){
- MPI_Group group = new simgrid::SMPI::Group(1);
- data->comm_self = new simgrid::SMPI::Comm(group, nullptr);
+ MPI_Group group = new simgrid::smpi::Group(1);
+ data->comm_self = new simgrid::smpi::Comm(group, nullptr);
group->set_mapping(smpi_process_index(), 0);
}
//if the process was launched through smpirun script we generate a global mpi_comm_world
//if not, we let MPI_COMM_NULL, and the comm world will be private to each mpi instance
if(smpirun){
- group = new simgrid::SMPI::Group(process_count);
- MPI_COMM_WORLD = new simgrid::SMPI::Comm(group, nullptr);
+ group = new simgrid::smpi::Group(process_count);
+ MPI_COMM_WORLD = new simgrid::smpi::Comm(group, nullptr);
MPI_Attr_put(MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, reinterpret_cast<void *>(process_count));
msg_bar_t bar = MSG_barrier_init(process_count);
#include "private.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_group, smpi, "Logging specific to SMPI (group)");
-simgrid::SMPI::Group mpi_MPI_GROUP_EMPTY;
+simgrid::smpi::Group mpi_MPI_GROUP_EMPTY;
MPI_Group MPI_GROUP_EMPTY=&mpi_MPI_GROUP_EMPTY;
namespace simgrid{
-namespace SMPI{
+namespace smpi{
Group::Group()
{
m_refcount=1; /* m_refcount: start > 0 so that this group never gets freed */
}
-Group::Group(int n)
+Group::Group(int n) : m_size(n)
{
int i;
-
- m_size = n;
m_rank_to_index_map = xbt_new(int, m_size);
m_index_to_rank_map = xbt_dict_new_homogeneous(xbt_free_f);
m_refcount = 1;
int Group::compare(MPI_Group group2)
{
int result;
- int i, index, rank, sz;
+ int i;
+ int index;
+ int rank;
+ int sz;
result = MPI_IDENT;
if (m_size != group2->size()) {
int Group::incl(int n, int* ranks, MPI_Group* newgroup)
{
- int i=0, index=0;
+ int i=0;
+ int index=0;
if (n == 0) {
*newgroup = MPI_GROUP_EMPTY;
} else if (n == m_size) {
if (size1 == 0) {
*newgroup = MPI_GROUP_EMPTY;
} else {
- *newgroup = new simgrid::SMPI::Group(size1);
+ *newgroup = new simgrid::smpi::Group(size1);
size2 = this->size();
for (int i = 0; i < size2; i++) {
int proc1 = this->index(i);
if (size2 == 0) {
*newgroup = MPI_GROUP_EMPTY;
} else {
- *newgroup = new simgrid::SMPI::Group(size2);
+ *newgroup = new simgrid::smpi::Group(size2);
int j=0;
for (int i = 0; i < group2->size(); i++) {
int proc2 = group2->index(i);
if (newsize == 0) {
*newgroup = MPI_GROUP_EMPTY;
} else {
- *newgroup = new simgrid::SMPI::Group(newsize);
+ *newgroup = new simgrid::smpi::Group(newsize);
for (int i = 0; i < size2; i++) {
int proc1 = this->index(i);
int proc2 = group2->rank(proc1);
int Group::excl(int n, int *ranks, MPI_Group * newgroup){
int oldsize = m_size;
int newsize = oldsize - n;
- *newgroup = new simgrid::SMPI::Group(newsize);
+ *newgroup = new simgrid::smpi::Group(newsize);
int* to_exclude=xbt_new0(int, m_size);
for (int i = 0; i < oldsize; i++)
to_exclude[i]=0;
}
}
}
- *newgroup = new simgrid::SMPI::Group(newsize);
+ *newgroup = new simgrid::smpi::Group(newsize);
int j = 0;
for (int i = 0; i < n; i++) {
for (int rank = ranges[i][0]; /* First */
if (newsize == 0) {
*newgroup = MPI_GROUP_EMPTY;
} else {
- *newgroup = new simgrid::SMPI::Group(newsize);
+ *newgroup = new simgrid::smpi::Group(newsize);
int newrank = 0;
int oldrank = 0;
while (newrank < newsize) {
#include "private.h"
namespace simgrid{
-namespace SMPI{
+namespace smpi{
class Group {
private:
return MPI_SUCCESS;
}else{
group->use();
- *newcomm = new simgrid::SMPI::Comm(group, nullptr);
+ *newcomm = new simgrid::smpi::Comm(group, nullptr);
return MPI_SUCCESS;
}
}
} else if (ndims < 0 || (ndims > 0 && (dims == nullptr || periodic == nullptr)) || comm_cart == nullptr) {
return MPI_ERR_ARG;
} else{
- return smpi_mpi_cart_create(comm_old, ndims, dims, periodic, reorder, comm_cart);
+ new simgrid::smpi::Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
+ return MPI_SUCCESS;
}
}
if (coords == nullptr) {
return MPI_ERR_ARG;
}
- return smpi_mpi_cart_rank(comm, coords, rank);
+ simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+ if (topo==nullptr) {
+ return MPI_ERR_ARG;
+ }
+ return topo->rank(coords, rank);
}
int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
if (source == nullptr || dest == nullptr || direction < 0 ) {
return MPI_ERR_ARG;
}
- return smpi_mpi_cart_shift(comm, direction, displ, source, dest);
+ simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+ if (topo==nullptr) {
+ return MPI_ERR_ARG;
+ }
+ return topo->shift(direction, displ, source, dest);
}
int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
if(coords == nullptr) {
return MPI_ERR_ARG;
}
- return smpi_mpi_cart_coords(comm, rank, maxdims, coords);
+ simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+ if (topo==nullptr) {
+ return MPI_ERR_ARG;
+ }
+ return topo->coords(rank, maxdims, coords);
}
int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
if(maxdims <= 0 || dims == nullptr || periods == nullptr || coords == nullptr) {
return MPI_ERR_ARG;
}
- return smpi_mpi_cart_get(comm, maxdims, dims, periods, coords);
+ simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+ if (topo==nullptr) {
+ return MPI_ERR_ARG;
+ }
+ return topo->get(maxdims, dims, periods, coords);
}
int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
if (ndims == nullptr) {
return MPI_ERR_ARG;
}
- return smpi_mpi_cartdim_get(comm, ndims);
+ simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+ if (topo==nullptr) {
+ return MPI_ERR_ARG;
+ }
+ return topo->dim_get(ndims);
}
int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
if (ndims < 1 || nnodes < 1) {
return MPI_ERR_DIMS;
}
-
- return smpi_mpi_dims_create(nnodes, ndims, dims);
+ return simgrid::smpi::Dims_create(nnodes, ndims, dims);
}
int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
if (comm_new == nullptr) {
return MPI_ERR_ARG;
}
- return smpi_mpi_cart_sub(comm, remain_dims, comm_new);
+ simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+ if (topo==nullptr) {
+ return MPI_ERR_ARG;
+ }
+ simgrid::smpi::Cart* cart = topo->sub(remain_dims, comm_new);
+ if(cart==nullptr)
+ return MPI_ERR_ARG;
+ return MPI_SUCCESS;
}
int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
#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{
+
+
+Graph::~Graph()
+{
+ delete[] m_index;
+ delete[] m_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);
- }
+Dist_Graph::~Dist_Graph()
+{
+ delete[] m_in;
+ delete[] m_in_weights;
+ delete[] m_out;
+ delete[] m_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);
- }
+Cart::~Cart()
+{
+ delete[] m_dims;
+ delete[] m_periodic;
+ delete[] m_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;
+Cart::Cart(int ndims)
+{
+ m_nnodes = 0;
+ m_ndims = ndims;
+ m_dims = new int[ndims];
+ m_periodic = new int[ndims];
+ m_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;
+Cart::Cart(MPI_Comm comm_old, int ndims, int dims[], int periods[], int reorder, MPI_Comm *comm_cart) : Cart(ndims) {
MPI_Group newGroup;
MPI_Group oldGroup;
int nranks;
}
if(rank >= newSize) {
*comm_cart = MPI_COMM_NULL;
- return retval;
+ return;
}
- newCart = smpi_cart_topo_create(ndims);
oldGroup = comm_old->group();
- newGroup = new simgrid::SMPI::Group(newSize);
+ newGroup = new simgrid::smpi::Group(newSize);
for (int i = 0 ; i < newSize ; i++) {
newGroup->set_mapping(oldGroup->index(i), i);
}
- newCart->topo.cart->nnodes = newSize;
+ m_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];
+ m_dims[i] = dims[i];
+ m_periodic[i] = periods[i];
nranks = nranks / dims[i];
/* FIXME: nranks could be zero (?) */
- newCart->topo.cart->position[i] = rank / nranks;
+ m_position[i] = rank / nranks;
rank = rank % nranks;
}
- *comm_cart = new simgrid::SMPI::Comm(newGroup, newCart);
+ *comm_cart = new simgrid::smpi::Comm(newGroup, this);
} else {
if (rank == 0) {
- newCart = smpi_cart_topo_create(ndims);
- *comm_cart = new simgrid::SMPI::Comm(new simgrid::SMPI::Group(MPI_COMM_SELF->group()), newCart);
+ *comm_cart = new simgrid::smpi::Comm(new simgrid::smpi::Group(MPI_COMM_SELF->group()), this);
} else {
*comm_cart = MPI_COMM_NULL;
}
}
- return retval;
+ m_comm=*comm_cart;
}
-int smpi_mpi_cart_sub(MPI_Comm comm, const int remain_dims[], MPI_Comm *newcomm) {
- MPI_Topology oldTopo = comm->topo();
- int oldNDims = oldTopo->topo.cart->ndims;
+Cart* Cart::sub(const int remain_dims[], MPI_Comm *newcomm) {
+ int oldNDims = m_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] =m_dims[i];
+ newPeriodic[j] =m_periodic[i];
j++;
}
}
}
- return smpi_mpi_cart_create(comm, newNDims, newDims, newPeriodic, 0, newcomm);
+ return new Cart(m_comm, newNDims, newDims, newPeriodic, 0, newcomm);
}
-int smpi_mpi_cart_coords(MPI_Comm comm, int rank, int maxdims, int coords[]) {
- MPI_Topology topo = comm->topo();
- int nnodes = topo->topo.cart->nnodes;
- for (int i = 0; i< topo->topo.cart->ndims; i++ ) {
- nnodes = nnodes / topo->topo.cart->dims[i];
+int Cart::coords(int rank, int maxdims, int coords[]) {
+ int nnodes = m_nnodes;
+ for (int i = 0; i< m_ndims; i++ ) {
+ nnodes = nnodes /m_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 = comm->topo();
- int ndims=topo->topo.cart->ndims < maxdims ? topo->topo.cart->ndims : maxdims;
+int Cart::get(int maxdims, int* dims, int* periods, int* coords) {
+ int ndims=m_ndims < maxdims ?m_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] =m_dims[i];
+ periods[i] =m_periodic[i];
+ coords[i] =m_position[i];
}
return MPI_SUCCESS;
}
-int smpi_mpi_cart_rank(MPI_Comm comm, int* coords, int* rank) {
- MPI_Topology topo = comm->topo();
- int ndims = topo->topo.cart->ndims;
+int Cart::rank(int* coords, int* rank) {
+ int ndims =m_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 >=m_dims[i]) {
+ if (m_periodic[i] ) {
+ coord = coord %m_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(m_periodic[i]) {
+ coord = coord %m_dims[i];
if (coord)
- coord = topo->topo.cart->dims[i] + coord;
+ coord =m_dims[i] + coord;
} else {
*rank = -1;
return MPI_ERR_ARG;
}
*rank += multiplier * coord;
- multiplier *= topo->topo.cart->dims[i];
+ multiplier *=m_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 = comm->topo();
- int position[topo->topo.cart->ndims];
+int Cart::shift(int direction, int disp, int *rank_source, int *rank_dest) {
- if(topo->topo.cart->ndims == 0) {
+ int position[m_ndims];
+
+ if(m_ndims == 0) {
return MPI_ERR_ARG;
}
- if (topo->topo.cart->ndims < direction) {
+ if (m_ndims < direction) {
return MPI_ERR_DIMS;
}
- smpi_mpi_cart_coords(comm, comm->rank(), topo->topo.cart->ndims, position);
+ this->coords(m_comm->rank(),m_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] >=m_dims[direction]) {
+ if(m_periodic[direction]) {
+ position[direction] %=m_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] = m_position[direction] - disp;
+ if(position[direction] < 0 || position[direction] >=m_dims[direction]) {
+ if(m_periodic[direction]) {
+ position[direction] %=m_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 = comm->topo();
-
- *ndims = topo->topo.cart->ndims;
+int Cart::dim_get(int *ndims) {
+ *ndims =m_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 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;
}
+
--- /dev/null
+/* Copyright (c) 2010-2015. 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. */
+
+#ifndef SMPI_TOPO_HPP_INCLUDED
+#define SMPI_TOPO_HPP_INCLUDED
+
+#include "private.h"
+
+
+namespace simgrid{
+namespace smpi{
+
+class Topo {
+ protected:
+ MPI_Comm m_comm;
+};
+
+
+class Cart: public Topo {
+ private:
+ int m_nnodes;
+ int m_ndims;
+ int *m_dims;
+ int *m_periodic;
+ int *m_position;
+ public:
+ Cart(int ndims);
+ ~Cart();
+ Cart(MPI_Comm comm_old, int ndims, int dims[], int periods[], int reorder, MPI_Comm *comm_cart);
+ Cart* sub(const int remain_dims[], MPI_Comm *newcomm) ;
+ int coords(int rank, int maxdims, int coords[]) ;
+ int get(int maxdims, int* dims, int* periods, int* coords);
+ int rank(int* coords, int* rank);
+ int shift(int direction, int disp, int *rank_source, int *rank_dest) ;
+ int dim_get(int *ndims);
+};
+
+
+class Graph: public Topo {
+ private:
+ int m_nnodes;
+ int m_nedges;
+ int *m_index;
+ int *m_edges;
+ public:
+ Graph();
+ ~Graph();
+};
+
+class Dist_Graph: public Topo {
+ private:
+ int m_indegree;
+ int *m_in;
+ int *m_in_weights;
+ int m_outdegree;
+ int *m_out;
+ int *m_out_weights;
+ int m_is_weighted;
+ public:
+ Dist_Graph();
+ ~Dist_Graph();
+};
+
+/*
+ * This is a utility function, no need to have anything in the lower layer for this at all
+ */
+extern int Dims_create(int nnodes, int ndims, int dims[]);
+
+}
+}
+
+
+#endif
src/smpi/smpi_replay.cpp
src/smpi/smpi_rma.cpp
src/smpi/smpi_topo.cpp
+ src/smpi/smpi_topo.hpp
src/smpi/smpi_utils.cpp
src/smpi/smpi_f77.cpp