C++ 17 可以使用 clang 与 CUDA 一起使用吗?

Posted

技术标签:

【中文标题】C++ 17 可以使用 clang 与 CUDA 一起使用吗?【英文标题】:Can C++17 be used together with CUDA using clang? 【发布时间】:2017-12-24 10:23:57 【问题描述】:

就使用nvcc而言,需要结合使用相应的gcc(我相信目前最大5.4)。这当然会在一定程度上阻止人们在主机端使用 C++17。

由于 C++17 可以使用clang 5 及更高版本进行编译(请参阅here),并且也可以编译 cuda 代码(请参阅here),是否可以同时使用 C+ +17 和 CUDA 同时(或者可能有问题,例如 CUDA 运行时)?

【问题讨论】:

有一个关于 cuda 和现代 C++ 的 cppcast 播客集,可能会让您开始研究以回答这个问题。或者我想您可以尝试一下,看看有什么用;像这样的东西会在这个时间点不断变化。例如,C++17 是指编译器支持还是库支持? 我也非常希望您能花时间自己尝试并回答这个问题...+1 【参考方案1】:

是的,正如您已经猜到的那样,CUDA clang 前端在 C++ 功能支持方面确实领先,甚至在设备代码中也是如此。在 NVCC 之前引入 C++14 特性已经是过去的事了,这几乎没有被社区注意到。

拿这个C++17,不必要的修改if constexpr,sn-p:Fibo

#include <cuda_runtime.h>
#include <cstdio>

constexpr unsigned
fibonacci(const unsigned x) 
    if constexpr (false)
    
        return 0u;
    
    if( x <= 1 )
        return 1;
    return fibonacci(x - 1) + fibonacci(x - 2);


__global__
void k()

    constexpr unsigned arg = fibonacci(5);
    printf("%u", arg);


int main()

    k<<<1,1>>>();
    return 0;

它已经与clang++ -std=c++17 -x cuda 一起运行:https://cuda.godbolt.org/z/GcIqeW

尽管如此,对于这个特定示例,C++17 扩展 lambda 和 C++14 宽松 constexpr 在现代 C++ 中非常重要,即使在 C++11 和 C++14 模式下也添加了 NVCC 8.0+ 标志已经启用这些功能:https://devblogs.nvidia.com/new-compiler-features-cuda-8/

这意味着在删除演示 C++17 if constexpr 构造并添加 -std=c++14 --expt-relaxed-constexpr 标志时,即使没有 __device__ 限定符,上述示例也可以使用 NVCC 9.2 进行编译。

这里是关于nvccclang -x cuda 的设备端C++ 标准支持的列表:https://gist.github.com/ax3l/9489132#device-side-c-standard-support(NVCC 11.0 现在支持设备端 C++17。)

【讨论】:

Visual Studio (msvc) 仍然不支持 C++17。 2020-04-15 甚至是最新版本的 cuda 10.2 和 Visual Studio 2019 msvc。 能否请您说明如何配置 CMake 来完成此任务?【参考方案2】:

目前在设备代码中最高支持 C++14(在CUDA 9 中引入)

--std c++03|c++11|c++14

Options for Specifying Behavior of Compiler/Linker

但是,如果您的主机仅使用 C++17,则应该可以使用单独的编译并将它们与库链接。 Separate Compilation and Linking of CUDA C++ Device Code

更新:格式化和更多信息

【讨论】:

【参考方案3】:

我也遇到过同样的问题,这里有一个简单的例子供遇到同样问题的人参考。

假设有3个文件:main.cppcuda_calling.cppcuda_calling.h, 其中,main.cpp 使用c++17 或您的nvcc 不支持的任何东西。顾名思义,cuda_calling.cpp 必须由nvcc 编译。

首先,将cuda_calling.cpp构建为lib(在实际情况下,可能有很多文件调用cuda。否则,可以构建为目标文件,即cuda_calling.o)。输出文件假定为lib_cudacalling.a。然后将main.cpp和整个项目构建为一个cmake文件:

cmake_minimun_required(VERSION 3.5)
project(separate)
add_compile_options(-std=c++17)
find_package(CUDA REQUIRED)

add_library($PROJECT_NAME.o OBJECT main.cpp) # build as an object file first
add_executable($PROJECT_NAME $<TARGET_OBJECTS:$PROJECT_NAME.o>)

target_link_libraries($PROJECT_NAME cuda_calling) # you may need to specify the path

您可以看到,关键是要单独构建它们

【讨论】:

以上是关于C++ 17 可以使用 clang 与 CUDA 一起使用吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用C ++ 11时CUDA nvcc编译器失败(Linux; clang 3.8)

可以跨 C 和 C++ 方法优化 gcc 或 clang 的 LTO

使用 clang-llvm 编译器在 CUDA 中添加对类似于 __shared__ 的内存类型的支持

使用 Nsight Systems 跟踪自定义 CUDA 内核

Cuda 数学与 C++ 数学

将 clang-format 与 c++20 概念一起使用