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];
129 delete [] local_dims;
132 int retv = pe_logical_layout(m_ndim, m_dims,
m_grid_size, m_grid_dims);
134 if (retv != EXIT_SUCCESS) {
135 fprintf(stderr,
"layout failed.\n");
140 physical_map_setup();
143 m_grid_coord =
new int [m_ndim];
147 m_ipe_up =
new int [m_ndim];
148 m_ipe_dn =
new int [m_ndim];
150 int *coord =
new int [m_ndim];
151 for (
int i = 0; i < m_ndim; ++i) {
152 for (
int j = 0; j < m_ndim; ++j) {
153 coord[j] = m_grid_coord[j];
157 coord[i] = (m_grid_coord[i] + 1) % m_grid_dims[i];
158 grid_rank(&m_ipe_up[i], coord);
161 coord[i] = (m_grid_coord[i] - 1 + m_grid_dims[i]) % m_grid_dims[i];
162 grid_rank(&m_ipe_dn[i], coord);
168 printf(
"rank %d: up=(%d,%d,%d,%d), dn=(%d,%d,%d,%d)\n",
170 m_ipe_up[0], m_ipe_up[1], m_ipe_up[2], m_ipe_up[3],
171 m_ipe_dn[0], m_ipe_dn[1], m_ipe_dn[2], m_ipe_dn[3]);
187 physical_map_delete();
190 delete [] m_grid_dims;
191 delete [] m_grid_coord;
205 static const int prime_table[] =
207 2, 3, 5, 7, 11, 13, 17, 19,
208 23, 29, 31, 37, 41, 43, 47, 53,
209 59, 61, 67, 71, 73, 79, 83, 89,
210 97, 101, 103, 107, 109, 113, 127, 131,
211 137, 139, 149, 151, 157, 163, 167, 173,
212 179, 181, 191, 193, 197, 199, 211, 223,
213 227, 229, 233, 239, 241, 251, 257, 263,
214 269, 271, 277, 281, 283, 293, 307, 311,
217 static const int nprime =
sizeof(prime_table) /
sizeof(
int);
222 static int pe_logical_layout(
const int ndim,
const int *dims,
int nproc,
int *npe)
224 int retv = EXIT_SUCCESS;
227 int nfreeproc = nproc;
229 for (
int i = 0; i < ndim; ++i) {
234 fprintf(stderr,
"illegal value: npe[%d]=%d.\n", i, npe[i]);
236 }
else if (nproc % npe[i] != 0) {
237 fprintf(stderr,
"illegal value: npe[%d]=%d does not divide NPE=%d.\n", i, npe[i], nproc);
239 }
else if (nfreeproc % npe[i] != 0) {
240 fprintf(stderr,
"illegal value: NPE=%d is not divisable by %d.\n", nproc, nproc / nfreeproc * npe[i]);
242 }
else if (dims[i] % npe[i] != 0) {
243 fprintf(stderr,
"illegal value: npe[%d]=%d does not divide L=%d.\n", i, npe[i], dims[i]);
252 fprintf(stderr,
"impossible layout.\n");
254 }
else if (nfreeproc == 1) {
255 for (
int i = 0; i < ndim; ++i) {
256 if (npe[i] == 0) npe[i] = 1;
261 fprintf(stderr,
"impossible layout. no room to divide.\n");
269 int *subdims =
new int [ndim];
271 for (
int i = 0; i < ndim; ++i) {
272 if (npe[i] == 0) subdims[nf++] = dims[i]; }
274 int *count =
new int [nprime];
275 for (
int i = 0; i < nprime; ++i) {
279 for (
int i = 0; i < nprime; ++i) {
280 int p = prime_table[i];
281 while (np > 1 && np % p == 0)
296 fprintf(stderr,
"insufficient prime table.\n");
307 for (
int i = nprime - 1; i >= 0; --i) {
308 if (count[i] == 0)
continue;
310 int p = prime_table[i];
312 for (
int j = 0; j < count[i]; ++j) {
315 for (
int k = 0; k < nf; ++k) {
316 if ((subdims[k] >= maxsubdim) && (subdims[k] % p == 0)) {
317 maxsubdim = subdims[k];
324 fprintf(stderr,
"not divisable. %d\n", p);
341 for (
int i = 0, k = 0; i < ndim; ++i) {
343 npe[i] = dims[i] / subdims[k];
357 static int find_primes(
const int n,
int *p)
359 if (n < 1)
return EXIT_FAILURE;
369 for (j = 0; j < i; ++j) {
370 if (k % p[j] == 0)
break;
375 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.