00001
00007 #ifndef _XT_TORUS_H_
00008 #define _XT_TORUS_H_
00009
00010 #include "converse.h"
00011
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014
00015 #if XE6_TOPOLOGY
00016 #define CPU_FACTOR 2
00017 #else
00018 #define CPU_FACTOR 1
00019 #endif
00020
00021 #if CMK_HAS_RCALIB
00022 #include <rca_lib.h>
00023 #endif
00024
00025 #if XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 extern "C" int *pid2nid;
00079 extern "C" int pidtonid(int numpes);
00080 extern "C" int getMeshCoord(int nid, int *x, int *y, int *z);
00081 extern "C" void getDimension(int *,int *, int *, int *);
00082 #if CMK_HAS_RCALIB
00083 extern "C" rca_mesh_coord_t *coords;
00084 #endif
00085
00086 struct loc {
00087 int x;
00088 int y;
00089 int z;
00090 int t;
00091 };
00092
00093 class XTTorusManager {
00094 private:
00095 int dimX;
00096 int dimY;
00097 int dimZ;
00098 int dimNX;
00099 int dimNY;
00100 int dimNZ;
00101 int dimNT;
00102 int xDIM, yDIM, zDIM, maxNID;
00103
00104 int torus[4];
00105 int procsPerNode;
00106
00107 int ****coords2pid;
00108 struct loc *pid2coords;
00109 struct loc origin;
00110
00111 public:
00112 XTTorusManager() {
00113 int nid = 0, oldnid = -1, lx, ly, lz;
00114 int i, j, k, l;
00115 int numCores;
00116 int minX, minY, minZ, minT=0, maxX=0, maxY=0, maxZ=0;
00117
00118 int numPes = CmiNumPes();
00119 pid2coords = (struct loc*)malloc(sizeof(struct loc) * numPes);
00120 _MEMCHECK(pid2coords);
00121
00122
00123
00124
00125
00126 getDimension(&maxNID,&xDIM,&yDIM,&zDIM);
00127 minX=xDIM, minY=yDIM, minZ=zDIM;
00128 numCores = CmiNumCores()*CPU_FACTOR;
00129
00130 coords2pid = (int ****)malloc(xDIM*sizeof(int***));
00131 _MEMCHECK(coords2pid);
00132 for(i=0; i<xDIM; i++) {
00133 coords2pid[i] = (int ***)malloc(yDIM*sizeof(int**));
00134 _MEMCHECK(coords2pid[i]);
00135 for(j=0; j<yDIM; j++) {
00136 coords2pid[i][j] = (int **)malloc(zDIM*sizeof(int*));
00137 _MEMCHECK(coords2pid[i][j]);
00138 for(k=0; k<zDIM; k++) {
00139 coords2pid[i][j][k] = (int *)malloc(numCores*sizeof(int*));
00140 _MEMCHECK(coords2pid[i][j][k]);
00141 }
00142 }
00143 }
00144
00145 for(i=0; i<xDIM; i++)
00146 for(j=0; j<yDIM; j++)
00147 for(k=0; k<zDIM; k++)
00148 for(l=0; l<numCores; l++)
00149 coords2pid[i][j][k][l] = -1;
00150
00151 dimNT = 1;
00152
00153 for(i=0; i<numPes; i++)
00154 {
00155 nid = pid2nid[i];
00156 if (nid != oldnid) {
00157 int ret = getMeshCoord(nid, &lx, &ly, &lz);
00158 CmiAssert(ret != -1);
00159 }
00160 oldnid = nid;
00161
00162 pid2coords[i].x = lx;
00163 pid2coords[i].y = ly;
00164 pid2coords[i].z = lz;
00165
00166 l = 0;
00167 while(coords2pid[lx][ly][lz][l] != -1)
00168 l++;
00169 CmiAssert(l<numCores);
00170 coords2pid[lx][ly][lz][l] = i;
00171 pid2coords[i].t = l;
00172 if((l+1) > dimNT)
00173 dimNT = l+1;
00174
00175 if (lx<minX) minX = lx; if (lx>maxX) maxX = lx;
00176 if (ly<minY) minY = ly; if (ly>maxY) maxY = ly;
00177 if (lz<minZ) minZ = lz; if (lz>maxZ) maxZ = lz;
00178 }
00179
00180
00181 origin.x = minX;
00182 origin.y = minY;
00183 origin.z = minZ;
00184 origin.t = minT;
00185
00186
00187
00188 dimNX = maxX - minX + 1;
00189 dimNY = maxY - minY + 1;
00190 dimNZ = maxZ - minZ + 1;
00191 procsPerNode = dimNT;
00192 dimX = dimNX * dimNT;
00193 dimY = dimNY;
00194 dimZ = dimNZ;
00195
00196
00197 torus[0] = 0;
00198 torus[1] = (dimNY == yDIM) ? 1 : 0;
00199 torus[2] = (dimNZ == zDIM) ? 1 : 0;
00200 torus[3] = 0;
00201 }
00202
00203 ~XTTorusManager() {
00204 int i,j,k;
00205 free(pid2coords);
00206 for(i=0; i<xDIM; i++) {
00207 for(j=0; j<yDIM; j++) {
00208 for(k=0; k<zDIM; k++) {
00209 free(coords2pid[i][j][k]);
00210 }
00211 free(coords2pid[i][j]);
00212 }
00213 free(coords2pid[i]);
00214 }
00215 free(coords2pid);
00216 }
00217
00218 inline int getDimX() { return dimX; }
00219 inline int getDimY() { return dimY; }
00220 inline int getDimZ() { return dimZ; }
00221
00222 inline int getDimNX() { return dimNX; }
00223 inline int getDimNY() { return dimNY; }
00224 inline int getDimNZ() { return dimNZ; }
00225 inline int getDimNT() { return dimNT; }
00226
00227 inline int getProcsPerNode() { return procsPerNode; }
00228
00229 inline int* isTorus() { return torus; }
00230
00231 inline void rankToCoordinates(int pe, int &x, int &y, int &z, int &t) {
00232 x = pid2coords[pe].x - origin.x;
00233 y = pid2coords[pe].y - origin.y;
00234 z = pid2coords[pe].z - origin.z;
00235 t = pid2coords[pe].t - origin.t;
00236 }
00237
00238 inline void realRankToCoordinates(int pe, int &x, int &y, int &z, int &t) {
00239 x = pid2coords[pe].x;
00240 y = pid2coords[pe].y;
00241 z = pid2coords[pe].z;
00242 t = pid2coords[pe].t;
00243 }
00244
00245 inline int coordinatesToRank(int x, int y, int z, int t) {
00246 if(coords2pid[x+origin.x][y+origin.y][z+origin.z][t+origin.t] == -1 && ((t+origin.t)>=(dimNT/2))) {
00247 return coords2pid[x+origin.x][y+origin.y][z+origin.z][t+origin.t-dimNT/2];
00248 } else {
00249 return coords2pid[x+origin.x][y+origin.y][z+origin.z][t+origin.t];
00250 }
00251 }
00252 };
00253
00254 #endif // XT4_TOPOLOGY || XT5_TOPOLOGY ||XE6_TOPOLOGY
00255 #endif //_XT_TORUS_H_