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 b56bc73..424e349 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2014-2019. 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. */
@@ -19,40 +19,27 @@ static int getfactors(int num, int *nfators, int **factors);
 namespace simgrid{
 namespace smpi{
 
-Topo_Graph::~Topo_Graph()
+void Topo::setComm(MPI_Comm comm)
 {
-  delete[] index_;
-  delete[] edges_;
-}
-
-Topo_Dist_Graph::~Topo_Dist_Graph()
-{
-  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;
 
@@ -64,14 +51,10 @@ Topo_Cart::Topo_Cart(MPI_Comm comm_old, int ndims, int dims[], int periods[], in
       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;
 
@@ -85,16 +68,26 @@ Topo_Cart::Topo_Cart(MPI_Comm comm_old, int ndims, int dims[], int periods[], in
       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;
+      }
     }
   }
-  comm_=*comm_cart;
+  if(comm_cart != nullptr)
+    setComm(*comm_cart);
 }
 
 Topo_Cart* Topo_Cart::sub(const int remain_dims[], MPI_Comm *newcomm) {
@@ -112,8 +105,8 @@ 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;
@@ -125,10 +118,29 @@ Topo_Cart* Topo_Cart::sub(const int remain_dims[], MPI_Comm *newcomm) {
       }
     }
   }
-  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];
@@ -148,7 +160,7 @@ int Topo_Cart::get(int maxdims, int* dims, int* periods, int* coords) {
   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;
@@ -184,10 +196,8 @@ int Topo_Cart::rank(int* coords, int* rank) {
   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;
   }
@@ -195,7 +205,8 @@ int Topo_Cart::shift(int direction, int disp, int *rank_source, int *rank_dest)
     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 ||
@@ -221,7 +232,7 @@ int Topo_Cart::shift(int direction, int disp, int *rank_source, int *rank_dest)
   } else {
     this->rank(position, rank_source);
   }
-
+  delete[] position;
   return MPI_SUCCESS;
 }
 
@@ -404,8 +415,8 @@ static int getfactors(int num, int *nfactors, int **factors) {
     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;