【问题标题】:Compiling CUDA with clang on math functions在数学函数上使用 clang 编译 CUDA
【发布时间】:2020-06-29 03:13:28
【问题描述】:

用clang-11编译以下CUDA代码helloWorld.cu

int main() {
    return max(1.0f, 2.0f);
}

,使用命令clang++-11 -o helloWorld helloWorld.cu --cuda-gpu-arch=sm_75 -ldl -lrt -lcudart_static -pthread -L/usr/local/cuda/lib64,遇到错误:

helloWorld.cu:2:12: error: no matching function for call to 'max'
    return max(1.0f, 2.0f);
           ^~~
/usr/lib/llvm-11/lib/clang/11.0.0/include/__clang_cuda_math.h:194:16: note: candidate function not viable: call to __device__ function from __host__ function
__DEVICE__ int max(int __a, int __b) { return __nv_max(__a, __b); }
...
/usr/local/cuda-10.2/include/crt/math_functions.hpp:1079:31: note: candidate function not viable: call to __device__ function from __host__ function
__MATH_FUNCTIONS_DECL__ float max(float a, float b)
...

请注意,匹配函数实际上被编译器正确定位(即“math_functions.hpp:1079:31”),但被错误地推断为“_device_”函数。

提前感谢您的帮助。

【问题讨论】:

    标签: c++ cuda clang


    【解决方案1】:

    您编写的代码是宿主代码,它在语法上不是有效的 C++。该代码不应编译,并且编译器行为是正确的。为了编译,代码应该如下所示:

    #include <algorithm>
    
    int main() {
        return std::max(1.0f, 2.0f);
    }
    

    即您必须实际包含定义max 函数的标准库头文件,并且您必须使用正确的命名空间。 C++ 没有内置的max 函数。 CUDA 可以。您所看到的只是 clang CUDA 编译轨迹的工件。

    【讨论】:

    • 感谢您的回答!我知道std::max 的使用,但据我了解,CUDA 还实现了自己的数学函数(即 math_functions.hpp 中的那些),因为它们可以在主机代码中使用回复__host__ __device__。实际上,如果使用 nvcc (nvcc -ccbin clang++ helloWorld.cu -o helloWorld) 编译,我的代码能够使用 CUDA 的 max
    • 你理解错了。所发生的一切是 nvcc c++ 前端在执行其模板覆盖魔术以使设备代码工作时将静默导入&lt;algorithm&gt;。 CUDA 不会重载或修改主机代码中的任何数学库函数。您不是在这里编译 CUDA 代码。与 clang CUDA 前端相比,nvcc CUDA 前端具有更好的标准库集成。如果您编写了损坏的代码,您应该期望它不会编译并且在它编译时会感到惊喜并担心
    • 酷它是有道理的。我在使用 clang 编译来自 CUDA-10.2_Samples 的 simpleMultiCopy 示例时遇到了这个问题。我们被 nvcc 宠坏了。 :)
    • 这基本上是总结。 nvcc 做了大多数前端没有的各种魔法,有时它使不应该编译的代码工作。甚至是 NVIDIA 员工编写的代码。它有时也会破坏和破坏它应该能够编译的代码。双刃剑之类的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    相关资源
    最近更新 更多