add a function to return Cray XE dimensions
[charm.git] / src / util / CrayNid.c
1 /** \file CrayNid.c
2  *  Author: Abhinav S Bhatele
3  *  Date created: October 10th, 2007  
4  *  
5  *  This file is needed because including the cnos_mpi_os.h in a C++ leads 
6  *  to a compiler error. Hence we have defined a wrapper function here which
7  *  can be called from C++ files
8  */
9
10 #include <stdlib.h>
11 #include "converse.h"
12
13 #if CMK_CRAYXT || CMK_CRAYXE
14
15 #if XT3_TOPOLOGY
16 #include <catamount/cnos_mpi_os.h>
17 #define MAXNID 2784
18 #define TDIM 2
19
20 #else   /* if it is a XT4/5 */
21 #include <pmi.h>
22 #endif
23
24 /** \function getXTNodeID
25  *  returns nodeID corresponding to the MPI rank (possibly obtained
26  *  from CmiMyNode()/CmiNodeOf(pe)) passed to it
27  */
28 int getXTNodeID(int mpirank, int nummpiranks) {
29   int nid = -1;
30
31 #if XT3_TOPOLOGY
32   cnos_nidpid_map_t *nidpid; 
33   int ierr;
34   
35   nidpid = (cnos_nidpid_map_t *)malloc(sizeof(cnos_nidpid_map_t) * nummpiranks);
36
37   ierr = cnos_get_nidpid_map(&nidpid);
38   nid = nidpid[mpirank].nid;
39   /* free(nidpid); */
40
41 #elif CMK_HAS_PMI_GET_NID       /* if it is a XT4/5 */
42   PMI_Get_nid(mpirank, &nid);
43 #else
44 #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"
45 #endif
46
47   return nid;
48 }
49
50 #endif /* CMK_CRAYXT || CMK_CRAYXE */
51
52 #if XT3_TOPOLOGY || XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
53
54 #if !CMK_HAS_RCALIB
55 #error "The Cray rca library is not available. Try 'module load rca' and rebuild"
56 #endif
57
58 #include <rca_lib.h>
59
60   #if XT4_TOPOLOGY
61   #define MAXNID 14000
62   #define TDIM 4
63
64   #elif XT5_TOPOLOGY
65   #define MAXNID 22020
66   #define TDIM 12
67
68   #elif XE6_TOPOLOGY
69     /* hopper */
70   #define MAXNID 6384
71   #define TDIM 24
72 #if 0
73     /* ESS */
74   #define MAXNID 4608
75   #define TDIM 32
76     /* JYC */
77   #define MAXNID 83
78   #define TDIM 32
79 #endif
80   #endif
81
82 int *pid2nid;                   /* rank to node ID */
83 int nid2pid[MAXNID][TDIM];      /* node ID to rank */
84
85 /** \function getMeshCoord
86  *  wrapper function for rca_get_meshcoord
87  */
88 int getMeshCoord(int nid, int *x, int *y, int *z) {
89   rca_mesh_coord_t xyz;
90   rca_get_meshcoord(nid, &xyz);
91   *x = xyz.mesh_x;
92   *y = xyz.mesh_y;
93   *z = xyz.mesh_z;
94 }
95
96 /** \function pidtonid
97  *  finds nids for pids 1 to CmiNumPes and stores them in an array
98  *  correspondingly also creates an array for nids to pids
99  */
100 void pidtonid(int numpes) {
101 #if XT3_TOPOLOGY
102   cnos_nidpid_map_t *nidpid; 
103   int ierr, i, j, nid;
104   
105   nidpid = (cnos_nidpid_map_t *)malloc(sizeof(cnos_nidpid_map_t) * numpes);
106   pid2nid = (int *)malloc(sizeof(int) * numpes);
107
108   for(i=0; i<MAXNID; i++) {
109     nid2pid[i][0] = -1;
110     nid2pid[i][1] = -1;
111   }
112       
113   ierr = cnos_get_nidpid_map(&nidpid);
114   for(i=0; i<numpes; i++) {
115     nid = nidpid[i].nid;
116     pid2nid[i] = nid;
117     
118     /* if the first position on the node is not filled */
119     /* put it there (0) else at (1) */
120     if (nid2pid[nid][0] == -1)
121       nid2pid[nid][0] = i;
122     else
123       nid2pid[nid][1] = i;
124   }
125   /* free(nidpid); */
126
127   /* CORRECTION FOR MPICH_RANK_REORDER_METHOD */
128
129   int k = -1;
130   for(i=0; i<MAXNID; i++) {
131     if(nid2pid[i][0] != -1) {
132       nid2pid[i][0] = k++;
133       pid2nid[k] = i;
134       nid2pid[i][1] = k++;
135       pid2nid[k] = i;
136     }
137   }
138   
139 #elif XT4_TOPOLOGY || XT5_TOPOLOGY || XE6_TOPOLOGY
140   int i, l, nid;
141   pid2nid = (int *)malloc(sizeof(int) * numpes);
142
143   for(i=0; i<MAXNID; i++)
144     for(l=0; l<TDIM; l++)
145       nid2pid[i][l] = -1;
146
147   for (i=0; i<numpes; i++) {
148     PMI_Get_nid(i, &nid);
149     pid2nid[i] = nid;
150
151     l = 0;
152     while(nid2pid[nid][l] != -1)
153       l++;
154     nid2pid[nid][l] = i;
155   }
156 #endif
157 }
158
159 /* get dimension for XE machine */
160 void getDimension(int maxnid, int *xdim, int *ydim, int *zdim)
161 {
162   int i;
163
164   *xdim = *ydim = *zdim = 0;
165   for (i=0; i<maxnid; i++) {
166       int x, y, z;
167       getMeshCoord(i, &x, &y, &z);
168       if (x>*xdim) *xdim = x;
169       if (y>*ydim) *ydim = y;
170       if (z>*zdim) *zdim = z;
171   }
172   *xdim++;
173   *ydim++;
174   *zdim++;
175 }
176
177 #endif /* XT3_TOPOLOGY || XT4_TOPOLOGY || XT5_TOPOLOGY */