Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Link Topo and Comm in both directions, and fix memory leak.
[simgrid.git] / src / smpi / mpi / smpi_topo.cpp
index 710eaaf..424e349 100644 (file)
@@ -19,6 +19,14 @@ static int getfactors(int num, int *nfators, int **factors);
 namespace simgrid{
 namespace smpi{
 
+void Topo::setComm(MPI_Comm comm)
+{
+  xbt_assert(not comm_);
+  comm_ = comm;
+  if (comm_)
+    comm_->topo_ = this;
+}
+
 /*******************************************************************************
  * Cartesian topologies
  ******************************************************************************/
@@ -43,14 +51,10 @@ Topo_Cart::Topo_Cart(MPI_Comm comm_old, int ndims, const int dims[], const int p
       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->actor(i), i);
-    }
 
     nnodes_ = newSize;
 
@@ -64,16 +68,26 @@ Topo_Cart::Topo_Cart(MPI_Comm comm_old, int ndims, const int dims[], const int p
       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) {
+        *comm_cart = new  Comm(new  Group(MPI_COMM_SELF->group()), this);
+      } else {
+        *comm_cart = MPI_COMM_NULL;
+      }
     }
   }
-  setComm(*comm_cart);
+  if(comm_cart != nullptr)
+    setComm(*comm_cart);
 }
 
 Topo_Cart* Topo_Cart::sub(const int remain_dims[], MPI_Comm *newcomm) {
@@ -104,7 +118,22 @@ Topo_Cart* Topo_Cart::sub(const int remain_dims[], MPI_Comm *newcomm) {
       }
     }
   }
-  Topo_Cart* res = new Topo_Cart(getComm(), 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;
@@ -167,10 +196,8 @@ int Topo_Cart::rank(const int* coords, int* rank) {
   return MPI_SUCCESS;
 }
 
-int Topo_Cart::shift(int direction, int disp, int *rank_source, int *rank_dest) {
-
-  int* position = new int[ndims_];
-
+int Topo_Cart::shift(int direction, int disp, int* rank_source, int* rank_dest)
+{
   if(ndims_ == 0) {
     return MPI_ERR_ARG;
   }
@@ -178,6 +205,7 @@ int Topo_Cart::shift(int direction, int disp, int *rank_source, int *rank_dest)
     return MPI_ERR_DIMS;
   }
 
+  int* position = new int[ndims_];
   this->coords(getComm()->rank(), ndims_, position);
   position[direction] += disp;