HILA
Loading...
Searching...
No Matches
lattice.h
1#ifndef HILA_LATTICE_H
2#define HILA_LATTICE_H
3
4#include <sstream>
5#include <iostream>
6#include <fstream>
7#include <array>
8#include <vector>
9
10// SUBNODE_LAYOUT is now defined in main.mk
11// #define SUBNODE_LAYOUT
12
13#include "plumbing/defs.h"
15#include "plumbing/timing.h"
16
17#ifdef SUBNODE_LAYOUT
18#ifndef VECTOR_SIZE
19#if defined(CUDA) || defined(HIP)
20#define VECTOR_SIZE 8 // Size of float, length 1 vectors
21#else
22#define VECTOR_SIZE (256 / 8) // this is for AVX2
23#endif
24#endif
25// This is the vector size used to determine the layout
26constexpr unsigned number_of_subnodes = VECTOR_SIZE / sizeof(float);
27#endif
28
29namespace hila {
30/// list of field boundary conditions - used only if SPECIAL_BOUNDARY_CONDITIONS defined
31enum class bc { PERIODIC, ANTIPERIODIC, DIRICHLET };
32
33/// False if we have b.c. which does not require communication
35 if (bc == hila::bc::DIRICHLET) {
36 return false;
37 } else {
38 return true;
39 }
40}
41
42} // namespace hila
43
44void test_std_gathers();
45void report_too_large_node(); // report on too large node
46
47/// useful information about a node
48struct node_info {
49 CoordinateVector min, size;
50 unsigned evensites, oddsites;
51};
52
53namespace hila {
54extern int64_t n_gather_done, n_gather_avoided;
55}
56
57/// Some backends need specialized lattice data
58/// in loops. Forward declaration here and
59/// implementations in backend headers.
60/// Loops generated by hilapp can access
61/// this through lattice.backend_lattice.
63
64/// The lattice struct defines the lattice geometry ans sets up MPI communication
65/// patterns
67 public:
68 CoordinateVector l_size;
69 size_t l_volume = 0; // use this to flag initialization
70
71 int l_label; // running number, identification of the lattice (TODO)
72
73 // Guarantee 64 bits for these - 32 can overflow!
74 MPI_Comm mpi_comm_lat;
75
76 // is this lattice derived from another, through e.g. .block()? Pointer to parent lattice
77 lattice_struct *parent;
78
79 /// Information about the node stored on this process
80 struct node_struct {
81 lattice_struct *parent; // parent lattice, for methods
82 size_t volume, evensites, oddsites;
83 size_t field_alloc_size; // how many sites/node in allocations
84 CoordinateVector min, size; // node local coordinate ranges
85 int rank; // rank of this node
86 bool first_site_even; // is location min even or odd?
87
88#ifdef EVEN_SITES_FIRST
89 std::vector<CoordinateVector> coordinates;
90#endif
91
92 Vector<NDIM, unsigned> size_factor; // components: 1, size[0], size[0]*size[1], ...
93
94 void setup(node_info &ni, lattice_struct &lattice);
95
96#ifdef SUBNODE_LAYOUT
97 /// If we have vectorized-style layout, we introduce "subnodes"
98 /// size is mynode.size/subnodes.divisions, which is not
99 /// constant across nodes
100 struct subnode_struct {
101 CoordinateVector divisions, size; // div to subnodes to directions, size
102 size_t sites, evensites, oddsites;
103 Direction merged_subnodes_dir;
104
105 void setup(const node_struct &tn);
106 } subnodes;
107#endif
108
109 /// true if this node is on the edge of the lattice to dir d
110 bool is_on_edge(Direction d) const {
111 return (is_up_dir(d) && min[d] + size[d] == parent->l_size[d]) ||
112 (!is_up_dir(d) && min[-d] == 0);
113 }
114
115 } mynode;
116
117 /// information about all nodes
118 struct allnodes {
119 int number; // number of nodes
120 CoordinateVector n_divisions; // number of node divisions to dir
121 // lattice division: divisors[d] will have n_divisions[d]+1 elements, last size to d
122 std::vector<unsigned> divisors[NDIM];
123 CoordinateVector max_size; // size of largest node
124
125 // std::vector<node_info> nodelist;
126 node_info nodeinfo(int i) const;
127
128 int *RESTRICT map_array; // mapping (optional)
129 int *RESTRICT map_inverse; // inv of it
130 void create_remap(); // create remap_node
131 int remap(int i) const; // use remap
132 int inverse_remap(int i) const; // inverse remap
133
134 } nodes;
135
136 /// Information necessary to communicate with a node
138 unsigned rank; // rank of communicated with node
139 size_t sites, evensites, oddsites;
140 size_t buffer; // offset from the start of field array
141 unsigned *sitelist;
142
143 // Get a vector containing the sites of parity par and number of elements
144 const unsigned *RESTRICT get_sitelist(Parity par, int &size) const {
145 if (par == ALL) {
146 size = sites;
147 return sitelist;
148 } else if (par == EVEN) {
149 size = evensites;
150 return sitelist;
151 } else {
152 size = oddsites;
153 return sitelist + evensites;
154 }
155 }
156
157 // The number of sites that need to be communicated
158 unsigned n_sites(Parity par) const {
159 if (par == ALL) {
160 return sites;
161 } else if (par == EVEN) {
162 return evensites;
163 } else {
164 return oddsites;
165 }
166 }
167
168 // The local index of a site that is sent to neighbour
169 unsigned site_index(unsigned site, Parity par) const {
170 if (par == ODD) {
171 return sitelist[evensites + site];
172 } else {
173 return sitelist[site];
174 }
175 }
176
177 // The offset of the halo from the start of the field array
178 unsigned offset(Parity par) const {
179 if (par == ODD) {
180 return buffer + evensites;
181 } else {
182 return buffer;
183 }
184 }
185
186 void init() {
187 sites = evensites = oddsites = 0;
188 buffer = 0;
189 sitelist = nullptr;
190 rank = hila::myrank();
191 }
192 };
193
194 /// nn-communication has only 1 node to talk to
196 unsigned *index;
197 comm_node_struct from_node, to_node;
198 unsigned receive_buf_size; // only for general gathers
199 };
200
201 /// general communication
203 unsigned *index;
204 std::vector<comm_node_struct> from_node;
205 std::vector<comm_node_struct> to_node;
206 size_t receive_buf_size;
207 };
208
209 /// nearest neighbour comminfo struct
210 std::array<nn_comminfo_struct, NDIRS> nn_comminfo;
211
212 /// Main neighbour index array
214
215 /// implement waiting using mask_t - unsigned char is good for up to 4 dim.
217
218#ifdef SPECIAL_BOUNDARY_CONDITIONS
219 /// special boundary pointers are needed only in cases neighbour
220 /// pointers must be modified (new halo elements). That is known only during
221 /// runtime.
222 struct special_boundary_struct {
223 unsigned *neighbours;
224 unsigned *move_index;
225 size_t offset, n_even, n_odd, n_total;
226 bool is_needed;
227 };
228 // holder for nb ptr info
229 special_boundary_struct special_boundaries[NDIRS];
230#endif
231
232#ifndef VANILLA
233 backend_lattice_struct *backend_lattice;
234#endif
235
236 void setup_base_lattice(const CoordinateVector &siz);
237
238 void setup_layout();
239 void setup_nodes();
240 void setup_node_divisors();
241
242 // std::vector<node_info> nodelist() { return nodes.nodelist; }
243 // CoordinateVector min_coordinate() const { return mynode.min; }
244 // int min_coordinate(Direction d) const { return mynode.min[d]; }
245
246 bool is_on_mynode(const CoordinateVector &c) const;
247 int node_rank(const CoordinateVector &c) const;
248 unsigned site_index(const CoordinateVector &c) const;
249 unsigned site_index(const CoordinateVector &c, const unsigned node) const;
250
251 void create_std_gathers();
252 gen_comminfo_struct create_general_gather(const CoordinateVector &r);
253 std::vector<comm_node_struct> create_comm_node_vector(CoordinateVector offset, unsigned *index,
254 bool receive);
255
256 // bool first_site_even() const {
257 // return mynode.first_site_even;
258 // };
259
260#ifdef SPECIAL_BOUNDARY_CONDITIONS
261 void init_special_boundaries();
262 void setup_special_boundary_array(Direction d);
263
264 const unsigned *get_neighbour_array(Direction d, hila::bc bc);
265#else
266 const unsigned *get_neighbour_array(Direction d, hila::bc bc) {
267 return neighb[d];
268 }
269#endif
270
271
272#ifdef EVEN_SITES_FIRST
273 unsigned loop_begin(Parity P) const {
274 if (P == ODD) {
275 return mynode.evensites;
276 } else {
277 return 0;
278 }
279 }
280 unsigned loop_end(Parity P) const {
281 if (P == EVEN) {
282 return mynode.evensites;
283 } else {
284 return mynode.volume;
285 }
286 }
287
288 inline const CoordinateVector &coordinates(unsigned idx) const {
289 return mynode.coordinates[idx];
290 }
291
292 inline int coordinate(unsigned idx, Direction d) const {
293 return mynode.coordinates[idx][d];
294 }
295
296 inline Parity site_parity(unsigned idx) const {
297 if (idx < mynode.evensites)
298 return EVEN;
299 else
300 return ODD;
301 }
302
303#else // Now not EVEN_SITES_FIRST
304
305 unsigned loop_begin(Parity P) const {
306 assert(P == ALL && "Only parity ALL when EVEN_SITES_FIRST is off");
307 return 0;
308 }
309 unsigned loop_end(Parity P) const {
310 return mynode.volume;
311 }
312
313 // Use computation to get coordinates: from fastest
314 // to lowest, dir = 0, 1, 2, ...
315 // each coordinate is c[d] = (idx/size_factor[d]) % size[d] + min[d], but
316 // do it like below to avoid the mod
317
318 inline const CoordinateVector coordinates(unsigned idx) const {
320 unsigned vdiv, ndiv;
321
322 vdiv = idx;
323 for (int d = 0; d < NDIM - 1; ++d) {
324 ndiv = vdiv / mynode.size[d];
325 c[d] = vdiv - ndiv * mynode.size[d] + mynode.min[d];
326 vdiv = ndiv;
327 }
328 c[NDIM - 1] = vdiv + mynode.min[NDIM - 1];
329
330 return c;
331 }
332
333 inline int coordinate(unsigned idx, Direction d) const {
334 return (idx / mynode.size_factor[d]) % mynode.size[d] + mynode.min[d];
335 }
336
337 inline Parity site_parity(unsigned idx) const {
338 return coordinates(idx).parity();
339 }
340
341#endif
342
343 CoordinateVector local_coordinates(unsigned idx) const {
344 return coordinates(idx) - mynode.min;
345 }
346
347 /* MPI functions and variables. Define here in lattice? */
348 void initialize_wait_arrays();
349
350
351 /// Return the coordinates of a site, where 1st dim (x) runs fastest etc.
352 /// Useful in
353 /// for (int64_t i=0; i<lattice.volume(); i++) {
354 /// auto c = lattice.global_coordinates(i);
355
357 CoordinateVector site;
358 foralldir(dir) {
359 site[dir] = index % l_size[dir];
360 index /= l_size[dir];
361 }
362 return site;
363 }
364
365 int id() const {
366 return l_label;
367 }
368
369
370 bool is_this_odd_boundary(Direction d) const;
371
372 lattice_struct *block_by_factor(const CoordinateVector &blocking_factor);
373
374 bool can_block_by_factor(const CoordinateVector &blocking_factor) const;
375
376 void setup_blocked_lattice(const CoordinateVector &vol, int label,
377 lattice_struct &orig_lattice);
378
379 void set_lattice_globals() const;
380};
381
382
383/**
384 * @brief global vector of defined lattice pointers
385 */
386
387extern std::vector<lattice_struct *> defined_lattices;
388
389
390/**
391 * @brief main interface class to lattices.
392 * @details Lightweight class, contains only pointer to lattice_struct so
393 * can be returned as such from functions.
394 */
395
396class Lattice {
397
398 private:
399 // ptr to current lattice_struct
400 lattice_struct *lat_ptr = nullptr;
401
402 public:
403 /**
404 * @internal Set the lattice_struct pointer only. Don't use this in normal code!
405 */
406
407 void set_lattice_pointer(lattice_struct *lat) {
408 lat_ptr = lat;
409 }
410
411 /**
412 * @internal check if the base lattice has been set
413 */
414
415 bool is_initialized() const {
416 return lat_ptr != nullptr;
417 }
418
419 /**
420 * @brief lattice.volume() returns lattice volume
421 * Can be used inside onsites()-loops
422 * @return lattice volume
423 */
424 inline int64_t volume() const {
425 return lat_ptr->l_volume;
426 }
427
428 /**
429 * @brief lattice.size() -> CoordinateVector or lattice.size(d) -> int returns the
430 * dimensions of the lattice, in latter case to direction d
431 * Can be used inside onsites()-loops
432 */
433 inline int size(Direction d) const {
434 return lat_ptr->l_size[d];
435 }
436 inline int size(int d) const {
437 return lat_ptr->l_size[d];
438 }
439 const CoordinateVector &size() const {
440 return lat_ptr->l_size;
441 }
442
443 /**
444 * @brief lattice.setup(CoordinateVector size) - set up the base lattice. Called at the
445 * beginning of the program. Can be called only once during the program run
446 */
447 void setup(const CoordinateVector &siz) {
448 assert(lat_ptr != nullptr);
449 lat_ptr->setup_base_lattice(siz);
450 }
451
452 /**
453 * @brief lattice-> defines an operator with which detailed lattice_struct fields
454 * can be accessed.
455 *
456 * @details For example:
457 * lattice->mynode.min: CoordinateVector of the min-corner managed by this MPI rank
458 * lattice->mynode.size: CV of the local node dimensions.
459 *
460 * For further info, check the class lattice_struct. This cannot be used
461 * within onsites(), copy the relevant field to local variable first.
462 */
463 inline const lattice_struct *operator->() const noexcept {
464 return lat_ptr;
465 }
466
467 /**
468 * @brief get non-const pointer to lattice_struct (cf. operator ->)
469 *
470 * @details This can be used to access fields of lattice_struct, this time
471 * returning non-const. reference. NOTE! you should not
472 */
473
474 inline lattice_struct *ptr() const {
475 return lat_ptr;
476 }
477
478 /**
479 * @brief get const ref to lattice_struct, lattice.ref(). is equivalent to lattice->
480 */
481 inline const lattice_struct &ref() const {
482 return *lat_ptr;
483 }
484
485 /**
486 * @brief Equality operator == is true if the two Lattices are the same, i.e. point
487 * to the same lattice
488 *
489 * @param rhs
490 */
491
492 bool operator==(const Lattice &rhs) {
493 return (this->lat_ptr == rhs.ptr());
494 }
495
496 bool operator!=(const Lattice &rhs) {
497 return (this->lat_ptr != rhs.ptr());
498 }
499
500 /**
501 * @brief With a valid lattice_struct pointer, switch this lattice to be active.
502 */
504 if (lat_ptr != lat) {
505 lat_ptr = lat;
506 lat->set_lattice_globals();
507 }
508 return *this;
509 }
510
511 /**
512 * @brief With a valid Lattice, switch this lattice to be active.
513 * @details useful e.g. in switching to lattice where field a belongs to:
514 * lattice.switch_to(a.mylattice());
515 *
516 */
518 if (lat_ptr != lat.ptr()) {
519 lat_ptr = lat.ptr();
520 lat_ptr->set_lattice_globals();
521 }
522 return *this;
523 }
524
525 /**
526 * @brief Test if lattice can be blocked by factor given in argument.
527 * @details lattice.size() must be element-by-element divisible by factor
528 *
529 * Example: lattice.can_block({2,2,2}) returns true if (3-dim) lattice dimensions are even
530 */
531 bool can_block(const CoordinateVector &factor) const {
532 return lat_ptr->can_block_by_factor(factor);
533 }
534
535 /**
536 * @brief block the lattice by factor, switching to smaller lattice.
537 * @details lattice.size() must be element-by-element divisible by factor
538 *
539 * @example lattice.block({2,2,2}) reduces current lattice size by 2 to each direction.
540 *
541 * @note Previously used Field variables cannot be used in onsites(). However,
542 * their content can be blocked to new Field with Field<T>::block_from(),
543 * which copies the content from the blocked (sparse) set of sites;
544 *
545 * @code{.cpp}
546 * Field<double> a;
547 * a[ALL] = X.x() + X.y() + X.z(); // in 3d
548 *
549 * CoordinateVector factor{2,2,2};
550 *
551 * lattice.block(factor);
552 * Field<double> b;
553 *
554 * b.block_from(a); // Now b contains 0+0+0, 2+0+0 ...
555 * b[ALL] = -b[X]; // Do operations, here flip sign
556 * // onsites(ALL) a[X] = 1; // ERROR, a belongs to original lattice
557 * b.unblock_to(a); // copy content of b back to a on blocked sites,
558 * // leaving other sites of a
559 * lattice.unblock(); // return to original lattice
560 *
561 * // Now a can be used, it contains -(0+0+0), 1+0+0, -(2+0+0), ...
562 * @endcode
563 *
564 * @note Fields which were not used previously can be used in blocked levels, or
565 * their association (and content) can be deleted with .clear():
566 *
567 * @code{.cpp}
568 * Field<double> a,b;
569 * a = 1;
570 * lattice.block({2,2,1});
571 * b = 2; // OK, b was not used before blocking
572 * a = 3; // ERROR; a belongs to non-blocked lattice
573 * a.clear();
574 * a = 3; // OK, now a belongs to blocked lattice
575 * @endcode
576 *
577 *
578 * @returns lattice_struct * to blocked lattice
579 */
580 Lattice block(const CoordinateVector &cv) {
581 lat_ptr->block_by_factor(cv);
582 return *this;
583 }
584
585 /**
586 * @brief Unblock lattice, returning to parent. Current lattice must be a blocked lattice
587 * @returns lattice_struct * to new lattice
588 */
590 if (lat_ptr->parent != nullptr) {
591 return switch_to(lat_ptr->parent);
592 } else {
593 hila::out0 << "ERROR : cannot unblock lattice, no parent\n";
595 return *this;
596 }
597 }
598
599 /**
600 * @brief lattice.is_base() is used to check if the current lattice is the original one,
601 * i.e. not a blocked one
602 * @returns true if current lattice is the base lattice, otherwise false
603 */
604
605 bool is_base() const {
606 return lat_ptr == defined_lattices.front();
607 }
608
609 /**
610 * @brief lattice.switch_to_base() switches the base lattice active (if not already)
611 * @returns The Lattice for the base lattice (i.e. the first lattice)
612 */
613
615 return switch_to(defined_lattices.front());
616 }
617};
618
619
620/**
621 * @brief global handle to lattice. For methods, see classes Lattice and lattice_struct
622 */
623extern Lattice lattice;
624
625
626#ifdef VANILLA
627#include "plumbing/backend_cpu/lattice.h"
628#elif defined(CUDA) || defined(HIP)
629#include "plumbing/backend_gpu/lattice.h"
630#elif defined(VECTORIZED)
631#include "plumbing/backend_vector/lattice_vector.h"
632#endif
633
634
635//////////////////////////////////////////////////////////////////////
636// Define looping utilities
637// forallcoordinates(cv) - loops over coordinates in "natural" order
638// forcoordinaterange(cv, min, max) - loops over a box subvolume in natural order
639// Note - not meant for regular lattice traversal.
640
641// clang-format off
642#if NDIM == 4
643
644#define forallcoordinates(cv) \
645for (cv[3] = 0; cv[3] < lattice.size(3); cv[3]++) \
646for (cv[2] = 0; cv[2] < lattice.size(2); cv[2]++) \
647for (cv[1] = 0; cv[1] < lattice.size(1); cv[1]++) \
648for (cv[0] = 0; cv[0] < lattice.size(0); cv[0]++)
649
650#define forcoordinaterange(cv,cmin,cmax) \
651for (cv[3] = cmin[3]; cv[3] <= cmax[3]; cv[3]++) \
652for (cv[2] = cmin[2]; cv[2] <= cmax[2]; cv[2]++) \
653for (cv[1] = cmin[1]; cv[1] <= cmax[1]; cv[1]++) \
654for (cv[0] = cmin[0]; cv[0] <= cmax[0]; cv[0]++)
655
656#elif NDIM == 3
657
658#define forallcoordinates(cv) \
659for (cv[2] = 0; cv[2] < lattice.size(2); cv[2]++) \
660for (cv[1] = 0; cv[1] < lattice.size(1); cv[1]++) \
661for (cv[0] = 0; cv[0] < lattice.size(0); cv[0]++)
662
663#define forcoordinaterange(cv,cmin,cmax) \
664for (cv[2] = cmin[2]; cv[2] <= cmax[2]; cv[2]++) \
665for (cv[1] = cmin[1]; cv[1] <= cmax[1]; cv[1]++) \
666for (cv[0] = cmin[0]; cv[0] <= cmax[0]; cv[0]++)
667
668#elif NDIM == 2
669
670#define forallcoordinates(cv) \
671for (cv[1] = 0; cv[1] < lattice.size(1); cv[1]++) \
672for (cv[0] = 0; cv[0] < lattice.size(0); cv[0]++)
673
674#define forcoordinaterange(cv,cmin,cmax) \
675for (cv[1] = cmin[1]; cv[1] <= cmax[1]; cv[1]++) \
676for (cv[0] = cmin[0]; cv[0] <= cmax[0]; cv[0]++)
677
678#elif NDIM == 1
679
680#define forallcoordinates(cv) \
681for (cv[0] = 0; cv[0] < lattice.size(0); cv[0]++)
682
683#define forcoordinaterange(cv,cmin,cmax) \
684for (cv[0] = cmin[0]; cv[0] <= cmax[0]; cv[0]++)
685
686#endif
687// clang-format on
688
689#endif
main interface class to lattices.
Definition lattice.h:396
Lattice switch_to_base()
lattice.switch_to_base() switches the base lattice active (if not already)
Definition lattice.h:614
const lattice_struct * operator->() const noexcept
lattice-> defines an operator with which detailed lattice_struct fields can be accessed.
Definition lattice.h:463
void setup(const CoordinateVector &siz)
lattice.setup(CoordinateVector size) - set up the base lattice. Called at the beginning of the progra...
Definition lattice.h:447
Lattice unblock()
Unblock lattice, returning to parent. Current lattice must be a blocked lattice.
Definition lattice.h:589
int size(Direction d) const
lattice.size() -> CoordinateVector or lattice.size(d) -> int returns the dimensions of the lattice,...
Definition lattice.h:433
Lattice switch_to(Lattice &lat)
With a valid Lattice, switch this lattice to be active.
Definition lattice.h:517
bool operator==(const Lattice &rhs)
Equality operator == is true if the two Lattices are the same, i.e. point to the same lattice.
Definition lattice.h:492
lattice_struct * ptr() const
get non-const pointer to lattice_struct (cf. operator ->)
Definition lattice.h:474
Lattice switch_to(lattice_struct *lat)
With a valid lattice_struct pointer, switch this lattice to be active.
Definition lattice.h:503
bool can_block(const CoordinateVector &factor) const
Test if lattice can be blocked by factor given in argument.
Definition lattice.h:531
bool is_base() const
lattice.is_base() is used to check if the current lattice is the original one, i.e....
Definition lattice.h:605
const lattice_struct & ref() const
get const ref to lattice_struct, lattice.ref(). is equivalent to lattice->
Definition lattice.h:481
int64_t volume() const
lattice.volume() returns lattice volume Can be used inside onsites()-loops
Definition lattice.h:424
Matrix class which defines matrix operations.
Definition matrix.h:1742
void setup_node_divisors()
Definition lattice.cpp:123
void setup_base_lattice(const CoordinateVector &siz)
General lattice setup.
Definition lattice.cpp:35
dir_mask_t *__restrict__ wait_arr_
implement waiting using mask_t - unsigned char is good for up to 4 dim.
Definition lattice.h:216
void setup_nodes()
Definition lattice.cpp:353
bool is_on_mynode(const CoordinateVector &c) const
Is the coordinate on THIS node ?
Definition lattice.cpp:147
CoordinateVector global_coordinates(size_t index) const
Definition lattice.h:356
unsigned *__restrict__ neighb[NDIRS]
Main neighbour index array.
Definition lattice.h:213
void create_std_gathers()
Definition lattice.cpp:471
std::array< nn_comminfo_struct, NDIRS > nn_comminfo
nearest neighbour comminfo struct
Definition lattice.h:210
unsigned site_index(const CoordinateVector &c) const
Definition lattice.cpp:165
int node_rank(const CoordinateVector &c) const
Definition lattice.cpp:102
This header file defines:
Parity
Parity enum with values EVEN, ODD, ALL; refers to parity of the site. Parity of site (x,...
constexpr Parity EVEN
bit pattern: 001
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:80
constexpr unsigned NDIRS
Number of directions.
Definition coordinates.h:57
constexpr Parity ODD
bit pattern: 010
unsigned char dir_mask_t
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
Definition coordinates.h:34
constexpr Parity ALL
bit pattern: 011
This file defines all includes for HILA.
#define RESTRICT
Definition defs.h:52
Implement hila::swap for gauge fields.
Definition array.h:982
int myrank()
rank of this node
Definition com_mpi.cpp:237
std::ostream out0
This writes output only from main process (node 0)
bc
list of field boundary conditions - used only if SPECIAL_BOUNDARY_CONDITIONS defined
Definition lattice.h:31
bool bc_need_communication(hila::bc bc)
False if we have b.c. which does not require communication.
Definition lattice.h:34
void terminate(int status)
Helper class for loading the vectorized lattice.
information about all nodes
Definition lattice.h:118
node_info nodeinfo(int i) const
Definition lattice.cpp:310
int remap(int i) const
And the call interface for remapping.
Information necessary to communicate with a node.
Definition lattice.h:137
general communication
Definition lattice.h:202
nn-communication has only 1 node to talk to
Definition lattice.h:195
Information about the node stored on this process.
Definition lattice.h:80
void setup(node_info &ni, lattice_struct &lattice)
Fill in mynode fields – node_rank() must be set up OK.
Definition lattice.cpp:380
bool is_on_edge(Direction d) const
true if this node is on the edge of the lattice to dir d
Definition lattice.h:110
useful information about a node
Definition lattice.h:48