-/* Copyright (c) 2014-2017. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2014-2020. 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 "private.h"
-#include <vector>
-#include <math.h>
+#include "private.hpp"
#include "smpi_comm.hpp"
#include "smpi_topo.hpp"
+#include "xbt/sysdep.h"
+#include <cmath>
+#include <vector>
/* static functions */
-static int assignnodes(int ndim, int nfactor, int *pfacts,int **pdims);
+static int assignnodes(int ndim, int nfactor, const int* pfacts, int** pdims);
static int getfactors(int num, int *nfators, int **factors);
namespace simgrid{
namespace smpi{
-Topo_Graph::~Topo_Graph()
-{
- delete[] index_;
- delete[] edges_;
-}
-
-Topo_Dist_Graph::~Topo_Dist_Graph()
+void Topo::setComm(MPI_Comm comm)
{
- delete[] in_;
- delete[] in_weights_;
- delete[] out_;
- delete[] out_weights_;
+ xbt_assert(not comm_);
+ comm_ = comm;
+ if (comm_)
+ comm_->topo_ = this;
}
/*******************************************************************************
* Cartesian topologies
******************************************************************************/
-Topo_Cart::~Topo_Cart()
-{
- delete[] dims_;
- delete[] periodic_;
- delete[] position_;
-}
-Topo_Cart::Topo_Cart(int ndims) : ndims_(ndims)
+Topo_Cart::Topo_Cart(int ndims) : ndims_(ndims), dims_(ndims), periodic_(ndims), position_(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*/
-Topo_Cart::Topo_Cart(MPI_Comm comm_old, int ndims, int dims[], int periods[], int reorder, MPI_Comm *comm_cart) : Topo_Cart(ndims) {
+Topo_Cart::Topo_Cart(MPI_Comm comm_old, int ndims, const int dims[], const int periods[], int /*reorder*/, MPI_Comm* comm_cart)
+ : Topo_Cart(ndims)
+{
MPI_Group newGroup;
MPI_Group oldGroup;
newSize *= dims[i];
}
if(rank >= newSize) {
- *comm_cart = MPI_COMM_NULL;
+ if(comm_cart != nullptr)
+ *comm_cart = MPI_COMM_NULL;
return;
}
- oldGroup = comm_old->group();
- newGroup = new Group(newSize);
- for (int i = 0 ; i < newSize ; i++) {
- newGroup->set_mapping(oldGroup->index(i), i);
- }
nnodes_ = newSize;
position_[i] = rank / nranks;
rank = rank % nranks;
}
-
- *comm_cart = new Comm(newGroup, this);
+
+ if(comm_cart != nullptr){
+ oldGroup = comm_old->group();
+ newGroup = new Group(newSize);
+ for (int i = 0 ; i < newSize ; i++) {
+ newGroup->set_mapping(oldGroup->actor(i), i);
+ }
+ *comm_cart = new Comm(newGroup, this);
+ }
} else {
- if (rank == 0) {
- *comm_cart = new Comm(new Group(MPI_COMM_SELF->group()), this);
- } else {
- *comm_cart = MPI_COMM_NULL;
+ if(comm_cart != nullptr){
+ if (rank == 0) {
+ MPI_Group group = new Group(MPI_COMM_SELF->group());
+ *comm_cart = new Comm(group, this);
+ } else {
+ *comm_cart = MPI_COMM_NULL;
+ }
}
}
- comm_=*comm_cart;
+ if(comm_cart != nullptr)
+ setComm(*comm_cart);
}
Topo_Cart* Topo_Cart::sub(const int remain_dims[], MPI_Comm *newcomm) {
}
if (newNDims > 0) {
- newDims = xbt_new(int, newNDims);
- newPeriodic = xbt_new(int, newNDims);
+ newDims = new int[newNDims];
+ newPeriodic = new int[newNDims];
// that should not segfault
int j = 0;
- for (int i = 0 ; j < newNDims ; i++) {
+ for (int i = 0; i < oldNDims; i++) {
if(remain_dims[i]) {
newDims[j] =dims_[i];
newPeriodic[j] =periodic_[i];
}
}
}
- return new Topo_Cart(comm_, newNDims, newDims, newPeriodic, 0, newcomm);
+
+ //split into several communicators
+ int color = 0;
+ for (int i = 0; i < oldNDims; i++) {
+ if (not remain_dims[i]) {
+ color = (color * dims_[i] + position_[i]);
+ }
+ }
+ Topo_Cart* res;
+ if (newNDims == 0){
+ res = new Topo_Cart(getComm(), newNDims, newDims, newPeriodic, 0, newcomm);
+ } else {
+ *newcomm = getComm()->split(color, getComm()->rank());
+ res = new Topo_Cart(getComm(), newNDims, newDims, newPeriodic, 0, nullptr);
+ res->setComm(*newcomm);
+ }
+ delete[] newDims;
+ delete[] newPeriodic;
+ return res;
}
-int Topo_Cart::coords(int rank, int maxdims, int coords[]) {
+int Topo_Cart::coords(int rank, int /*maxdims*/, int coords[])
+{
int nnodes = nnodes_;
for (int i = 0; i< ndims_; i++ ) {
nnodes = nnodes /dims_[i];
return MPI_SUCCESS;
}
-int Topo_Cart::rank(int* coords, int* rank) {
+int Topo_Cart::rank(const int* coords, int* rank) {
int ndims =ndims_;
*rank = 0;
int multiplier = 1;
return MPI_SUCCESS;
}
-int Topo_Cart::shift(int direction, int disp, int *rank_source, int *rank_dest) {
-
- int position[ndims_];
-
+int Topo_Cart::shift(int direction, int disp, int* rank_source, int* rank_dest)
+{
if(ndims_ == 0) {
return MPI_ERR_ARG;
}
return MPI_ERR_DIMS;
}
- this->coords(comm_->rank(),ndims_, position);
+ int* position = new int[ndims_];
+ this->coords(getComm()->rank(), ndims_, position);
position[direction] += disp;
if(position[direction] < 0 ||
} else {
this->rank(position, rank_source);
}
-
+ delete[] position;
return MPI_SUCCESS;
}
/* Get # of free-to-be-assigned processes and # of free dimensions */
int freeprocs = nnodes;
int freedims = 0;
- int *p = dims;
+ const int* p = dims;
for (int i = 0; i < ndims; ++i) {
if (*p == 0) {
++freedims;
* - ptr to array of dimensions (returned value)
* Returns: - 0 or ERROR
*/
-static int assignnodes(int ndim, int nfactor, int *pfacts, int **pdims)
+static int assignnodes(int ndim, int nfactor, const int* pfacts, int** pdims)
{
int *pmin;
return MPI_SUCCESS;
}
/* Allocate the array of prime factors which cannot exceed log_2(num) entries */
- int sqrtnum = ceil(sqrt(num));
- int size = ceil(log(num) / log(2));
+ int sqrtnum = ceil(sqrt(double(num)));
+ int size = ceil(log(double(num)) / log(2.0));
*factors = new int[size];
int i = 0;