Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_MachineTorusTopoMgrForTesting.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_TOPOMANAGERTEST_HPP_
11 #define _ZOLTAN2_MACHINE_TORUS_TOPOMANAGERTEST_HPP_
12 
13 #include <Teuchos_Comm.hpp>
14 #include <Teuchos_CommHelpers.hpp>
15 #include <Zoltan2_Machine.hpp>
16 
17 
18 namespace Zoltan2{
19 
24 template <typename pcoord_t, typename part_t>
25 class MachineTorusBGQTest : public Machine <pcoord_t, part_t> {
26 
27 public:
32  MachineTorusBGQTest(const Teuchos::Comm<int> &comm ):
33  Machine<pcoord_t,part_t>(comm),
34  networkDim(6),
35  procCoords(NULL),machine_extent(NULL),
36  delete_transformed_coords(false),
37  transformed_network_dim(0),
38  transformed_coordinates (NULL), pl(NULL)
39  {
40  transformed_network_dim = networkDim - 1;
41  transformed_coordinates = procCoords;
42 
43  machine_extent = new int[networkDim];
44  this->getMachineExtent(this->machine_extent);
45  machine_extent[5] = 1;
46 
47  // Allocate memory for processor coordinates.
48  procCoords = new pcoord_t *[networkDim];
49  for (int i = 0; i < networkDim; ++i) {
50  procCoords[i] = new pcoord_t[this->numRanks];
51  memset(procCoords[i], 0, sizeof(pcoord_t) * this->numRanks);
52  }
53 
54  // Obtain the coordinate of the processor.
55  pcoord_t *xyz = new pcoord_t[networkDim];
57  for (int i = 0; i < networkDim; i++)
58  procCoords[i][this->myRank] = xyz[i];
59  delete [] xyz;
60 
61  // reduceAll the coordinates of each processor.
62  gatherMachineCoordinates(comm);
63 
64  }
65 
66  MachineTorusBGQTest(const Teuchos::Comm<int> &comm,
67  const Teuchos::ParameterList &pl_):
68  Machine<pcoord_t,part_t>(comm),
69  networkDim(6),
70  procCoords(NULL),machine_extent(NULL),
71  delete_transformed_coords(false),
72  transformed_network_dim(0),
73  transformed_coordinates (NULL),
74  pl(&pl_)
75  {
76  transformed_network_dim = networkDim - 1;
77  transformed_coordinates = procCoords;
78  machine_extent = new int[networkDim];
79 
80  this->getMachineExtent(this->machine_extent);
81  machine_extent[5] = 1;
82 
83  // Allocate memory for processor coordinates.
84  procCoords = new pcoord_t *[networkDim];
85  for (int i = 0; i < networkDim; ++i) {
86  procCoords[i] = new pcoord_t[this->numRanks];
87  memset(procCoords[i], 0, sizeof(pcoord_t) * this->numRanks);
88  }
89 
90  // Obtain the coordinate of the processor.
91  pcoord_t *xyz = new pcoord_t[networkDim];
93  for (int i = 0; i < networkDim; i++)
94  procCoords[i][this->myRank] = xyz[i];
95  delete [] xyz;
96 
97  // reduceAll the coordinates of each processor.
98  gatherMachineCoordinates(comm);
99 
100  const Teuchos::ParameterEntry *pe =
101  this->pl->getEntryPtr("Machine_Optimization_Level");
102 
103  if (pe) {
104  int optimization_level = 0;
105 
106  optimization_level = pe->getValue<int>(&optimization_level);
107 
108  if (optimization_level == 0) {
109  transformed_network_dim = networkDim - 1;
110  transformed_coordinates = procCoords;
111  }
112  else if (optimization_level >= 1) {
113  transformed_network_dim = networkDim - 2;
114  transformed_coordinates = procCoords;
115  }
116  }
117  }
118 
119 
121  for (int i = 0; i < networkDim; i++) {
122  delete [] procCoords[i];
123  }
124  delete [] procCoords;
125 
126  delete [] machine_extent;
127  if (delete_transformed_coords) {
128  for (int i = 0; i < transformed_network_dim; i++) {
129  delete [] transformed_coordinates[i];
130  }
131  delete [] transformed_coordinates;
132  }
133  }
134 
135  bool hasMachineCoordinates() const { return true; }
136 
137  int getMachineDim() const { return transformed_network_dim; }
138 
139  bool getMachineExtentWrapArounds(bool *wrap_around) const {
140  int dim = 0;
141  if (dim < transformed_network_dim)
142  wrap_around[dim++] = true;
143 
144  if (dim < transformed_network_dim)
145  wrap_around[dim++] = true;
146 
147  if (dim < transformed_network_dim)
148  wrap_around[dim++] = true;
149 
150  if (dim < transformed_network_dim)
151  wrap_around[dim++] = true;
152 
153  if (dim < transformed_network_dim)
154  wrap_around[dim++] = true;
155 
156  if (dim < transformed_network_dim)
157  wrap_around[dim++] = true;
158  return true;
159  }
160 
161 
162  bool getMachineExtentWrapArounds(part_t *wrap_around) const {
163  int dim = 0;
164  if (dim < transformed_network_dim)
165  wrap_around[dim++] = true;
166 
167  if (dim < transformed_network_dim)
168  wrap_around[dim++] = true;
169 
170  if (dim < transformed_network_dim)
171  wrap_around[dim++] = true;
172 
173  if (dim < transformed_network_dim)
174  wrap_around[dim++] = true;
175 
176  if (dim < transformed_network_dim)
177  wrap_around[dim++] = true;
178 
179  if (dim < transformed_network_dim)
180  wrap_around[dim++] = true;
181  return true;
182  }
183 
184  bool getMachineExtent(part_t *extent) const {
185  part_t nxyz[6];
186 
187  nxyz[0] = 1;
188  nxyz[1] = 1;
189  nxyz[2] = 1;
190  nxyz[3] = 1;
191  nxyz[4] = 1;
192  nxyz[5] = 1;
193  const int rank_per_node = 1;
194  const int num_nodes = this->numRanks / rank_per_node;
195 
196  if (num_nodes <= 1) {
197  nxyz[0] = nxyz[1] = nxyz[2] = nxyz[3] = 1;
198  nxyz[4] = 1;
199  nxyz[5] = 1;
200  }
201  else if (num_nodes <= 2) {
202  nxyz[0] = nxyz[1] = nxyz[2] = nxyz[3] = 1;
203  nxyz[4] = 2;
204  nxyz[5] = 1;
205  }
206  else if (num_nodes <= 4) {
207  nxyz[0] = nxyz[1] = nxyz[2] = 1;
208  nxyz[3] = 2;
209  nxyz[4] = 2;
210  nxyz[5] = 1;
211  }
212  else if (num_nodes <= 8) {
213  nxyz[0] = nxyz[1] = 1;
214  nxyz[2] = 2;
215  nxyz[3] = 2;
216  nxyz[4] = 2;
217  nxyz[5] = 1;
218  }
219  else if (num_nodes <= 16) {
220  nxyz[0] = 1;
221  nxyz[1] = 2;
222  nxyz[2] = 2;
223  nxyz[3] = 2;
224  nxyz[4] = 2;
225  nxyz[5] = 1;
226  }
227  else if (num_nodes <= 32) {
228  nxyz[0] = 1;
229  nxyz[1] = 2;
230  nxyz[2] = 2;
231  nxyz[3] = 4;
232  nxyz[4] = 2;
233  nxyz[5] = 1;
234  }
235  else if (num_nodes <= 64) {
236  nxyz[0] = 1;
237  nxyz[1] = 2;
238  nxyz[2] = 4;
239  nxyz[3] = 4;
240  nxyz[4] = 2;
241  nxyz[5] = 1;
242  }
243  else if (num_nodes <= 128) {
244  nxyz[0] = 2;
245  nxyz[1] = 2;
246  nxyz[2] = 4;
247  nxyz[3] = 4;
248  nxyz[4] = 2;
249  nxyz[5] = 1;
250  }
251  else if (num_nodes <= 256) {
252  nxyz[0] = 4;
253  nxyz[1] = 2;
254  nxyz[2] = 4;
255  nxyz[3] = 4;
256  nxyz[4] = 2;
257  nxyz[5] = 1;
258  }
259  else if (num_nodes <= 512) {
260  nxyz[0] = 4;
261  nxyz[1] = 4;
262  nxyz[2] = 4;
263  nxyz[3] = 4;
264  nxyz[4] = 2;
265  nxyz[5] = 1;
266  }
267  else if (num_nodes <= 1024) {
268  nxyz[0] = 4;
269  nxyz[1] = 4;
270  nxyz[2] = 4;
271  nxyz[3] = 8;
272  nxyz[4] = 2;
273  nxyz[5] = 1;
274  }
275  else if (num_nodes <= 2048) {
276  nxyz[0] = 4;
277  nxyz[1] = 4;
278  nxyz[2] = 4;
279  nxyz[3] = 16;
280  nxyz[4] = 2;
281  nxyz[5] = 1;
282  }
283  else if (num_nodes <= 4096) {
284  nxyz[0] = 8;
285  nxyz[1] = 4;
286  nxyz[2] = 4;
287  nxyz[3] = 16;
288  nxyz[4] = 2;
289  nxyz[5] = 1;
290  }
291  else {
292  std::cerr << "Too many ranks to test" << std::endl;
293  }
294  nxyz[5] = rank_per_node;
295 
296  int dim = 0;
297  if (dim < transformed_network_dim)
298  extent[dim] = nxyz[dim];
299  ++dim;
300  if (dim < transformed_network_dim)
301  extent[dim] = nxyz[dim];
302  ++dim;
303  if (dim < transformed_network_dim)
304  extent[dim] = nxyz[dim];
305  ++dim;
306  if (dim < transformed_network_dim)
307  extent[dim] = nxyz[dim];
308  ++dim;
309  if (dim < transformed_network_dim)
310  extent[dim] = nxyz[dim];
311  ++dim;
312  if (dim < transformed_network_dim)
313  extent[dim] = nxyz[dim];
314 
315  return true;
316  }
317 
318 
319  bool getMyMachineCoordinate(pcoord_t *xyz) {
320  for (int i = 0; i < this->transformed_network_dim; ++i) {
321  xyz[i] = transformed_coordinates[i][this->myRank];
322  }
323  return true;
324  }
325 
326  bool getMyActualMachineCoordinate(pcoord_t *xyz) {
327  int a,b,c,d,e,t;
328 
329  int me = this->myRank;
330  t = me % machine_extent[5];
331 
332  me = me / machine_extent[5];
333  e = me % machine_extent[4];
334 
335  me = me / machine_extent[4];
336  d = me % machine_extent[3];
337 
338  me = me / machine_extent[3];
339  c = me % machine_extent[2];
340 
341  me = me / machine_extent[2];
342  b = me % machine_extent[1];
343 
344  me = me / machine_extent[1];
345  a = me % machine_extent[0];
346 
347  xyz[0] = a; xyz[1] = b; xyz[2] = c; xyz[3] = d; xyz[4] = e; xyz[5] = t;
348 
349 // std::cout << "me:" << this->myRank << " " << a << " " << b
350 // << " " << c << " " << d << " " << e << " " << t << std::endl;
351  return true;
352  }
353 
354 
355  inline bool getMachineCoordinate(const int rank,
356  pcoord_t *xyz) const {
357  return false;
358  }
359  bool getMachineCoordinate(const char *nodename, pcoord_t *xyz) {
360  return false; // cannot yet return from nodename
361  }
362 
363  bool getAllMachineCoordinatesView(pcoord_t **&allCoords) const {
364  allCoords = procCoords;
365  return true;
366  }
367 
368  virtual bool getHopCount(int rank1, int rank2, pcoord_t &hops) const override {
369 
370  hops = 0;
371  for (int i = 0; i < networkDim - 1; ++i) {
372  pcoord_t distance = procCoords[i][rank1] - procCoords[i][rank2];
373  if (distance < 0 )
374  distance = -distance;
375  if (machine_extent[i] - distance < distance)
376  distance = machine_extent[i] - distance;
377  hops += distance;
378  }
379 
380 /*
381  if (this->myRank == 0) {
382  std::cout << "rank1:" << rank1 << " rank2:" << rank2
383  << " hops:" << hops << std::endl;
384  }
385 */
386 
387  return true;
388  }
389 
390 
391 private:
392 
393  int networkDim;
394  pcoord_t **procCoords; // KDD Maybe should be RCP?
395  part_t *machine_extent;
396 
397  bool delete_transformed_coords;
398  int transformed_network_dim;
399  pcoord_t **transformed_coordinates;
400  const Teuchos::ParameterList *pl;
401 
402  void gatherMachineCoordinates(const Teuchos::Comm<int> &comm) {
403  // Reduces and stores all machine coordinates.
404  pcoord_t *tmpVect = new pcoord_t [this->numRanks];
405 
406  for (int i = 0; i < networkDim; i++) {
407  Teuchos::reduceAll<int, pcoord_t>(comm, Teuchos::REDUCE_SUM,
408  this->numRanks,
409  procCoords[i], tmpVect);
410  pcoord_t *tmp = tmpVect;
411  tmpVect = procCoords[i];
412  procCoords[i] = tmp;
413  }
414  delete [] tmpVect;
415  }
416 };
417 }
418 #endif
MachineTorusBGQTest(const Teuchos::Comm< int > &comm)
Constructor: A BlueGeneQ network machine description;.
A TopoManager Machine Class (Torus Networks) for testing only A more realistic machine should be used...
MachineClass Base class for representing machine coordinates, networks, etc.
bool getMachineExtentWrapArounds(bool *wrap_around) const
bool getMachineCoordinate(const char *nodename, pcoord_t *xyz)
SparseMatrixAdapter_t::part_t part_t
bool getMachineExtentWrapArounds(part_t *wrap_around) const
bool getAllMachineCoordinatesView(pcoord_t **&allCoords) const
MachineTorusBGQTest(const Teuchos::Comm< int > &comm, const Teuchos::ParameterList &pl_)
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 getMachineCoordinate(const int rank, pcoord_t *xyz) const