DiFfRG
Loading...
Searching...
No Matches
tex_linear_interpolation_2D.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 TexLinearInterpolator2D
23 {
24 static_assert(Coordinates::dim == 2, "TexLinearInterpolator2D requires 2D coordinates");
25
26 public:
33 TexLinearInterpolator2D(const std::vector<NT> &data, const Coordinates &coordinates);
40 TexLinearInterpolator2D(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
85 __device__ __host__ ReturnType operator()(const float x, const float y) const
86 {
87 auto [idx_x, idx_y] = coordinates.backward(x, y);
88#ifdef __CUDA_ARCH__
89 if constexpr (std::is_same_v<ReturnType, autodiff::real>)
90 return std::array<double, 2>{tex2D<float>(texture, idx_y + 0.5f, idx_x + 0.5f),
91 tex2D<float>(texture_AD, idx_y + 0.5f, idx_x + 0.5f)};
92 else if constexpr (std::is_same_v<ReturnType, float>)
93 return tex2D<float>(texture, idx_y + 0.5f, idx_x + 0.5f);
94#else
95 using std::ceil;
96 using std::floor;
97 using std::max;
98 using std::min;
99
100 idx_x = max(static_cast<decltype(idx_x)>(0), min(idx_x, static_cast<decltype(idx_x)>(shape[0] - 1)));
101 idx_y = max(static_cast<decltype(idx_y)>(0), min(idx_y, static_cast<decltype(idx_y)>(shape[1] - 1)));
102
103 uint x1 = min(ceil(idx_x + static_cast<decltype(idx_x)>(1e-16)), static_cast<decltype(idx_x)>(shape[0] - 1));
104 const auto x0 = x1 - 1;
105 uint y1 = min(ceil(idx_y + static_cast<decltype(idx_y)>(1e-16)), static_cast<decltype(idx_y)>(shape[1] - 1));
106 const auto y0 = y1 - 1;
107
108 const auto corner00 = m_data[x0 * shape[1] + y0];
109 const auto corner01 = m_data[x0 * shape[1] + y1];
110 const auto corner10 = m_data[x1 * shape[1] + y0];
111 const auto corner11 = m_data[x1 * shape[1] + y1];
112
113 const auto ret = corner00 * (x1 - idx_x) * (y1 - idx_y) + corner01 * (x1 - idx_x) * (idx_y - y0) +
114 corner10 * (idx_x - x0) * (y1 - idx_y) + corner11 * (idx_x - x0) * (idx_y - y0);
115
116 if constexpr (std::is_same_v<ReturnType, autodiff::real>) {
117 const auto corner00_AD = m_data_AD[x0 * shape[1] + y0];
118 const auto corner01_AD = m_data_AD[x0 * shape[1] + y1];
119 const auto corner10_AD = m_data_AD[x1 * shape[1] + y0];
120 const auto corner11_AD = m_data_AD[x1 * shape[1] + y1];
121
122 const auto ret_AD = corner00_AD * (x1 - idx_x) * (y1 - idx_y) + corner01_AD * (x1 - idx_x) * (idx_y - y0) +
123 corner10_AD * (idx_x - x0) * (y1 - idx_y) + corner11_AD * (idx_x - x0) * (idx_y - y0);
124
125 return std::array<double, 2>{{ret, ret_AD}};
126 } else if constexpr (std::is_same_v<ReturnType, float>)
127 return ret;
128#endif
129 }
130
132 const ReturnType &operator[](const uint i) const;
133
139 const Coordinates &get_coordinates() const { return coordinates; }
140
141 private:
142 const uint size;
143 const std::array<uint, 2> shape;
144 const Coordinates coordinates;
145
146 std::shared_ptr<float[]> m_data;
147 cudaArray_t device_array;
148 cudaTextureObject_t texture;
149
150 std::shared_ptr<float[]> m_data_AD;
151 cudaArray_t device_array_AD;
152 cudaTextureObject_t texture_AD;
153
154 const bool owner;
155 };
156} // namespace DiFfRG
A linear interpolator for 2D data, using texture memory on the GPU and floating point arithmetic on t...
Definition tex_linear_interpolation_2D.hh:23
cudaArray_t device_array
Definition tex_linear_interpolation_2D.hh:147
__device__ __host__ ReturnType operator()(const float x, const float y) const
Interpolate the data at a given point.
Definition tex_linear_interpolation_2D.hh:85
ReturnType & operator[](const uint i)
cudaTextureObject_t texture_AD
Definition tex_linear_interpolation_2D.hh:152
TexLinearInterpolator2D(const std::vector< NT > &data, const Coordinates &coordinates)
Construct a TexLinearInterpolator2D object from a vector of data and a coordinate system.
typename internal::__TLITypes< NT >::ReturnType ReturnType
Definition tex_linear_interpolation_2D.hh:76
std::shared_ptr< float[]> m_data
Definition tex_linear_interpolation_2D.hh:146
cudaTextureObject_t texture
Definition tex_linear_interpolation_2D.hh:148
std::shared_ptr< float[]> m_data_AD
Definition tex_linear_interpolation_2D.hh:150
const Coordinates & get_coordinates() const
Get the coordinate system of the data.
Definition tex_linear_interpolation_2D.hh:139
TexLinearInterpolator2D(const NT *data, const Coordinates &coordinates)
Construct a TexLinearInterpolator2D object from a pointer to data and a coordinate system.
const Coordinates coordinates
Definition tex_linear_interpolation_2D.hh:144
TexLinearInterpolator2D(const Coordinates &coordinates)
Construct a TexLinearInterpolator2D with internal, zeroed data and a coordinate system.
void update(const NT2 *data)
Definition tex_linear_interpolation_2D.hh:56
const ReturnType & operator[](const uint i) const
TexLinearInterpolator2D(const TexLinearInterpolator2D &other)
Construct a copy of a TexLinearInterpolator2D object.
const bool owner
Definition tex_linear_interpolation_2D.hh:154
const std::array< uint, 2 > shape
Definition tex_linear_interpolation_2D.hh:143
cudaArray_t device_array_AD
Definition tex_linear_interpolation_2D.hh:151
const uint size
Definition tex_linear_interpolation_2D.hh:142
Definition complex_math.hh:14
unsigned int uint
Definition utils.hh:22
Definition common.hh:10