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...