00001
00010 #include <stdlib.h>
00011 #include "converse.h"
00012
00013 #if CMK_CRAYXT || CMK_CRAYXE
00014
00015 #if XT3_TOPOLOGY
00016 #include <catamount/cnos_mpi_os.h>
00017
00018 #else
00019 #include <pmi.h>
00020 #endif
00021
00022 CmiNodeLock cray_lock, cray_lock2;
00023
00028 int getXTNodeID(int mpirank, int nummpiranks) {
00029 int nid = -1;
00030
00031 #if XT3_TOPOLOGY
00032 cnos_nidpid_map_t *nidpid;
00033 int ierr;
00034
00035 nidpid = (cnos_nidpid_map_t *)malloc(sizeof(cnos_nidpid_map_t) * nummpiranks);
00036
00037 ierr = cnos_get_nidpid_map(&nidpid);
00038 nid = nidpid[mpirank].nid;
00039 free(nidpid);
00040
00041 #elif CMK_HAS_PMI_GET_NID
00042 PMI_Get_nid(mpirank, &nid);
00043 #else
00044 #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"
00045 #endif
00046
00047 return nid;
00048 }
00049
00050 #endif
00051
00052 #if XT3_TOPOLOGY || XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
00053
00054 #if !CMK_HAS_RCALIB
00055 #error "The Cray rca library is not available. Try 'module load rca' and rebuild"
00056 #endif
00057
00058 #include <rca_lib.h>
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 int *pid2nid = NULL;
00092 int maxX = -1;
00093 int maxY = -1;
00094 int maxZ = -1;
00095 int maxNID = -1;
00096 #if CMK_HAS_RCALIB
00097 rca_mesh_coord_t *coords = NULL;
00098 #endif
00099
00100 void getDimension(int *maxnid, int *xdim, int *ydim, int *zdim);
00101
00106 int getMeshCoord(int nid, int *x, int *y, int *z) {
00107 #if CMK_HAS_RCALIB
00108 if (coords == NULL) {
00109 rca_mesh_coord_t xyz;
00110 int ret = -1;
00111 ret = rca_get_meshcoord(nid, &xyz);
00112 if (ret == -1) return -1;
00113 *x = xyz.mesh_x;
00114 *y = xyz.mesh_y;
00115 *z = xyz.mesh_z;
00116 return ret;
00117 }
00118 else {
00119 *x = coords[nid].mesh_x;
00120 *y = coords[nid].mesh_y;
00121 *z = coords[nid].mesh_z;
00122 return *x==-1?-1:0;
00123 }
00124 #else
00125 CmiAbort("rca_get_meshcoord not exist");
00126 return -1;
00127 #endif
00128 }
00129
00134 void pidtonid(int numpes) {
00135 CmiLock(cray_lock);
00136 if (pid2nid != NULL) {
00137 CmiUnlock(cray_lock);
00138 return;
00139 }
00140
00141 getDimension(&maxNID,&maxX,&maxY,&maxZ);
00142 int numCores = CmiNumCores();
00143
00144 pid2nid = (int *)malloc(sizeof(int) * numpes);
00145
00146 #if XT3_TOPOLOGY
00147 cnos_nidpid_map_t *nidpid;
00148 int ierr, i, nid;
00149 int *nid2pid;
00150
00151 nid2pid = (int*)malloc(maxNID*2*sizeof(int));
00152 nidpid = (cnos_nidpid_map_t *)malloc(sizeof(cnos_nidpid_map_t) * numpes);
00153
00154 for(i=0; i<maxNID; i++) {
00155 nid2pid[2*i+0] = -1;
00156 nid2pid[2*i+1] = -1;
00157 }
00158
00159 ierr = cnos_get_nidpid_map(&nidpid);
00160 for(i=0; i<numpes; i++) {
00161 nid = nidpid[i].nid;
00162 pid2nid[i] = nid;
00163
00164
00165
00166 if (nid2pid[2*nid+0] == -1)
00167 nid2pid[2*nid+0] = i;
00168 else
00169 nid2pid[2*nid+1] = i;
00170 }
00171
00172
00173
00174 int k = -1;
00175 for(i=0; i<maxNID; i++) {
00176 if(nid2pid[2*i+0] != -1) {
00177 nid2pid[2*i+0] = k++;
00178 pid2nid[k] = i;
00179 nid2pid[2*i+1] = k++;
00180 pid2nid[k] = i;
00181 }
00182 }
00183 free(nidpid);
00184 free(nid2pid);
00185
00186 #elif XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
00187 int i, nid, ret;
00188 CmiAssert(coords == NULL);
00189 coords = (rca_mesh_coord_t *)malloc(sizeof(rca_mesh_coord_t)*(maxNID+1));
00190 for (i=0; i<maxNID; i++) {
00191 coords[i].mesh_x = coords[i].mesh_y = coords[i].mesh_z = -1;
00192 }
00193 for (i=0; i<numpes; i++) {
00194 PMI_Get_nid(CmiNodeOf(i), &nid);
00195 pid2nid[i] = nid;
00196 CmiAssert(nid < maxNID);
00197 ret = rca_get_meshcoord(nid, &coords[nid]);
00198 CmiAssert(ret != -1);
00199 }
00200 #endif
00201 CmiUnlock(cray_lock);
00202 }
00203
00204
00205 void getDimension(int *maxnid, int *xdim, int *ydim, int *zdim)
00206 {
00207 int i = 0, ret;
00208 CmiLock(cray_lock2);
00209
00210 if(maxNID != -1) {
00211 *xdim = maxX;
00212 *ydim = maxY;
00213 *zdim = maxZ;
00214 *maxnid = maxNID;
00215 CmiUnlock(cray_lock2);
00216 return;
00217 }
00218
00219 *xdim = *ydim = *zdim = 0;
00220
00221 do {
00222 int x, y, z;
00223 ret = getMeshCoord(i, &x, &y, &z);
00224 if (x>*xdim) *xdim = x;
00225 if (y>*ydim) *ydim = y;
00226 if (z>*zdim) *zdim = z;
00227 i++;
00228 } while (ret == 0);
00229 maxNID = *maxnid = i;
00230 maxX = *xdim = *xdim+1;
00231 maxY = *ydim = *ydim+1;
00232 maxZ = *zdim = *zdim+1;
00233 CmiUnlock(cray_lock2);
00234 }
00235
00236 void craynid_init()
00237 {
00238 if (CmiMyRank()==0) {
00239 cray_lock = CmiCreateLock();
00240 cray_lock2 = CmiCreateLock();
00241
00242 pidtonid(CmiNumPes());
00243 }
00244 }
00245
00246 #endif