15#include "plumbing/timing.h"
19#if defined(CUDA) || defined(HIP)
22#define VECTOR_SIZE (256 / 8)
26constexpr unsigned number_of_subnodes = VECTOR_SIZE /
sizeof(float);
31enum class bc { PERIODIC, ANTIPERIODIC, DIRICHLET };
35 if (
bc == hila::bc::DIRICHLET) {
44void test_std_gathers();
45void report_too_large_node();
50 unsigned evensites, oddsites;
54extern int64_t n_gather_done, n_gather_avoided;
74 MPI_Comm mpi_comm_lat;
82 size_t volume, evensites, oddsites;
83 size_t field_alloc_size;
88#ifdef EVEN_SITES_FIRST
89 std::vector<CoordinateVector> coordinates;
100 struct subnode_struct {
102 size_t sites, evensites, oddsites;
111 return (is_up_dir(d) && min[d] + size[d] == parent->l_size[d]) ||
112 (!is_up_dir(d) && min[-d] == 0);
122 std::vector<unsigned> divisors[NDIM];
131 int remap(
int i)
const;
132 int inverse_remap(
int i)
const;
139 size_t sites, evensites, oddsites;
144 const unsigned *
RESTRICT get_sitelist(
Parity par,
int &size)
const {
148 }
else if (par ==
EVEN) {
153 return sitelist + evensites;
158 unsigned n_sites(
Parity par)
const {
161 }
else if (par ==
EVEN) {
169 unsigned site_index(
unsigned site,
Parity par)
const {
171 return sitelist[evensites + site];
173 return sitelist[site];
178 unsigned offset(
Parity par)
const {
180 return buffer + evensites;
187 sites = evensites = oddsites = 0;
198 unsigned receive_buf_size;
204 std::vector<comm_node_struct> from_node;
205 std::vector<comm_node_struct> to_node;
206 size_t receive_buf_size;
218#ifdef SPECIAL_BOUNDARY_CONDITIONS
222 struct special_boundary_struct {
223 unsigned *neighbours;
224 unsigned *move_index;
225 size_t offset, n_even, n_odd, n_total;
229 special_boundary_struct special_boundaries[
NDIRS];
253 std::vector<comm_node_struct> create_comm_node_vector(
CoordinateVector offset,
unsigned *index,
260#ifdef SPECIAL_BOUNDARY_CONDITIONS
261 void init_special_boundaries();
262 void setup_special_boundary_array(
Direction d);
272#ifdef EVEN_SITES_FIRST
273 unsigned loop_begin(
Parity P)
const {
275 return mynode.evensites;
280 unsigned loop_end(
Parity P)
const {
282 return mynode.evensites;
284 return mynode.volume;
289 return mynode.coordinates[idx];
292 inline int coordinate(
unsigned idx,
Direction d)
const {
293 return mynode.coordinates[idx][d];
296 inline Parity site_parity(
unsigned idx)
const {
297 if (idx < mynode.evensites)
305 unsigned loop_begin(
Parity P)
const {
306 assert(P ==
ALL &&
"Only parity ALL when EVEN_SITES_FIRST is off");
309 unsigned loop_end(
Parity P)
const {
310 return mynode.volume;
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];
328 c[NDIM - 1] = vdiv + mynode.min[NDIM - 1];
333 inline int coordinate(
unsigned idx,
Direction d)
const {
334 return (idx / mynode.size_factor[d]) % mynode.size[d] + mynode.min[d];
337 inline Parity site_parity(
unsigned idx)
const {
338 return coordinates(idx).parity();
344 return coordinates(idx) - mynode.min;
348 void initialize_wait_arrays();
359 site[dir] = index % l_size[dir];
360 index /= l_size[dir];
370 bool is_this_odd_boundary(
Direction d)
const;
379 void set_lattice_globals()
const;
387extern std::vector<lattice_struct *> defined_lattices;
415 bool is_initialized()
const {
416 return lat_ptr !=
nullptr;
425 return lat_ptr->l_volume;
434 return lat_ptr->l_size[d];
436 inline int size(
int d)
const {
437 return lat_ptr->l_size[d];
440 return lat_ptr->l_size;
448 assert(lat_ptr !=
nullptr);
493 return (this->lat_ptr == rhs.
ptr());
496 bool operator!=(
const Lattice &rhs) {
497 return (this->lat_ptr != rhs.
ptr());
504 if (lat_ptr != lat) {
506 lat->set_lattice_globals();
518 if (lat_ptr != lat.
ptr()) {
520 lat_ptr->set_lattice_globals();
532 return lat_ptr->can_block_by_factor(factor);
581 lat_ptr->block_by_factor(cv);
590 if (lat_ptr->parent !=
nullptr) {
593 hila::out0 <<
"ERROR : cannot unblock lattice, no parent\n";
606 return lat_ptr == defined_lattices.front();
615 return switch_to(defined_lattices.front());
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"
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]++)
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]++)
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]++)
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]++)
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]++)
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]++)
680#define forallcoordinates(cv) \
681for (cv[0] = 0; cv[0] < lattice.size(0); cv[0]++)
683#define forcoordinaterange(cv,cmin,cmax) \
684for (cv[0] = cmin[0]; cv[0] <= cmax[0]; cv[0]++)
main interface class to lattices.
Lattice switch_to_base()
lattice.switch_to_base() switches the base lattice active (if not already)
const lattice_struct * operator->() const noexcept
lattice-> defines an operator with which detailed lattice_struct fields can be accessed.
void setup(const CoordinateVector &siz)
lattice.setup(CoordinateVector size) - set up the base lattice. Called at the beginning of the progra...
Lattice unblock()
Unblock lattice, returning to parent. Current lattice must be a blocked lattice.
int size(Direction d) const
lattice.size() -> CoordinateVector or lattice.size(d) -> int returns the dimensions of the lattice,...
Lattice switch_to(Lattice &lat)
With a valid Lattice, switch this lattice to be active.
bool operator==(const Lattice &rhs)
Equality operator == is true if the two Lattices are the same, i.e. point to the same lattice.
lattice_struct * ptr() const
get non-const pointer to lattice_struct (cf. operator ->)
Lattice switch_to(lattice_struct *lat)
With a valid lattice_struct pointer, switch this lattice to be active.
bool can_block(const CoordinateVector &factor) const
Test if lattice can be blocked by factor given in argument.
bool is_base() const
lattice.is_base() is used to check if the current lattice is the original one, i.e....
const lattice_struct & ref() const
get const ref to lattice_struct, lattice.ref(). is equivalent to lattice->
int64_t volume() const
lattice.volume() returns lattice volume Can be used inside onsites()-loops
Matrix class which defines matrix operations.
void setup_node_divisors()
void setup_base_lattice(const CoordinateVector &siz)
General lattice setup.
dir_mask_t *__restrict__ wait_arr_
implement waiting using mask_t - unsigned char is good for up to 4 dim.
bool is_on_mynode(const CoordinateVector &c) const
Is the coordinate on THIS node ?
CoordinateVector global_coordinates(size_t index) const
unsigned *__restrict__ neighb[NDIRS]
Main neighbour index array.
void create_std_gathers()
std::array< nn_comminfo_struct, NDIRS > nn_comminfo
nearest neighbour comminfo struct
unsigned site_index(const CoordinateVector &c) const
int node_rank(const CoordinateVector &c) const
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)
constexpr unsigned NDIRS
Number of directions.
constexpr Parity ODD
bit pattern: 010
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
constexpr Parity ALL
bit pattern: 011
This file defines all includes for HILA.
Implement hila::swap for gauge fields.
int myrank()
rank of this node
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
bool bc_need_communication(hila::bc bc)
False if we have b.c. which does not require communication.
void terminate(int status)
Helper class for loading the vectorized lattice.
information about all nodes
node_info nodeinfo(int i) const
int remap(int i) const
And the call interface for remapping.
Information necessary to communicate with a node.
nn-communication has only 1 node to talk to
Information about the node stored on this process.
void setup(node_info &ni, lattice_struct &lattice)
Fill in mynode fields – node_rank() must be set up OK.
bool is_on_edge(Direction d) const
true if this node is on the edge of the lattice to dir d
useful information about a node