add a function to return Cray XE dimensions
[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 XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
16
17 // XDIM, YDIM, ZDIM and MAXNID depend on a specific Cray installation.
18 // Please do NOT expect things to work if you use this code on a new
19 // Cray machine.
20
21 #if XT4_TOPOLOGY
22 #define MAXNID 14000
23 #define XDIM 21
24 #define YDIM 16
25 #define ZDIM 24
26 #define TDIM 4
27
28 #elif XT5_TOPOLOGY
29 #define MAXNID 22020
30 #define XDIM 25
31 #define YDIM 32
32 #define ZDIM 24
33 #define TDIM 12
34
35 #elif XE6_TOPOLOGY
36 /* hopper */
37 #define MAXNID 6384
38 #define XDIM 17
39 #define YDIM 8
40 #define ZDIM 24
41 #define TDIM 24
42 #if 0
43 /* titan */
44 #define MAXNID 9600
45 #define XDIM 25
46 #define YDIM 16
47 #define ZDIM 24
48 #define TDIM 16
49 /* ESS */
50 #define MAXNID 4608
51 #define XDIM 12
52 #define YDIM 8
53 #define ZDIM 24
54 #define TDIM 32
55 /* JYC */
56 #define MAXNID 83
57 #define XDIM 1
58 #define YDIM 6
59 #define ZDIM 8
60 #define TDIM 32
61 #endif
62
63 #endif
64
65 extern "C" int *pid2nid;
66 extern "C" int nid2pid[MAXNID][TDIM];
67 extern "C" int pidtonid(int numpes);
68 extern "C" int getMeshCoord(int nid, int *x, int *y, int *z);
69
70 struct loc {
71   int x;
72   int y;
73   int z;
74   int t;
75 };
76
77 class XTTorusManager {
78   private:
79     int dimX;   // dimension of the allocation in X (processors)
80     int dimY;   // dimension of the allocation in Y (processors)
81     int dimZ;   // dimension of the allocation in Z (processors)
82     int dimNX;  // dimension of the allocation in X (nodes)
83     int dimNY;  // dimension of the allocation in Y (nodes)
84     int dimNZ;  // dimension of the allocation in Z (nodes)
85     int dimNT;  // number of processors per node (2 for XT3)
86
87     int torus[4];
88     int procsPerNode;   // number of cores per node
89
90     int coords2pid[XDIM][YDIM][ZDIM][TDIM];     // coordinates to rank
91     struct loc *pid2coords;                     // rank to coordinates
92     struct loc origin;
93
94   public:
95     XTTorusManager() {
96       int nid = 0, oldnid = -1, lx, ly, lz;
97       int i, j, k, l;
98       int minX=XDIM, minY=YDIM, minZ=ZDIM, minT=0, maxX=0, maxY=0, maxZ=0;
99
100       int numPes = CmiNumPes();
101       pid2coords = (struct loc*)malloc(sizeof(struct loc) * numPes);
102
103       // fill the nid2pid and pid2nid data structures
104       pidtonid(numPes);
105
106       for(i=0; i<XDIM; i++)
107         for(j=0; j<YDIM; j++)
108           for(k=0; k<ZDIM; k++)
109             for(l=0; l<TDIM; l++)
110               coords2pid[i][j][k][l] = -1;
111
112       dimNT = 1;                        // assume SN mode first
113       // now fill the coords2pid and pid2coords data structures
114       for(i=0; i<numPes; i++)
115       {
116         nid = pid2nid[i];
117         if (nid != oldnid)
118           getMeshCoord(nid, &lx, &ly, &lz);
119         oldnid = nid;
120
121         pid2coords[i].x = lx;      
122         pid2coords[i].y = ly;
123         pid2coords[i].z = lz;
124
125         l = 0;
126         while(coords2pid[lx][ly][lz][l] != -1)
127           l++;
128         coords2pid[lx][ly][lz][l] = i;
129         pid2coords[i].t = l;
130
131         if (lx<minX) minX = lx; if (lx>maxX) maxX = lx;
132         if (ly<minY) minY = ly; if (ly>maxY) maxY = ly;
133         if (lz<minZ) minZ = lz; if (lz>maxZ) maxZ = lz;
134       }
135
136       // set the origin as the element on the lower end of the torus
137       origin.x =  minX;
138       origin.y =  minY;
139       origin.z =  minZ;
140       origin.t =  minT;
141
142       // assuming a contiguous allocation find the dimensions of 
143       // the torus
144       dimNX = maxX - minX + 1;
145       dimNY = maxY - minY + 1;
146       dimNZ = maxZ - minZ + 1;
147       procsPerNode = dimNT;
148       dimX = dimNX * dimNT;
149       dimY = dimNY;
150       dimZ = dimNZ;
151
152       // pick a random node (1) to find the number of cores per node being
153       // actually used - assumes same number of cores per node
154       lx = pid2coords[1].x;
155       ly = pid2coords[1].y;
156       lz = pid2coords[1].z;
157       for(l=0; l<TDIM; l++) {
158         if(coords2pid[lx][ly][lz][l] == -1)
159           break;
160       }
161       dimNT = l;
162
163       // we get a torus only if the size of the dimension is the biggest
164       torus[0] = 0;             // Jaguar is a mesh in X dimension always
165       torus[1] = (dimNY == YDIM) ? 1 : 0;
166       torus[2] = (dimNZ == ZDIM) ? 1 : 0;
167       torus[3] = 0;
168     }
169
170     ~XTTorusManager() { }
171
172     inline int getDimX() { return dimX; }
173     inline int getDimY() { return dimY; }
174     inline int getDimZ() { return dimZ; }
175
176     inline int getDimNX() { return dimNX; }
177     inline int getDimNY() { return dimNY; }
178     inline int getDimNZ() { return dimNZ; }
179     inline int getDimNT() { return dimNT; }
180
181     inline int getProcsPerNode() { return procsPerNode; }
182
183     inline int* isTorus() { return torus; }
184
185     inline void rankToCoordinates(int pe, int &x, int &y, int &z, int &t) {
186       x = pid2coords[pe].x - origin.x; 
187       y = pid2coords[pe].y - origin.y; 
188       z = pid2coords[pe].z - origin.z; 
189       t = pid2coords[pe].t - origin.t; 
190     }
191
192     inline void realRankToCoordinates(int pe, int &x, int &y, int &z, int &t) {
193       x = pid2coords[pe].x; 
194       y = pid2coords[pe].y; 
195       z = pid2coords[pe].z; 
196       t = pid2coords[pe].t; 
197     }
198
199     inline int coordinatesToRank(int x, int y, int z, int t) {
200       return coords2pid[x+origin.x][y+origin.y][z+origin.z][t+origin.t];
201     }
202 };
203
204 #endif // XT4_TOPOLOGY || XT5_TOPOLOGY
205 #endif //_XT_TORUS_H_