HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CE_Array.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: CE_Array.h ( CE Library, C++)
7  *
8  * COMMENTS: UT_Array style class on GPU.
9  */
10 
11 #ifndef __CE_Array__
12 #define __CE_Array__
13 
14 
15 #include "CE_API.h"
16 #include "CE_ArrayView.h"
17 #include "CE_BufferDevice.h"
18 #include "CE_Context.h"
19 
20 #include <SYS/SYS_TypeTraits.h>
21 #include <UT/UT_Array.h>
22 #include <UT/UT_WorkBuffer.h>
23 
24 #include <limits>
25 
26 /// A simple OpenCL-based array class.
27 template <typename T>
29 {
30 public:
31 
32  typedef T value_type;
33 
34  exint size() const { return CE_BufferDevice<T>::size(); }
35  bool isEmpty() const { return CE_BufferDevice<T>::isEmpty(); }
36  void init(exint size) { return CE_BufferDevice<T>::init(size); }
37  const cl::Buffer &buffer() const { return CE_BufferDevice<T>::buffer(); }
38 
39  /// Initialize to empty,
40  /// and init must be called later with the desired size.
42  CE_BufferDevice<T>() {}
43 
44  /// Initialize to given size.
45  /// Size can be zero in which case no allocation is done,
46  /// and init must be called later with the desired size.
48  CE_BufferDevice<T>(size) {}
49 
50  /// Move construct from a raw cl::Buffer, which this object now owns.
51  /// If size is not provided, calc from the buffer size and type.
52  /// The input cl::Buffer is empty after this call.
54  CE_BufferDevice<T>(std::move(buf), size) {}
55 
56  /// Copy constructor. It duplicates the data.
57  /// It's marked explicit so that it's not accidentally passed by value.
58  explicit CE_Array(const CE_Array<T> &a): CE_BufferDevice<T>()
59  {
62  }
63 
64  /// Move constructor. Steals the buffer from the original.
65  CE_Array(CE_Array<T> &&a) noexcept:
66  CE_BufferDevice<T>(std::move(a)) {}
67 
68  /// Move constructor. Steals the buffer from the original.
70  CE_BufferDevice<T>(std::move(b)) {}
71 
72  /// Move assignment. Note that copy assignment is intentionally
73  /// deleted.
75  { swap(*this, other); other.init(0); return *this; }
76  CE_Array<T> &operator=(const CE_Array<T> &other) = delete;
77 
78  /// CE_BufferDevice base class will release buffer.
79  ~CE_Array() {}
80 
81  // Returns a fixed view of this array, which cannot resize or reallocate.
83  { return CE_BufferDevice<T>::template arrayView<T>(); }
84  const CE_ArrayView<T> view() const
85  { return CE_BufferDevice<T>::template arrayView<T>(); }
86 
87  /// Initalize the array of elements of type T that are at the offset
88  /// within type V in the buffer.
89  template <typename V>
91  {
93  cl::size_t<3> src_origin, dst_origin, region;
94  // 2D copy starts at offset in src.
95  src_origin[0] = offset;
96  src_origin[1] = 0;
97  src_origin[2] = 0;
98 
99  // Destination is origin of this array.
100  dst_origin[0] = 0;
101  dst_origin[1] = 0;
102  dst_origin[2] = 0;
103 
104  // The region is sizeof(T) bytes across, and size() long.
105  region[0] = sizeof(T);
106  region[1] = src.size();
107  region[2] = 1;
108 
109  // Each src row is sizeof<V> bytes across, each dst row is sizeof(T).
110  size_t src_row_pitch = sizeof(V);
111  size_t dst_row_pitch = sizeof(T);
112 
114  q.enqueueCopyBufferRect(src.buffer(), CE_BufferDevice<T>::buffer(),
115  src_origin, dst_origin, region,
116  src_row_pitch, 0, dst_row_pitch, 0);
117  }
118 
119  /// Initialize the array from an array of another type and/or tuple size.
120  /// Extra tuple components in the source array are discarded.
121  /// Extra tuple components in the destination array are set to the default.
122  /// It's up to the caller to ensure that the types can convert with
123  /// sufficient precision.
124  template <typename V>
126  int src_tuplesize = 1, int dst_tuplesize = 1,
127  T default_value = 0)
128  {
129  UT_ASSERT(src_tuplesize >= 1 && dst_tuplesize >= 1);
130  if (!(src_tuplesize >= 1 && dst_tuplesize >= 1))
131  return;
132 
133  exint nelem = src.size() / src_tuplesize;
134  init(nelem * dst_tuplesize);
135  convertFrom(src, src_tuplesize, dst_tuplesize, 0, 0, nelem, default_value);
136  }
137 
138  /// The same as initAndConvertFrom(), except this converts a selection of
139  /// tuples listed in the index array. The indices should be in the range
140  /// [0, src.size()/src_tuplesize - 1].
141  template <typename V, typename I>
143  const CE_Array<I> &indices,
144  int src_tuplesize = 1, int dst_tuplesize = 1,
145  T default_value = 0)
146  {
147  SYS_STATIC_ASSERT(SYS_IsIntegral_v<I>);
148  UT_ASSERT(src_tuplesize >= 1 && dst_tuplesize >= 1);
149  if (!(src_tuplesize >= 1 && dst_tuplesize >= 1))
150  return;
151 
152  init(indices.size() * dst_tuplesize);
153  convertFromIndices(src, indices,
154  src_tuplesize, dst_tuplesize,
155  0, default_value);
156  }
157 
158  /// Copy/convert data from an array of another type and/or tuple size.
159  /// Does not allocate or reallocate this array's underlying cl::Buffer.
160  /// Extra tuple components in the source array are discarded.
161  /// Extra tuple components in the destination array are set to the default.
162  /// It's up to the caller to ensure that the types can convert with
163  /// sufficient precision.
164  /// src_offset, dst_offset, and nelements each expect a number of tuples.
165  /// If nelements >= 0, only the given number of tuples are copied.
166  template <typename V>
168  int src_tuplesize = 1, int dst_tuplesize = 1,
169  exint src_offset = 0, exint dst_offset = 0,
170  exint nelements = -1, T default_value = 0)
171  {
172  UT_ASSERT(src_tuplesize >= 1 && dst_tuplesize >= 1);
173  if (!(src_tuplesize >= 1 && dst_tuplesize >= 1))
174  return;
175 
176  view().convertFrom(src.view(),
177  src_tuplesize, dst_tuplesize,
178  src_offset, dst_offset,
179  nelements, default_value);
180  }
181 
182  /// The same as convertFrom(), except this converts a selection of
183  /// tuples listed in the index array. The indices should be in the range
184  /// [0, src.size()/src_tuplesize - 1].
185  template <typename V, typename I>
187  const CE_Array<I> &indices,
188  int src_tuplesize = 1, int dst_tuplesize = 1,
189  exint dst_offset = 0,
190  T default_value = 0)
191  {
192  view().convertFromIndices(src.view(), indices.view(),
193  src_tuplesize, dst_tuplesize,
194  dst_offset,
195  default_value);
196  }
197 
198  /// Extract the channel from this into dst.
199  void extractChannel(CE_Array<T> &dst, int tuplesize, int comp) const;
200 
201  /// Insert the channel from src into this.
202  void insertChannel(const CE_Array<T> &src, int tuplesize, int comp);
203 
204  /// Sum entries of this into dst. exclusive true will have dst
205  /// elements only include the values of this strictly prior to itself.
206  /// oneifnonzero will count number of non-zero entries in this.
207  void prefixSum(CE_Array<T> &dst, bool exclusive=true,
208  CE_ScanOp op = CE_ScanOp::ADD) const
209  {
210  CE_ArrayView<T> dstview = dst.view();
211  view().prefixSum(dstview, exclusive, op);
212  }
213 
214  void iota()
215  {
216  view().iota();
217  }
218 
219  /// Reads a single value from the array, blocking.
220  /// May throw CE Exceptions
221  T readValue(int idx) const;
222  /// Writes a single value to the array.
223  /// May throw CE Exceptions
224  void writeValue(int idx, const T &val, bool blocking=true);
225 
226  /// Sort the array.
227  void sort(bool is_descending = false, int maxbits = 0)
228  {
229  view().sort(is_descending, maxbits);
230  }
231 
232  /// Sort the array and the values.
233  template <typename V>
234  void sortValues(CE_Array<V> &vals, bool is_descending = false, int maxbits = 0)
235  {
236  CE_ArrayView<V> valsview = vals.view();
237  view().sortValues(valsview, is_descending, maxbits);
238  }
239 
240  /// Reduce to long for integral types and fpreal64 for floats,
241  /// since the caller can always downcast after the fact if desired.
242  using reduce_t = typename std::conditional<std::is_integral<T>::value,
244 
245  reduce_t min(int tuplesize = 1, int comp = 0) const
246  { return view().min(tuplesize, comp); }
247  reduce_t minAbs(int tuplesize = 1, int comp = 0) const
248  { return view().minAbs(tuplesize, comp); }
249  reduce_t minLength(int tuplesize = 1) const
250  { return view().minLength(tuplesize); }
251  reduce_t max(int tuplesize = 1, int comp = 0) const
252  { return view().max(tuplesize, comp); }
253  reduce_t maxAbs(int tuplesize = 1, int comp = 0) const
254  { return view().maxAbs(tuplesize, comp); }
255  reduce_t maxLength(int tuplesize = 1) const
256  { return view().maxLength(tuplesize); }
257  reduce_t sum(int tuplesize = 1, int comp = 0) const
258  { return view().sum(tuplesize, comp); }
259  reduce_t sumAbs(int tuplesize = 1, int comp = 0) const
260  { return view().sumAbs(tuplesize, comp); }
261  reduce_t sumSqr(int tuplesize = 1, int comp = 0) const
262  { return view().sumSqr(tuplesize, comp); }
263 
264  fpreal64 average(int tuplesize = 1, int comp = 0) const
265  { return view().average(tuplesize, comp); }
266  fpreal64 rms(int tuplesize = 1, int comp = 0) const
267  { return view().rms(tuplesize, comp); }
268 
269  reduce_t dot(const CE_Array<T> &b) const
270  { return view().dot(b.view()); }
271 
272  void constant(T cval)
273  { return view().constant(cval); }
274 
275  // Reorder the array to the ordering in the supplied order array.
276  template <typename I>
277  void reorder(const CE_Array<I> &order)
278  { return view().reorder(order.view()); }
279 
280 
281  cl::KernelFunctor bind(cl::Kernel &k) const;
282  cl::KernelFunctor bind(const char *kernel_name) const;
283 
284 private:
285 
286  cl::Kernel loadKernel(const char *kernel_name,
287  const char *opt = NULL) const;
288 
289  // Appends a type name we use as part of type defines in array.cl
290  template <typename V>
291  static void appendElemType(UT_WorkBuffer &wb)
292  {
293  CE_ArrayView<T>::template appendElemType<V>(wb);
294  }
295 
296  // Promote 16-bit float kernel arguments to 32-bit float.
297  using scalar_arg_t = typename std::conditional_t<
298  std::is_same_v<T, fpreal16>,
299  fpreal32, T>;
300 
301  scalar_arg_t scalarKernelArg(T v) { return static_cast<scalar_arg_t>(v); }
302 };
303 // Exported instantiantions from libCE:
315 
316 // Convenience array names
320 
321 // Reorder the input buffer to the ordering in the supplied
322 // order array.
323 template <typename V>
324 void
326  const CE_BufferDevice<V> &src,
328  const CE_UInt32Array &order)
329 {
330  exint nelem = src.size();
331  UT_ASSERT(nelem == order.size());
332  dst.init(nelem);
333  cl::KernelFunctor reorder = order.bind("buffer_reorder");
334  int elemsize = sizeof(V);
335  reorder(src.buffer(), dst.buffer(), nelem, elemsize, order.buffer());
336 }
337 
338 #endif
#define CE_API
Definition: CE_API.h:13
type
Definition: core.h:556
reduce_t sumSqr(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:261
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
A simple OpenCL-based array class.
Definition: CE_Array.h:28
#define SYS_STATIC_ASSERT(expr)
reduce_t min(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:245
GLsizei GLenum const void * indices
Definition: glcorearb.h:406
void initFromBuffer(const CE_BufferDevice< V > &src, int offset)
Definition: CE_Array.h:90
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:266
const GLdouble * v
Definition: glcorearb.h:837
exint size() const
Definition: CE_Array.h:34
GLsizei const GLfloat * value
Definition: glcorearb.h:824
void sortValues(CE_Array< V > &vals, bool is_descending=false, int maxbits=0)
Sort the array and the values.
Definition: CE_Array.h:234
CE_Array(CE_Array< T > &&a) noexcept
Move constructor. Steals the buffer from the original.
Definition: CE_Array.h:65
int64 exint
Definition: SYS_Types.h:125
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
bool isEmpty() const
Definition: CE_Array.h:35
reduce_t minLength(int tuplesize=1) const
Definition: CE_Array.h:249
void copyFrom(const CE_BufferDevice< T > &b, exint len=-1)
GLdouble GLdouble GLdouble q
Definition: glad.h:2445
float fpreal32
Definition: SYS_Types.h:200
exint size() const
Returns the buffer length.
void init(exint size)
CE_ArrayView< T > view()
Definition: CE_Array.h:82
cl::CommandQueue getQueue() const
Definition: CE_Context.h:112
void convertFromIndices(const CE_Array< V > &src, const CE_Array< I > &indices, int src_tuplesize=1, int dst_tuplesize=1, exint dst_offset=0, T default_value=0)
Definition: CE_Array.h:186
void initAndConvertFromIndices(const CE_Array< V > &src, const CE_Array< I > &indices, int src_tuplesize=1, int dst_tuplesize=1, T default_value=0)
Definition: CE_Array.h:142
double fpreal64
Definition: SYS_Types.h:201
fpreal64 average(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:264
void convertFrom(const CE_Array< V > &src, int src_tuplesize=1, int dst_tuplesize=1, exint src_offset=0, exint dst_offset=0, exint nelements=-1, T default_value=0)
Definition: CE_Array.h:167
CE_Array< float > CE_FloatArray
Definition: CE_Array.h:319
void sort(bool is_descending=false, int maxbits=0)
Sort the array.
Definition: CE_Array.h:227
GLintptr offset
Definition: glcorearb.h:665
static CE_Context * getContext(bool gl_shared=true, bool shared_fallback=true)
void constant(T cval)
Definition: CE_Array.h:272
reduce_t dot(const CE_Array< T > &b) const
Definition: CE_Array.h:269
void initAndConvertFrom(const CE_Array< V > &src, int src_tuplesize=1, int dst_tuplesize=1, T default_value=0)
Definition: CE_Array.h:125
~CE_Array()
CE_BufferDevice base class will release buffer.
Definition: CE_Array.h:79
reduce_t max(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:251
fpreal64 rms(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:266
void prefixSum(CE_Array< T > &dst, bool exclusive=true, CE_ScanOp op=CE_ScanOp::ADD) const
Definition: CE_Array.h:207
void iota()
Definition: CE_Array.h:214
GLdouble GLdouble GLint GLint order
Definition: glad.h:2676
CE_Array< int > CE_Int32Array
Definition: CE_Array.h:317
typename std::conditional< std::is_integral< int >::value, exint, fpreal64 >::type reduce_t
Definition: CE_Array.h:243
const cl::Buffer & buffer() const
Definition: CE_Array.h:37
CE_Array< T > & operator=(CE_Array< T > &&other)
Definition: CE_Array.h:74
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
const CE_ArrayView< T > view() const
Definition: CE_Array.h:84
CE_ScanOp
CE_Array prefix sum operators.
Definition: CE_ArrayView.h:30
reduce_t sum(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:257
CE_Array(cl::Buffer &&buf, exint size=-1)
Definition: CE_Array.h:53
CE_Array(const CE_Array< T > &a)
Definition: CE_Array.h:58
friend void swap(CE_BufferDevice< T > &a, CE_BufferDevice< T > &b)
GLsizeiptr size
Definition: glcorearb.h:664
GLenum GLenum dst
Definition: glcorearb.h:1793
void reorder(const CE_Array< I > &order)
Definition: CE_Array.h:277
CommandQueue interface for cl_command_queue.
Definition: cl.hpp:2852
reduce_t minAbs(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:247
CE_Array(exint size)
Definition: CE_Array.h:47
reduce_t sumAbs(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:259
reduce_t maxAbs(int tuplesize=1, int comp=0) const
Definition: CE_Array.h:253
LeafData & operator=(const LeafData &)=delete
GLuint GLfloat * val
Definition: glcorearb.h:1608
Kernel functor interface.
Definition: cl.hpp:3587
CE_Array(CE_BufferDevice< T > &&b) noexcept
Move constructor. Steals the buffer from the original.
Definition: CE_Array.h:69
CE_Array< uint32_t > CE_UInt32Array
Definition: CE_Array.h:318
Memory buffer interface.
Definition: cl.hpp:1867
T value_type
Definition: CE_Array.h:32
const cl::Buffer & buffer() const
Kernel interface that implements cl_kernel.
Definition: cl.hpp:2544
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
CE_EXTERN_TEMPLATE(CE_Array< uint8 >)
CE_Array()
Definition: CE_Array.h:41
cl::KernelFunctor bind(cl::Kernel &k) const
void CEreorderBuffer(const CE_BufferDevice< V > &src, CE_BufferDevice< V > &dst, const CE_UInt32Array &order)
Definition: CE_Array.h:325
bool isEmpty() const
Returns true iff there are no occupied elements in the buffer.
reduce_t maxLength(int tuplesize=1) const
Definition: CE_Array.h:255
void init(exint size)
Definition: CE_Array.h:36
GLenum src
Definition: glcorearb.h:1793