48748ca8f73a5173933b1a8a89ac057333345211
[charm.git] / src / util / XTTorus.h
1 /** \file XTTorus.h
2  *  Author: Abhinav S Bhatele
3  *  Date created: August 19th, 2008
4  *  
5  */
6
7 #ifndef _XT_TORUS_H_
8 #define _XT_TORUS_H_
9
10 #include "converse.h"
11
12 #include <stdlib.h>
13 #include <stdio.h>
14
15 #if XE6_TOPOLOGY
16 #define CPU_FACTOR 2
17 #else
18 #define CPU_FACTOR 1
19 #endif
20
21 #if XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
22
23 // XDIM, YDIM, ZDIM and MAXNID depend on a specific Cray installation.
24 // Please do NOT expect things to work if you use this code on a new
25 // Cray machine.
26
27 /*
28 #if XT4_TOPOLOGY
29 #define MAXNID 14000
30 #define XDIM 21
31 #define YDIM 16
32 #define ZDIM 24
33 #define TDIM 4
34 #define CPU_FACTOR 1
35
36 #elif XT5_TOPOLOGY
37 #define MAXNID 22020
38 #define XDIM 25
39 #define YDIM 32
40 #define ZDIM 24
41 #define TDIM 12
42 #define CPU_FACTOR 1
43
44 #elif XE6_TOPOLOGY
45 #define CPU_FACTOR 2
46 // hopper 
47 #define MAXNID 6384
48 #define XDIM 17
49 #define YDIM 8
50 #define ZDIM 24
51 #define TDIM 24
52 #if 0
53 // titan 
54 #define MAXNID 9600
55 #define XDIM 25
56 #define YDIM 16
57 #define ZDIM 24
58 #define TDIM 16
59 // ESS 
60 #define MAXNID 4608
61 #define XDIM 12
62 #define YDIM 8
63 #define ZDIM 24
64 #define TDIM 32
65 // JYC 
66 #define MAXNID 97
67 #define XDIM 1
68 #define YDIM 6
69 #define ZDIM 8
70 #define TDIM 32
71 #endif
72 #endif
73 */
74 extern "C" int *pid2nid;
75 extern "C" int pidtonid(int numpes);
76 extern "C" int getMeshCoord(int nid, int *x, int *y, int *z);
77 extern "C" void getDimension(int *,int *, int *, int *);
78
79 struct loc {
80   int x;
81   int y;
82   int z;
83   int t;
84 };
85
86 class XTTorusManager {
87   private:
88     int dimX;   // dimension of the allocation in X (processors)
89     int dimY;   // dimension of the allocation in Y (processors)
90     int dimZ;   // dimension of the allocation in Z (processors)
91     int dimNX;  // dimension of the allocation in X (nodes)
92     int dimNY;  // dimension of the allocation in Y (nodes)
93     int dimNZ;  // dimension of the allocation in Z (nodes)
94     int dimNT;  // number of processors per node (2 for XT3)
95     int xDIM, yDIM, zDIM, maxNID;
96
97     int torus[4];
98     int procsPerNode;   // number of cores per node
99
100     int ****coords2pid;     // coordinates to rank
101     struct loc *pid2coords;                     // rank to coordinates
102     struct loc origin;
103
104   public:
105     XTTorusManager() {
106       int nid = 0, oldnid = -1, lx, ly, lz;
107       int i, j, k, l;
108                         int numCores;
109       int minX, minY, minZ, minT=0, maxX=0, maxY=0, maxZ=0;
110
111       int numPes = CmiNumPes();
112       pid2coords = (struct loc*)malloc(sizeof(struct loc) * numPes);
113
114       // fill the nid2pid and pid2nid data structures
115       pidtonid(numPes);
116                         getDimension(&maxNID,&xDIM,&yDIM,&zDIM);
117       minX=xDIM, minY=yDIM, minZ=zDIM;
118                         numCores = CmiNumCores()*CPU_FACTOR;
119
120                         coords2pid = (int ****)malloc(xDIM*sizeof(int***));
121                         for(i=0; i<xDIM; i++) {
122                                 coords2pid[i] = (int ***)malloc(yDIM*sizeof(int**));
123                                 for(j=0; j<yDIM; j++) {
124                                         coords2pid[i][j] = (int **)malloc(zDIM*sizeof(int*));
125                                         for(k=0; k<zDIM; k++) {
126                                                 coords2pid[i][j][k] = (int *)malloc(numCores*sizeof(int*));
127                                         }
128                                 }
129                         }
130
131       for(i=0; i<xDIM; i++)
132         for(j=0; j<yDIM; j++)
133           for(k=0; k<zDIM; k++)
134             for(l=0; l<numCores; l++)
135               coords2pid[i][j][k][l] = -1;
136
137       dimNT = 1;        
138       // now fill the coords2pid and pid2coords data structures
139       for(i=0; i<numPes; i++)
140       {
141         nid = pid2nid[i];
142         if (nid != oldnid)
143           getMeshCoord(nid, &lx, &ly, &lz);
144         oldnid = nid;
145
146         pid2coords[i].x = lx;      
147         pid2coords[i].y = ly;
148         pid2coords[i].z = lz;
149
150         l = 0;
151         while(coords2pid[lx][ly][lz][l] != -1)
152           l++;
153         coords2pid[lx][ly][lz][l] = i;
154         pid2coords[i].t = l;
155                                 if((l+1) > dimNT)
156                                         dimNT = l+1;
157
158         if (lx<minX) minX = lx; if (lx>maxX) maxX = lx;
159         if (ly<minY) minY = ly; if (ly>maxY) maxY = ly;
160         if (lz<minZ) minZ = lz; if (lz>maxZ) maxZ = lz;
161       }
162
163       // set the origin as the element on the lower end of the torus
164       origin.x =  minX;
165       origin.y =  minY;
166       origin.z =  minZ;
167       origin.t =  minT;
168
169       // assuming a contiguous allocation find the dimensions of 
170       // the torus
171       dimNX = maxX - minX + 1;
172       dimNY = maxY - minY + 1;
173       dimNZ = maxZ - minZ + 1;
174       procsPerNode = dimNT;
175       dimX = dimNX * dimNT;
176       dimY = dimNY;
177       dimZ = dimNZ;
178
179       // we get a torus only if the size of the dimension is the biggest
180       torus[0] = 0;             
181       torus[1] = (dimNY == yDIM) ? 1 : 0;
182       torus[2] = (dimNZ == zDIM) ? 1 : 0;
183       torus[3] = 0;
184     }
185
186     ~XTTorusManager() { 
187                         int i,j,k;
188                         free(pid2coords); 
189                         for(i=0; i<xDIM; i++) {
190                                 for(j=0; j<yDIM; j++) {
191                                         for(k=0; k<zDIM; k++) {
192                                                 free(coords2pid[i][j][k]);
193                                         }
194                                         free(coords2pid[i][j]);
195                                 }
196                                 free(coords2pid[i]);
197                         }
198                 }
199
200     inline int getDimX() { return dimX; }
201     inline int getDimY() { return dimY; }
202     inline int getDimZ() { return dimZ; }
203
204     inline int getDimNX() { return dimNX; }
205     inline int getDimNY() { return dimNY; }
206     inline int getDimNZ() { return dimNZ; }
207     inline int getDimNT() { return dimNT; }
208
209     inline int getProcsPerNode() { return procsPerNode; }
210
211     inline int* isTorus() { return torus; }
212
213     inline void rankToCoordinates(int pe, int &x, int &y, int &z, int &t) {
214       x = pid2coords[pe].x - origin.x; 
215       y = pid2coords[pe].y - origin.y; 
216       z = pid2coords[pe].z - origin.z; 
217       t = pid2coords[pe].t - origin.t;
218     }
219
220     inline void realRankToCoordinates(int pe, int &x, int &y, int &z, int &t) {
221       x = pid2coords[pe].x; 
222       y = pid2coords[pe].y; 
223       z = pid2coords[pe].z; 
224       t = pid2coords[pe].t; 
225     }
226
227     inline int coordinatesToRank(int x, int y, int z, int t) {
228       if(coords2pid[x+origin.x][y+origin.y][z+origin.z][t+origin.t] == -1 && ((t+origin.t)>=CmiNumCores)) {
229                                 return coords2pid[x+origin.x][y+origin.y][z+origin.z][t+origin.t-CmiNumCores()]; 
230                         } else {
231                                 return coords2pid[x+origin.x][y+origin.y][z+origin.z][t+origin.t];
232                         }
233     }
234 };
235
236 #endif // XT4_TOPOLOGY || XT5_TOPOLOGY ||XE6_TOPOLOGY
237 #endif //_XT_TORUS_H_