7#include "plumbing/lattice.h" 
   13const static int prime[NPRIMES] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
 
   18void lattice_struct::setup_layout() {
 
   19    int nfactors[NPRIMES];
 
   22    hila::print_dashed_line();
 
   23    hila::out0 << 
"LAYOUT: subnode lattice, with " << VECTOR_SIZE / 
sizeof(float) << 
" subnodes\n" 
   24               << 
"Enabling vector length " << VECTOR_SIZE * 8
 
   25               << 
" bits = " << VECTOR_SIZE / 
sizeof(
double) << 
" doubles or " 
   26               << VECTOR_SIZE / 
sizeof(float) << 
" floats/ints\n";
 
   35    hila::out0 << 
"Layout using vector of " << number_of_subnodes << 
" elements\n";
 
   38        hila::out0 << 
"Lattice must be even to all directions for vector/AVX layout.\n" 
   39                   << 
"Use std layout or GPU for odd sizes\n";
 
   55    for (
int n = 0; n < NPRIMES; n++) {
 
   57        while (i % prime[n] == 0) {
 
   64                   << prime[NPRIMES - 1] << 
'\n';
 
   75        int64_t cosize = l_volume / l_size[d];
 
   76        int64_t n = l_size[d];
 
   77        while ((n * cosize) % nn != 0)
 
   80        ghosts[d] = (n - l_size[d]) * cosize;
 
   84    int64_t ghost_volume = 1;
 
   95    bool secondtime = 
false;
 
   99        if (ghost_volume > l_volume) {
 
  101            foralldir(j) 
if (ghosts[gdir] > ghosts[j]) gdir = j;
 
  110            nodesiz[i] = (i == gdir) ? nsize[i] : l_size[i]; 
 
  114        for (
int n = NPRIMES - 1; n >= 0; n--)
 
  115            for (i = 0; i < nfactors[n]; i++) {
 
  126                for (dir = 0; dir < NDIM; dir++) {
 
  127                    if (nodesiz[dir] > msize &&
 
  128                        ((dir == gdir && nodesiz[dir] % prime[n] == 0) ||
 
  129                         (dir != gdir && nodesiz[dir] % (2 * prime[n]) == 0)) &&
 
  130                        nodesiz[dir] / prime[n] > 3) {
 
  131                        msize = nodesiz[dir];
 
  138                    for (dir = 0; dir < NDIM; dir++) {
 
  139                        if (nodesiz[dir] > msize && dir != gdir && nodesiz[dir] % (prime[n]) == 0) {
 
  140                            msize = nodesiz[dir];
 
  148                    hila::out0 << 
"CANNOT HAPPEN! in setup_layout_vector.c\n";
 
  153                nodesiz[mdir] /= prime[n];
 
  154                divisions[mdir] *= prime[n];
 
  163        foralldir(dir) 
if (nodesiz[dir] < 3) fail = 
true; 
 
  180                    int sd = subdiv[dir] * 2;
 
  181                    if (dir != gdir && nodesiz[dir] % 2 == 0 && divisions[dir] % sd == 0 &&
 
  182                        n_subn < number_of_subnodes) {
 
  186                        mynode.subnodes.merged_subnodes_dir = dir;
 
  189            } 
while (div_done && n_subn < number_of_subnodes);
 
  191            if (n_subn != number_of_subnodes)
 
  195        if (fail && !secondtime && gdir >= 0) {
 
  200            hila::out0 << 
"Could not successfully lay out the lattice with " 
  209                       << 
" nodes with vector layout can be done\n";
 
  210            hila::out0 << 
"  if the lattice can be divided into ";
 
  212                       << 
" virtual nodes so that the virtual node size is\n";
 
  213            hila::out0 << 
"  even to directions where the extra divisions are done, " 
  214                          "and the node size is > 2.\n";
 
  219    } 
while (secondtime);
 
  224        nodesiz[dir] *= subdiv[dir];
 
  225        nodes.n_divisions[dir] = divisions[dir] / subdiv[dir];
 
  226        nodes.divisors[dir].resize(nodes.n_divisions[dir] + 1);
 
  232        for (
int i = 0; i <= l_size[dir]; i++)
 
  233            if ((i * nodes.n_divisions[dir]) / l_size[dir] != n) {
 
  235                nodes.divisors[dir][n] = i;
 
  240    foralldir(d) mynode.subnodes.divisions[d] = subdiv[d];
 
  245    int ghost_slices = 0;
 
  247        ghost_slices = nsize[gdir] - l_size[gdir];
 
  249        hila::out0 << 
"\nUsing uneven node division to direction " << gdir << 
":\n";
 
  250        hila::out0 << 
"Lengths: " << nodes.n_divisions[gdir] - ghost_slices << 
" * (" 
  251                   << nodesiz[gdir] << 
" sites) + " << ghost_slices << 
" * (" << nodesiz[gdir] - 1
 
  254        for (
int i = 0; i < nodes.n_divisions[gdir]; i++) {
 
  257            hila::out0 << nodes.divisors[gdir][i + 1] - nodes.divisors[gdir][i];
 
  259        hila::out0 << 
"\nFilling efficiency: " << (100.0 * l_size[gdir]) / nsize[gdir] << 
"%\n";
 
  261        if (ghost_slices > nodes.n_divisions[gdir] / 2)
 
  262            hila::out0 << 
"NOTE: number of smaller nodes > large nodes \n";
 
  272                hila::out0 << 
'(' << nodesiz[dir] - 1 << 
'-' << nodesiz[dir] << 
')';
 
  278        if (ghost_slices > 0) {
 
  279            int64_t ns2 = ns * (nodesiz[gdir] - 1) / nodesiz[gdir];
 
  280            hila::out0 << 
"  =  " << ns2 << 
" - " << ns << 
'\n';
 
  295        hila::out0 << 
"Node subdivision to 32bit elems: ";
 
  301        hila::out0 << 
"  =  " << number_of_subnodes << 
" subnodes\n";
 
  308                hila::out0 << 
'(' << nodesiz[dir] - 1 << 
'-' << nodesiz[dir] << 
')';
 
  314        Direction dmerge = mynode.subnodes.merged_subnodes_dir;
 
  316        hila::out0 << 
"Node subdivision to 64bit elems: ";
 
  320            hila::out0 << ((dir == dmerge) ? subdiv[dir] / 2 : subdiv[dir]);
 
  322        hila::out0 << 
"  =  " << number_of_subnodes / 2 << 
" subnodes\n";
 
  329                hila::out0 << 
'(' << nodesiz[dir] - 1 << 
'-' << nodesiz[dir] << 
')';
 
  331                hila::out0 << ((dir == dmerge) ? 2 * nodesiz[dir] / subdiv[dir]
 
  332                                               : nodesiz[dir] / subdiv[dir]);
 
  348    hila::print_dashed_line();
 
int size(Direction d) const
lattice.size() -> CoordinateVector or lattice.size(d) -> int returns the dimensions of the lattice,...
 
const auto & fill(const S rhs)
Matrix fill.
 
#define foralldir(d)
Macro to loop over (all) Direction(s)
 
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
 
This file defines all includes for HILA.
 
int number_of_nodes()
how many nodes there are
 
std::ostream out0
This writes output only from main process (node 0)
 
void finishrun()
Normal, controlled exit - all nodes must call this. Prints timing information and information about c...