HILA
Loading...
Searching...
No Matches
backend_cpu/field_storage_backend.h
1#ifndef VANILLA_BACKEND
2#define VANILLA_BACKEND
3
4#include "../lattice.h"
5#include "../field_storage.h"
6
7// Array of Structures layout (standard)
8
9template <typename T>
10inline auto field_storage<T>::get(const unsigned i, const unsigned field_alloc_size) const {
11 return fieldbuf[i];
12}
13
14template <typename T>
15// template <typename A>
16inline void field_storage<T>::set(const T &value, const unsigned i,
17 const unsigned field_alloc_size) {
18 fieldbuf[i] = value;
19}
20
21template <typename T>
23 fieldbuf = (T *)memalloc(sizeof(T) * lattice.field_alloc_size());
24 if (fieldbuf == nullptr) {
25 std::cout << "Failure in Field memory allocation\n";
26 exit(1);
27 }
28#pragma acc enter data create(fieldbuf)
29}
30
31template <typename T>
33#pragma acc exit data delete (fieldbuf)
34 if (fieldbuf != nullptr)
35 free(fieldbuf);
36 fieldbuf = nullptr;
37}
38
39
40template <typename T>
41void field_storage<T>::gather_elements(T *RESTRICT buffer, const unsigned *RESTRICT index_list,
42 int n, const lattice_struct &lattice) const {
43
44// decorate with pragma omp, should not matter if omp not used
45#pragma omp parallel for
46 for (unsigned j = 0; j < n; j++) {
47 unsigned index = index_list[j];
48 buffer[j] = get(index, lattice.field_alloc_size());
49 // std::memcpy( buffer + j, (char *) (&element), sizeof(T) );
50 }
51}
52
53template <typename T>
55 const unsigned *RESTRICT index_list, int n,
56 const lattice_struct &lattice) const {
57 if constexpr (hila::has_unary_minus<T>::value) {
58#pragma omp parallel for
59 for (unsigned j = 0; j < n; j++) {
60 unsigned index = index_list[j];
61 buffer[j] = -get(index, lattice.field_alloc_size()); /// requires unary - !!
62 // std::memcpy( buffer + j, (char *) (&element), sizeof(T) );
63 }
64 } else {
65 // sizeof(T) here to prevent compile time evaluation of assert
66 assert(sizeof(T) < 1 && "Antiperiodic boundary conditions require that unary - "
67 "-operator is defined!");
68 }
69}
70
71template <typename T>
72void field_storage<T>::place_elements(T *RESTRICT buffer, const unsigned *RESTRICT index_list,
73 int n, const lattice_struct &lattice) {
74#pragma omp parallel for
75 for (unsigned j = 0; j < n; j++) {
76 set(buffer[j], index_list[j], lattice.field_alloc_size());
77 }
78}
79
80template <typename T>
82 const lattice_struct &lattice,
83 bool antiperiodic) {
84 // Only need to do something for antiperiodic boundaries
85
86#ifdef SPECIAL_BOUNDARY_CONDITIONS
87
88 if (antiperiodic) {
89 unsigned n, start = 0;
90 if (par == ODD) {
91 n = lattice.special_boundaries[dir].n_odd;
92 start = lattice.special_boundaries[dir].n_even;
93 } else {
94 if (par == EVEN)
95 n = lattice.special_boundaries[dir].n_even;
96 else
97 n = lattice.special_boundaries[dir].n_total;
98 }
99 unsigned offset = lattice.special_boundaries[dir].offset + start;
100 gather_elements_negated(fieldbuf + offset,
101 lattice.special_boundaries[dir].move_index + start, n, lattice);
102 }
103
104#else
105 assert(!antiperiodic && "antiperiodic BC possible only if SPECIAL_BOUNDARY_CONDITIONS defined");
106#endif
107}
108
109template <typename T>
112 Parity par, const lattice_struct &lattice,
113 bool antiperiodic) const {
114 int n;
115 const unsigned *index_list = to_node.get_sitelist(par, n);
116
117 if (antiperiodic) {
118 gather_elements_negated(buffer, index_list, n, lattice);
119 } else {
120 gather_elements(buffer, index_list, n, lattice);
121 }
122}
123
124template <typename T>
125inline auto field_storage<T>::get_element(const unsigned i, const lattice_struct &lattice) const {
126 return this->get(i, lattice.field_alloc_size());
127}
128
129template <typename T>
130template <typename A>
131inline void field_storage<T>::set_element(A &value, const unsigned i,
132 const lattice_struct &lattice) {
133 this->set(value, i, lattice.field_alloc_size());
134}
135
136template <typename T>
137void field_storage<T>::free_mpi_buffer(T *buffer) {
138 std::free(buffer);
139}
140
141template <typename T>
143 return (T *)memalloc(n * sizeof(T));
144}
145
146#endif
The field_storage struct contains minimal information for using the field in a loop....
void place_elements(T *__restrict__ buffer, const unsigned *__restrict__ index_list, int n, const lattice_struct &lattice)
CUDA implementation of place_elements without CUDA aware MPI.
void gather_elements(T *__restrict__ buffer, const unsigned *__restrict__ index_list, int n, const lattice_struct &lattice) const
CUDA implementation of gather_elements without CUDA aware MPI.
void gather_elements_negated(T *__restrict__ buffer, const unsigned *__restrict__ index_list, int n, const lattice_struct &lattice) const
CUDA implementation of gather_elements_negated without CUDA aware MPI.
void set_local_boundary_elements(Direction dir, Parity par, const lattice_struct &lattice, bool antiperiodic)
Place boundary elements from local lattice (used in vectorized version)
auto get_element(const unsigned i, const lattice_struct &lattice) const
Parity
Parity enum with values EVEN, ODD, ALL; refers to parity of the site. Parity of site (x,...
constexpr Parity EVEN
bit pattern: 001
constexpr Parity ODD
bit pattern: 010
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
Definition coordinates.h:34
#define RESTRICT
Definition defs.h:50
Information necessary to communicate with a node.
Definition lattice.h:134