Fermat
vector.h
1 /*
2  * cugar
3  * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the NVIDIA CORPORATION nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
32 #pragma once
33 
34 #include <cugar/basic/types.h>
35 #include <cugar/basic/iterator.h>
36 #include <cugar/basic/thrust_view.h>
37 #include <cugar/basic/vector_view.h>
38 #include <cugar/basic/cuda/allocator.h>
39 #include <thrust/host_vector.h>
40 #include <thrust/device_vector.h>
41 
42 namespace cugar {
43 namespace cuda {
44 
65 
68 
69 // utility function to copy a thrust device vector to a thrust host vector
70 // the sole reason for this is to eliminate warnings from thrust when using the assignment operator
71 template<typename TTargetVector, typename TSourceVector>
72 static CUGAR_FORCEINLINE void thrust_copy_vector(TTargetVector& target, TSourceVector& source)
73 {
74  if (target.size() != source.size())
75  {
76  target.clear();
77  target.resize(source.size());
78  }
79 
80  thrust::copy(source.begin(), source.end(), target.begin());
81 }
82 
83 template<typename TTargetVector, typename TSourceVector>
84 static CUGAR_FORCEINLINE void thrust_copy_vector(TTargetVector& target, TSourceVector& source, uint32 count)
85 {
86  if (target.size() != count)
87  {
88  target.clear();
89  target.resize(count);
90  }
91 
92  thrust::copy(source.begin(), source.begin() + count, target.begin());
93 }
94 
95 } // namespace cuda
96 
99 template <typename system_tag, typename T>
101 
102 template <typename T>
104 {
105  typedef std::allocator<T> type;
106 };
107 
108 template <typename T>
110 {
111  typedef thrust::device_malloc_allocator<T> type;
112 };
113 
116 template <typename system_tag, typename T, typename Alloc = typename default_vector_allocator<system_tag,T>::type>
117 struct vector {};
118 
121 template <typename T, typename Alloc>
122 struct vector<host_tag,T,Alloc> : public thrust::host_vector<T,Alloc>
123 {
124  typedef host_tag system_tag;
125 
126  typedef thrust::host_vector<T,Alloc> base_type;
127  typedef typename base_type::const_iterator const_iterator;
128  typedef typename base_type::iterator iterator;
129  typedef typename base_type::value_type value_type;
130 
133 
136  vector(const size_t size = 0, const T val = T()) : base_type( size, val ) {}
137 
138  template <typename OtherAlloc>
139  vector(const thrust::host_vector<T,OtherAlloc>& v) : base_type( v ) {}
140 
141  template <typename OtherAlloc>
142  vector(const thrust::device_vector<T,OtherAlloc>& v) : base_type( v ) {}
143 
144  template <typename OtherAlloc>
145  vector<host_tag,T,Alloc>& operator= (const thrust::host_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
146 
147  template <typename OtherAlloc>
148  vector<host_tag,T,Alloc>& operator= (const thrust::device_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
149 
152  operator plain_view_type() { return plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
153 
156  operator const_plain_view_type() const { return const_plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
157 
160  void expand(const size_t sz)
161  {
162  if (size() < sz)
163  resize( sz );
164  }
165 
166  T& last() { return (*this)[size() - 1]; }
167  const T& last() const { return (*this)[size() - 1]; }
168 };
169 
172 template <typename T, typename Alloc>
173 struct vector<device_tag,T,Alloc> : public thrust::device_vector<T,Alloc>
174 {
175  typedef device_tag system_tag;
176 
177  typedef thrust::device_vector<T,Alloc> base_type;
178  typedef typename base_type::const_iterator const_iterator;
179  typedef typename base_type::iterator iterator;
180  typedef typename base_type::value_type value_type;
181 
182  typedef cugar::vector_view<T*,uint64> plain_view_type;
183  typedef cugar::vector_view<const T*,uint64> const_plain_view_type;
184 
187  vector(const size_t size = 0, const T val = T()) : base_type( size, val ) {}
188 
189  template <typename OtherAlloc>
190  vector(const thrust::host_vector<T,OtherAlloc>& v) : base_type( v ) {}
191 
192  template <typename OtherAlloc>
193  vector(const thrust::device_vector<T,OtherAlloc>& v) : base_type( v ) {}
194 
195  template <typename OtherAlloc>
196  vector<device_tag,T,Alloc>& operator= (const thrust::host_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
197 
198  template <typename OtherAlloc>
199  vector<device_tag,T,Alloc>& operator= (const thrust::device_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
200 
203  operator plain_view_type() { return plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
204 
207  operator const_plain_view_type() const { return const_plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
208 
211  void expand(const size_t sz)
212  {
213  if (size() < sz)
214  resize( sz );
215  }
216 
217  T& last() { return (*this)[size() - 1]; }
218  const T& last() const { return (*this)[size() - 1]; }
219 };
220 
223 template <typename T>
224 struct host_vector : public vector<host_tag,T>
225 {
226  typedef host_tag system_tag;
227 
228  typedef vector<host_tag,T> base_type;
229  typedef typename base_type::const_iterator const_iterator;
230  typedef typename base_type::iterator iterator;
231  typedef typename base_type::value_type value_type;
232 
233  typedef typename base_type::plain_view_type plain_view_type;
234  typedef typename base_type::const_plain_view_type const_plain_view_type;
235 
238  host_vector(const size_t size = 0, const T val = T()) : base_type( size, val ) {}
239 
240  template <typename OtherAlloc>
241  host_vector(const thrust::host_vector<T,OtherAlloc>& v) : base_type( v ) {}
242 
243  template <typename OtherAlloc>
244  host_vector(const thrust::device_vector<T,OtherAlloc>& v) : base_type( v ) {}
245 
246  template <typename OtherAlloc>
247  host_vector<T>& operator= (const thrust::host_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
248 
249  template <typename OtherAlloc>
250  host_vector<T>& operator= (const thrust::device_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
251 
254  operator plain_view_type() { return plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
255 
258  operator const_plain_view_type() const { return const_plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
259 };
260 
263 template <typename T>
264 struct device_vector : public vector<device_tag,T>
265 {
266  typedef device_tag system_tag;
267 
268  typedef vector<device_tag,T> base_type;
269  typedef typename base_type::const_iterator const_iterator;
270  typedef typename base_type::iterator iterator;
271  typedef typename base_type::value_type value_type;
272 
273  typedef typename base_type::plain_view_type plain_view_type;
274  typedef typename base_type::const_plain_view_type const_plain_view_type;
275 
278  device_vector(const size_t size = 0, const T val = T()) : base_type( size, val ) {}
279 
280  template <typename OtherAlloc>
281  device_vector(const thrust::host_vector<T,OtherAlloc>& v) : base_type( v ) {}
282 
283  template <typename OtherAlloc>
284  device_vector(const thrust::device_vector<T,OtherAlloc>& v) : base_type( v ) {}
285 
286  template <typename OtherAlloc>
287  device_vector<T>& operator= (const thrust::host_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
288 
289  template <typename OtherAlloc>
290  device_vector<T>& operator= (const thrust::device_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
291 
294  operator plain_view_type() { return plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
295 
298  operator const_plain_view_type() const { return const_plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
299 };
300 
303 template <typename T>
304 struct caching_device_vector : public vector<device_tag,T,caching_device_allocator<T> >
305 {
306  typedef device_tag system_tag;
307 
309  typedef typename base_type::const_iterator const_iterator;
310  typedef typename base_type::iterator iterator;
311  typedef typename base_type::value_type value_type;
312 
313  typedef typename base_type::plain_view_type plain_view_type;
314  typedef typename base_type::const_plain_view_type const_plain_view_type;
315 
318  caching_device_vector(const size_t size = 0, const T val = T()) : base_type( size, val ) {}
319 
320  template <typename OtherAlloc>
321  caching_device_vector(const thrust::host_vector<T,OtherAlloc>& v) : base_type( v ) {}
322 
323  template <typename OtherAlloc>
324  caching_device_vector(const thrust::device_vector<T,OtherAlloc>& v) : base_type( v ) {}
325 
326  template <typename OtherAlloc>
327  caching_device_vector<T>& operator= (const thrust::host_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
328 
329  template <typename OtherAlloc>
330  caching_device_vector<T>& operator= (const thrust::device_vector<T,OtherAlloc>& v) { cuda::thrust_copy_vector( *this, v ); return *this; }
331 
334  operator plain_view_type() { return plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
335 
338  operator const_plain_view_type() const { return const_plain_view_type( base_type::size(), cugar::raw_pointer( *this ) ); }
339 };
340 
343 template <typename T> struct device_iterator_type { typedef T type; };
344 template <typename T> struct device_iterator_type<T*> { typedef thrust::device_ptr<T> type; };
345 template <typename T> struct device_iterator_type<const T*> { typedef thrust::device_ptr<const T> type; };
346 
349 template <typename T>
350 typename device_iterator_type<T>::type device_iterator(const T it)
351 {
352  // wrap the plain iterator
353  return typename device_iterator_type<T>::type( it );
354 }
355 
356 template <typename domain_tag, typename T>
357 void make_room(vector<domain_tag, T>& vec, const size_t min_size)
358 {
359  if (vec.size() < min_size)
360  vec.resize(min_size);
361 }
362 
365 template <typename T>
367 {
368  typedef typename thrust::device_vector<T>::const_reference const_reference;
369  typedef typename thrust::device_vector<T>::reference reference;
370 
373  device_var(const T val = T())
374  {
375  x.resize(1);
376  x[0] = val;
377  }
378 
381  device_var<T>& operator= (const T& val)
382  {
383  x[0] = val;
384  return *this;
385  }
386 
389  device_var<T>& operator+= (const T& val)
390  {
391  x[0] += val;
392  return *this;
393  }
394 
397  device_var<T>& operator-= (const T& val)
398  {
399  x[0] += val;
400  return *this;
401  }
402 
405  operator T() const
406  {
407  return x[0];
408  }
409 
412  const T* ptr() const { return cugar::raw_pointer(x); }
413 
416  T* ptr() { return cugar::raw_pointer(x); }
417 
419 };
420 
423 template <typename T>
424 const T* raw_pointer(const device_var<T>& var) { return var.ptr(); }
425 
428 template <typename T>
429 T* raw_pointer(device_var<T>& var) { return var.ptr(); }
430 
432 
433 } // namespace cugar
device_vector(const size_t size=0, const T val=T())
Definition: vector.h:278
CUGAR_HOST_DEVICE diff_var< VT, N, O > & operator+=(diff_var< VT, N, O > &a, const diff_var< VT, N, O > b)
Definition: diff.h:931
Definition: vector.h:343
Definition: vector.h:304
void expand(const size_t sz)
Definition: vector.h:160
Definition: vector_view.h:87
vector(const size_t size=0, const T val=T())
Definition: vector.h:187
device_iterator_type< T >::type device_iterator(const T it)
Definition: vector.h:350
Definition: vector.h:264
Definition: vector.h:366
Definition: types.h:181
Definition: vector.h:100
T * raw_pointer(thrust::device_vector< T, Alloc > &vec)
Definition: thrust_view.h:69
Definition: vector.h:122
host_vector(const size_t size=0, const T val=T())
Definition: vector.h:238
Definition: types.h:185
void expand(const size_t sz)
Definition: vector.h:211
const T * ptr() const
Definition: vector.h:412
T * ptr()
Definition: vector.h:416
Definition: vector.h:117
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
device_var(const T val=T())
Definition: vector.h:373
Definition: vector.h:224
vector(const size_t size=0, const T val=T())
Definition: vector.h:136
CUGAR_HOST_DEVICE diff_var< VT, N, O > & operator-=(diff_var< VT, N, O > &a, const diff_var< VT, N, O > b)
Definition: diff.h:940
caching_device_vector(const size_t size=0, const T val=T())
Definition: vector.h:318