简体   繁体   English

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

[英]How to easily switch between single and double precision in CUDA?

When debugging developing and debugging, I would like to run my code with double precision. 在调试开发和调试时,我想以双精度运行我的代码。 However, once I know it's working, I'd like the option to run my code using single precision (ie float s) only. 但是,一旦我知道它正在工作,我想选择使用单精度(即float )运行我的代码。 So I'd like to be able to easily switch between these precisions without a large rewrite of code. 因此,我希望能够轻松地在这些精度之间切换而无需大量重写代码。 I was thinking of some #define flag like 我在考虑一些#define旗帜

#define PRECISION double
...

thrust::device_vector<PRECISION> myVec;

but the compiler doesn't seem to like that. 但编译器似乎并不喜欢这样。 Any ideas on how to implement this? 有关如何实现这一点的任何想法?

I know this question is very similar in that it solves the problem with compiler flags. 我知道这个问题非常相似,因为它解决了编译器标志的问题。 But I was hoping to be able to directly set a flag directly from within my source code. 但我希望能够直接在我的源代码中直接设置标志。

You can do it like this: 你可以这样做:

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

....

thrust::device_vector<Real> myVec;

using MY_USE_DOUBLE_PRECISION to control the definition of the floating point type Real . 使用MY_USE_DOUBLE_PRECISION来控制浮点类型Real的定义。 If you have your own kernels you can also use Real in place of either float or double ie. 如果你有自己的内核,你也可以使用Real来代替floatdouble :

__global__ void kernel (Real *input, Real *output)
{
   ...
}

If you want to have both single and double precision versions of the kernel code compiled and select which one to use outside of the compilation unit where they are defined (in a library, for example), you can template the kernel: 如果你想有编译内核代码的精度和双精度版本,并选择在那里它们被定义(在图书馆等)的编译单元之外使用哪一种,你可以模板内核:

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

template __global__ void kernel<float>(float *, float *);
template __global__ void kernel<double>(double *, double *);

and then in another source file 然后在另一个源文件中

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

....

kernel<Real><<<griddim, blockdim>>>(....);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM