00001 
00007 #ifndef _BGQ_TORUS_H_
00008 #define _BGQ_TORUS_H_
00009 
00010 #include "topomanager_config.h"
00011 
00012 #ifndef __TPM_STANDALONE__
00013 #include "converse.h"
00014 #else
00015 #include "tpm_standalone.h"
00016 #endif
00017 
00018 #if CMK_BLUEGENEQ
00019 
00020 extern int *bgq_localNodes;
00021 extern int bgq_isLocalSet;
00022 
00023 class BGQTorusManager {
00024   private:
00025     int dimA;   
00026     int dimB;   
00027     int dimC;   
00028     int dimD;   
00029     int dimE;   
00030     
00031     int hw_NA;  
00032     int hw_NB;  
00033     int hw_NC;  
00034     int hw_ND;  
00035     int hw_NE;  
00036     int hw_NT; 
00037   
00038     int rn_NA;  
00039     int rn_NB;  
00040     int rn_NC;  
00041     int rn_ND;  
00042     int rn_NE;  
00043     
00044     int thdsPerProc; 
00045     int procsPerNode; 
00046     int torus[5];    
00047     int order[6], dims[6];
00048     char mapping[10];
00049 
00050   public:
00051     BGQTorusManager();
00052     ~BGQTorusManager() {
00053      }
00054 
00055     void populateLocalNodes();
00056 
00057     inline int getDimX() { return dimA*dimB; }
00058     inline int getDimY() { return dimC*dimD; }
00059     inline int getDimZ() { return dimE; }
00060 
00061     inline int getDimNX() { return rn_NA*rn_NB; }
00062     inline int getDimNY() { return rn_NC*rn_ND; }
00063     inline int getDimNZ() { return rn_NE; }
00064     inline int getDimNT() { return hw_NT; }
00065 
00066     inline int getDimNA() { return rn_NA; }
00067     inline int getDimNB() { return rn_NB; }
00068     inline int getDimNC() { return rn_NC; }
00069     inline int getDimND() { return rn_ND; }
00070     inline int getDimNE() { return rn_NE; }
00071 
00072     inline int getProcsPerNode() { return procsPerNode; }
00073     inline int* isTorus() { return torus; }
00074 
00075     inline void rankToCoordinates(int pe, int &x, int &y, int &z, int &t) const { 
00076         pe = CmiGetPeGlobal(pe, CmiMyPartition());
00077         t = pe % (thdsPerProc*procsPerNode);
00078         int e = pe / (thdsPerProc*procsPerNode) % rn_NE;
00079         int d = pe / (thdsPerProc*procsPerNode*rn_NE) % (rn_ND);
00080         int c = pe / (thdsPerProc*procsPerNode*rn_NE*rn_ND) % (rn_NC);
00081         int b = pe / (thdsPerProc*procsPerNode*rn_NE*rn_ND*rn_NC) % (rn_NB);
00082         int a = pe / (thdsPerProc*procsPerNode*rn_NE*rn_ND*rn_NC*rn_NB);
00083 
00084         z = e;
00085         y = (c + 1) * rn_ND - 1 - (((c % 2)==0)?(rn_ND - d - 1) : d);
00086         x = (a + 1) * rn_NB - 1 - (((a % 2)==0)?(rn_NB - b - 1) : b);
00087     }
00088 
00089     inline void rankToCoordinates(int pe, int &a, int &b, int &c, int &d, int &e, int &t) const {
00090         int tempdims[6];
00091 
00092         pe = CmiGetPeGlobal(pe, CmiMyPartition());
00093         tempdims[order[0]] = pe % dims[order[0]];
00094         tempdims[order[1]] = (pe / dims[order[0]]) % dims[order[1]];
00095         tempdims[order[2]] = (pe / (dims[order[0]]*dims[order[1]])) % dims[order[2]];
00096         tempdims[order[3]] = (pe / (dims[order[0]]*dims[order[1]]*dims[order[2]])) % dims[order[3]];
00097         tempdims[order[4]] = (pe / (dims[order[0]]*dims[order[1]]*dims[order[2]]*dims[order[3]])) % dims[order[4]];
00098         tempdims[order[5]] = (pe / (dims[order[0]]*dims[order[1]]*dims[order[2]]*dims[order[3]]*dims[order[4]])) % dims[order[5]];
00099         
00100         a = tempdims[0];
00101         b = tempdims[1];
00102         c = tempdims[2];
00103         d = tempdims[3];
00104         e = tempdims[4];
00105         t = tempdims[5];
00106 
00107     }
00108    
00109     inline int coordinatesToRank(int x, int y, int z, int t) const {  
00110         int pe;
00111         int a = x/rn_NB;
00112         int b = ((a % 2)==0)?(x % rn_NB) : (rn_NB - (x % rn_NB) - 1);
00113         int c = y/rn_ND;
00114         int d = ((c % 2)==0)?(y % rn_ND) : (rn_ND - (y % rn_ND) - 1);
00115         int e = z;
00116 
00117         int a_mult = rn_NB * rn_NC * rn_ND * rn_NE;
00118         int b_mult = rn_NC * rn_ND * rn_NE;
00119         int c_mult = rn_ND * rn_NE;
00120         int d_mult = rn_NE;
00121         
00122         pe = (a * a_mult + b * b_mult + c * c_mult + d * d_mult + e) * thdsPerProc * procsPerNode + t;
00123         
00124 #ifndef __TPM_STANDALONE__
00125         if(CmiNumPartitions() == 1 || !bgq_isLocalSet)
00126           return pe;
00127         else {
00128           int node = CmiNodeOf(pe);
00129           int rank = CmiRankOf(pe);
00130           if(bgq_localNodes[node] == -1)     return -1;
00131           else return (CmiNodeFirst(bgq_localNodes[node]) + rank);
00132         }
00133 #else
00134         return pe;
00135 #endif
00136     }    
00137 
00138     inline int coordinatesToRank(int a, int b, int c, int d, int e, int t) const {
00139         int pe;
00140         int tempdims[6];
00141         tempdims[0] = a;
00142         tempdims[1] = b;
00143         tempdims[2] = c;
00144         tempdims[3] = d;
00145         tempdims[4] = e;
00146         tempdims[5] = t;
00147 
00148         pe = 0;
00149 
00150         pe += tempdims[order[0]];
00151         pe += (tempdims[order[1]]*dims[order[0]]);
00152         pe += (tempdims[order[2]]*dims[order[0]]*dims[order[1]]);
00153         pe += (tempdims[order[3]]*dims[order[0]]*dims[order[1]]*dims[order[2]]);
00154         pe += (tempdims[order[4]]*dims[order[0]]*dims[order[1]]*dims[order[2]]*dims[order[3]]);
00155         pe += (tempdims[order[5]]*dims[order[0]]*dims[order[1]]*dims[order[2]]*dims[order[3]]*dims[order[4]]);
00156 
00157 #ifndef __TPM_STANDALONE__
00158         if(CmiNumPartitions() == 1 || !bgq_isLocalSet)
00159           return pe;
00160         else {
00161           int node = CmiNodeOf(pe);
00162           int rank = CmiRankOf(pe);
00163           if(bgq_localNodes[node] == -1)     return -1;
00164           else return (CmiNodeFirst(bgq_localNodes[node]) + rank);
00165         }
00166 #else
00167         return pe;
00168 #endif
00169     }
00170      
00171     inline int getTotalPhyNodes(){
00172       return rn_NA * rn_NB * rn_NC * rn_ND * rn_NE;
00173     }
00174     inline int getMyPhyNodeID(int pe){
00175       int x,y,z,t;
00176       rankToCoordinates(pe, x, y, z, t);
00177       int a = x/rn_NB;
00178       int b = ((a % 2)==0)?(x % rn_NB) : (rn_NB - (x % rn_NB) - 1);
00179       int c = y/rn_ND;
00180       int d = ((c % 2)==0)?(y % rn_ND) : (rn_ND - (y % rn_ND) - 1);
00181       int e = z;                
00182       return a * rn_NB * rn_NC * rn_ND * rn_NE + b * rn_NC * rn_ND * rn_NE + c * rn_ND * rn_NE + d * rn_NE + e;
00183     }
00184     
00185 };
00186 
00187 #endif // CMK_BLUEGENEQ
00188 #endif //_BGQ_TORUS_H_