31 static const char rcsid[] = 
"$Id: layout.cpp 1145 2014-09-16 09:27:22Z namekawa $";
 
   35   static int pe_logical_layout(
const int ndim, 
const int *dims, 
int nproc, 
int *npe);
 
   36   static int find_primes(
const int n, 
int *p);
 
   69   return m_grid_dims[idir];
 
   75   for (
int i = 0; i < 
m_ndim; ++i) {
 
   76     dims[i] = m_grid_dims[i];
 
   85   return 2 * 
m_ndim * rank + idir + ((ipm > 0) ? 0 : 
m_ndim);
 
  102   m_grid_dims = 
new int [
m_ndim];
 
  110   int *local_dims = 
new int [
m_ndim];
 
  117   for (
int i = 0; i < 
m_ndim; ++i) {
 
  118     if (local_dims[i] != 0) {  
 
  119       if (m_grid_dims[i] != 0) {
 
  120         if (m_grid_dims[i] * local_dims[i] != m_dims[i]) {
 
  121           fprintf(stderr, 
"layout mismatch.\n");
 
  127         if (m_dims[i] % local_dims[i] != 0) {
 
  128           fprintf(stderr, 
"layout mismatch. lattice undivisable by local volume.\n");
 
  131           m_grid_dims[i] = m_dims[i] / local_dims[i];
 
  138   int retv = pe_logical_layout(m_ndim, m_dims, 
m_grid_size, m_grid_dims);
 
  141     fprintf(stderr, 
"layout failed.\n");
 
  146   physical_map_setup();
 
  149   m_grid_coord = 
new int [
m_ndim];
 
  153   m_ipe_up = 
new int [
m_ndim];
 
  154   m_ipe_dn = 
new int [
m_ndim];
 
  156   int *coord = 
new int [
m_ndim];
 
  157   for (
int i = 0; i < 
m_ndim; ++i) {
 
  158     for (
int j = 0; j < 
m_ndim; ++j) {
 
  159       coord[j] = m_grid_coord[j];
 
  163     coord[i] = (m_grid_coord[i] + 1) % m_grid_dims[i];
 
  164     grid_rank(&m_ipe_up[i], coord);
 
  167     coord[i] = (m_grid_coord[i] - 1 + m_grid_dims[i]) % m_grid_dims[i];
 
  168     grid_rank(&m_ipe_dn[i], coord);
 
  174   printf(
"rank %d: up=(%d,%d,%d,%d), dn=(%d,%d,%d,%d)\n",
 
  176          m_ipe_up[0], m_ipe_up[1], m_ipe_up[2], m_ipe_up[3],
 
  177          m_ipe_dn[0], m_ipe_dn[1], m_ipe_dn[2], m_ipe_dn[3]);
 
  192   physical_map_delete();
 
  195   delete [] m_grid_dims;
 
  196   delete [] m_grid_coord;
 
  209   static const int prime_table[] =
 
  211     2,     3,   5,   7,  11,  13,  17,  19,
 
  212     23,   29,  31,  37,  41,  43,  47,  53,
 
  213     59,   61,  67,  71,  73,  79,  83,  89,
 
  214     97,  101, 103, 107, 109, 113, 127, 131,
 
  215     137, 139, 149, 151, 157, 163, 167, 173,
 
  216     179, 181, 191, 193, 197, 199, 211, 223,
 
  217     227, 229, 233, 239, 241, 251, 257, 263,
 
  218     269, 271, 277, 281, 283, 293, 307, 311,
 
  221   static const int nprime = 
sizeof(prime_table) / 
sizeof(
int);
 
  226   static int pe_logical_layout(
const int ndim, 
const int *dims, 
int nproc, 
int *npe)
 
  231     int nfreeproc = nproc;
 
  233     for (
int i = 0; i < ndim; ++i) {
 
  238           fprintf(stderr, 
"illegal value: npe[%d]=%d.\n", i, npe[i]);
 
  240         } 
else if (nproc % npe[i] != 0) {
 
  241           fprintf(stderr, 
"illegal value: npe[%d]=%d does not divide NPE=%d.\n", i, npe[i], nproc);
 
  243         } 
else if (nfreeproc % npe[i] != 0) {
 
  244           fprintf(stderr, 
"illegal value: NPE=%d is not divisable by %d.\n", nproc, nproc / nfreeproc * npe[i]);
 
  246         } 
else if (dims[i] % npe[i] != 0) {
 
  247           fprintf(stderr, 
"illegal value: npe[%d]=%d does not divide L=%d.\n", i, npe[i], dims[i]);
 
  256       fprintf(stderr, 
"impossible layout.\n");
 
  258     } 
else if (nfreeproc == 1) {
 
  259       for (
int i = 0; i < ndim; ++i) {
 
  260         if (npe[i] == 0) npe[i] = 1;
 
  265         fprintf(stderr, 
"impossible layout. no room to divide.\n");
 
  273     int *subdims = 
new int [ndim];
 
  275     for (
int i = 0; i < ndim; ++i) {
 
  276       if (npe[i] == 0) subdims[nf++] = dims[i]; }
 
  278     int *count = 
new int [nprime];
 
  279     for (
int i = 0; i < nprime; ++i) {
 
  283     for (
int i = 0; i < nprime; ++i) {
 
  284       int p = prime_table[i];
 
  285       while (np > 1 && np % p == 0)
 
  300       fprintf(stderr, 
"insufficient prime table.\n");
 
  311     for (
int i = nprime - 1; i >= 0; --i) {
 
  312       if (count[i] == 0) 
continue;
 
  314       int p = prime_table[i];
 
  316       for (
int j = 0; j < count[i]; ++j) {
 
  319         for (
int k = 0; k < nf; ++k) {
 
  320           if ((subdims[k] >= maxsubdim) && (subdims[k] % p == 0)) {
 
  321             maxsubdim = subdims[k];
 
  328           fprintf(stderr, 
"not divisable. %d\n", p);
 
  345     for (
int i = 0, k = 0; i < ndim; ++i) {
 
  347         npe[i] = dims[i] / subdims[k];
 
  361   static int find_primes(
const int n, 
int *p)
 
  373       for (j = 0; j < i; ++j) {
 
  374         if (k % p[j] == 0) 
break;
 
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 const char rcsid[]
 
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.