16 static const char rcsid[] =
"$Id: layout.cpp 942 2013-07-22 06:50:06Z aoym $";
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];
140 int retv = pe_logical_layout(m_ndim, m_dims,
m_grid_size, m_grid_dims);
142 if (retv != EXIT_SUCCESS) {
143 fprintf(stderr,
"layout failed.\n");
148 physical_map_setup();
151 m_grid_coord =
new int [
m_ndim];
155 m_ipe_up =
new int [
m_ndim];
156 m_ipe_dn =
new int [
m_ndim];
158 int *coord =
new int [
m_ndim];
159 for (
int i = 0; i <
m_ndim; ++i) {
160 for (
int j = 0; j <
m_ndim; ++j) {
161 coord[j] = m_grid_coord[j];
165 coord[i] = (m_grid_coord[i] + 1) % m_grid_dims[i];
166 grid_rank(&m_ipe_up[i], coord);
169 coord[i] = (m_grid_coord[i] - 1 + m_grid_dims[i]) % m_grid_dims[i];
170 grid_rank(&m_ipe_dn[i], coord);
176 printf(
"rank %d: up=(%d,%d,%d,%d), dn=(%d,%d,%d,%d)\n",
178 m_ipe_up[0], m_ipe_up[1], m_ipe_up[2], m_ipe_up[3],
179 m_ipe_dn[0], m_ipe_dn[1], m_ipe_dn[2], m_ipe_dn[3]);
194 physical_map_delete();
197 delete [] m_grid_dims;
198 delete [] m_grid_coord;
210 m_sub_comm =
new MPI_Comm [(1 <<
m_ndim)];
212 for (
int imask = 0; imask < (1 <<
m_ndim); ++imask) {
214 for (
int i = 0; i <
m_ndim; ++i) {
215 coord[i] = m_grid_coord[i];
218 for (
int i = 0; i <
m_ndim; ++i) {
219 bool mask = ((imask >> i) & 1) == 1 ?
true :
false;
220 if (!mask) coord[i] = 0;
224 grid_rank(coord, &rank);
234 MPI_Comm_split(
m_comm, rank, 0 , &m_sub_comm[imask]);
243 delete [] m_sub_comm;
251 static const int prime_table[] =
253 2, 3, 5, 7, 11, 13, 17, 19,
254 23, 29, 31, 37, 41, 43, 47, 53,
255 59, 61, 67, 71, 73, 79, 83, 89,
256 97, 101, 103, 107, 109, 113, 127, 131,
257 137, 139, 149, 151, 157, 163, 167, 173,
258 179, 181, 191, 193, 197, 199, 211, 223,
259 227, 229, 233, 239, 241, 251, 257, 263,
260 269, 271, 277, 281, 283, 293, 307, 311,
263 static const int nprime =
sizeof(prime_table) /
sizeof(
int);
268 static int pe_logical_layout(
const int ndim,
const int *dims,
int nproc,
int *npe)
270 int retv = EXIT_SUCCESS;
273 int nfreeproc = nproc;
275 for (
int i = 0; i < ndim; ++i) {
280 fprintf(stderr,
"illegal value: npe[%d]=%d.\n", i, npe[i]);
282 }
else if (nproc % npe[i] != 0) {
283 fprintf(stderr,
"illegal value: npe[%d]=%d does not divide NPE=%d.\n", i, npe[i], nproc);
285 }
else if (nfreeproc % npe[i] != 0) {
286 fprintf(stderr,
"illegal value: NPE=%d is not divisable by %d.\n", nproc, nproc / nfreeproc * npe[i]);
288 }
else if (dims[i] % npe[i] != 0) {
289 fprintf(stderr,
"illegal value: npe[%d]=%d does not divide L=%d.\n", i, npe[i], dims[i]);
298 fprintf(stderr,
"impossible layout.\n");
300 }
else if (nfreeproc == 1) {
301 for (
int i = 0; i < ndim; ++i) {
302 if (npe[i] == 0) npe[i] = 1;
307 fprintf(stderr,
"impossible layout. no room to divide.\n");
315 int *subdims =
new int [ndim];
317 for (
int i = 0; i < ndim; ++i) {
318 if (npe[i] == 0) subdims[nf++] = dims[i]; }
320 int *count =
new int [nprime];
321 for (
int i = 0; i < nprime; ++i) {
325 for (
int i = 0; i < nprime; ++i) {
326 int p = prime_table[i];
327 while (np > 1 && np % p == 0)
342 fprintf(stderr,
"insufficient prime table.\n");
353 for (
int i = nprime - 1; i >= 0; --i) {
354 if (count[i] == 0)
continue;
356 int p = prime_table[i];
358 for (
int j = 0; j < count[i]; ++j) {
361 for (
int k = 0; k < nf; ++k) {
362 if ((subdims[k] >= maxsubdim) && (subdims[k] % p == 0)) {
363 maxsubdim = subdims[k];
370 fprintf(stderr,
"not divisable. %d\n", p);
387 for (
int i = 0, k = 0; i < ndim; ++i) {
389 npe[i] = dims[i] / subdims[k];
403 static int find_primes(
const int n,
int *p)
405 if (n < 1)
return EXIT_FAILURE;
415 for (j = 0; j < i; ++j) {
416 if (k % p[j] == 0)
break;
421 if (i >= n)
return EXIT_FAILURE;