我在编译包含使用nvcc编译的.cu文件和使用gcc编译的.cpp文件的代码时遇到问题 我有一个相当大的C++代码(超过60个单独的文件),我试图用CUDA-9框架将一些计算转换成GPU。代码通常使用gcc(v7)编译得很好。作为练习,我将其中一个源文件的扩展名从.cpp更改为.cu,而没有更改其中的任何代码。我运行make,它用g++编译.cpp文件,用nvcc编译.cu文件,我得到了一个可执行文件。然而,当我运行可执行文件时,我几乎立即得到一个seg错误。不用说,当使用gcc编译时,代码运行良好。事实上,它也可以使用英特尔编译器进行编译和运行。这些是传递给nvcc编译器的标志

我在编译包含使用nvcc编译的.cu文件和使用gcc编译的.cpp文件的代码时遇到问题 我有一个相当大的C++代码(超过60个单独的文件),我试图用CUDA-9框架将一些计算转换成GPU。代码通常使用gcc(v7)编译得很好。作为练习,我将其中一个源文件的扩展名从.cpp更改为.cu,而没有更改其中的任何代码。我运行make,它用g++编译.cpp文件,用nvcc编译.cu文件,我得到了一个可执行文件。然而,当我运行可执行文件时,我几乎立即得到一个seg错误。不用说,当使用gcc编译时,代码运行良好。事实上,它也可以使用英特尔编译器进行编译和运行。这些是传递给nvcc编译器的标志,gcc,cuda,Gcc,Cuda,nvcc-g-Xcudafe“-diag\u suppress=code\u无法访问”-Xcudafe“-diag\u suppress=extra\u分号” 而g++的标志是 g++-fPIC-O3-g-Wno未使用的变量-Wno注释-Wno可能未初始化-Wno严格别名-Wno长-Wno符号比较-Wno已弃用 -ftemplate-depth-39-Wno可变maris-m64 由于代码的大小,我希望避免将所有文件重命名为.cu。此外,它依赖于使用gcc编译的库,因此将整个问题切换到nvcc是

nvcc-g-Xcudafe“-diag\u suppress=code\u无法访问”-Xcudafe“-diag\u suppress=extra\u分号”

而g++的标志是

g++-fPIC-O3-g-Wno未使用的变量-Wno注释-Wno可能未初始化-Wno严格别名-Wno长-Wno符号比较-Wno已弃用 -ftemplate-depth-39-Wno可变maris-m64

由于代码的大小,我希望避免将所有文件重命名为.cu。此外,它依赖于使用gcc编译的库,因此将整个问题切换到nvcc是不现实的,更不用说nvcc与gcc相比似乎非常慢。cuda-9.0/bin中用于gcc的符号链接指向gcc-7。我还尝试将开关--device-c添加到nvcc,但在本例中,它不会链接。。。
感谢您的帮助

这听起来确实像是一个链接问题。这里有一个关于CUDA设备代码与C++代码的综合说明:

很遗憾,您没有提供链接命令。我会尽量使我的建议尽可能笼统。它的缺点是只有nvcc知道如何将设备代码链接到CPU目标代码,因此它需要参与链接过程,而不仅仅是作为一个编译器。看看上面链接中的“使用设备代码链接”和“高级用法:使用不同的链接器”部分。您可以使用nvcc作为编译器和链接器,也可以使用nvcc使用-dlink选项将cpu和设备代码组合对象文件链接在一起,然后您可以正常地将所有内容链接在一起。在这两种情况下,在编译包含设备代码的源文件时,都应该将-dc选项传递给nvcc(这表示您希望稍后将设备代码链接在一起)


还请注意,nvcc可以编译.cpp文件;默认情况下,它将假定.cpp文件只包含cpu代码。使用nvcc编译源文件时,不需要重命名仅cpu的源文件。

这听起来肯定像是链接问题。这里有一个关于CUDA设备代码与C++代码的综合说明:

很遗憾,您没有提供链接命令。我会尽量使我的建议尽可能笼统。它的缺点是只有nvcc知道如何将设备代码链接到CPU目标代码,因此它需要参与链接过程,而不仅仅是作为一个编译器。看看上面链接中的“使用设备代码链接”和“高级用法:使用不同的链接器”部分。您可以使用nvcc作为编译器和链接器,也可以使用nvcc使用-dlink选项将cpu和设备代码组合对象文件链接在一起,然后您可以正常地将所有内容链接在一起。在这两种情况下,在编译包含设备代码的源文件时,都应该将-dc选项传递给nvcc(这表示您希望稍后将设备代码链接在一起)


还请注意,nvcc可以编译.cpp文件;默认情况下,它将假定.cpp文件只包含cpu代码。使用nvcc编译源文件时,不需要重命名仅cpu的源文件。

我忘了提到:将哪些文件更改为.cu并不重要。唯一的区别在于错误的性质。有时会触发segfault,有时会触发扩展名为.cu的文件中不应触发的断言。当来自nvcc和g++的对象文件链接在一起时,整个事情都有损坏堆栈的味道……您显示的传递到
nvcc
的标志包括
--device-c
。困惑,对不起,我的错。代码编译(但SEGFULTS)时不带--device-c标志。我已经在主测试中修复了它。我忘了提到:将哪些文件更改为.cu并不重要。唯一的区别在于错误的性质。有时会触发segfault,有时会触发扩展名为.cu的文件中不应触发的断言。当来自nvcc和g++的对象文件链接在一起时,整个事情都有损坏堆栈的味道……您显示的传递到
nvcc
的标志包括
--device-c
。困惑,对不起,我的错。代码编译(但SEGFULTS)时不带--device-c标志。我已经在主测试中修复了它。谢谢你提供我将学习的帖子链接。还很高兴知道nvcc可以编译常规的.cpp代码。我想我应该首先尝试编译并将整个代码与nvcc和report链接起来。NVCC的C++编译器是什么?我问这个问题是因为它给了我一些警告,我不能使用g++(主要与SFINAE情况有关)。好的,我调整了Makefile,将nvcc用于.cpp和.cu文件,尽管目前只有.cpp文件。一切都编译得很好,但奇怪的是,我不得不使用g++来链接文件。使用nvcc(在nvcc生成的对象文件上)我得到了大量的“警告:忽略空字符”和结尾的“错误:未终止的注释”。用于链接的命令是nvcc-g-xcu*.o-l-omain。正如我所说,使用g++生成了一个运行良好的可执行文件。接下来,我将尝试编译实际涉及设备功能的代码谢谢你提供我将要学习的文章的链接。还很高兴知道nvcc可以编译常规的.cpp代码