CUDAStdVector-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_STD_VECTOR_IMPL_HPP
12 #define CUBBYFLOW_CUDA_STD_VECTOR_IMPL_HPP
13 
14 #ifdef CUBBYFLOW_USE_CUDA
15 
17 
18 #include <algorithm>
19 
20 namespace CubbyFlow
21 {
22 template <typename T>
23 CUDAStdVector<T>::CUDAStdVector(size_t n, const ValueType& initVal)
24 {
25  ResizeUninitialized(n);
26  CUDAFill(m_ptr, n, initVal);
27 }
28 
29 template <typename T>
30 template <typename A>
31 CUDAStdVector<T>::CUDAStdVector(const std::vector<T, A>& other)
32  : CUDAStdVector{ other.size() }
33 {
34  CUDACopyHostToDevice(other.data(), m_size, m_ptr);
35 }
36 
37 template <typename T>
38 CUDAStdVector<T>::CUDAStdVector(const CUDAStdVector& other)
39  : CUDAStdVector{ other.Size() }
40 {
41  CUDACopyDeviceToDevice(other.m_ptr, m_size, m_ptr);
42 }
43 
44 template <typename T>
45 CUDAStdVector<T>::CUDAStdVector(CUDAStdVector&& other) noexcept
46 {
47  *this = std::move(other);
48 }
49 
50 template <typename T>
51 CUDAStdVector<T>::~CUDAStdVector()
52 {
53  Clear();
54 }
55 
56 template <typename T>
57 template <typename A>
58 CUDAStdVector<T>& CUDAStdVector<T>::operator=(const std::vector<T, A>& other)
59 {
60  CopyFrom(other);
61  return *this;
62 }
63 
64 template <typename T>
65 CUDAStdVector<T>& CUDAStdVector<T>::operator=(const CUDAStdVector& other)
66 {
67  CopyFrom(other);
68  return *this;
69 }
70 
71 template <typename T>
72 CUDAStdVector<T>& CUDAStdVector<T>::operator=(CUDAStdVector&& other) noexcept
73 {
74  Clear();
75 
76  Swap(other);
77  return *this;
78 }
79 
80 template <typename T>
81 typename CUDAStdVector<T>::Pointer CUDAStdVector<T>::data()
82 {
83  return m_ptr;
84 }
85 
86 template <typename T>
87 typename CUDAStdVector<T>::ConstPointer CUDAStdVector<T>::data() const
88 {
89  return m_ptr;
90 }
91 
92 template <typename T>
93 size_t CUDAStdVector<T>::Size() const
94 {
95  return m_size;
96 }
97 
98 #ifdef __CUDA_ARCH__
99 template <typename T>
100 __device__ typename CUDAStdVector<T>::Reference CUDAStdVector<T>::At(size_t i)
101 {
102  return m_ptr[i];
103 }
104 
105 template <typename T>
106 __device__ typename CUDAStdVector<T>::ConstReference CUDAStdVector<T>::At(
107  size_t i) const
108 {
109  return m_ptr[i];
110 }
111 #else
112 template <typename T>
113 typename CUDAStdVector<T>::ReferenceType CUDAStdVector<T>::At(size_t i)
114 {
115  ReferenceType r(m_ptr + i);
116  return r;
117 }
118 
119 template <typename T>
120 T CUDAStdVector<T>::At(size_t i) const
121 {
122  T tmp;
123  CUDACopyDeviceToHost(m_ptr + i, 1, &tmp);
124  return tmp;
125 }
126 #endif
127 
128 template <typename T>
129 void CUDAStdVector<T>::Clear()
130 {
131  if (m_ptr != nullptr)
132  {
133  CUBBYFLOW_CUDA_CHECK(cudaFree(m_ptr));
134  }
135 
136  m_ptr = nullptr;
137  m_size = 0;
138 }
139 
140 template <typename T>
141 void CUDAStdVector<T>::Fill(const ValueType& val)
142 {
143  CUDAFill(m_ptr, m_size, val);
144 }
145 
146 template <typename T>
147 void CUDAStdVector<T>::Resize(size_t n, const ValueType& initVal)
148 {
149  CUDAStdVector newBuffer(n, initVal);
150 
151  CUDACopy(m_ptr, std::min(n, m_size), newBuffer.m_ptr);
152  Swap(newBuffer);
153 }
154 
155 template <typename T>
156 void CUDAStdVector<T>::ResizeUninitialized(size_t n)
157 {
158  Clear();
159 
160  CUBBYFLOW_CUDA_CHECK(cudaMalloc(&m_ptr, n * sizeof(T)));
161  m_size = n;
162 }
163 
164 template <typename T>
165 void CUDAStdVector<T>::Swap(CUDAStdVector& other)
166 {
167  std::swap(m_ptr, other.m_ptr);
168  std::swap(m_size, other.m_size);
169 }
170 
171 template <typename T>
172 void CUDAStdVector<T>::PushBack(const ValueType& val)
173 {
174  CUDAStdVector newBuffer;
175  newBuffer.ResizeUninitialized(m_size + 1);
176 
177  CUDACopy(m_ptr, m_size, newBuffer.m_ptr);
178  CUDACopyHostToDevice(&val, 1, newBuffer.m_ptr + m_size);
179  Swap(newBuffer);
180 }
181 
182 template <typename T>
183 void CUDAStdVector<T>::Append(const ValueType& val)
184 {
185  PushBack(val);
186 }
187 
188 template <typename T>
189 void CUDAStdVector<T>::Append(const CUDAStdVector& other)
190 {
191  CUDAStdVector newBuffer;
192  newBuffer.ResizeUninitialized(m_size + other.m_size);
193 
194  CUDACopy(m_ptr, m_size, newBuffer.m_ptr);
195  CUDACopy(other.m_ptr, other.m_size, newBuffer.m_ptr + m_size);
196  Swap(newBuffer);
197 }
198 
199 template <typename T>
200 template <typename A>
201 void CUDAStdVector<T>::CopyFrom(const std::vector<T, A>& other)
202 {
203  if (m_size == other.size())
204  {
205  CUDACopyHostToDevice(other.data(), m_size, m_ptr);
206  }
207  else
208  {
209  CUDAStdVector newBuffer(other);
210  Swap(newBuffer);
211  }
212 }
213 
214 template <typename T>
215 void CUDAStdVector<T>::CopyFrom(const CUDAStdVector& other)
216 {
217  if (m_size == other.Size())
218  {
219  CUDACopyDeviceToDevice(other.data(), m_size, m_ptr);
220  }
221  else
222  {
223  CUDAStdVector newBuffer(other);
224  Swap(newBuffer);
225  }
226 }
227 
228 template <typename T>
229 template <typename A>
230 void CUDAStdVector<T>::CopyTo(std::vector<T, A>& other)
231 {
232  other.resize(m_size);
233  CUDACopyDeviceToHost(m_ptr, m_size, other.data());
234 }
235 
236 #ifdef __CUDA_ARCH__
237 template <typename T>
238 typename CUDAStdVector<T>::Reference CUDAStdVector<T>::operator[](size_t i)
239 {
240  return At(i);
241 }
242 
243 template <typename T>
244 typename CUDAStdVector<T>::ConstReference CUDAStdVector<T>::operator[](
245  size_t i) const
246 {
247  return At(i);
248 }
249 #else
250 template <typename T>
251 typename CUDAStdVector<T>::ReferenceType CUDAStdVector<T>::operator[](size_t i)
252 {
253  return At(i);
254 }
255 
256 template <typename T>
257 T CUDAStdVector<T>::operator[](size_t i) const
258 {
259  return At(i);
260 }
261 #endif
262 } // namespace CubbyFlow
263 
264 #endif
265 
266 #endif
T ValueType
Definition: ArrayBase.hpp:23
Pointer m_ptr
Definition: ArrayBase.hpp:124
Vector< size_t, N > m_size
Definition: ArrayBase.hpp:125
Definition: pybind11Utils.hpp:20
void Fill(ArrayView< T, N > a, const Vector< size_t, N > &begin, const Vector< size_t, N > &end, const T &val)
Definition: ArrayUtils-Impl.hpp:19
Reference At(size_t i)
Definition: ArrayBase-Impl.hpp:138