Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_MachineTorusTopoMgr.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Zoltan2: A package of combinatorial algorithms for scientific computing
4 //
5 // Copyright 2012 NTESS and the Zoltan2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef _ZOLTAN2_MACHINE_TORUS_TOPOMANAGER_HPP_
11 #define _ZOLTAN2_MACHINE_TORUS_TOPOMANAGER_HPP_
12 
13 #include <Teuchos_Comm.hpp>
14 #include <Teuchos_CommHelpers.hpp>
15 #include <Zoltan2_Machine.hpp>
16 
17 #ifdef HAVE_ZOLTAN2_TOPOMANAGER
18 #include <TopoManager.h>
19 #endif
20 
21 namespace Zoltan2{
22 
26 template <typename pcoord_t, typename part_t>
27 class MachineTorusTopoMgr : public Machine <pcoord_t, part_t> {
28 
29 public:
34  MachineTorusTopoMgr(const Teuchos::Comm<int> &comm):
35  Machine<pcoord_t,part_t>(comm),
36 #if defined (CMK_BLUEGENEQ)
37  networkDim(6), tmgr(comm.getSize()),
38 #elif defined (CMK_BLUEGENEP)
39  networkDim(4), tmgr(comm.getSize()),
40 #else
41  networkDim(3),
42 #endif
43  procCoords(NULL), machine_extent(NULL),
44  delete_transformed_coords(false),
45  transformed_network_dim(0),
46  transformed_coordinates (NULL), pl(NULL)
47  {
48  transformed_network_dim = networkDim - 1;
49  transformed_coordinates = procCoords;
50  machine_extent = new int[networkDim];
51  this->getMachineExtent(this->machine_extent);
52 
53  // Allocate memory for processor coordinates.
54  procCoords = new pcoord_t *[networkDim];
55  for (int i = 0; i < networkDim; ++i) {
56  procCoords[i] = new pcoord_t[this->numRanks];
57  memset(procCoords[i], 0, sizeof(pcoord_t) * this->numRanks);
58  }
59 
60  // Obtain the coordinate of the processor.
61  pcoord_t *xyz = new pcoord_t[networkDim];
63  for (int i = 0; i < networkDim; i++)
64  procCoords[i][this->myRank] = xyz[i];
65  delete [] xyz;
66 
67  // reduceAll the coordinates of each processor.
68  gatherMachineCoordinates(comm);
69 
70  }
71 
72  MachineTorusTopoMgr(const Teuchos::Comm<int> &comm,
73  const Teuchos::ParameterList &pl_ ):
74  Machine<pcoord_t,part_t>(comm),
75 #if defined (CMK_BLUEGENEQ)
76  networkDim(6), tmgr(comm.getSize()),
77 #elif defined (CMK_BLUEGENEP)
78  networkDim(4), tmgr(comm.getSize()),
79 #else
80  networkDim(3),
81 #endif
82  procCoords(NULL), machine_extent(NULL),
83  delete_transformed_coords(false),
84  transformed_network_dim(0),
85  transformed_coordinates (NULL),
86  pl(&pl_)
87  {
88  transformed_network_dim = networkDim - 1;
89  transformed_coordinates = procCoords;
90  machine_extent = new int[networkDim];
91  this->getMachineExtent(this->machine_extent);
92 
93  // Allocate memory for processor coordinates.
94  procCoords = new pcoord_t *[networkDim];
95  for (int i = 0; i < networkDim; ++i) {
96  procCoords[i] = new pcoord_t[this->numRanks];
97  memset(procCoords[i], 0, sizeof(pcoord_t) * this->numRanks);
98  }
99 
100  // Obtain the coordinate of the processor.
101  pcoord_t *xyz = new pcoord_t[networkDim];
103  for (int i = 0; i < networkDim; i++)
104  procCoords[i][this->myRank] = xyz[i];
105  delete [] xyz;
106 
107  // reduceAll the coordinates of each processor.
108  gatherMachineCoordinates(comm);
109 
110  const Teuchos::ParameterEntry *pe =
111  this->pl->getEntryPtr("Machine_Optimization_Level");
112  if (pe) {
113 
114  int optimization_level = 0;
115 
116  optimization_level = pe->getValue<int>(&optimization_level);
117 
118  if (optimization_level == 0) {
119  transformed_network_dim = networkDim - 1;
120  transformed_coordinates = procCoords;
121  }
122 
123  else if (optimization_level >= 1) {
124  transformed_network_dim = networkDim - 2;
125  transformed_coordinates = procCoords;
126  }
127  }
128 
129  }
130 
132  for (int i = 0; i < networkDim; i++) {
133  delete [] procCoords[i];
134  }
135  delete [] procCoords;
136  delete [] machine_extent;
137 
138  if (delete_transformed_coords) {
139  for (int i = 0; i < transformed_network_dim; i++) {
140  delete [] transformed_coordinates[i];
141  }
142  delete [] transformed_coordinates;
143  }
144 
145  }
146 
147  bool hasMachineCoordinates() const { return true; }
148 
149  int getMachineDim() const { return transformed_network_dim; }
150 
151  int getRealMachineDim() const { return networkDim; }
152 
153  bool getMachineExtent(int *nxyz) const {
154 #if defined (CMK_BLUEGENEQ)
155  int dim = 0;
156  if (dim < transformed_network_dim)
157  nxyz[dim++] = tmgr.getDimNA();
158  if (dim < transformed_network_dim)
159  nxyz[dim++] = tmgr.getDimNB();
160  if (dim < transformed_network_dim)
161  nxyz[dim++] = tmgr.getDimNC();
162  if (dim < transformed_network_dim)
163  nxyz[dim++] = tmgr.getDimND();
164  if (dim < transformed_network_dim)
165  nxyz[dim++] = tmgr.getDimNE();
166  if (dim < transformed_network_dim)
167  nxyz[dim++] = tmgr.getDimNT();
168  return true;
169 #elif defined (CMK_BLUEGENEP)
170  int dim = 0;
171  if (dim < transformed_network_dim)
172  nxyz[dim++] = tmgr.getDimNX();
173  if (dim < transformed_network_dim)
174  nxyz[dim++] = tmgr.getDimNY();
175  if (dim < transformed_network_dim)
176  nxyz[dim++] = tmgr.getDimNZ();
177  if (dim < transformed_network_dim)
178  nxyz[dim++] = tmgr.getDimNT();
179  return true;
180 #else
181  return false;
182 #endif
183  }
184 
185  // MD TODO: Not always it has wrap-around links.
186  bool getMachineExtentWrapArounds(bool *wrap_around) const {
187 #if defined (CMK_BLUEGENEQ)
188  // Leave it as this for now, figure out if there is a way to
189  // determine tourus from topomanager.
190  int dim = 0;
191  if (dim < transformed_network_dim)
192  wrap_around[dim++] = true;
193  if (dim < transformed_network_dim)
194  wrap_around[dim++] = true;
195  if (dim < transformed_network_dim)
196  wrap_around[dim++] = true;
197  if (dim < transformed_network_dim)
198  wrap_around[dim++] = true;
199  if (dim < transformed_network_dim)
200  wrap_around[dim++] = true;
201  if (dim < transformed_network_dim)
202  wrap_around[dim++] = true;
203 #elif defined (CMK_BLUEGENEP)
204  int dim = 0;
205  if (dim < transformed_network_dim)
206  wrap_around[dim++] = true;
207  if (dim < transformed_network_dim)
208  wrap_around[dim++] = true;
209  if (dim < transformed_network_dim)
210  wrap_around[dim++] = true;
211  if (dim < transformed_network_dim)
212  wrap_around[dim++] = true;
213 #else
214 #endif
215  return true;
216  }
217 
218  bool getMyMachineCoordinate(pcoord_t *xyz) {
219  for (int i = 0; i < this->transformed_network_dim; ++i) {
220  xyz[i] = transformed_coordinates[i][this->myRank];
221  }
222  return true;
223  }
224 
225  bool getMyActualMachineCoordinate(pcoord_t *xyz) {
226 #if defined (CMK_BLUEGENEQ)
227  int a,b,c,d,e,t;
228  tmgr.rankToCoordinates(this->myRank, a,b,c,d,e,t);
229  xyz[0] = a; xyz[1] = b; xyz[2] = c; xyz[3] = d; xyz[4] = e; xyz[5] = t;
230  //std::cout << "me:" << this->myRank
231  // << " " << a << " " << b << " " << c << " " << d
232  // << " " << e << " " << t << std::endl;
233  return true;
234 #elif defined (CMK_BLUEGENEP)
235  int a,b,c,t;
236  tmgr.rankToCoordinates(this->myRank, a,b,c,t);
237  xyz[0] = a; xyz[1] = b; xyz[2] = c; xyz[3] = t;
238  return true;
239 #else
240  return false;
241 #endif
242  }
243 
244  bool getMachineExtentWrapArounds(part_t *wrap_around) const {
245 
246  int dim = 0;
247  if (dim < transformed_network_dim)
248  wrap_around[dim++] = true;
249 
250  if (dim < transformed_network_dim)
251  wrap_around[dim++] = true;
252 
253  if (dim < transformed_network_dim)
254  wrap_around[dim++] = true;
255 
256  if (dim < transformed_network_dim)
257  wrap_around[dim++] = true;
258 
259  if (dim < transformed_network_dim)
260  wrap_around[dim++] = true;
261 
262  if (dim < transformed_network_dim)
263  wrap_around[dim++] = true;
264  return true;
265  }
266  inline bool getMachineCoordinate(const int rank,
267  pcoord_t *xyz) const {
268  return false;
269  }
270 
271 
272  bool getMachineCoordinate(const char *nodename, pcoord_t *xyz) {
273  return false; // cannot yet return from nodename
274  }
275 
276  bool getAllMachineCoordinatesView(pcoord_t **&allCoords) const {
277  allCoords = procCoords;
278  return true;
279  }
280 
281  virtual bool getHopCount(int rank1, int rank2, pcoord_t &hops) const override {
282  hops = 0;
283  for (int i = 0; i < networkDim - 1; ++i) {
284  pcoord_t distance = procCoords[i][rank1] - procCoords[i][rank2];
285  if (distance < 0 )
286  distance = -distance;
287  if (machine_extent[i] - distance < distance)
288  distance = machine_extent[i] - distance;
289  hops += distance;
290  }
291  return true;
292  }
293 
294 
295 private:
296 
297  int networkDim;
298 
299 #ifdef HAVE_ZOLTAN2_TOPOMANAGER
300  TopoManager tmgr;
301 #endif
302  pcoord_t **procCoords; // KDD Maybe should be RCP?
303  part_t *machine_extent;
304  const Teuchos::ParameterList *pl;
305 
306 
307  bool delete_transformed_coords;
308  int transformed_network_dim;
309  pcoord_t **transformed_coordinates;
310 
311  void gatherMachineCoordinates(const Teuchos::Comm<int> &comm) {
312  // reduces and stores all machine coordinates.
313  pcoord_t *tmpVect = new pcoord_t [this->numRanks];
314 
315  for (int i = 0; i < networkDim; i++) {
316  Teuchos::reduceAll<int, pcoord_t>(comm, Teuchos::REDUCE_SUM,
317  this->numRanks,
318  procCoords[i], tmpVect);
319  pcoord_t *tmp = tmpVect;
320  tmpVect = procCoords[i];
321  procCoords[i] = tmp;
322  }
323  delete [] tmpVect;
324  }
325 };
326 }
327 #endif
bool getMachineExtentWrapArounds(bool *wrap_around) const
bool getAllMachineCoordinatesView(pcoord_t **&allCoords) const
bool getMachineCoordinate(const char *nodename, pcoord_t *xyz)
MachineClass Base class for representing machine coordinates, networks, etc.
A TopoManager Machine Class on Torus Networks.
SparseMatrixAdapter_t::part_t part_t
virtual bool getHopCount(int rank1, int rank2, pcoord_t &hops) const override
getHopCount function set hops between rank1 and rank2 return true if coordinates are available ...
bool getMachineExtentWrapArounds(part_t *wrap_around) const
bool getMachineCoordinate(const int rank, pcoord_t *xyz) const
MachineTorusTopoMgr(const Teuchos::Comm< int > &comm)
Constructor: A BlueGeneQ network machine description;.
MachineTorusTopoMgr(const Teuchos::Comm< int > &comm, const Teuchos::ParameterList &pl_)