如何重载内置的CUDA功能?

时间:2017-07-09 02:07:49

标签: cuda pycuda

CUDA有一些内置的数学函数,比如norm()。我想创建自己的norm()函数版本,并在整个代码中使用我的版本。但是当我像我这样定义自己的norm()函数时:

__device__ float norm(float a, float b) {
    return sqrt(a*a+b*b);
}

我收到以下编译错误:

kernel.cu(9): error: more than one instance of overloaded function "norm" has "C" linkage

有没有办法可以重载norm()函数,还是只需要给自己的函数一个唯一的名字?

我正在使用PyCuda来编译我的CUDA代码。

2 个答案:

答案 0 :(得分:3)

这里的问题是在代码中使用C链接。

您可能会或可能不会在任何地方明确指定extern "C"。无论您是否,如果您使用PyCUDA SourceModule工具来编译代码,它都会(无)帮助您自动包围您使用extern "C"提交的代码。

如果查看SourceModule的{​​{3}},您会看到选项no_extern_c。将其设置为True,这个问题就会消失。但请注意,您编译的所有现在将使用C ++链接和符号修改进行编译。您将不得不相应地调整您的Python代码(有关一些血腥的详细信息,请参阅documentation。)

然后,阅读另一个答案,其中包含一些关于重载标准库和最佳实践替代方案的危险建议。

答案 1 :(得分:1)

除了@talonmies' answer之外,我还会提出两条建议 - 如果您确实设法让重载工作:

  1. 一般非CUDA特定建议:避免重载库的内置/ API函数,除非绝对必要(在您的情况下不是这样)。
    原因:

    • 可能会混淆其他读者的代码
    • 将“包装”代码与内置函数混合 - 这不是一种“干净”的代码方式。
    • 如果内置更改,使用内置+重载的代码可能也需要更改,有时候是您没想到的。
  2. 在您的情况下,我会认真考虑在您的实用程序功能中使用一些命名空间,例如:

    namespace math {
        template <typename T>  
        __device__ T norm(T a, T b) { return math::sqrt<T>(a*a+b*b); }
    }
    

    (当然你需要一个math::sqrt模板,它可以从单精度sqrtf(),双精度sqrt()等中抽象出来。)