25 static int pe_logical_layout(
const int ndim,
const int *dims,
int nproc,
int *npe);
26 static int find_primes(
const int n,
int *p);
59 return m_grid_dims[idir];
66 for (
int i = 0; i < m_ndim; ++i) {
67 dims[i] = m_grid_dims[i];
77 return 2 * m_ndim * rank + idir + ((ipm > 0) ? 0 : m_ndim);
87 m_dims =
new int [m_ndim];
95 m_grid_dims =
new int [m_ndim];
103 int *local_dims =
new int [m_ndim];
110 for (
int i = 0; i < m_ndim; ++i) {
111 if (local_dims[i] != 0) {
112 if (m_grid_dims[i] != 0) {
113 if (m_grid_dims[i] * local_dims[i] != m_dims[i]) {
114 fprintf(stderr,
"layout mismatch.\n");
120 if (m_dims[i] % local_dims[i] != 0) {
121 fprintf(stderr,
"layout mismatch. lattice undivisable by local volume.\n");
124 m_grid_dims[i] = m_dims[i] / local_dims[i];
131 int retv = pe_logical_layout(m_ndim, m_dims,
m_grid_size, m_grid_dims);
133 if (retv != EXIT_SUCCESS) {
134 fprintf(stderr,
"layout failed.\n");
139 physical_map_setup();
142 m_grid_coord =
new int [m_ndim];
146 m_ipe_up =
new int [m_ndim];
147 m_ipe_dn =
new int [m_ndim];
149 int *coord =
new int [m_ndim];
150 for (
int i = 0; i < m_ndim; ++i) {
151 for (
int j = 0; j < m_ndim; ++j) {
152 coord[j] = m_grid_coord[j];
156 coord[i] = (m_grid_coord[i] + 1) % m_grid_dims[i];
157 grid_rank(&m_ipe_up[i], coord);
160 coord[i] = (m_grid_coord[i] - 1 + m_grid_dims[i]) % m_grid_dims[i];
161 grid_rank(&m_ipe_dn[i], coord);
167 printf(
"rank %d: up=(%d,%d,%d,%d), dn=(%d,%d,%d,%d)\n",
169 m_ipe_up[0], m_ipe_up[1], m_ipe_up[2], m_ipe_up[3],
170 m_ipe_dn[0], m_ipe_dn[1], m_ipe_dn[2], m_ipe_dn[3]);
186 physical_map_delete();
189 delete [] m_grid_dims;
190 delete [] m_grid_coord;
204 static const int prime_table[] =
206 2, 3, 5, 7, 11, 13, 17, 19,
207 23, 29, 31, 37, 41, 43, 47, 53,
208 59, 61, 67, 71, 73, 79, 83, 89,
209 97, 101, 103, 107, 109, 113, 127, 131,
210 137, 139, 149, 151, 157, 163, 167, 173,
211 179, 181, 191, 193, 197, 199, 211, 223,
212 227, 229, 233, 239, 241, 251, 257, 263,
213 269, 271, 277, 281, 283, 293, 307, 311,
216 static const int nprime =
sizeof(prime_table) /
sizeof(
int);
221 static int pe_logical_layout(
const int ndim,
const int *dims,
int nproc,
int *npe)
223 int retv = EXIT_SUCCESS;
226 int nfreeproc = nproc;
228 for (
int i = 0; i < ndim; ++i) {
233 fprintf(stderr,
"illegal value: npe[%d]=%d.\n", i, npe[i]);
235 }
else if (nproc % npe[i] != 0) {
236 fprintf(stderr,
"illegal value: npe[%d]=%d does not divide NPE=%d.\n", i, npe[i], nproc);
238 }
else if (nfreeproc % npe[i] != 0) {
239 fprintf(stderr,
"illegal value: NPE=%d is not divisable by %d.\n", nproc, nproc / nfreeproc * npe[i]);
241 }
else if (dims[i] % npe[i] != 0) {
242 fprintf(stderr,
"illegal value: npe[%d]=%d does not divide L=%d.\n", i, npe[i], dims[i]);
251 fprintf(stderr,
"impossible layout.\n");
253 }
else if (nfreeproc == 1) {
254 for (
int i = 0; i < ndim; ++i) {
255 if (npe[i] == 0) npe[i] = 1;
260 fprintf(stderr,
"impossible layout. no room to divide.\n");
268 int *subdims =
new int [ndim];
270 for (
int i = 0; i < ndim; ++i) {
271 if (npe[i] == 0) subdims[nf++] = dims[i]; }
273 int *count =
new int [nprime];
274 for (
int i = 0; i < nprime; ++i) {
278 for (
int i = 0; i < nprime; ++i) {
279 int p = prime_table[i];
280 while (np > 1 && np % p == 0)
295 fprintf(stderr,
"insufficient prime table.\n");
306 for (
int i = nprime - 1; i >= 0; --i) {
307 if (count[i] == 0)
continue;
309 int p = prime_table[i];
311 for (
int j = 0; j < count[i]; ++j) {
314 for (
int k = 0; k < nf; ++k) {
315 if ((subdims[k] >= maxsubdim) && (subdims[k] % p == 0)) {
316 maxsubdim = subdims[k];
323 fprintf(stderr,
"not divisable. %d\n", p);
340 for (
int i = 0, k = 0; i < ndim; ++i) {
342 npe[i] = dims[i] / subdims[k];
356 static int find_primes(
const int n,
int *p)
358 if (n < 1)
return EXIT_FAILURE;
368 for (j = 0; j < i; ++j) {
369 if (k % p[j] == 0)
break;
374 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 npe(const int idir)
static int grid_dims(int *gdims)
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.