DiFfRG
Loading...
Searching...
No Matches
tex_linear_interpolation_3D.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
7
8// standard library
9#include <memory>
10
11// external libraries
12#include <autodiff/forward/real.hpp>
13
14namespace DiFfRG
15{
22 template <typename NT, typename Coordinates> class TexLinearInterpolator3D
23 {
24 static_assert(Coordinates::dim == 3, "TexLinearInterpolator3D requires 3D coordinates");
25
26 public:
33 TexLinearInterpolator3D(const std::vector<NT> &data, const Coordinates &coordinates);
40 TexLinearInterpolator3D(const NT *data, const Coordinates &coordinates);
53
55
56 template <typename NT2> void update(const NT2 *data)
57 {
58 if (!owner) throw std::runtime_error("Cannot update data of non-owner interpolator");
59
60 if constexpr (std::is_same_v<NT2, autodiff::real>)
61 for (uint i = 0; i < size; ++i) {
62 m_data[i] = static_cast<float>(val(data[i]));
63 m_data_AD[i] = static_cast<float>(derivative(data[i]));
64 }
65 else
66 for (uint i = 0; i < size; ++i)
67 m_data[i] = static_cast<float>(data[i]);
68
69 update();
70 }
71 void update();
72
73 float *data() const;
74 float *data_AD() const;
75
77
86 __device__ __host__ ReturnType operator()(const float x, const float y, const float z) const
87 {
88 auto [idx_x, idx_y, idx_z] = coordinates.backward(x, y, z);
89#ifdef __CUDA_ARCH__
90 if constexpr (std::is_same_v<ReturnType, autodiff::real>)
91 return std::array<double, 2>{tex3D<float>(texture, idx_z + 0.5f, idx_y + 0.5f, idx_x + 0.5f),
92 tex3D<float>(texture_AD, idx_z + 0.5f, idx_y + 0.5f, idx_x + 0.5f)};
93 else if constexpr (std::is_same_v<ReturnType, float>)
94 return tex3D<float>(texture, idx_z + 0.5f, idx_y + 0.5f, idx_x + 0.5f);
95#else
96 using std::ceil;
97 using std::floor;
98 using std::max;
99 using std::min;
100
101 idx_x = max(static_cast<decltype(idx_x)>(0), min(idx_x, static_cast<decltype(idx_x)>(shape[0] - 1)));
102 idx_y = max(static_cast<decltype(idx_y)>(0), min(idx_y, static_cast<decltype(idx_y)>(shape[1] - 1)));
103 idx_z = max(static_cast<decltype(idx_z)>(0), min(idx_z, static_cast<decltype(idx_z)>(shape[2] - 1)));
104
105 uint x1 = min(ceil(idx_x + static_cast<decltype(idx_x)>(1e-16)), static_cast<decltype(idx_x)>(shape[0] - 1));
106 const auto x0 = x1 - 1;
107 uint y1 = min(ceil(idx_y + static_cast<decltype(idx_y)>(1e-16)), static_cast<decltype(idx_y)>(shape[1] - 1));
108 const auto y0 = y1 - 1;
109 uint z1 = min(ceil(idx_z + static_cast<decltype(idx_z)>(1e-16)), static_cast<decltype(idx_z)>(shape[2] - 1));
110 const auto z0 = z1 - 1;
111
112 const auto corner000 = m_data[x0 * shape[1] * shape[2] + y0 * shape[2] + z0];
113 const auto corner001 = m_data[x0 * shape[1] * shape[2] + y0 * shape[2] + z1];
114 const auto corner010 = m_data[x0 * shape[1] * shape[2] + y1 * shape[2] + z0];
115 const auto corner011 = m_data[x0 * shape[1] * shape[2] + y1 * shape[2] + z1];
116 const auto corner100 = m_data[x1 * shape[1] * shape[2] + y0 * shape[2] + z0];
117 const auto corner101 = m_data[x1 * shape[1] * shape[2] + y0 * shape[2] + z1];
118 const auto corner110 = m_data[x1 * shape[1] * shape[2] + y1 * shape[2] + z0];
119 const auto corner111 = m_data[x1 * shape[1] * shape[2] + y1 * shape[2] + z1];
120
121 const auto ret = corner000 * (x1 - idx_x) * (y1 - idx_y) * (z1 - idx_z) +
122 corner001 * (x1 - idx_x) * (y1 - idx_y) * (idx_z - z0) +
123 corner010 * (x1 - idx_x) * (idx_y - y0) * (z1 - idx_z) +
124 corner011 * (x1 - idx_x) * (idx_y - y0) * (idx_z - z0) +
125 corner100 * (idx_x - x0) * (y1 - idx_y) * (z1 - idx_z) +
126 corner101 * (idx_x - x0) * (y1 - idx_y) * (idx_z - z0) +
127 corner110 * (idx_x - x0) * (idx_y - y0) * (z1 - idx_z) +
128 corner111 * (idx_x - x0) * (idx_y - y0) * (idx_z - z0);
129
130 if constexpr (std::is_same_v<ReturnType, autodiff::real>) {
131 const auto corner000_AD = m_data_AD[x0 * shape[1] * shape[2] + y0 * shape[2] + z0];
132 const auto corner001_AD = m_data_AD[x0 * shape[1] * shape[2] + y0 * shape[2] + z1];
133 const auto corner010_AD = m_data_AD[x0 * shape[1] * shape[2] + y1 * shape[2] + z0];
134 const auto corner011_AD = m_data_AD[x0 * shape[1] * shape[2] + y1 * shape[2] + z1];
135 const auto corner100_AD = m_data_AD[x1 * shape[1] * shape[2] + y0 * shape[2] + z0];
136 const auto corner101_AD = m_data_AD[x1 * shape[1] * shape[2] + y0 * shape[2] + z1];
137 const auto corner110_AD = m_data_AD[x1 * shape[1] * shape[2] + y1 * shape[2] + z0];
138 const auto corner111_AD = m_data_AD[x1 * shape[1] * shape[2] + y1 * shape[2] + z1];
139
140 const auto ret_AD = corner000_AD * (x1 - idx_x) * (y1 - idx_y) * (z1 - idx_z) +
141 corner001_AD * (x1 - idx_x) * (y1 - idx_y) * (idx_z - z0) +
142 corner010_AD * (x1 - idx_x) * (idx_y - y0) * (z1 - idx_z) +
143 corner011_AD * (x1 - idx_x) * (idx_y - y0) * (idx_z - z0) +
144 corner100_AD * (idx_x - x0) * (y1 - idx_y) * (z1 - idx_z) +
145 corner101_AD * (idx_x - x0) * (y1 - idx_y) * (idx_z - z0) +
146 corner110_AD * (idx_x - x0) * (idx_y - y0) * (z1 - idx_z) +
147 corner111_AD * (idx_x - x0) * (idx_y - y0) * (idx_z - z0);
148
149 return std::array<double, 2>{{ret, ret_AD}};
150 } else if constexpr (std::is_same_v<ReturnType, float>)
151 return ret;
152#endif
153 }
154
156 const ReturnType &operator[](const uint i) const;
157
163 const Coordinates &get_coordinates() const { return coordinates; }
164
165 private:
166 const uint size;
167 const std::array<uint, 3> shape;
168 const Coordinates coordinates;
169
170 std::shared_ptr<float[]> m_data;
171 cudaArray_t device_array;
172 cudaTextureObject_t texture;
173
174 std::shared_ptr<float[]> m_data_AD;
175 cudaArray_t device_array_AD;
176 cudaTextureObject_t texture_AD;
177
178 const bool owner;
179 };
180} // namespace DiFfRG
A linear interpolator for 3D data, using texture memory on the GPU and floating point arithmetic on t...
Definition tex_linear_interpolation_3D.hh:23
const ReturnType & operator[](const uint i) const
const uint size
Definition tex_linear_interpolation_3D.hh:166
cudaTextureObject_t texture_AD
Definition tex_linear_interpolation_3D.hh:176
TexLinearInterpolator3D(const Coordinates &coordinates)
Construct a TexLinearInterpolator3D with internal, zeroed data and a coordinate system.
cudaArray_t device_array_AD
Definition tex_linear_interpolation_3D.hh:175
TexLinearInterpolator3D(const NT *data, const Coordinates &coordinates)
Construct a TexLinearInterpolator3D object from a pointer to data and a coordinate system.
__device__ __host__ ReturnType operator()(const float x, const float y, const float z) const
Interpolate the data at a given point.
Definition tex_linear_interpolation_3D.hh:86
ReturnType & operator[](const uint i)
const Coordinates & get_coordinates() const
Get the coordinate system of the data.
Definition tex_linear_interpolation_3D.hh:163
typename internal::__TLITypes< NT >::ReturnType ReturnType
Definition tex_linear_interpolation_3D.hh:76
cudaArray_t device_array
Definition tex_linear_interpolation_3D.hh:171
TexLinearInterpolator3D(const TexLinearInterpolator3D &other)
Construct a copy of a TexLinearInterpolator3D object.
void update(const NT2 *data)
Definition tex_linear_interpolation_3D.hh:56
const Coordinates coordinates
Definition tex_linear_interpolation_3D.hh:168
TexLinearInterpolator3D(const std::vector< NT > &data, const Coordinates &coordinates)
Construct a TexLinearInterpolator3D object from a vector of data and a coordinate system.
const bool owner
Definition tex_linear_interpolation_3D.hh:178
const std::array< uint, 3 > shape
Definition tex_linear_interpolation_3D.hh:167
std::shared_ptr< float[]> m_data
Definition tex_linear_interpolation_3D.hh:170
std::shared_ptr< float[]> m_data_AD
Definition tex_linear_interpolation_3D.hh:174
cudaTextureObject_t texture
Definition tex_linear_interpolation_3D.hh:172
Definition complex_math.hh:14
unsigned int uint
Definition utils.hh:22
Definition common.hh:10