CUDAArrayBase-Impl.hpp
Go to the documentation of this file.
1 // This code is based on Jet framework.
2 // Copyright (c) 2018 Doyub Kim
3 // CubbyFlow is voxel-based fluid simulation engine for computer games.
4 // Copyright (c) 2020 CubbyFlow Team
5 // Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6 // AI Part: Dongheon Cho, Minseo Kim
7 // We are making my contributions/submissions to this project solely in our
8 // personal capacity and are not conveying any rights to any intellectual
9 // property of any third parties.
10 
11 #ifndef CUBBYFLOW_CUDA_ARRAY_BASE_IMPL_HPP
12 #define CUBBYFLOW_CUDA_ARRAY_BASE_IMPL_HPP
13 
14 #ifdef CUBBYFLOW_USE_CUDA
15 
16 namespace CubbyFlow
17 {
18 template <typename T, size_t N, typename Derived>
19 size_t CUDAArrayBase<T, N, Derived>::Index(size_t i) const
20 {
21  return i;
22 }
23 
24 template <typename T, size_t N, typename Derived>
25 template <typename... Args>
26 size_t CUDAArrayBase<T, N, Derived>::Index(size_t i, Args... args) const
27 {
28  static_assert(sizeof...(args) == N - 1, "Invalid number of indices.");
29  return i + m_size[0] * IndexInternal(1, args...);
30 }
31 
32 template <typename T, size_t N, typename Derived>
33 template <size_t... I>
34 size_t CUDAArrayBase<T, N, Derived>::Index(
35  const CUDAStdArray<size_t, N>& idx) const
36 {
37  return IndexInternal(idx, std::make_index_sequence<N>{});
38 }
39 
40 template <typename T, size_t N, typename Derived>
41 T* CUDAArrayBase<T, N, Derived>::data()
42 {
43  return m_ptr;
44 }
45 
46 template <typename T, size_t N, typename Derived>
47 const T* CUDAArrayBase<T, N, Derived>::data() const
48 {
49  return m_ptr;
50 }
51 
52 template <typename T, size_t N, typename Derived>
53 const CUDAStdArray<size_t, N>& CUDAArrayBase<T, N, Derived>::Size() const
54 {
55  return m_size;
56 }
57 
58 template <typename T, size_t N, typename Derived>
59 template <size_t M>
60 std::enable_if_t<(M > 0), size_t> CUDAArrayBase<T, N, Derived>::Width() const
61 {
62  return m_size[0];
63 }
64 
65 template <typename T, size_t N, typename Derived>
66 template <size_t M>
67 std::enable_if_t<(M > 1), size_t> CUDAArrayBase<T, N, Derived>::Height() const
68 {
69  return m_size[1];
70 }
71 
72 template <typename T, size_t N, typename Derived>
73 template <size_t M>
74 std::enable_if_t<(M > 2), size_t> CUDAArrayBase<T, N, Derived>::Depth() const
75 {
76  return m_size[2];
77 }
78 
79 template <typename T, size_t N, typename Derived>
80 size_t CUDAArrayBase<T, N, Derived>::Length() const
81 {
82  size_t l = m_size[0];
83 
84  for (size_t i = 1; i < N; ++i)
85  {
86  l *= m_size[i];
87  }
88 
89  return l;
90 }
91 
92 #ifdef __CUDA_ARCH__
93 template <typename T, size_t N, typename Derived>
94 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::Reference
95 CUDAArrayBase<T, N, Derived>::At(size_t i)
96 {
97  return m_ptr[i];
98 }
99 
100 template <typename T, size_t N, typename Derived>
101 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::ConstReference
102 CUDAArrayBase<T, N, Derived>::At(size_t i) const
103 {
104  return m_ptr[i];
105 }
106 
107 template <typename T, size_t N, typename Derived>
108 template <typename... Args>
109 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::Reference
110 CUDAArrayBase<T, N, Derived>::At(size_t i, Args... args)
111 {
112  return At(Index(i, args...));
113 }
114 
115 template <typename T, size_t N, typename Derived>
116 template <typename... Args>
117 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::ConstReference
118 CUDAArrayBase<T, N, Derived>::At(size_t i, Args... args) const
119 {
120  return At(Index(i, args...));
121 }
122 
123 template <typename T, size_t N, typename Derived>
124 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::Reference
125 CUDAArrayBase<T, N, Derived>::At(const CUDAStdArray<size_t, N>& idx)
126 {
127  return At(Index(idx));
128 }
129 
130 template <typename T, size_t N, typename Derived>
131 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::ConstReference
132 CUDAArrayBase<T, N, Derived>::At(const CUDAStdArray<size_t, N>& idx) const
133 {
134  return At(Index(idx));
135 }
136 
137 template <typename T, size_t N, typename Derived>
138 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::Reference
139 CUDAArrayBase<T, N, Derived>::operator[](size_t i)
140 {
141  return At(i);
142 }
143 
144 template <typename T, size_t N, typename Derived>
145 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::ConstReference
146 CUDAArrayBase<T, N, Derived>::operator[](size_t i) const
147 {
148  return At(i);
149 }
150 
151 template <typename T, size_t N, typename Derived>
152 template <typename... Args>
153 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::Reference
154 CUDAArrayBase<T, N, Derived>::operator()(size_t i, Args... args)
155 {
156  return At(i, args...);
157 }
158 
159 template <typename T, size_t N, typename Derived>
160 template <typename... Args>
161 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::ConstReference
162 CUDAArrayBase<T, N, Derived>::operator()(size_t i, Args... args) const
163 {
164  return At(i, args...);
165 }
166 
167 template <typename T, size_t N, typename Derived>
168 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::Reference
169 CUDAArrayBase<T, N, Derived>::operator()(const CUDAStdArray<size_t, N>& idx)
170 {
171  return At(idx);
172 }
173 
174 template <typename T, size_t N, typename Derived>
175 CUBBYFLOW_CUDA_DEVICE typename CUDAArrayBase<T, N, Derived>::ConstReference
176 CUDAArrayBase<T, N, Derived>::operator()(
177  const CUDAStdArray<size_t, N>& idx) const
178 {
179  return At(idx);
180 }
181 #else
182 template <typename T, size_t N, typename Derived>
183 typename CUDAArrayBase<T, N, Derived>::HostReference
184 CUDAArrayBase<T, N, Derived>::At(size_t i)
185 {
186  return HostReference(m_ptr + i);
187 }
188 
189 template <typename T, size_t N, typename Derived>
190 T CUDAArrayBase<T, N, Derived>::At(size_t i) const
191 {
192  return (T)HostReference(m_ptr + i);
193 }
194 
195 template <typename T, size_t N, typename Derived>
196 template <typename... Args>
197 typename CUDAArrayBase<T, N, Derived>::HostReference
198 CUDAArrayBase<T, N, Derived>::At(size_t i, Args... args)
199 {
200  return At(Index(i, args...));
201 }
202 
203 template <typename T, size_t N, typename Derived>
204 template <typename... Args>
205 T CUDAArrayBase<T, N, Derived>::At(size_t i, Args... args) const
206 {
207  return At(Index(i, args...));
208 }
209 
210 template <typename T, size_t N, typename Derived>
211 typename CUDAArrayBase<T, N, Derived>::HostReference
212 CUDAArrayBase<T, N, Derived>::At(const CUDAStdArray<size_t, N>& idx)
213 {
214  return At(Index(idx));
215 }
216 
217 template <typename T, size_t N, typename Derived>
218 T CUDAArrayBase<T, N, Derived>::At(const CUDAStdArray<size_t, N>& idx) const
219 {
220  return At(Index(idx));
221 }
222 
223 template <typename T, size_t N, typename Derived>
224 typename CUDAArrayBase<T, N, Derived>::HostReference
225 CUDAArrayBase<T, N, Derived>::operator[](size_t i)
226 {
227  return At(i);
228 }
229 
230 template <typename T, size_t N, typename Derived>
231 T CUDAArrayBase<T, N, Derived>::operator[](size_t i) const
232 {
233  return At(i);
234 }
235 
236 template <typename T, size_t N, typename Derived>
237 template <typename... Args>
238 typename CUDAArrayBase<T, N, Derived>::HostReference
239 CUDAArrayBase<T, N, Derived>::operator()(size_t i, Args... args)
240 {
241  return At(i, args...);
242 }
243 
244 template <typename T, size_t N, typename Derived>
245 template <typename... Args>
246 T CUDAArrayBase<T, N, Derived>::operator()(size_t i, Args... args) const
247 {
248  return At(i, args...);
249 }
250 
251 template <typename T, size_t N, typename Derived>
252 typename CUDAArrayBase<T, N, Derived>::HostReference
253 CUDAArrayBase<T, N, Derived>::operator()(const CUDAStdArray<size_t, N>& idx)
254 {
255  return At(idx);
256 }
257 
258 template <typename T, size_t N, typename Derived>
259 T CUDAArrayBase<T, N, Derived>::operator()(
260  const CUDAStdArray<size_t, N>& idx) const
261 {
262  return At(idx);
263 }
264 #endif
265 
266 template <typename T, size_t N, typename Derived>
267 CUDAArrayBase<T, N, Derived>::CUDAArrayBase() : m_size{}
268 {
269  // Do nothing
270 }
271 
272 template <typename T, size_t N, typename Derived>
273 CUDAArrayBase<T, N, Derived>::CUDAArrayBase(const CUDAArrayBase& other)
274 {
275  SetPtrAndSize(other.m_ptr, other.m_size);
276 }
277 
278 template <typename T, size_t N, typename Derived>
279 CUDAArrayBase<T, N, Derived>::CUDAArrayBase(CUDAArrayBase&& other) noexcept
280 {
281  *this = std::move(other);
282 }
283 
284 template <typename T, size_t N, typename Derived>
285 CUDAArrayBase<T, N, Derived>& CUDAArrayBase<T, N, Derived>::operator=(
286  const CUDAArrayBase& other)
287 {
288  SetPtrAndSize(other.m_ptr, other.m_size);
289  return *this;
290 }
291 
292 template <typename T, size_t N, typename Derived>
293 CUDAArrayBase<T, N, Derived>& CUDAArrayBase<T, N, Derived>::operator=(
294  CUDAArrayBase&& other) noexcept
295 {
296  SetPtrAndSize(other.m_ptr, other.m_size);
297  other.SetPtrAndSize(nullptr, CUDAStdArray<size_t, N>{});
298  return *this;
299 }
300 
301 template <typename T, size_t N, typename Derived>
302 template <typename... Args>
303 void CUDAArrayBase<T, N, Derived>::SetPtrAndSize(Pointer ptr, size_t ni,
304  Args... args)
305 {
306  SetPtrAndSize(ptr, CUDAStdArray<size_t, N>{ ni, args... });
307 }
308 
309 template <typename T, size_t N, typename Derived>
310 void CUDAArrayBase<T, N, Derived>::SetPtrAndSize(Pointer ptr,
311  CUDAStdArray<size_t, N> size)
312 {
313  m_ptr = ptr;
314  m_size = size;
315 }
316 
317 template <typename T, size_t N, typename Derived>
318 void CUDAArrayBase<T, N, Derived>::SwapPtrAndSize(CUDAArrayBase& other)
319 {
320  CUDASwap(m_ptr, other.m_ptr);
321  CUDASwap(m_size, other.m_size);
322 }
323 
324 template <typename T, size_t N, typename Derived>
325 void CUDAArrayBase<T, N, Derived>::ClearPtrAndSize()
326 {
327  SetPtrAndSize(nullptr, CUDAStdArray<size_t, N>{});
328 }
329 
330 template <typename T, size_t N, typename Derived>
331 template <typename... Args>
332 size_t CUDAArrayBase<T, N, Derived>::IndexInternal(size_t d, size_t i,
333  Args... args) const
334 {
335  return i + m_size[d] * IndexInternal(d + 1, args...);
336 }
337 
338 template <typename T, size_t N, typename Derived>
339 size_t CUDAArrayBase<T, N, Derived>::IndexInternal(size_t, size_t i) const
340 {
341  return i;
342 }
343 
344 template <typename T, size_t N, typename Derived>
345 template <size_t... I>
346 size_t CUDAArrayBase<T, N, Derived>::IndexInternal(
347  const CUDAStdArray<size_t, N>& idx, std::index_sequence<I...>) const
348 {
349  return Index(idx[I]...);
350 }
351 } // namespace CubbyFlow
352 
353 #endif
354 
355 #endif
Pointer m_ptr
Definition: ArrayBase.hpp:124
Vector< size_t, N > m_size
Definition: ArrayBase.hpp:125
Definition: pybind11Utils.hpp:20
size_t Index(size_t i) const
Definition: ArrayBase-Impl.hpp:17
T * Pointer
Definition: ArrayBase.hpp:26
void SetPtrAndSize(Pointer ptr, size_t ni, Args... args)
Definition: ArrayBase-Impl.hpp:250