Loading...
Searching...
No Matches
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
20namespace CubbyFlow
21{
22template <typename T>
23CUDAStdVector<T>::CUDAStdVector(size_t n, const ValueType& initVal)
24{
26 CUDAFill(m_ptr, n, initVal);
27}
28
29template <typename T>
30template <typename A>
31CUDAStdVector<T>::CUDAStdVector(const std::vector<T, A>& other)
33{
34 CUDACopyHostToDevice(other.data(), m_size, m_ptr);
35}
36
37template <typename T>
38CUDAStdVector<T>::CUDAStdVector(const CUDAStdVector& other)
39 : CUDAStdVector{ other.Size() }
40{
41 CUDACopyDeviceToDevice(other.m_ptr, m_size, m_ptr);
42}
43
44template <typename T>
45CUDAStdVector<T>::CUDAStdVector(CUDAStdVector&& other) noexcept
46{
47 *this = std::move(other);
48}
49
50template <typename T>
51CUDAStdVector<T>::~CUDAStdVector()
52{
53 Clear();
54}
55
56template <typename T>
57template <typename A>
58CUDAStdVector<T>& CUDAStdVector<T>::operator=(const std::vector<T, A>& other)
59{
60 CopyFrom(other);
61 return *this;
62}
63
64template <typename T>
65CUDAStdVector<T>& CUDAStdVector<T>::operator=(const CUDAStdVector& other)
66{
67 CopyFrom(other);
68 return *this;
69}
70
71template <typename T>
72CUDAStdVector<T>& CUDAStdVector<T>::operator=(CUDAStdVector&& other) noexcept
73{
74 Clear();
75
76 Swap(other);
77 return *this;
78}
79
80template <typename T>
81typename CUDAStdVector<T>::Pointer CUDAStdVector<T>::data()
82{
83 return m_ptr;
84}
85
86template <typename T>
87typename CUDAStdVector<T>::ConstPointer CUDAStdVector<T>::data() const
88{
89 return m_ptr;
90}
91
92template <typename T>
93size_t CUDAStdVector<T>::Size() const
94{
95 return m_size;
96}
97
98#ifdef __CUDA_ARCH__
99template <typename T>
100__device__ typename CUDAStdVector<T>::Reference CUDAStdVector<T>::At(size_t i)
101{
102 return m_ptr[i];
103}
104
105template <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
112template <typename T>
113typename CUDAStdVector<T>::ReferenceType CUDAStdVector<T>::At(size_t i)
114{
115 ReferenceType r(m_ptr + i);
116 return r;
117}
118
119template <typename T>
120T 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
128template <typename T>
129void 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
140template <typename T>
141void CUDAStdVector<T>::Fill(const ValueType& val)
142{
143 CUDAFill(m_ptr, m_size, val);
144}
145
146template <typename T>
147void 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
155template <typename T>
156void 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
164template <typename T>
165void CUDAStdVector<T>::Swap(CUDAStdVector& other)
166{
167 std::swap(m_ptr, other.m_ptr);
168 std::swap(m_size, other.m_size);
169}
170
171template <typename T>
172void 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
182template <typename T>
183void CUDAStdVector<T>::Append(const ValueType& val)
184{
185 PushBack(val);
186}
187
188template <typename T>
189void 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
199template <typename T>
200template <typename A>
201void 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
214template <typename T>
215void 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
228template <typename T>
229template <typename A>
230void 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__
237template <typename T>
238typename CUDAStdVector<T>::Reference CUDAStdVector<T>::operator[](size_t i)
239{
240 return At(i);
241}
242
243template <typename T>
244typename CUDAStdVector<T>::ConstReference CUDAStdVector<T>::operator[](
245 size_t i) const
246{
247 return At(i);
248}
249#else
250template <typename T>
251typename CUDAStdVector<T>::ReferenceType CUDAStdVector<T>::operator[](size_t i)
252{
253 return At(i);
254}
255
256template <typename T>
257T CUDAStdVector<T>::operator[](size_t i) const
258{
259 return At(i);
260}
261#endif
262} // namespace CubbyFlow
263
264#endif
265
266#endif
Definition pybind11Utils.hpp:21
Matrix< T, Rows, 1 > Vector
Definition Matrix.hpp:738