20 static int pe_logical_layout(
const int ndim,
const int *dims,
int nproc,
int *npe);
21 static int find_primes(
const int n,
int *p);
53 return m_grid_dims[idir];
59 for (
int i = 0; i <
m_ndim; ++i) {
60 dims[i] = m_grid_dims[i];
69 return 2 *
m_ndim * rank + idir + ((ipm > 0) ? 0 :
m_ndim);
104 m_grid_dims =
new int [
m_ndim];
112 int *local_dims =
new int [
m_ndim];
119 for (
int i = 0; i <
m_ndim; ++i) {
120 if (local_dims[i] != 0) {
121 if (m_grid_dims[i] != 0) {
122 if (m_grid_dims[i] * local_dims[i] != m_dims[i]) {
123 fprintf(stderr,
"layout mismatch.\n");
129 if (m_dims[i] % local_dims[i] != 0) {
130 fprintf(stderr,
"layout mismatch. lattice undivisable by local volume.\n");
133 m_grid_dims[i] = m_dims[i] / local_dims[i];
139 delete [] local_dims;
143 int retv = pe_logical_layout(m_ndim, m_dims,
m_grid_size, m_grid_dims);
145 if (retv != EXIT_SUCCESS) {
146 fprintf(stderr,
"layout failed.\n");
151 physical_map_setup();
154 m_grid_coord =
new int [
m_ndim];
158 m_ipe_up =
new int [
m_ndim];
159 m_ipe_dn =
new int [
m_ndim];
161 int *coord =
new int [
m_ndim];
162 for (
int i = 0; i <
m_ndim; ++i) {
163 for (
int j = 0; j <
m_ndim; ++j) {
164 coord[j] = m_grid_coord[j];
168 coord[i] = (m_grid_coord[i] + 1) % m_grid_dims[i];
169 grid_rank(&m_ipe_up[i], coord);
172 coord[i] = (m_grid_coord[i] - 1 + m_grid_dims[i]) % m_grid_dims[i];
173 grid_rank(&m_ipe_dn[i], coord);
179 printf(
"rank %d: up=(%d,%d,%d,%d), dn=(%d,%d,%d,%d)\n",
181 m_ipe_up[0], m_ipe_up[1], m_ipe_up[2], m_ipe_up[3],
182 m_ipe_dn[0], m_ipe_dn[1], m_ipe_dn[2], m_ipe_dn[3]);
196 physical_map_delete();
199 delete [] m_grid_dims;
200 delete [] m_grid_coord;
217 m_sub_comm =
new MPI_Comm [Nmask];
219 for (
int imask = 0; imask < Nmask; ++imask) {
221 for (
int i = 0; i <
m_ndim; ++i) {
222 coord[i] = m_grid_coord[i];
225 for (
int i = 0; i <
m_ndim; ++i) {
226 bool mask = ((imask >> i) & 1) == 1 ?
true :
false;
227 if (!mask) coord[i] = 0;
231 grid_rank(&rank, coord);
241 MPI_Comm_split(
m_comm, rank, 0 , &m_sub_comm[imask]);
250 delete [] m_sub_comm;
258 static const int prime_table[] =
260 2, 3, 5, 7, 11, 13, 17, 19,
261 23, 29, 31, 37, 41, 43, 47, 53,
262 59, 61, 67, 71, 73, 79, 83, 89,
263 97, 101, 103, 107, 109, 113, 127, 131,
264 137, 139, 149, 151, 157, 163, 167, 173,
265 179, 181, 191, 193, 197, 199, 211, 223,
266 227, 229, 233, 239, 241, 251, 257, 263,
267 269, 271, 277, 281, 283, 293, 307, 311,
270 static const int nprime =
sizeof(prime_table) /
sizeof(
int);
275 static int pe_logical_layout(
const int ndim,
const int *dims,
int nproc,
int *npe)
277 int retv = EXIT_SUCCESS;
280 int nfreeproc = nproc;
282 for (
int i = 0; i < ndim; ++i) {
287 fprintf(stderr,
"illegal value: npe[%d]=%d.\n", i, npe[i]);
289 }
else if (nproc % npe[i] != 0) {
290 fprintf(stderr,
"illegal value: npe[%d]=%d does not divide NPE=%d.\n", i, npe[i], nproc);
292 }
else if (nfreeproc % npe[i] != 0) {
293 fprintf(stderr,
"illegal value: NPE=%d is not divisable by %d.\n", nproc, nproc / nfreeproc * npe[i]);
295 }
else if (dims[i] % npe[i] != 0) {
296 fprintf(stderr,
"illegal value: npe[%d]=%d does not divide L=%d.\n", i, npe[i], dims[i]);
305 fprintf(stderr,
"impossible layout.\n");
307 }
else if (nfreeproc == 1) {
308 for (
int i = 0; i < ndim; ++i) {
309 if (npe[i] == 0) npe[i] = 1;
314 fprintf(stderr,
"impossible layout. no room to divide.\n");
322 int *subdims =
new int [ndim];
324 for (
int i = 0; i < ndim; ++i) {
325 if (npe[i] == 0) subdims[nf++] = dims[i]; }
327 int *count =
new int [nprime];
328 for (
int i = 0; i < nprime; ++i) {
332 for (
int i = 0; i < nprime; ++i) {
333 int p = prime_table[i];
334 while (np > 1 && np % p == 0)
349 fprintf(stderr,
"insufficient prime table.\n");
360 for (
int i = nprime - 1; i >= 0; --i) {
361 if (count[i] == 0)
continue;
363 int p = prime_table[i];
365 for (
int j = 0; j < count[i]; ++j) {
368 for (
int k = 0; k < nf; ++k) {
369 if ((subdims[k] >= maxsubdim) && (subdims[k] % p == 0)) {
370 maxsubdim = subdims[k];
377 fprintf(stderr,
"not divisable. %d\n", p);
394 for (
int i = 0, k = 0; i < ndim; ++i) {
396 npe[i] = dims[i] / subdims[k];
410 static int find_primes(
const int n,
int *p)
412 if (n < 1)
return EXIT_FAILURE;
422 for (j = 0; j < i; ++j) {
423 if (k % p[j] == 0)
break;
428 if (i >= n)
return EXIT_FAILURE;
static int * m_grid_coord
grid coordinate.
static int layout_setup()
layout_setup() – setup logical layout
static int self()
rank within small world.
static int * m_dims
lattice extent (Lx, Ly, Lz, Lt)
static int * m_physical_to_logical
map between physical and logical grid
static int m_ndim
number of dimensions.
static int subgrid_setup()
static int subgrid_delete()
static int npe(const int idir)
static int grid_dims(int *gdims)
static int m_comm
instead of MPI_Comm m_comm;
static int * m_grid_dims
grid dimensions in directions.
static char m_map_grid[16]
static int * m_ipe_up
rank of upward neighbour in directions.
static int ipe(const int idir)
static int tag(int rank, int idir, int ipm)
static int layout_delete()
static int * m_ipe_dn
rank of downward neighbour in directions.