00001 
00010 #include "topomanager_config.h"
00011 #include <stdlib.h>
00012 #ifndef __TPM_STANDALONE__
00013 #include "converse.h"
00014 #else
00015 #include "tpm_standalone.h"
00016 #endif
00017 
00018 #ifndef CLINKAGE
00019 # ifdef __cplusplus
00020 #  define CLINKAGE extern "C"
00021 # else
00022 #  define CLINKAGE
00023 # endif
00024 #endif
00025 
00026 #if CMK_CRAYXE || CMK_CRAYXC
00027 
00028 #if XT3_TOPOLOGY
00029 #else   
00030 #include <pmi.h>
00031 #endif
00032 
00033 CmiNodeLock  cray_lock, cray_lock2;
00034 
00039 CLINKAGE int getXTNodeID(int mpirank, int nummpiranks)
00040 {
00041   int nid = -1;
00042 
00043 #if CMK_HAS_PMI_GET_NID 
00044   PMI_Get_nid(mpirank, &nid);
00045 #else
00046 #error "Cannot get network topology information on a Cray build. Swap current module xt-mpt with xt-mpt/5.0.0 or higher and xt-asyncpe with xt-asyncpe/4.0 or higher and then rebuild"
00047 #endif
00048 
00049   return nid;
00050 }
00051 
00052 #endif 
00053 
00054 #if XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
00055 
00056 #if !CMK_HAS_RCALIB
00057 #error "The Cray rca library is not available. Try 'module load rca' and rebuild"
00058 #endif
00059 
00060 #ifdef __cplusplus
00061 extern "C" {
00062 #endif
00063 #include <rca_lib.h>
00064 #ifdef __cplusplus
00065 }
00066 #endif
00067 
00068 int *pid2nid = NULL;            
00069 int maxX = -1;
00070 int maxY = -1;
00071 int maxZ = -1;
00072 int maxNID = -1;
00073 #if CMK_HAS_RCALIB
00074 rca_mesh_coord_t  *rca_coords = NULL;
00075 #endif
00076 
00077 CLINKAGE void getDimension(int *maxnid, int *xdim, int *ydim, int *zdim);
00078 
00083 CLINKAGE int getMeshCoord(int nid, int *x, int *y, int *z)
00084 {
00085 #if CMK_HAS_RCALIB
00086   if (rca_coords == NULL) {
00087   rca_mesh_coord_t xyz;
00088   int ret = -1;
00089   ret = rca_get_meshcoord(nid, &xyz);
00090   if (ret == -1) return -1;
00091   *x = xyz.mesh_x;
00092   *y = xyz.mesh_y;
00093   *z = xyz.mesh_z;
00094   return ret;
00095   }
00096   else {
00097   *x = rca_coords[nid].mesh_x;
00098   *y = rca_coords[nid].mesh_y;
00099   *z = rca_coords[nid].mesh_z;
00100   return *x==-1?-1:0;
00101   }
00102 #else
00103   CmiAbort("rca_get_meshcoord does not exist");
00104   return -1;
00105 #endif
00106 }
00107 
00112 CLINKAGE void pidtonid(int numpes)
00113 {
00114   CmiLock(cray_lock);
00115   if (pid2nid != NULL) {
00116       CmiUnlock(cray_lock);
00117       return;          
00118   }
00119 
00120   getDimension(&maxNID,&maxX,&maxY,&maxZ);
00121   
00122   pid2nid = (int *)malloc(sizeof(int) * numpes);
00123 
00124 #if XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
00125   int i, nid, ret;
00126   CmiAssert(rca_coords == NULL);
00127   rca_coords = (rca_mesh_coord_t *)malloc(sizeof(rca_mesh_coord_t)*(maxNID+1));
00128   for (i=0; i<maxNID; i++) {
00129     rca_coords[i].mesh_x = rca_coords[i].mesh_y = rca_coords[i].mesh_z = -1;
00130   }
00131   for (i=0; i<numpes; i++) {
00132     PMI_Get_nid(CmiGetNodeGlobal(CmiNodeOf(i),CmiMyPartition()), &nid);
00133     pid2nid[i] = nid;
00134     CmiAssert(nid < maxNID);
00135     ret = rca_get_meshcoord(nid, &rca_coords[nid]);
00136     CmiAssert(ret != -1);
00137   }
00138 #endif
00139   CmiUnlock(cray_lock);
00140 }
00141 
00142 
00143 CLINKAGE void getDimension(int *maxnid, int *xdim, int *ydim, int *zdim)
00144 {
00145   int i = 0, nid, ret;
00146   rca_mesh_coord_t dimsize;
00147 
00148   CmiLock(cray_lock2);
00149 
00150   if(maxNID != -1) {
00151     *xdim = maxX;
00152     *ydim = maxY;
00153     *zdim = maxZ;
00154     *maxnid = maxNID;
00155         CmiUnlock(cray_lock2);
00156     return;
00157   }
00158 
00159 #if CMK_HAS_RCA_MAX_DIMENSION
00160   
00161   rca_get_max_dimension(&dimsize);
00162   maxX = *xdim = dimsize.mesh_x+1;
00163   maxY = *ydim = dimsize.mesh_y+1;
00164   maxZ = *zdim = dimsize.mesh_z+1;
00165   maxNID = 0;
00166 
00167   for(i = 0; i < CmiNumNodesGlobal(); i++) {
00168     PMI_Get_nid(i, &nid);
00169     if(nid >= maxNID) maxNID = nid + 1;
00170   }
00171   *maxnid = maxNID;
00172 
00173 #else
00174 
00175   *xdim = *ydim = *zdim = 0;
00176      
00177   do {
00178       int x, y, z;
00179       ret = getMeshCoord(i, &x, &y, &z);
00180       if (ret == -1) {
00181 #if CMK_CRAY_MAXNID
00182           if (i<=CMK_CRAY_MAXNID) {
00183               i++;
00184               ret = 0;
00185               continue;
00186           }
00187 #endif
00188           break;
00189       }
00190       if (x>*xdim) *xdim = x;
00191       if (y>*ydim) *ydim = y;
00192       if (z>*zdim) *zdim = z;
00193       i++;
00194   } while (ret == 0);
00195   maxNID = *maxnid = i;
00196   maxX = *xdim = *xdim+1;
00197   maxY = *ydim = *ydim+1;
00198   maxZ = *zdim = *zdim+1;
00199 #endif
00200 
00201   CmiUnlock(cray_lock2);
00202 
00203   
00204 }
00205 
00206 CLINKAGE void craynid_free(void)
00207 {
00208   CmiLock(cray_lock);
00209   free(pid2nid);
00210   pid2nid = NULL;
00211 #if CMK_HAS_RCALIB
00212   free(rca_coords);
00213   rca_coords = NULL;
00214 #endif
00215   CmiUnlock(cray_lock);
00216 }
00217 
00218 CLINKAGE void craynid_reset(void)
00219 {
00220   craynid_free();
00221   CmiLock(cray_lock);
00222   maxX = -1;
00223   maxY = -1;
00224   maxZ = -1;
00225   maxNID = -1;
00226   CmiUnlock(cray_lock);
00227 }
00228 
00229 CLINKAGE void craynid_init(void)
00230 {
00231   static int init_done = 0;
00232   if (!init_done) {
00233     cray_lock = CmiCreateLock();
00234     cray_lock2 = CmiCreateLock();
00235     init_done = 1;
00236   }
00237 }
00238 
00239 #endif