Zoltan2
Loading...
Searching...
No Matches
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
21namespace Zoltan2{
22
26template <typename pcoord_t, typename part_t>
27class MachineTorusTopoMgr : public Machine <pcoord_t, part_t> {
28
29public:
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
295private:
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
A TopoManager Machine Class on Torus Networks.
bool getMachineCoordinate(const char *nodename, pcoord_t *xyz)
bool getAllMachineCoordinatesView(pcoord_t **&allCoords) const
MachineTorusTopoMgr(const Teuchos::Comm< int > &comm)
Constructor: A BlueGeneQ network machine description;.
bool getMachineExtentWrapArounds(bool *wrap_around) const
bool getMachineExtentWrapArounds(part_t *wrap_around) const
MachineTorusTopoMgr(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
MachineClass Base class for representing machine coordinates, networks, etc.
Created by mbenlioglu on Aug 31, 2020.
SparseMatrixAdapter_t::part_t part_t