Zoltan2
Loading...
Searching...
No Matches
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
18namespace Zoltan2{
19
24template <typename pcoord_t, typename part_t>
25class MachineTorusBGQTest : public Machine <pcoord_t, part_t> {
26
27public:
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
391private:
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
A TopoManager Machine Class (Torus Networks) for testing only A more realistic machine should be used...
MachineTorusBGQTest(const Teuchos::Comm< int > &comm)
Constructor: A BlueGeneQ network machine description;.
bool getMachineCoordinate(const int rank, pcoord_t *xyz) const
bool getMachineCoordinate(const char *nodename, pcoord_t *xyz)
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(bool *wrap_around) const
MachineTorusBGQTest(const Teuchos::Comm< int > &comm, const Teuchos::ParameterList &pl_)
bool getMachineExtentWrapArounds(part_t *wrap_around) const
bool getAllMachineCoordinatesView(pcoord_t **&allCoords) const
MachineClass Base class for representing machine coordinates, networks, etc.
Created by mbenlioglu on Aug 31, 2020.
SparseMatrixAdapter_t::part_t part_t