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