/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/physics/interpolation/linear_interpolator_3d.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/physics/interpolation/linear_interpolator_3d.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
linear_interpolator_3d.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
8
9namespace DiFfRG
10{
19 template <typename NT, typename Coordinates> class LinearInterpolator3D
20 {
21 static_assert(Coordinates::dim == 3, "LinearInterpolator3D requires 3D coordinates");
22
26
27 using ViewType = Kokkos::View<NT ***, GPU_memory, Kokkos::MemoryTraits<Kokkos::RandomAccess>>;
28 using HostViewType = typename ViewType::host_mirror_type;
29
30 static constexpr bool has_separate_device =
31 !std::is_same_v<typename ViewType::memory_space, typename HostViewType::memory_space>;
32
33 public:
34 using ctype = typename Coordinates::ctype;
35 using value_type = NT;
36 static constexpr size_t dim = 3;
37
45 device_data("LinearInterpolator3D_data", coordinates.sizes()[0], coordinates.sizes()[1],
46 coordinates.sizes()[2]),
47 host_data(Kokkos::create_mirror_view(device_data))
48 {
49 }
50
52 KOKKOS_DEFAULTED_FUNCTION LinearInterpolator3D(const LinearInterpolator3D &) = default;
53
61 template <typename NT2> void update(const NT2 *in_data)
62 {
63 for (size_t i = 0; i < sizes[0]; ++i)
64 for (size_t j = 0; j < sizes[1]; ++j)
65 for (size_t k = 0; k < sizes[2]; ++k)
66 host_data(i, j, k) = in_data[(i * sizes[1] + j) * sizes[2] + k];
67
68 if constexpr (has_separate_device) {
69 typename ViewType::execution_space exec;
70 Kokkos::deep_copy(exec, device_data, host_data);
71 exec.fence();
72 }
73 }
74
78 NT operator[](size_t i) const
79 {
80 return host_data(i / (sizes[1] * sizes[2]), (i / sizes[2]) % sizes[1], i % sizes[2]);
81 }
82
100 device::array<ctype, 3> KOKKOS_FUNCTION index(const ctype &x, const ctype &y, const ctype &z) const
101 {
102 return coordinates.backward(x, y, z);
103 }
104
108 NT KOKKOS_FUNCTION at(const device::array<ctype, 3> &idx) const
109 {
110 const auto idx_x = idx[0];
111 const auto idx_y = idx[1];
112 const auto idx_z = idx[2];
113 // Clamped [i, i+1] stencil on bounded axes, wrapping [i, (i+1) % n] on periodic ones
114 const auto sx = make_interpolation_stencil<periodic_x>(idx_x, sizes[0]);
115 const auto sy = make_interpolation_stencil<periodic_y>(idx_y, sizes[1]);
116 const auto sz = make_interpolation_stencil<periodic_z>(idx_z, sizes[2]);
117
118 const size_t x0 = sx.lower, x1 = sx.upper;
119 const size_t y0 = sy.lower, y1 = sy.upper;
120 const size_t z0 = sz.lower, z1 = sz.upper;
121
122 const auto corner000 = value(x0, y0, z0);
123 const auto corner010 = value(x0, y1, z0);
124 const auto corner100 = value(x1, y0, z0);
125 const auto corner110 = value(x1, y1, z0);
126 const auto corner001 = value(x0, y0, z1);
127 const auto corner011 = value(x0, y1, z1);
128 const auto corner101 = value(x1, y0, z1);
129 const auto corner111 = value(x1, y1, z1);
130
131 const auto tx = sx.t;
132 const auto ty = sy.t;
133 const auto tz = sz.t;
134
135 if constexpr (std::is_arithmetic_v<NT>)
136 return Kokkos::fma(
137 tx,
138 Kokkos::fma(ty, Kokkos::fma(tz, corner111, Kokkos::fma(-tz, corner110, corner110)),
139 (1 - ty) * Kokkos::fma(tz, corner101, Kokkos::fma(-tz, corner100, corner100))),
140 (1 - tx) * Kokkos::fma(ty, Kokkos::fma(tz, corner011, Kokkos::fma(-tz, corner010, corner010)),
141 (1 - ty) * Kokkos::fma(tz, corner001, Kokkos::fma(-tz, corner000, corner000))));
142 else
143 return corner000 * (1 - tx) * (1 - ty) * (1 - tz) + corner001 * (1 - tx) * (1 - ty) * tz +
144 corner010 * (1 - tx) * ty * (1 - tz) + corner011 * (1 - tx) * ty * tz +
145 corner100 * tx * (1 - ty) * (1 - tz) + corner101 * tx * (1 - ty) * tz +
146 corner110 * tx * ty * (1 - tz) + corner111 * tx * ty * tz;
147 }
148
152 NT KOKKOS_FUNCTION operator()(const ctype &x, const ctype &y, const ctype &z) const
153 {
154 return at(index(x, y, z));
155 }
156
162 const Coordinates &get_coordinates() const { return coordinates; }
163
169 const NT *data() const { return host_data.data(); }
170
171 private:
173 KOKKOS_FORCEINLINE_FUNCTION NT value(const size_t i, const size_t j, const size_t k) const
174 {
175 KOKKOS_IF_ON_DEVICE((return device_data(i, j, k);))
176 KOKKOS_IF_ON_HOST((return host_data(i, j, k);))
177 }
178
179 const Coordinates coordinates;
181
184 };
185} // namespace DiFfRG
A linear interpolator for 3D data, callable from host AND device code.
Definition linear_interpolator_3d.hh:20
Kokkos::View< NT ***, GPU_memory, Kokkos::MemoryTraits< Kokkos::RandomAccess > > ViewType
Definition linear_interpolator_3d.hh:27
const Coordinates coordinates
Definition linear_interpolator_3d.hh:179
HostViewType host_data
Definition linear_interpolator_3d.hh:183
device::array< ctype, 3 > KOKKOS_FUNCTION index(const ctype &x, const ctype &y, const ctype &z) const
Map physical coordinates onto grid indices.
Definition linear_interpolator_3d.hh:100
static constexpr bool has_separate_device
Definition linear_interpolator_3d.hh:30
static constexpr bool periodic_x
Definition linear_interpolator_3d.hh:23
NT KOKKOS_FUNCTION at(const device::array< ctype, 3 > &idx) const
Interpolate at grid indices previously obtained from index().
Definition linear_interpolator_3d.hh:108
NT KOKKOS_FUNCTION operator()(const ctype &x, const ctype &y, const ctype &z) const
Interpolate the data at a given point.
Definition linear_interpolator_3d.hh:152
NT value_type
Definition linear_interpolator_3d.hh:35
static constexpr bool periodic_z
Definition linear_interpolator_3d.hh:25
typename Coordinates::ctype ctype
Definition linear_interpolator_3d.hh:34
ViewType device_data
Definition linear_interpolator_3d.hh:182
KOKKOS_FORCEINLINE_FUNCTION NT value(const size_t i, const size_t j, const size_t k) const
Read one element from whichever buffer belongs to the executing side.
Definition linear_interpolator_3d.hh:173
const NT * data() const
Read-only handle to the host values, in the mirror's storage order.
Definition linear_interpolator_3d.hh:169
static constexpr bool periodic_y
Definition linear_interpolator_3d.hh:24
NT operator[](size_t i) const
Host-side element access, in the row-major order update() takes its input in.
Definition linear_interpolator_3d.hh:78
const Coordinates & get_coordinates() const
Get the coordinate system of the data.
Definition linear_interpolator_3d.hh:162
const device::array< size_t, 3 > sizes
Definition linear_interpolator_3d.hh:180
LinearInterpolator3D(const Coordinates &coordinates)
Construct a LinearInterpolator3D with internal, zeroed data and a coordinate system.
Definition linear_interpolator_3d.hh:43
KOKKOS_DEFAULTED_FUNCTION LinearInterpolator3D(const LinearInterpolator3D &)=default
Shallow copy of BOTH views, valid in host and in device code. See LinearInterpolator1D.
void update(const NT2 *in_data)
Replace the data, leaving host AND device current. The only mutator.
Definition linear_interpolator_3d.hh:61
typename ViewType::host_mirror_type HostViewType
Definition linear_interpolator_3d.hh:28
static constexpr size_t dim
Definition linear_interpolator_3d.hh:36
std::array< T, N > array
Definition kokkos.hh:155
Definition complex_math.hh:10
constexpr bool is_periodic_axis_v
Whether axis i of a (possibly multi-dimensional) coordinate system is periodic. Falls back to false f...
Definition coordinates.hh:59
KOKKOS_FORCEINLINE_FUNCTION InterpolationStencil< CT > make_interpolation_stencil(CT idx, const size_t n)
Resolve a fractional grid index into the linear-interpolation stencil along one axis.
Definition interpolation_stencil.hh:34
Definition kokkos.hh:538