19#include "plumbing/lattice.h"
22#include "plumbing/backend_vector/vector_types.h"
24#include "plumbing/com_mpi.h"
28#define onsites(p) for (Parity par_dummy__(p); par_dummy__ == EVEN; par_dummy__ = ODD)
34void ensure_field_operators_exist();
36#include "plumbing/ensure_loop_functions.h"
65 enum class gather_status_t :
unsigned { NOT_DONE, STARTED, DONE };
85 gather_status_t gather_status_arr[3][
NDIRS];
92 MPI_Request receive_request[3][
NDIRS];
93 MPI_Request send_request[3][
NDIRS];
96 T *receive_buffer[
NDIRS];
98 T *send_buffer[
NDIRS];
103 void initialize_communication() {
104 for (
int d = 0; d <
NDIRS; d++) {
105 for (
int p = 0; p < 3; p++)
106 gather_status_arr[p][d] = gather_status_t::NOT_DONE;
107 send_buffer[d] =
nullptr;
109 receive_buffer[d] =
nullptr;
119 void free_communication() {
120 for (
int d = 0; d <
NDIRS; d++) {
121 if (send_buffer[d] !=
nullptr)
122 payload.free_mpi_buffer(send_buffer[d]);
124 if (receive_buffer[d] !=
nullptr)
125 payload.free_mpi_buffer(receive_buffer[d]);
134 void allocate_payload() {
135 payload.allocate_field(lattice);
142 void free_payload() {
143 payload.free_field();
154 inline auto get(
const unsigned i)
const {
155 return payload.get(i, lattice->mynode.field_alloc_size);
158 template <
typename A>
159 inline void set(
const A &value,
const unsigned i) {
160 payload.set(value, i, lattice->mynode.field_alloc_size);
168 inline auto get_element(
const unsigned i)
const {
172 template <
typename A>
173 inline void set_element(
const A &value,
const unsigned i) {
174 payload.set_element(value, i, lattice);
177 template <
typename vecT>
178 inline vecT get_vector(
const unsigned i)
const {
179 return payload.template get_vector<vecT>(i);
181 inline T get_element(
const unsigned i)
const {
185 template <
typename vecT>
186 inline void set_vector(
const vecT &val,
const unsigned i) {
187 return payload.set_vector(val, i);
189 inline void set_element(
const T &val,
const unsigned i) {
190 return payload.set_element(val, i);
221 void gather_elements(T *buffer,
const std::vector<CoordinateVector> &coord_list,
223 void scatter_elements(T *buffer,
const std::vector<CoordinateVector> &coord_list,
234 static_assert(std::is_trivial<T>::value && std::is_standard_layout<T>::value,
235 "Field expects only pod-type elements (plain data): default "
236 "constructor, copy and delete");
282 static_assert(
sizeof(hila::arithmetic_type<T>) == 4 ||
283 sizeof(hila::arithmetic_type<T>) == 8,
284 "In vectorized arch (e.g. AVX2), only 4 or 8 byte (32 or 64 bit) numbers for "
285 "Field<> implemented, sorry!");
287#if defined(CUDA) || defined(HIP)
288 static_assert(!std::is_same<hila::arithmetic_type<T>,
long double>::value,
289 "Type 'long double' numbers in Field<> not supported by cuda/hip");
302 (*this)[
ALL] = other[X];
310 template <typename A, std::enable_if_t<std::is_convertible<A, T>::value,
int> = 0>
314 (*this)[
ALL] = other[X];
323 template <
typename A,
325 hila::is_assignable<T &, A>::value || std::is_convertible<A, T>::value,
int> = 0>
346 assert(rhs.fs->mylattice.ptr() == lattice.
ptr());
358 ensure_field_operators_exist<T>();
367 assert(lattice.is_initialized() &&
"Fields cannot be used before lattice.setup()");
368 assert(
fs ==
nullptr);
369 fs = (field_struct *)memalloc(
sizeof(field_struct));
370 fs->mylattice = lattice;
371 fs->allocate_payload();
372 fs->initialize_communication();
378#if !defined(CUDA) && !defined(HIP)
379 fs->neighbours[d] = lattice->
neighb[d];
381 fs->payload.neighbours[d] = lattice->backend_lattice->
d_neighb[d];
385#ifdef SPECIAL_BOUNDARY_CONDITIONS
387 fs->boundary_condition[dir] = hila::bc::PERIODIC;
388 fs->boundary_condition[-dir] = hila::bc::PERIODIC;
394 fs->vector_lattice = lattice->backend_lattice
397 fs->vector_lattice =
nullptr;
407 if (
fs !=
nullptr && !hila::about_to_finish) {
411 fs->free_communication();
422 return (
fs !=
nullptr);
431 return fs !=
nullptr && ((
fs->assigned_to & parity_bits(p)) != 0);
441 gather_status_t gather_status(
Parity p,
int d)
const {
442 assert(parity_bits(p) && d >= 0 && d <
NDIRS);
443 return fs->gather_status_arr[(int)p - 1][d];
445 void set_gather_status(
Parity p,
int d, gather_status_t stat)
const {
446 assert(parity_bits(p) && d >= 0 && d <
NDIRS);
447 fs->gather_status_arr[(int)p - 1][d] = stat;
478 void mark_changed(
const Parity p)
const {
482 drop_comms(i, opp_parity(p));
484 set_gather_status(opp_parity(p), i, gather_status_t::NOT_DONE);
486 set_gather_status(
ALL, i, gather_status_t::NOT_DONE);
488 set_gather_status(
EVEN, i, gather_status_t::NOT_DONE);
489 set_gather_status(
ODD, i, gather_status_t::NOT_DONE);
492 fs->assigned_to |= parity_bits(p);
508 void mark_gathered(
int dir,
const Parity p)
const {
509 set_gather_status(p, dir, gather_status_t::DONE);
522 bool is_gathered(
int dir,
Parity par)
const {
524 return gather_status(par, dir) == gather_status_t::DONE ||
525 gather_status(
ALL, dir) == gather_status_t::DONE;
527 return gather_status(
ALL, dir) == gather_status_t::DONE ||
528 (gather_status(
EVEN, dir) == gather_status_t::DONE &&
529 gather_status(
ODD, dir) == gather_status_t::DONE);
539 void mark_gather_started(
int dir,
Parity p)
const {
540 set_gather_status(p, dir, gather_status_t::STARTED);
550 bool is_gather_started(
int dir,
Parity par)
const {
551 return gather_status(par, dir) == gather_status_t::STARTED;
554 bool gather_not_done(
int dir,
Parity par)
const {
555 return gather_status(par, dir) == gather_status_t::NOT_DONE;
563 bool boundary_need_to_communicate(
const Direction dir)
const {
564#ifdef SPECIAL_BOUNDARY_CONDITIONS
567 !
fs->mylattice->mynode.is_on_edge(dir);
581#ifdef SPECIAL_BOUNDARY_CONDITIONS
589 "BC possible only for types which implement unary "
590 "minus (-) -operator and are not unsigned");
592 ensure_unary_minus_is_loop_function<T>();
599 fs->boundary_condition[dir] = bc;
600 fs->boundary_condition[-dir] = bc;
601#if !defined(CUDA) && !defined(HIP)
602 fs->neighbours[dir] = mylat->get_neighbour_array(dir, bc);
603 fs->neighbours[-dir] = mylat->get_neighbour_array(-dir, bc);
605 if (bc == hila::bc::PERIODIC) {
606 fs->payload.neighbours[dir] = mylat->backend_lattice->
d_neighb[dir];
607 fs->payload.neighbours[-dir] = mylat->backend_lattice->
d_neighb[-dir];
609 fs->payload.neighbours[dir] = mylat->backend_lattice->d_neighb_special[dir];
610 fs->payload.neighbours[-dir] = mylat->backend_lattice->d_neighb_special[-dir];
617 assert(bc == hila::bc::PERIODIC &&
618 "Only periodic bondary conditions when SPECIAL_BOUNDARY_CONDITIONS is undefined");
628#ifdef SPECIAL_BOUNDARY_CONDITIONS
629 return fs->boundary_condition[dir];
631 return hila::bc::PERIODIC;
635 void print_boundary_condition() {
638 for (
int dir = 0; dir <
NDIRS; dir++) {
650 template <
typename A>
660 T operator[](
const Parity p)
const;
665 T &operator[](
const Parity p);
672 inline auto field_buffer()
const {
673 return fs->payload.get_buffer();
686 return fs->get_element(i);
690 return fs->get_element(i);
692 template <
typename vecT>
693 inline auto get_vector_at(
unsigned i)
const {
694 return fs->template get_vector<vecT>(i);
696 inline auto get_value_at_nb_site(
Direction d,
unsigned i)
const {
697 return fs->get_element(
fs->vector_lattice->site_neighbour(d, i));
709 template <
typename A>
711 fs->set_element(value, i);
715 template <
typename vecT>
716 inline void set_vector_at(
const vecT &value,
unsigned i) {
717 fs->set_vector(value, i);
720 template <
typename A>
722 fs->set_element(value, i);
751 (*this)[
ALL] = rhs[X];
781 template <
typename A,
783 hila::is_assignable<T &, A>::value || std::is_convertible<A, T>::value,
int> = 0>
785 (*this)[
ALL] = rhs[X];
797 template <
typename A,
799 hila::is_assignable<T &, A>::value || std::is_convertible<A, T>::value,
int> = 0>
825 assert((
fs ==
nullptr || (rhs.fs->mylattice.ptr() ==
fs->mylattice.ptr())) &&
826 "Field = Field assignment possible only if fields belong to the same lattice");
860 template <
typename A,
861 std::enable_if_t<std::is_convertible<hila::type_plus<T, A>, T>::value,
int> = 0>
863 (*this)[
ALL] += rhs[X];
893 template <
typename A,
894 std::enable_if_t<std::is_convertible<hila::type_minus<T, A>, T>::value,
int> = 0>
896 (*this)[
ALL] -= rhs[X];
926 template <
typename A,
927 std::enable_if_t<std::is_convertible<hila::type_mul<T, A>, T>::value,
int> = 0>
929 (*this)[
ALL] *= rhs[X];
959 template <
typename A,
960 std::enable_if_t<std::is_convertible<hila::type_div<T, A>, T>::value,
int> = 0>
962 (*this)[
ALL] /= rhs[X];
975 template <
typename A,
976 std::enable_if_t<std::is_convertible<hila::type_plus<T, A>, T>::value,
int> = 0>
990 template <
typename A,
991 std::enable_if_t<std::is_convertible<hila::type_minus<T, A>, T>::value,
int> = 0>
1005 template <
typename A,
1006 std::enable_if_t<std::is_convertible<hila::type_mul<T, A>, T>::value,
int> = 0>
1008 (*this)[
ALL] *= rhs;
1020 template <
typename A,
1021 std::enable_if_t<std::is_convertible<hila::type_div<T, A>, T>::value,
int> = 0>
1023 (*this)[
ALL] /= rhs;
1113 f[
ALL] = -(*this)[X];
1125 template <
typename S>
1128 onsites(
ALL) s += !((*this)[X] == rhs[X]);
1132 template <
typename S>
1133 bool operator!=(
const Field<S> &rhs)
const {
1134 return !(*
this == rhs);
1187 template <typename R = T, typename A = decltype(::dagger(std::declval<R>()))>
1201 template <typename R = T, typename A = decltype(::real(std::declval<R>()))>
1215 template <typename R = T, typename A = decltype(::imag(std::declval<R>()))>
1267 template <typename A, std::enable_if_t<std::is_assignable<T &, A>::value,
int> = 0>
1272 if (
fs->mylattice->is_on_mynode(coord)) {
1275 mark_changed(coord.parity());
1289 int owner =
fs->mylattice->node_rank(coord);
1309 void set_elements(
const std::vector<T> &elements,
1310 const std::vector<CoordinateVector> &coord_list);
1318 std::vector<T>
get_elements(
const std::vector<CoordinateVector> &coord_list,
1319 bool broadcast =
false)
const;
1322 bool broadcast =
false)
const;
1326 void copy_local_data(std::vector<T> &buffer)
const;
1327 void set_local_data(
const std::vector<T> &buffer);
1329 void copy_local_data_with_halo(std::vector<T> &buffer)
const;
1347 template <
typename A,
1348 std::enable_if_t<std::is_assignable<T &, hila::type_plus<T, A>>::value,
int> = 0>
1349 inline void compound_add_element(
const CoordinateVector &coord,
const A &av) {
1351 if (
fs->mylattice->is_on_mynode(coord)) {
1352 auto i =
fs->mylattice->site_index(coord);
1357 mark_changed(coord.parity());
1360 template <
typename A,
1361 std::enable_if_t<std::is_assignable<T &, hila::type_minus<T, A>>::value,
int> = 0>
1362 inline void compound_sub_element(
const CoordinateVector &coord,
const A &av) {
1364 if (
fs->mylattice->is_on_mynode(coord)) {
1365 auto i =
fs->mylattice->site_index(coord);
1370 mark_changed(coord.parity());
1373 template <
typename A,
1374 std::enable_if_t<std::is_assignable<T &, hila::type_mul<T, A>>::value,
int> = 0>
1375 inline void compound_mul_element(
const CoordinateVector &coord,
const A &av) {
1377 if (
fs->mylattice->is_on_mynode(coord)) {
1378 auto i =
fs->mylattice->site_index(coord);
1383 mark_changed(coord.parity());
1386 template <
typename A,
1387 std::enable_if_t<std::is_assignable<T &, hila::type_div<T, A>>::value,
int> = 0>
1388 inline void compound_div_element(
const CoordinateVector &coord,
const A &av) {
1390 if (
fs->mylattice->is_on_mynode(coord)) {
1391 auto i =
fs->mylattice->site_index(coord);
1396 mark_changed(coord.parity());
1445 FFT_complex_to_real(
fft_direction fdir = fft_direction::forward)
const;
1454 void write(std::ofstream &outputfile,
bool binary =
true,
int precision = 8)
const;
1455 void write(
const std::string &filename,
bool binary =
true,
int precision = 8)
const;
1457 void read(std::ifstream &inputfile);
1459 void read(
const std::string &filename);
1466 template <
typename Out>
1467 void write_slice(Out &outputfile,
const CoordinateVector &slice,
int precision = 6)
const;
1476 T
sum(
Parity par = Parity::all,
bool allreduce =
true)
const;
1485 T
product(
Parity par = Parity::all,
bool allreduce =
true)
const;
1535 void gaussian_random(
double width = 1.0);
1600 return fs->mylattice;
1616template <
typename A,
typename B>
1619 tmp[
ALL] = lhs[X] + rhs[X];
1626template <
typename A,
typename B>
1629 tmp[
ALL] = lhs[X] + rhs;
1636template <
typename A,
typename B>
1644template <
typename A,
typename B>
1647 tmp[
ALL] = lhs[X] - rhs[X];
1654template <
typename A,
typename B>
1657 tmp[
ALL] = lhs[X] - rhs;
1664template <
typename A,
typename B>
1667 tmp[
ALL] = lhs - rhs[X];
1704template <
typename A,
typename B>
1707 tmp[
ALL] = lhs[X] * rhs[X];
1714template <
typename A,
typename B>
1717 tmp[
ALL] = lhs * rhs[X];
1724template <
typename A,
typename B>
1727 tmp[
ALL] = lhs[X] * rhs;
1764template <
typename A,
typename B>
1767 tmp[
ALL] = l[X] / r[X];
1774template <
typename A,
typename B>
1777 tmp[
ALL] = lhs / rhs[X];
1783template <
typename A,
typename B>
1786 tmp[
ALL] = lhs[X] / rhs;
1795template <
typename T>
1797 std::swap(A.
fs, B.
fs);
1821template <typename T, typename R = decltype(exp(std::declval<T>()))>
1825 res[X] = exp(
arg[X]);
1833template <typename T, typename R = decltype(log(std::declval<T>()))>
1837 res[X] = log(
arg[X]);
1845template <typename T, typename R = decltype(sin(std::declval<T>()))>
1849 res[X] = sin(
arg[X]);
1857template <typename T, typename R = decltype(cos(std::declval<T>()))>
1861 res[X] = cos(
arg[X]);
1869template <typename T, typename R = decltype(tan(std::declval<T>()))>
1873 res[X] = tan(
arg[X]);
1881template <typename T, typename R = decltype(asin(std::declval<T>()))>
1885 res[X] = asin(
arg[X]);
1893template <typename T, typename R = decltype(acos(std::declval<T>()))>
1897 res[X] = acos(
arg[X]);
1905template <typename T, typename R = decltype(atan(std::declval<T>()))>
1909 res[X] = atan(
arg[X]);
1917template <typename T, typename R = decltype(abs(std::declval<T>()))>
1930template <typename T, typename P, typename R = decltype(pow(std::declval<T>()), std::declval<P>())>
1934 res[X] = pow(
arg[X], p);
1942template <
typename T>
1952template <
typename T>
1957template <
typename T>
1962template <typename T, typename A = decltype(::dagger(std::declval<T>()))>
1964 return arg.dagger();
1967template <typename T, typename A = decltype(::real(std::declval<T>()))>
1972template <typename T, typename A = decltype(::imag(std::declval<T>()))>
1986template <typename A, typename B, typename R = decltype(std::declval<A>() - std::declval<B>())>
1997template <
typename T>
2014template <
typename T>
2017 if (hila::is_comm_initialized()) {
2018 if (is_gather_started(d,
ALL)) {
2019 drop_comms_timer.start();
2020 wait_gather(d,
ALL);
2021 drop_comms_timer.stop();
2024 if (is_gather_started(d, p)) {
2025 drop_comms_timer.start();
2027 drop_comms_timer.stop();
2030 if (is_gather_started(d,
EVEN)) {
2031 drop_comms_timer.start();
2032 wait_gather(d,
EVEN);
2033 drop_comms_timer.stop();
2035 if (is_gather_started(d,
ODD)) {
2036 drop_comms_timer.start();
2037 wait_gather(d,
ODD);
2038 drop_comms_timer.stop();
2046template <
typename T>
2058template <
typename T>
2061#if defined(CUDA) || defined(HIP)
2065 std::vector<T> rng_buffer(lattice->mynode.volume);
2066 for (
auto &element : rng_buffer)
2068 (*this).set_local_data(rng_buffer);
2084template <
typename T>
2087#if defined(CUDA) || defined(HIP)
2091 std::vector<T> rng_buffer(lattice->mynode.volume);
2092 for (
auto &element : rng_buffer)
2094 (*this).set_local_data(rng_buffer);
2124inline void dummy_X_f() {
2146 vec[e_x] = vec[0] + vec[e_y] + vec.
e(e_y);
2156template <
typename T>
2157inline void ensure_field_operators_exist() {
2159 ensure_unary_minus_is_loop_function<T>();
2160 ensure_assign_zero_is_loop_function<T>();
Array< n, m, T > conj(const Array< n, m, T > &arg)
Return conjugate Array.
Array< n, m, hila::arithmetic_type< T > > imag(const Array< n, m, T > &arg)
Return imaginary part of Array.
hila::arithmetic_type< T > squarenorm(const Array< n, m, T > &rhs)
Return square norm of Array.
Array< n, m, hila::arithmetic_type< T > > real(const Array< n, m, T > &arg)
Return real part of Array.
The field class implements the standard methods for accessing Fields. Hilapp replaces the parity acce...
Field< T > & operator=(const Field< T > &rhs)
Assignment operator.
Field()
Field constructor.
Field< A > real() const
Returns real part of Field.
Field< R > acos(const Field< T > &arg)
Arccosine.
std::vector< T > get_subvolume(const CoordinateVector &cmin, const CoordinateVector &cmax, bool broadcast=false) const
Get a subvolume of the field elements to all nodes.
Field< T > & shift(const CoordinateVector &v, Field< T > &r, Parity par) const
Create a periodically shifted copy of the field.
void set_boundary_condition(Direction dir, hila::bc bc)
Set the boundary condition in a given Direction (periodic or antiperiodic)
void write_subvolume(std::ofstream &outputfile, const CoordinateVector &cmin, const CoordinateVector &cmax, int precision=6) const
const T get_element(const CoordinateVector &coord) const
Get singular element which will be broadcast to all nodes.
hila::bc get_boundary_condition(Direction dir) const
Get the boundary condition of the Field.
Field< A > imag() const
Returns imaginary part of Field.
Lattice mylattice() const
Return the lattice to which this field instance belongs to.
T gpu_minmax(bool min_or_max, Parity par, CoordinateVector &loc) const
Declare gpu_reduce here, defined only for GPU targets.
Field< A > dagger() const
Returns dagger or Hermitian conjugate of Field depending on how it is defined for Field type T.
const T set_element(const CoordinateVector &coord, const A &value)
Get singular element which will be broadcast to all nodes.
T max(Parity par=ALL) const
Find maximum value from Field.
Field< T > operator+() const
Summation operator.
auto operator*(const Field< A > &lhs, const Field< B > &rhs) -> Field< hila::type_mul< A, B > >
Multiplication operator.
bool is_initialized(Parity p) const
Returns true if the Field has been assigned to.
Field< R > log(const Field< T > &arg)
Logarithm.
auto get_value_at(const unsigned i) const
Get an individual element outside a loop. This is also used as a getter in the vanilla code.
Field< R > pow(const Field< T > &arg, const P p)
Power.
field_struct *__restrict__ fs
Field::fs holds all of the field content in Field::field_struct.
void clear()
Destroys field data.
Field< R > tan(const Field< T > &arg)
Tangent.
void set_value_at(const A &value, unsigned i)
Set an individual element outside a loop. This is also used as a getter in the vanilla code.
double squarenorm_relative(const Field< A > &a, const Field< B > &b)
Squarenorm relative .
Field< T > operator-() const
Subtraction operator.
Field< R > abs(const Field< T > &arg)
Absolute value.
auto operator/(const Field< A > &l, const Field< B > &r) -> Field< hila::type_div< A, B > >
Division operator.
Field< R > asin(const Field< T > &arg)
Arcsine.
double squarenorm(const Field< T > &arg)
Squared norm .
Field< Complex< hila::arithmetic_type< T > > > FFT_real_to_complex(fft_direction fdir=fft_direction::forward) const
Field< R > sin(const Field< T > &arg)
Sine.
Field< R > atan(const Field< T > &arg)
Arctangent.
Field< T > & operator=(Field< T > &&rhs)
Move Assignment.
Field< T > & operator*=(const Field< A > &rhs)
Product assignment operator.
Field< R > cos(const Field< T > &arg)
Cosine.
bool is_allocated() const
Returns true if the Field data has been allocated.
void copy_boundary_condition(const Field< A > &rhs)
Copy the boundary condition from another field.
Field< T > conj() const
Returns field with all elements conjugated depending how conjugate is defined for type.
T product(Parity par=Parity::all, bool allreduce=true) const
Product reduction of Field.
void check_alloc()
Allocate Field if it is not already allocated.
Field< R > exp(const Field< T > &arg)
Exponential.
bool operator==(const Field< S > &rhs) const
Field comparison operator.
double squarenorm() const
Squarenorm.
dir_mask_t start_gather(Direction d, Parity p=ALL) const
Field< T > & operator-=(const Field< A > &rhs)
Subtraction assignment operator.
void write(std::ofstream &outputfile, bool binary=true, int precision=8) const
Write the field to a file stream.
std::vector< T > get_elements(const std::vector< CoordinateVector > &coord_list, bool broadcast=false) const
Get a list of elements and store them into a vector.
T minmax(bool is_min, Parity par, CoordinateVector &loc) const
Function to perform min or max operations.
T min(Parity par=ALL) const
Find minimum value from Field.
T sum(Parity par=Parity::all, bool allreduce=true) const
Sum reduction of Field.
void read(std::ifstream &inputfile)
Read the Field from a stream.
std::vector< T > get_slice(const CoordinateVector &c, bool broadcast=false) const
Get a slice (subvolume)
void unblock_to(Field< T > &target) const
Copy content to the argument Field on blocked (sparse) sites. a.unblock_to(b) is the inverse of a....
Field< T > & operator/=(const Field< A > &rhs)
Division assignment operator.
Field< T > & operator+=(const Field< A > &rhs)
Addition assignment operator.
main interface class to lattices.
lattice_struct * ptr() const
get non-const pointer to lattice_struct (cf. operator ->)
T e(const int i, const int j) const
Standard array indexing operation for matrices.
X-coordinate type - "dummy" class.
The field_storage struct contains minimal information for using the field in a loop....
auto get_element(const unsigned i, const Lattice lattice) const
Conditionally reture bool type false if type T does't have unary - operator.
unsigned *__restrict__ neighb[NDIRS]
Main neighbour index array.
Complex< T > dagger(const Complex< T > &val)
Return dagger of Complex number.
T abs(const Complex< T > &a)
Return absolute value of Complex number.
T arg(const Complex< T > &a)
Return argument of Complex number.
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.
fft_direction
define a class for FFT direction
Implement hila::swap for gauge fields.
T gaussian_random()
Template function T hila::gaussian_random<T>(),generates gaussian random value of type T,...
double random()
Real valued uniform random number generator.
int myrank()
rank of this node
bool is_device_rng_on()
Check if the RNG on GPU is allocated and ready to use.
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
T broadcast(T &var, int rank=0)
Broadcast the value of var to all MPI ranks from rank (default=0).
bool bc_need_communication(hila::bc bc)
False if we have b.c. which does not require communication.
T gaussian_random(out_only T &val, double w=1.0)
Template function const T & hila::gaussian_random(T & variable,double width=1)
X + coordinate offset, used in f[X+CoordinateVector] or f[X+dir1+dir2] etc.
vectorized_lattice_struct< vector_size > * get_vectorized_lattice()
Returns a vectorized lattice with given vector size.
unsigned * d_neighb[NDIRS]
Storage for the neighbour indexes. Stored on device.
is_vectorizable_type<T>::value is always false if the target is not vectorizable
Information necessary to communicate with a node.