如何重载内置CUDA函数?

如何重载内置CUDA函数?,cuda,pycuda,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" linkag

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代码。

此外,我还将提出两个建议,以防您设法使重载正常工作:

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

    • 可能会混淆代码的其他读者
    • 将“包装器”代码与内置代码混为一谈——这不是一种“干净”的编码方式
    • 如果内置项发生了变化,那么使用内置项+重载的代码可能也会发生变化,有时会以出乎意料的方式发生变化
  • >p>在您的情况下,我将认真考虑使用您的实用函数(例如

    )来使用名称空间。
    namespace math {
        template <typename T>  
        __device__ T norm(T a, T b) { return math::sqrt<T>(a*a+b*b); }
    }
    
    名称空间数学{
    样板
    __设备规范(ta,tb){返回数学::sqrt(a*a+b*b);}
    }
    
    (当然,您需要一个
    math::sqrt
    模板,它将从单精度
    sqrtf()
    、双精度
    sqrt()
    等中提取出来。)


    除此之外,我还将提出两个建议,以防您设法使过载正常工作:

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

    • 可能会混淆代码的其他读者
    • 将“包装器”代码与内置代码混为一谈——这不是一种“干净”的编码方式
    • 如果内置项发生了变化,那么使用内置项+重载的代码可能也会发生变化,有时会以出乎意料的方式发生变化
  • >p>在您的情况下,我将认真考虑使用您的实用函数(例如

    )来使用名称空间。
    namespace math {
        template <typename T>  
        __device__ T norm(T a, T b) { return math::sqrt<T>(a*a+b*b); }
    }
    
    名称空间数学{
    样板
    __设备规范(ta,tb){返回数学::sqrt(a*a+b*b);}
    }
    
    (当然,您需要一个
    math::sqrt
    模板,它将从单精度
    sqrtf()
    、双精度
    sqrt()
    等中提取出来。)


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

    您可以在任何地方明确指定
    extern“C”
    ,也可以不明确指定。无论您是否是,如果您使用PyCUDA
    SourceModule
    工具编译代码,它都是(非)有帮助的,自动将您提交的代码括在
    extern“C”

    如果查看for
    SourceModule
    ,您将看到选项
    no\u extern\u c
    。将该值设置为
    True
    ,此问题将消失。但是请注意,你编译的所有东西现在都会用C++链接和符号修改编译。您必须相应地调整Python代码(请参阅以了解一些血淋淋的细节)


    然后,阅读另一个答案,其中包含一些关于标准库过载的危险的非常明智的建议和最佳实践选择。

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

    您可以在任何地方明确指定
    extern“C”
    ,也可以不明确指定。无论您是否是,如果您使用PyCUDA
    SourceModule
    工具编译代码,它都是(非)有帮助的,自动将您提交的代码括在
    extern“C”

    如果查看for
    SourceModule
    ,您将看到选项
    no\u extern\u c
    。将该值设置为
    True
    ,此问题将消失。但是请注意,你编译的所有东西现在都会用C++链接和符号修改编译。您必须相应地调整Python代码(请参阅以了解一些血淋淋的细节)


    然后,阅读另一个答案,其中包含一些关于标准库过载危险的明智建议和最佳实践选择。

    不要使用C链接,显然不要使用C链接,obviously@talonmies:如果他在命名空间中实现了自定义的
    norm
    函数,他将不会得到链接错误,因为它不会与任何C链接功能冲突。问题是PyCUDA默认使用C链接编译所有内容。这就是为什么代码首先会被破坏。您可以按您的建议执行,但当您尝试在同一命名空间内编译多个模板实例时,您遇到了相同的问题。不确定您的意思是什么:“CUDA没有内置的双精度平方根”,当然有。@RobertCrovella:错过了,抱歉。我使用了“sqrt”的搜索功能,找到了Mathematic functions部分,而没有查看double precision部分。@Talonmes:如果他在命名空间中实现了自定义
    norm
    函数,他将不会得到链接错误,因为它不会与任何C链接函数冲突。问题是PyCUDA默认使用C链接编译所有内容。这就是为什么代码首先会被破坏。您可以按您的建议执行,但当您尝试在同一命名空间内编译多个模板实例时,您遇到了相同的问题。不确定您的意思是什么:“CUDA没有内置的双精度平方根”,当然有。@RobertCrovella:错过了,抱歉。我使用了“sqrt”的搜索功能,找到了数学函数部分,没有查看双精度部分。你的意思是“no_extern_c”需要设置为True吗?是的,对不起,这就是我的意思。你的意思是“no_extern_c”需要设置为True吗?是的,对不起,这就是我的意思