I'm writing a hobby raytracer in CUDA and C++ and I'm running into an issue that I haven't been able to get an answer on. I have written CPU and GPU code such that it can execute on machines with or without CUDA-capable devices. However, this has lead to some code duplication in the following sense:
A small set of functions require random number generation, which is achieved with stdlib
on host and curand
on device. I would love to have __host__ __device__
functions that take a Sampler
struct that either calls rand()
on host or curand_uniform()
on device. I've tried some things but can't get the program to compile - the compiler complains about not calling __device__
functions from __host__
code and vice versa.
Ideally I'd like my rendering functions to take a Sampler *
which looks something like the code below.
Thanks!
struct Sampler {
__host__ virtual float getNextFloat() { return rand() / (RAND_MAX + 1.f); }
};
struct CudaSampler : Sampler {
curandState* p_curandState;
__device__ float getNextFloat() { return curand_uniform(p_curandState); }
};