muda
dense_3d.h
1 #pragma once
2 #include <muda/viewer/viewer_base.h>
3 
4 namespace muda
5 {
6 /*****************************************************************************************
7  *
8  * Dense2D (3D array)
9  * indexing (x,y,z)
10  * 1) non-pitched: x * dim_y * dimz + y * dim_z + z
11  * 2) pitched: x * dim_y * pitch + y * pitch + z
12  *
13  * Note:
14  * 1) z moves faster than y, y moves faster than x, which is the same as C/C++ 2d array
15  * 2) as for CUDA Memory3D, x index into depth, y index into height, z index into width
16  ****************************************************************************************/
17 
18 template <bool IsConst, typename T>
19 class Dense3DBase : public ViewerBase<IsConst>
20 {
21  using Base = ViewerBase<IsConst>;
22  MUDA_VIEWER_COMMON_NAME(Dense3DBase);
23 
24  protected:
25  template <typename U>
26  using auto_const_t = typename Base::template auto_const_t<U>;
27 
28  auto_const_t<T>* m_data;
29  int3 m_offset;
30  int3 m_dim;
31  int m_pitch_bytes;
32  int m_pitch_bytes_area;
33 
34  public:
35  using value_type = T;
39 
40  MUDA_GENERIC Dense3DBase() MUDA_NOEXCEPT : m_data(nullptr){};
41 
42  MUDA_GENERIC Dense3DBase(auto_const_t<T>* p,
43  const int3& offset,
44  const int3& dim,
45  int pitch_bytes,
46  int pitch_bytes_area) MUDA_NOEXCEPT
47  : m_data(p),
48  m_offset(offset),
49  m_dim(dim),
50  m_pitch_bytes(pitch_bytes),
51  m_pitch_bytes_area(pitch_bytes_area)
52  {
53  }
54 
55  MUDA_GENERIC auto as_const() const MUDA_NOEXCEPT
56  {
57  return ConstViewer{m_data, m_offset, m_dim, m_pitch_bytes, m_pitch_bytes_area};
58  }
59 
60  MUDA_GENERIC operator ConstViewer() const MUDA_NOEXCEPT
61  {
62  return as_const();
63  }
64 
65  MUDA_GENERIC auto_const_t<T>& operator()(int x, int y, int z) MUDA_NOEXCEPT
66  {
67  check();
68  check_range(x, y, z);
69  auto depth_begin = reinterpret_cast<std::byte*>(m_data) + x * m_pitch_bytes_area;
70  auto height_begin = depth_begin + y * m_pitch_bytes;
71  return *(reinterpret_cast<T*>(height_begin) + z);
72  }
73 
74  MUDA_GENERIC auto_const_t<T>& operator()(const int3& xyz) MUDA_NOEXCEPT
75  {
76  return operator()(xyz.x, xyz.y, xyz.z);
77  }
78 
79  MUDA_GENERIC auto_const_t<T>& flatten(int i) MUDA_NOEXCEPT
80  {
81  if constexpr(DEBUG_VIEWER)
82  {
83  MUDA_KERNEL_ASSERT(i >= 0 && i < total_size(),
84  "Dense3D[%s:%s]: out of range, index=%d, total_size=%d",
85  this->name(),
86  this->kernel_name(),
87  i,
88  total_size());
89  }
90  auto area = m_dim.y * m_dim.z;
91  auto x = i / area;
92  auto i_in_area = i % area;
93  auto y = i_in_area / m_dim.z;
94  auto i_in_width = i_in_area % m_dim.z;
95  auto z = i_in_width;
96  return operator()(x, y, z);
97  }
98 
99  MUDA_GENERIC auto_const_t<T>* data() MUDA_NOEXCEPT { return m_data; }
100 
101 
102  MUDA_GENERIC const T& operator()(int x, int y, int z) const MUDA_NOEXCEPT
103  {
104  return remove_const(*this)(x, y, z);
105  }
106 
107 
108  MUDA_GENERIC const T& operator()(const int3& xyz) const MUDA_NOEXCEPT
109  {
110  return remove_const(*this)(xyz.x, xyz.y, xyz.z);
111  }
112 
113  MUDA_GENERIC const T& flatten(int i) const MUDA_NOEXCEPT
114  {
115  return remove_const(*this).flatten(i);
116  }
117 
118  MUDA_GENERIC const T* data() const MUDA_NOEXCEPT { return m_data; }
119 
120 
121  MUDA_GENERIC auto dim() const MUDA_NOEXCEPT { return m_dim; }
122  MUDA_GENERIC int area() const MUDA_NOEXCEPT { return m_dim.y * m_dim.z; }
123  MUDA_GENERIC int volume() const MUDA_NOEXCEPT { return total_size(); }
124  MUDA_GENERIC int total_size() const MUDA_NOEXCEPT
125  {
126  return m_dim.x * area();
127  }
128  MUDA_GENERIC int pitch_bytes() const MUDA_NOEXCEPT { return m_pitch_bytes; }
129  MUDA_GENERIC int pitch_bytes_area() const MUDA_NOEXCEPT
130  {
131  return m_pitch_bytes_area;
132  }
133  MUDA_GENERIC int total_bytes() const MUDA_NOEXCEPT
134  {
135  return m_pitch_bytes_area * m_dim.x;
136  }
137 
138  protected:
139  MUDA_INLINE MUDA_GENERIC void check_range(int x, int y, int z) const MUDA_NOEXCEPT
140  {
141  if constexpr(DEBUG_VIEWER)
142  {
143  if(!(x >= 0 && x < m_dim.x && y >= 0 && y < m_dim.y && z >= 0
144  && z < m_dim.z))
145  MUDA_KERNEL_ERROR("Dense3D[%s:%s]: out of range, index=(%d,%d,%d) dim=(%d,%d,%d)",
146  this->name(),
147  this->kernel_name(),
148  x,
149  y,
150  z,
151  m_dim.x,
152  m_dim.y,
153  m_dim.z);
154  }
155  }
156 
157  MUDA_INLINE MUDA_GENERIC void check() const MUDA_NOEXCEPT
158  {
159  if constexpr(DEBUG_VIEWER)
160  if(m_data == nullptr)
161  MUDA_KERNEL_ERROR("Dense3D[%s:%s]: data is null",
162  this->name(),
163  this->kernel_name());
164  }
165 };
166 
167 template <typename T>
169 
170 template <typename T>
172 
173 // viewer traits
174 template <typename T>
176 {
177  using type = CDense3D<T>;
178 };
179 
180 template <typename T>
182 {
183  using type = Dense3D<T>;
184 };
185 
186 // make functions
187 template <typename T>
188 MUDA_INLINE MUDA_GENERIC auto make_cdense_3d(const T* data, const int3& dim) MUDA_NOEXCEPT
189 {
190  auto pitch_bytes = dim.z * sizeof(T);
191  return CDense3D<T>{data,
192  make_int3(0, 0, 0),
193  dim,
194  static_cast<int>(pitch_bytes),
195  static_cast<int>(dim.y * pitch_bytes)};
196 }
197 
198 template <typename T>
199 MUDA_INLINE MUDA_GENERIC auto make_dense_3d(T* data, const int3& dim) MUDA_NOEXCEPT
200 {
201  auto pitch_bytes = dim.z * sizeof(T);
202  return Dense3D<T>{data,
203  make_int3(0, 0, 0),
204  dim,
205  static_cast<int>(pitch_bytes),
206  static_cast<int>(dim.y * pitch_bytes)};
207 }
208 
209 template <typename T>
210 MUDA_INLINE MUDA_GENERIC auto make_cdense_3d(const T* data, int dimx, int dimy, int dimz) MUDA_NOEXCEPT
211 {
212  return make_cdense_3d(data, make_int3(dimx, dimy, dimz));
213 }
214 
215 template <typename T>
216 MUDA_INLINE MUDA_GENERIC auto make_dense_3d(T* data, int dimx, int dimy, int dimz) MUDA_NOEXCEPT
217 {
218  return make_dense_3d(data, make_int3(dimx, dimy, dimz));
219 }
220 } // namespace muda
Definition: dense_3d.h:19
Definition: type_modifier.h:21
Definition: type_modifier.h:27
Definition: assert.h:13
Definition: viewer_base.h:21