9#if defined(NANOVDB_USE_CUDA)
10#include <cuda_runtime_api.h>
13#if defined(NANOVDB_USE_TBB)
14#include <tbb/parallel_for.h>
15#include <tbb/blocked_range.h>
22#if defined(__CUDACC__)
24static inline bool checkCUDA(cudaError_t result,
const char* file,
const int line)
26 if (result != cudaSuccess) {
27 std::cerr <<
"CUDA Runtime API error " << result <<
" in file " << file <<
", line " << line <<
" : " << cudaGetErrorString(result) <<
".\n";
33#define NANOVDB_CUDA_SAFE_CALL(x) checkCUDA(x, __FILE__, __LINE__)
35static inline void checkErrorCUDA(cudaError_t result,
const char* file,
const int line)
37 if (result != cudaSuccess) {
38 std::cerr <<
"CUDA Runtime API error " << result <<
" in file " << file <<
", line " << line <<
" : " << cudaGetErrorString(result) <<
".\n";
43#define NANOVDB_CUDA_CHECK_ERROR(result, file, line) checkErrorCUDA(result, file, line)
47template<
typename Fn,
typename... Args>
51 ApplyFunc(
int count,
int blockSize,
const Fn& fn, Args... args)
53 , mBlockSize(blockSize)
59 template<std::size_t... Is>
60 void call(
int start,
int end, std::index_sequence<Is...>)
const
62 mFunc(start, end, std::get<Is>(mArgs)...);
67 int start = i * mBlockSize;
68 int end = i * mBlockSize + mBlockSize;
71 call(start, end, std::make_index_sequence<
sizeof...(Args)>());
74#if defined(NANOVDB_USE_TBB)
75 void operator()(
const tbb::blocked_range<int>& r)
const
77 int start = r.begin();
81 call(start, end, std::make_index_sequence<
sizeof...(Args)>());
89 std::tuple<Args...> mArgs;
92#if defined(__CUDACC__)
94template<
int WorkPerThread,
typename FnT,
typename... Args>
95__global__ void parallelForKernel(
int numItems, FnT f, Args... args)
97 for (
int j=0;j<WorkPerThread;++j)
99 int i = threadIdx.x + blockIdx.x * blockDim.x + j * blockDim.x * gridDim.x;
101 f(i, i + 1, args...);
109#if defined(__CUDACC__)
111 NANOVDB_CUDA_CHECK_ERROR(cudaDeviceSynchronize(), file, line);
116inline void computeFill(
bool useCuda,
void* data, uint8_t value,
size_t size)
119#if defined(__CUDACC__)
120 cudaMemset(data, value, size);
123 std::memset(data, value, size);
127template<
typename FunctorT,
typename... Args>
128inline void computeForEach(
bool useCuda,
int numItems,
int blockSize,
const char* file,
int line,
const FunctorT& op, Args... args)
134#if defined(__CUDACC__)
135 static const int WorkPerThread = 1;
136 int blockCount = ((numItems/WorkPerThread) + (blockSize - 1)) / blockSize;
137 parallelForKernel<WorkPerThread, FunctorT, Args...><<<blockCount, blockSize, 0, 0>>>(numItems, op, args...);
138 NANOVDB_CUDA_CHECK_ERROR(cudaGetLastError(), file, line);
141#if defined(NANOVDB_USE_TBB)
142 tbb::blocked_range<int> range(0, numItems, blockSize);
145 for (
int i = 0; i < numItems; ++i)
146 op(i, i + 1, args...);
154#if defined(__CUDACC__)
155 cudaMemcpy(dst, src, size, cudaMemcpyDeviceToHost);
158 std::memcpy(dst, src, size);
162inline void computeCopy(
bool useCuda,
void* dst,
const void* src,
size_t size)
165#if defined(__CUDACC__)
166 cudaMemcpy(dst, src, size, cudaMemcpyDeviceToDevice);
169 std::memcpy(dst, src, size);
void computeForEach(bool useCuda, int numItems, int blockSize, const char *file, int line, const FunctorT &op, Args... args)
Definition ComputePrimitives.h:128
void computeDownload(bool useCuda, void *dst, const void *src, size_t size)
Definition ComputePrimitives.h:151
void computeSync(bool useCuda, const char *file, int line)
Definition ComputePrimitives.h:107
void computeFill(bool useCuda, void *data, uint8_t value, size_t size)
Definition ComputePrimitives.h:116
void computeCopy(bool useCuda, void *dst, const void *src, size_t size)
Definition ComputePrimitives.h:162
Definition ComputePrimitives.h:49
void operator()(int i) const
Definition ComputePrimitives.h:65
ApplyFunc(int count, int blockSize, const Fn &fn, Args... args)
Definition ComputePrimitives.h:51
void call(int start, int end, std::index_sequence< Is... >) const
Definition ComputePrimitives.h:60
#define __global__
Definition Util.h:79