fixed an issue that TopoManager used in multiple workder threads in SMP mode.
authorGengbin Zheng <gzheng@illinois.edu>
Thu, 26 Apr 2012 00:54:44 +0000 (19:54 -0500)
committerGengbin Zheng <gzheng@illinois.edu>
Thu, 26 Apr 2012 00:54:44 +0000 (19:54 -0500)
src/ck-core/init.C
src/util/CrayNid.c
src/util/TopoManager.C
src/util/XTTorus.h

index 07c331d62f1f2d50eaf3302ee2c5bac7f2b6fbeb..84485b7332322742eea3ba482c0cc3dc4a1d02d2 100644 (file)
@@ -886,6 +886,8 @@ extern "C" void CmiInitCPUAffinity(char **argv);
 extern "C" void CmiInitMemAffinity(char **argv);
 extern "C" void CmiInitPxshm(char **argv);
 
+extern void TopoManager_init();
+
 //extern "C" void CldCallback();
 
 void _registerInitCall(CkInitCallFn fn, int isNodeCall)
@@ -1241,6 +1243,9 @@ void _initCharm(int unused_argc, char **argv)
                }*/
        }       
 
+    TopoManager_init();
+    CmiNodeAllBarrier();
+
     if (!_replaySystem) {
         if (faultFunc == NULL) {         // this is not restart
             // these two are blocking calls for non-bigsim
index 7cf5d7d8c8cb6121ac05d6e9bf145b319c255ee3..a1f9b364ef50c6b1db2aca8016b63eaab65a30a2 100644 (file)
@@ -19,6 +19,9 @@
 #include <pmi.h>
 #endif
 
+CmiNodeLock  cray_lock =  PTHREAD_LOCK_INITIALIZER;
+CmiNodeLock  cray_lock2 =  PTHREAD_LOCK_INITIALIZER;
+
 /** \function getXTNodeID
  *  returns nodeID corresponding to the MPI rank (possibly obtained
  *  from CmiMyNode()/CmiNodeOf(pe)) passed to it
@@ -91,6 +94,9 @@ int maxX = -1;
 int maxY = -1;
 int maxZ = -1;
 int maxNID = -1;
+#if CMK_HAS_RCALIB
+rca_mesh_coord_t  *coords = NULL;
+#endif
 
 void getDimension(int *maxnid, int *xdim, int *ydim, int *zdim);
 
@@ -100,13 +106,22 @@ void getDimension(int *maxnid, int *xdim, int *ydim, int *zdim);
  */
 int getMeshCoord(int nid, int *x, int *y, int *z) {
 #if CMK_HAS_RCALIB
+  if (coords == NULL) {
   rca_mesh_coord_t xyz;
-  int ret;
+  int ret = -1;
   ret = rca_get_meshcoord(nid, &xyz);
+  if (ret == -1) return -1;
   *x = xyz.mesh_x;
   *y = xyz.mesh_y;
   *z = xyz.mesh_z;
   return ret;
+  }
+  else {
+  *x = coords[nid].mesh_x;
+  *y = coords[nid].mesh_y;
+  *z = coords[nid].mesh_z;
+  return *x==-1?-1:0;
+  }
 #else
   CmiAbort("rca_get_meshcoord not exist");
   return -1;
@@ -118,19 +133,23 @@ int getMeshCoord(int nid, int *x, int *y, int *z) {
  *  correspondingly also creates an array for nids to pids
  */
 void pidtonid(int numpes) {
-  if (pid2nid != NULL) return;          /* did once already */
+  CmiLock(cray_lock);
+  if (pid2nid != NULL) {
+      CmiUnlock(cray_lock);
+      return;          /* did once already */
+  }
 
-       getDimension(&maxNID,&maxX,&maxY,&maxZ);
-       int numCores = CmiNumCores();
+  getDimension(&maxNID,&maxX,&maxY,&maxZ);
+  int numCores = CmiNumCores();
   
-       pid2nid = (int *)malloc(sizeof(int) * numpes);
+  pid2nid = (int *)malloc(sizeof(int) * numpes);
 
 #if XT3_TOPOLOGY
   cnos_nidpid_map_t *nidpid; 
   int ierr, i, nid;
        int *nid2pid;
        
-       nid2pid = (int*)malloc(maxNID*2*sizeof(int));
+  nid2pid = (int*)malloc(maxNID*2*sizeof(int));
   nidpid = (cnos_nidpid_map_t *)malloc(sizeof(cnos_nidpid_map_t) * numpes);
 
   for(i=0; i<maxNID; i++) {
@@ -166,27 +185,37 @@ void pidtonid(int numpes) {
        free(nid2pid);
 
 #elif XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
-  int i, nid;
+  int i, nid, ret;
+  CmiAssert(coords == NULL);
+  coords = (rca_mesh_coord_t *)malloc(sizeof(rca_mesh_coord_t)*(maxNID+1));
+  for (i=0; i<maxNID; i++) {
+    coords[i].mesh_x = coords[i].mesh_y = coords[i].mesh_z = -1;
+  }
   for (i=0; i<numpes; i++) {
     PMI_Get_nid(CmiNodeOf(i), &nid);
     pid2nid[i] = nid;
     CmiAssert(nid < maxNID);
+    ret = rca_get_meshcoord(nid, &coords[nid]);
+    CmiAssert(ret != -1);
   }
 #endif
+  CmiUnlock(cray_lock);
 }
 
 /* get size and dimension for XE machine */
 void getDimension(int *maxnid, int *xdim, int *ydim, int *zdim)
 {
   int i = 0, ret;
-
-       if(maxNID != -1) {
-               *xdim = maxX;
-               *ydim = maxY;
-               *zdim = maxZ;
-               *maxnid = maxNID;
-               return;
-       }
+  CmiLock(cray_lock2);
+
+  if(maxNID != -1) {
+       *xdim = maxX;
+       *ydim = maxY;
+       *zdim = maxZ;
+       *maxnid = maxNID;
+        CmiUnlock(cray_lock2);
+       return;
+  }
 
   *xdim = *ydim = *zdim = 0;
     /* loop until fails to find the max */ 
@@ -202,6 +231,17 @@ void getDimension(int *maxnid, int *xdim, int *ydim, int *zdim)
   maxX = *xdim = *xdim+1;
   maxY = *ydim = *ydim+1;
   maxZ = *zdim = *zdim+1;
+  CmiUnlock(cray_lock2);
+}
+
+void craynid_init()
+{
+  if (CmiMyRank()==0) {
+    cray_lock = CmiCreateLock();
+    cray_lock2 = CmiCreateLock();
+
+    pidtonid(CmiNumPes());
+  }
 }
 
 #endif /* XT3_TOPOLOGY || XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY */
index 560d5af2a905adb1ff39c6c01164f79f30a432bb..97d7d97eb3336c61e6a9b3a7c6e418f8cca1eec8 100644 (file)
@@ -427,6 +427,16 @@ void TopoManager::printAllocation(FILE *fp)
        }
 }
 
+#if XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
+extern "C" void craynid_init();
+#endif
+
+void TopoManager_init()
+{
+#if XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
+    craynid_init();
+#endif
+}
 
 extern "C" int CmiGetHopsBetweenRanks(int pe1, int pe2)
 {
index 8f495d209f4a199a72dfe128e170dce906082214..a404334a0c5ae521fd34e4bc054c2b243efe1c55 100644 (file)
 #define CPU_FACTOR 1
 #endif
 
+#if CMK_HAS_RCALIB
+#include <rca_lib.h>
+#endif
+
 #if XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
 
 // XDIM, YDIM, ZDIM and MAXNID depend on a specific Cray installation.
@@ -75,6 +79,9 @@ extern "C" int *pid2nid;
 extern "C" int pidtonid(int numpes);
 extern "C" int getMeshCoord(int nid, int *x, int *y, int *z);
 extern "C" void getDimension(int *,int *, int *, int *);
+#if CMK_HAS_RCALIB
+extern "C" rca_mesh_coord_t  *coords;
+#endif
 
 struct loc {
   int x;
@@ -105,28 +112,35 @@ class XTTorusManager {
     XTTorusManager() {
       int nid = 0, oldnid = -1, lx, ly, lz;
       int i, j, k, l;
-                       int numCores;
+      int numCores;
       int minX, minY, minZ, minT=0, maxX=0, maxY=0, maxZ=0;
 
       int numPes = CmiNumPes();
       pid2coords = (struct loc*)malloc(sizeof(struct loc) * numPes);
+      _MEMCHECK(pid2coords);
 
       // fill the nid2pid and pid2nid data structures
+/*
       pidtonid(numPes);
-                       getDimension(&maxNID,&xDIM,&yDIM,&zDIM);
+*/
+      getDimension(&maxNID,&xDIM,&yDIM,&zDIM);
       minX=xDIM, minY=yDIM, minZ=zDIM;
-                       numCores = CmiNumCores()*CPU_FACTOR;
-
-                       coords2pid = (int ****)malloc(xDIM*sizeof(int***));
-                       for(i=0; i<xDIM; i++) {
-                               coords2pid[i] = (int ***)malloc(yDIM*sizeof(int**));
-                               for(j=0; j<yDIM; j++) {
-                                       coords2pid[i][j] = (int **)malloc(zDIM*sizeof(int*));
-                                       for(k=0; k<zDIM; k++) {
-                                               coords2pid[i][j][k] = (int *)malloc(numCores*sizeof(int*));
-                                       }
-                               }
+      numCores = CmiNumCores()*CPU_FACTOR;
+
+      coords2pid = (int ****)malloc(xDIM*sizeof(int***));
+      _MEMCHECK(coords2pid);
+      for(i=0; i<xDIM; i++) {
+               coords2pid[i] = (int ***)malloc(yDIM*sizeof(int**));
+                _MEMCHECK(coords2pid[i]);
+               for(j=0; j<yDIM; j++) {
+                       coords2pid[i][j] = (int **)malloc(zDIM*sizeof(int*));
+                        _MEMCHECK(coords2pid[i][j]);
+                       for(k=0; k<zDIM; k++) {
+                               coords2pid[i][j][k] = (int *)malloc(numCores*sizeof(int*));
+                                _MEMCHECK(coords2pid[i][j][k]);
                        }
+               }
+      }
 
       for(i=0; i<xDIM; i++)
         for(j=0; j<yDIM; j++)
@@ -139,8 +153,10 @@ class XTTorusManager {
       for(i=0; i<numPes; i++)
       {
         nid = pid2nid[i];
-        if (nid != oldnid)
-          getMeshCoord(nid, &lx, &ly, &lz);
+        if (nid != oldnid) {
+          int ret = getMeshCoord(nid, &lx, &ly, &lz);
+          CmiAssert(ret != -1);
+        }
         oldnid = nid;
 
         pid2coords[i].x = lx;      
@@ -150,10 +166,11 @@ class XTTorusManager {
         l = 0;
         while(coords2pid[lx][ly][lz][l] != -1)
           l++;
+        CmiAssert(l<numCores);
         coords2pid[lx][ly][lz][l] = i;
         pid2coords[i].t = l;
-                               if((l+1) > dimNT)
-                                       dimNT = l+1;
+       if((l+1) > dimNT)
+               dimNT = l+1;
 
         if (lx<minX) minX = lx; if (lx>maxX) maxX = lx;
         if (ly<minY) minY = ly; if (ly>maxY) maxY = ly;
@@ -184,18 +201,19 @@ class XTTorusManager {
     }
 
     ~XTTorusManager() { 
-                       int i,j,k;
-                       free(pid2coords); 
-                       for(i=0; i<xDIM; i++) {
-                               for(j=0; j<yDIM; j++) {
-                                       for(k=0; k<zDIM; k++) {
-                                               free(coords2pid[i][j][k]);
-                                       }
-                                       free(coords2pid[i][j]);
-                               }
-                               free(coords2pid[i]);
+       int i,j,k;
+       free(pid2coords); 
+       for(i=0; i<xDIM; i++) {
+               for(j=0; j<yDIM; j++) {
+                       for(k=0; k<zDIM; k++) {
+                               free(coords2pid[i][j][k]);
                        }
+                       free(coords2pid[i][j]);
                }
+               free(coords2pid[i]);
+       }
+        free(coords2pid);
+    }
 
     inline int getDimX() { return dimX; }
     inline int getDimY() { return dimY; }