| 93 | |
| 94 | #ifdef AMREX_PMI |
| 95 | void PMI_Initialize() |
| 96 | { |
| 97 | int pmi_nid; |
| 98 | pmi_mesh_coord_t pmi_mesh_coord; |
| 99 | int PMI_stat; |
| 100 | int spawned; |
| 101 | int appnum; |
| 102 | int pmi_size = ParallelDescriptor::NProcs(); |
| 103 | int pmi_rank = ParallelDescriptor::MyProc(); |
| 104 | |
| 105 | PMI_stat = PMI2_Init(&spawned, &pmi_size, &pmi_rank, &appnum); |
| 106 | if (PMI_stat != PMI_SUCCESS) { |
| 107 | ParallelDescriptor::Abort(); |
| 108 | } |
| 109 | PMI_stat = PMI_Get_nid(pmi_rank, &pmi_nid); |
| 110 | if (PMI_stat != PMI_SUCCESS) { |
| 111 | ParallelDescriptor::Abort(); |
| 112 | } |
| 113 | PMI_stat = PMI_Get_meshcoord(pmi_nid, &pmi_mesh_coord); |
| 114 | if (PMI_stat != PMI_SUCCESS) { |
| 115 | ParallelDescriptor::Abort(); |
| 116 | } |
| 117 | |
| 118 | // Now each MPI Process knows where it lives in the network mesh. On |
| 119 | // Aries (the interconnect on the Cray XC40), the x-coord indicates the |
| 120 | // electrical group (1 group = 1 pair of adjacent cabinets); the y-coord |
| 121 | // indicates the chassis (3 chassis per cabinet; 6 chassis per group); |
| 122 | // and the z-coord indicates the slot (blade) within each chassis (16 per |
| 123 | // chassis). Each slot contains 4 nodes, so there are at most 64 nodes |
| 124 | // per chassis, 192 per cabinet, and 384 per group. (Usually there are |
| 125 | // fewer than this per cabinet, since cabinets are usually a mixture of |
| 126 | // compute nodes, I/O nodes, service nodes, and other things.) The slots |
| 127 | // within each chassis (same x and y) are connected all-to-all, as are |
| 128 | // slots in the same row across chasses within each group (same x and z). |
| 129 | |
| 130 | // One can use this information apply any kind of optimization we like, |
| 131 | // e.g., splitting MPI processes into separate communicators within which |
| 132 | // all processes are connected all-to-all. The following is a placeholder |
| 133 | // for such an optimization, in which we merely collect the mesh |
| 134 | // coordinates onto the IOProcessor and print the unique number of |
| 135 | // groups, chassis, and slots occupied by the job. (This is a crude |
| 136 | // measure of how fragmented the job is across the network.) |
| 137 | |
| 138 | PMI_PrintMeshcoords(&pmi_mesh_coord); |
| 139 | } |
| 140 | |
| 141 | void PMI_PrintMeshcoords(const pmi_mesh_coord_t *pmi_mesh_coord) { |
| 142 | unsigned short all_x_meshcoords[ParallelDescriptor::NProcs()]; |
no test coverage detected