如何在CUDA中轻松切换单精度和双精度?

mch*_*hen 2 c precision cuda gpgpu

在调试开发和调试时,我想以双精度运行我的代码.但是,一旦我知道它正在工作,我想选择float仅使用单精度(即s)运行我的代码.因此,我希望能够轻松地在这些精度之间切换而无需大量重写代码.我在考虑一些#define旗帜

#define PRECISION double
...

thrust::device_vector<PRECISION> myVec;
Run Code Online (Sandbox Code Playgroud)

但编译器似乎并不喜欢这样.有关如何实现这一点的任何想法?

我知道这个问题非常相似,因为它解决了编译器标志的问题.但我希望能够直接在我的源代码中直接设置标志.

tal*_*ies 8

你可以这样做:

#ifdef MY_USE_DOUBLE_PRECISION
typedef double Real;
#else
typedef float Real;
#endif

....

thrust::device_vector<Real> myVec;
Run Code Online (Sandbox Code Playgroud)

使用MY_USE_DOUBLE_PRECISION来控制浮点类型的定义Real.如果你有自己的内核,你也可以用它们Real代替float或者double.:

__global__ void kernel (Real *input, Real *output)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

如果你想有两个编译内核代码的单精度和双精度版本,并选择在那里它们被定义(在图书馆等)的编译单元之外使用哪一种,你可以模板内核:

 template<typename T>
__global__ void kernel (T *input, T *output)
{
   ...
}

template __global__ void kernel<float>(float *, float *);
template __global__ void kernel<double>(double *, double *);
Run Code Online (Sandbox Code Playgroud)

然后在另一个源文件中

#ifdef MY_USE_DOUBLE_PRECISION
typedef double Real;
#else
typedef float Real;
#endif

....

kernel<Real><<<griddim, blockdim>>>(....);
Run Code Online (Sandbox Code Playgroud)