11 #ifndef __CE_ArraySortImpl__
12 #define __CE_ArraySortImpl__
89 int src_tuplesize,
int dst_tuplesize,
91 exint nelements, T default_value)
93 UT_ASSERT(src_tuplesize >= 1 && dst_tuplesize >= 1);
94 if (!(src_tuplesize >= 1 && dst_tuplesize >= 1))
97 exint src_nelem = src.
size() / src_tuplesize;
100 nelements =
SYSmin(src_nelem - src_offset, dst_nelem - dst_offset);
102 UT_ASSERT(src_offset >= 0 && dst_offset >= 0 &&
103 (src_nelem - src_offset) >= nelements &&
104 (dst_nelem - dst_offset) >= nelements);
109 wb.
append(
" -D CEARRAY_VALUE_");
110 appendElemType<V>(wb);
111 const char *opt = wb.
buffer();
112 cl::Kernel k = loadKernel(
"convertFrom", opt);
116 context->
get1DRanges(k, nelements, global_range, local_range);
118 global_range, local_range);
121 src_tuplesize, dst_tuplesize,
122 src_offset, dst_offset,
123 nelements, scalarKernelArg(default_value));
127 template <
typename T>
128 template <
typename V,
typename I>
132 int src_tuplesize,
int dst_tuplesize,
137 UT_ASSERT(src_tuplesize >= 1 && dst_tuplesize >= 1);
138 if (!(src_tuplesize >= 1 && dst_tuplesize >= 1))
144 UT_ASSERT(dst_offset >= 0 && (dst_nelem - dst_offset) >= indices.
size());
149 wb.
append(
" -D CEARRAY_VALUE_");
150 appendElemType<V>(wb);
151 wb.
append(
" -D CEARRAY_INDEX_");
152 appendElemType<I>(wb);
153 const char *opt = wb.
buffer();
154 cl::Kernel k = loadKernel(
"convertFromIndices", opt);
160 global_range, local_range);
163 src_tuplesize, dst_tuplesize, dst_offset,
164 indices.
size(), scalarKernelArg(default_value));
168 template <
typename T>
169 template <
typename I>
180 wb.
append(
" -D CEARRAY_INDEX_");
181 appendElemType<I>(wb);
182 const char *opt = wb.
buffer();
183 cl::Kernel k = loadKernel(
"buffer_reorder", opt);
189 global_range, local_range);
192 int elemsize =
sizeof(
T);
199 template <
typename T>
200 template <
typename V>
210 bool has_vals = !vals.
isEmpty();
219 constexpr
size_t radixbits = 8;
221 constexpr
size_t radix = 1 << radixbits;
223 size_t totalbits = 8 *
sizeof(
T);
228 totalbits =
SYSmin(SYSroundUpToMultipleOf(
size_t(maxbits), radixbits),
231 size_t npasses = totalbits / radixbits;
233 constexpr
size_t maxelemperworkitem = 256;
235 size_t nworkitems = 16;
237 size_t localsize =
sizeof(
uint32) * radix * nworkitems;
239 while (localsize > nlocal * 1.2)
242 localsize =
sizeof(
uint32) * radix * nworkitems;
245 size_t maxelempergroup = maxelemperworkitem * nworkitems;
248 size_t ngroups =
SYSmin(
size_t(128), ncompute * 4);
250 size_t mingroups = SYSroundUpToMultipleOf(
size_t(nelem), maxelempergroup) / maxelempergroup;
252 ngroups =
SYSclamp((
int)ngroups, 1, (
int)mingroups);
257 const char *opt = is_descending ?
"-D SORT_DESCENDING" :
nullptr;
263 wb.
append(
" -D HAS_values -D CEARRAY_VALUE_");
264 appendElemType<V>(wb);
267 cl::Kernel khist = loadKernel(
"radix_sort_histogram", opt);
269 cl::Kernel kreorder = loadKernel(
"radix_sort_reorder", opt);
284 Buffer<V> dst_vals(has_vals ? nelem : 0);
293 for(
size_t pass=0; pass < npasses; pass++)
296 hist(src->
buffer(), nelem,
static_cast<int>(pass), histogram.
buffer(), localarg);
298 histogram_view.
prefixSum(histosums_view);
302 reorder(src->
buffer(), nelem,
static_cast<int>(pass), histosums.buffer(),
308 reorder(src->
buffer(), nelem,
static_cast<int>(pass),
309 histosums.buffer(), dst->
buffer(), localarg);
OIIO_API std::vector< imagesize_t > histogram(const ImageBuf &src, int channel=0, int bins=256, float min=0.0f, float max=1.0f, bool ignore_empty=false, ROI roi={}, int nthreads=0)
#define SYS_STATIC_ASSERT(expr)
GLsizei GLenum const void * indices
void convertFromIndices(const CE_ArrayView< V > &src, const CE_ArrayView< I > &indices, int src_tuplesize=1, int dst_tuplesize=1, exint dst_offset=0, T default_value=0)
cl::Device getDevice() const
Returns the OpenCL Device object.
GLsizei const GLfloat * value
const cl::Buffer & buffer() const
LocalSpaceArg __local(::size_t size)
void releaseBuffer(cl::Buffer &&buf, bool use_pool=true)
Release the specified buffer, possibly to the CE_MemoryPool.
SYS_FORCE_INLINE const char * buffer() const
void convertFrom(const CE_ArrayView< 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)
void prefixSum(CE_ArrayView< T > &dst, bool exclusive=true, CE_ScanOp op=CE_ScanOp::ADD) const
cl::CommandQueue getQueue() const
#define utZoneValue(value)
static CE_Context * getContext(bool gl_shared=true, bool shared_fallback=true)
const cl::Buffer myBuffer
exint size() const
Returns the number of elements in the array.
void reorder(const CE_ArrayView< I > &order)
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
GLdouble GLdouble GLint GLint order
cl::Buffer allocBuffer(int64 size, bool use_pool=true, bool read=true, bool write=true, uint32 ogl_bind=SYS_UINT32_MAX)
#define CL_DEVICE_LOCAL_MEM_SIZE
void sortInternal(CE_ArrayView< V > &vals, bool is_descending, int maxbits)
static void appendElemType(UT_WorkBuffer &wb)
void get1DRanges(const cl::Kernel &k, size_t items, cl::NDRange &g, cl::NDRange &l)
const cl::Buffer & buffer()
#define CL_DEVICE_MAX_COMPUTE_UNITS
cl_int getInfo(cl_device_info name, T *param) const
SYS_FORCE_INLINE void append(char character)
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Kernel functor interface.
const cl::Buffer & buffer() const
Kernel interface that implements cl_kernel.
KernelFunctor bind(const CommandQueue &queue, const NDRange &offset, const NDRange &global, const NDRange &local)
Device interface for cl_device_id.
void copyBuffer(const cl::Buffer &src, const cl::Buffer &dst, size_t size, size_t src_offset=0, size_t dst_offset=0)