CUDA 与我的 gcc 版本不兼容

Posted

技术标签:

【中文标题】CUDA 与我的 gcc 版本不兼容【英文标题】:CUDA incompatible with my gcc version 【发布时间】:2011-10-01 03:15:23 【问题描述】:

我在编译一些随 CUDA SDK 提供的示例时遇到了麻烦。 我已经安装了开发者驱动程序(版本 270.41.19)和 CUDA 工具包, 最后是 SDK(均为 4.0.17 版本)。

最初它根本没有编译:

error -- unsupported GNU version! gcc 4.5 and up are not supported!

我在 81:/usr/local/cuda/include/host_config.h 中找到了负责的那一行,并将其更改为:

//#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)

从那时起,我只编译了几个示例,它停止了:

In file included from /usr/include/c++/4.6/x86_64-linux-gnu/bits/gthr.h:162:0,
             from /usr/include/c++/4.6/ext/atomicity.h:34,
             from /usr/include/c++/4.6/bits/ios_base.h:41,
             from /usr/include/c++/4.6/ios:43,
             from /usr/include/c++/4.6/ostream:40,
             from /usr/include/c++/4.6/iterator:64,
             from /usr/local/cuda/include/thrust/iterator/iterator_categories.h:38,
             from /usr/local/cuda/include/thrust/device_ptr.h:26,
             from /usr/local/cuda/include/thrust/device_malloc_allocator.h:27,
             from /usr/local/cuda/include/thrust/device_vector.h:26,
             from lineOfSight.cu:37:
/usr/include/c++/4.6/x86_64-linux-gnu/bits/gthr-default.h:251:1: error: pasting         "__gthrw_" and "/* android's C library does not provide pthread_cancel, check for
`pthread_create' instead.  */" does not give a valid preprocessing token
make[1]: *** [obj/x86_64/release/lineOfSight.cu.o] Error 1

编译某些示例时,我认为这不是驱动程序问题,而是与不受支持的 gcc 版本有关。降级不是一个选项,因为此时 gcc4.6 将整个系统作为依赖项......

【问题讨论】:

对于未来的读者:确保您使用的是最新版本的 CUDA(除非您绝对必须使用早期版本)。 NVIDIA 几乎在每个版本中都提升了最大支持的编译器版本。 这可能对那些使用 CUDA 10 并遇到 gnu 编译器链版本太高的错误有所帮助:***.com/questions/53344283/… 【参考方案1】:

CUDA 不支持 gcc 4.5 和 4.6 - 代码无法编译,工具链的其余部分(包括 cuda-gdb)将无法正常工作。你不能使用它们,而且限制是不可协商的。

您唯一的解决方案是安装 gcc 4.4 版本作为 second 编译器(大多数发行版都允许这样做)。 nvcc --compiler-bindir 有一个选项,可用于指向替代编译器。创建一个本地目录,然后对支持的 gcc 版本的可执行文件进行符号链接。通过 --compiler-bindir 选项将该本地目录传递给 nvcc,您应该能够编译 CUDA 代码而不会影响系统的其余部分。


编辑

请注意,此问题和答案与 CUDA 4 相关。

自编写以来,NVIDIA 一直在更新的 CUDA 工具链版本中扩展对更高版本 gcc 的支持

从 CUDA 4.1 版本开始,现在支持 gcc 4.5。 gcc 4.6 和 4.7 不受支持。 从 CUDA 5.0 版本开始,现在支持 gcc 4.6。 gcc 4.7 不受支持。 从 CUDA 6.0 版本开始,现在支持 gcc 4.7。 从 CUDA 7.0 版本开始,完全支持 gcc 4.8,Ubuntu 14.04 和 Fedora 21 支持 4.9。 从 CUDA 7.5 版本开始,完全支持 gcc 4.8,Ubuntu 14.04 和 Fedora 21 支持 4.9。 从 CUDA 8 版本开始,Ubuntu 16.06 和 Fedora 23 完全支持 gcc 5.3。 从 CUDA 9 版本开始,gcc 6 在 Ubuntu 16.04、Ubuntu 17.04 和 Fedora 25 上得到完全支持。 CUDA 9.2 版本增加了对 gcc 7 的支持 CUDA 10.1 版本增加了对 gcc 8 的支持 CUDA 10.2 版本继续支持 gcc 8 CUDA 11.0 版本在 Ubuntu 20.04 上增加了对 gcc 9 的支持 CUDA 11.1 版本扩展了大多数发行版对 gcc 9 的支持,并在 Fedora linux 上增加了对 gcc 10 的支持

目前(从 CUDA 11.1 开始)除了 Fedora linux 之外,CUDA 不支持 gcc 10

请注意,NVIDIA 最近添加了一个非常有用的表 here,其中包含当前 CUDA 版本支持的编译器和操作系统矩阵。

【讨论】:

知道什么用于 CUDA 7.5 吗? 我在 SLES 11 SP3 上使用带有 gcc 4.9.3 的 CUDA 7.5 没有任何问题。 什么?代码应该如何不使用更高版本编译(当然除了硬编码限制)?我唯一能想到的是,由于某些版本默认启用了 C11/C++11,但如果这导致旧代码出现问题,则可以通过命令行开关轻松解决。 第二个@Hi-Angel。 #talonmies“限制是不可协商的”是什么意思?较新版本的 gcc 和 gdb 支持目标文件的较旧二进制标头,因为它们“总是”(有点)具有,没有理由较新的 gcc 版本不应该工作。除了符号链接解决方案之外,任何其他问题很可能是 c 预处理器版本标志设置,如果 gcc 版本测试在某些 cuda 标头中作为定义或宏的一部分“硬编码”,则很容易修复。例外可能是 cuda gpu 编译器本身。 这不是二进制兼容性问题。 CUDA 工具链要求 nvcc 和 GPU 前端解析器可以拦截和重载各种编译器和 libc/libc++ 内部头文件,以编译主机和设备代码并将它们集成在一起。除其他外,CUDA 解析器需要能够正确解析 gcc 内部标头。未经测试的 gcc 版本可能并且确实会失败,而与 NVIDIA 标头中内置的预处理器保护无关。您可以相信我(作为一个已经在 CUDA 工具链上进行黑客攻击近 10 年的人),也可以不相信。在这一点上,我真的不【参考方案2】:

如前所述,nvcc 依赖于 gcc 4.4。通过将软链接添加到使用 nvcc 安装创建的 bin 目录,可以将 nvcc 配置为使用正确版本的 gcc,而无需传递任何编译器参数。

默认的cuda二进制目录(安装默认)是/usr/local/cuda/bin,从这个目录添加一个指向正确版本gcc的软链接就足够了:

sudo ln -s /usr/bin/gcc-4.4 /usr/local/cuda/bin/gcc

【讨论】:

"update-alternatives" 命令也可能有帮助,尤其是在安装 CUDA 5.0 时 我还必须添加一个指向正确版本的 g++ 的符号链接。 我还必须链接到 g++。否则,简单的nvcc 调用可以工作,但是说,将make 应用于CUDA 示例,很快就会引入以nvcc -ccbin g++ 开头的调用。对我来说,我使用了 sudo ln -s /usr/bin/gcc-4.9 /usr/local/cuda/bin/gccsudo ln -s /usr/bin/g++-4.9 /usr/local/cuda/bin/g++ 如果你用cmake .. && make编译你可以trycmake -D CUDA_NVCC_FLAGS="-ccbin gcc-4.4" .. && make。如果你使用普通的Makefile,你可以trymake CXX=g++-4.4 CC=gcc-4.4 当我尝试这个命令时,它说“文件存在”并且不执行链接。有什么帮助吗?【参考方案3】:

Gearoid Murphy 的解决方案对我来说效果更好,因为在我的发行版(Ubuntu 11.10)上,gcc-4.4 和 gcc-4.6 位于同一目录中,所以 --compiler-bindir 没有帮助。唯一需要注意的是我还必须安装 g++-4.4 并对其进行符号链接:

sudo ln -s /usr/bin/gcc-4.4 /usr/local/cuda/bin/gcc
sudo ln -s /usr/bin/g++-4.4 /usr/local/cuda/bin/g++

【讨论】:

【参考方案4】:

Gearoid Murphy 的解决方案非常有效。对我来说,我有两个 cuda 目录 -

/usr/local/cuda 
/usr/local/cuda-5.0

只能将软链接添加到下面提到的目录 -

/usr/local/cuda 

此外,如 SchighSchagh 所述,g++ 和 gcc 软链接都是必需的。

【讨论】:

【参考方案5】:

配置 nvcc 以使用特定版本的 gcc(例如 gcc-4.4)的另一种方法是编辑 nvcc.profile 并更改 PATH 以包含您要首先使用的 gcc 的路径。

例如(gcc-4.4.6安装在/opt):

PATH += /opt/gcc-4.4.6/lib/gcc/x86_64-unknown-linux-gnu/4.4.6:/opt/gcc-4.4.6/bin:$(TOP)/open64/bin:$(TOP)/share/cuda/nvvm:$(_HERE_):

nvcc.profile 的位置有所不同,但它应该与 nvcc 可执行文件本身位于同一目录中。

这有点小题大做,因为 nvcc.profile 不适合按照 nvcc 手册进行用户配置,但它是最适合我的解决方案。

【讨论】:

我建议这样做,但将路径指向带有 g++ 符号链接到正确 gcc 版本的目录(如果您的发行版提供受支持的 gcc 版本特别有用)。例如:mkdir /usr/local/bin/cuda-hack && ln -s /usr/bin/g++-5 /usr/local/bin/cuda-hack【参考方案6】:

查看how to use "update-alternatives" 以解决此问题:

...如果您安装 gcc 4.6,您还可以使用 update-alternatives 命令以允许在版本之间轻松切换。这可以是 配置:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6 
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7 
sudo update-alternatives --config gcc

【讨论】:

【参考方案7】:

CUDA 经过一些与 gcc4.7 以及更高版本兼容的标头修改后: https://www.udacity.com/wiki/cs344/troubleshoot_gcc47

【讨论】:

【参考方案8】:

对于像我这样在使用 cmake 时感到困惑的人,FindCUDA.cmake 脚本会覆盖 nvcc.profile 中的一些内容。您可以按照http://public.kitware.com/Bug/view.php?id=13674 设置CUDA_HOST_COMPILER 来指定nvcc 主机编译器。

【讨论】:

cmake .. -DCMAKE_INSTALL_PREFIX=/InstallPos_GPU/ -DCMAKE_C_COMPILER="/gcc-8.3.0/bin/gcc" -DCMAKE_CXX_COMPILER="/gcc-8.3.0/bin/g++" -DGMX_GPU=ON -DCUDA_TOOLKIT_ROOT_DIR=/cuda-7.5/ -D NVCCFLAGS=" -ccbin /cuda-7.5/bin/" -DCUDA_HOST_COMPILER=/cuda-7.5/bin/gcc我已经成功安装了支持GPU的gromacs。【参考方案9】:

在大多数发行版上,您可以在最新的编译器(如 gcc-4.7)旁边安装另一个 gcc 和 g++ 版本。此外,大多数构建系统都知道CCCXX 环境变量,它们可以分别指定其他C 和C++ 编译器。所以我建议如下:

CC=gcc-4.4 CXX=g++-4.4 cmake path/to/your/CMakeLists.txt

对于 Makefiles 应该有类似的方法。我不建议在 /usr/local 中设置自定义符号链接,除非您知道自己在做什么。

【讨论】:

【参考方案10】:

我必须安装旧版本的 gcc、g++。

    sudo apt-get install gcc-4.4
    sudo apt-get install g++-4.4

检查 gcc-4.4 是否在 /usr/bin/ 中,对于 g++ 也是如此 然后我可以使用上面的解决方案:

    sudo ln -s /usr/bin/gcc-4.4 /opt/cuda/bin/gcc
    sudo ln -s /usr/bin/g++-4.4 /opt/cuda/bin/g++

【讨论】:

当我尝试这个命令时,它说“文件存在”并且不执行链接。有什么帮助吗? 恐怕我离思考这个问题太远了,不知道该说什么。希望其他人可以提供帮助。【参考方案11】:

这适用于 fedora 23。compat gcc 存储库会根据您的 fedora 版本而略有不同。

如果您安装以下存储库:

sudo yum install compat-gcc-34-c++-3.4.6-37.fc23.x86_64 compat-gcc-34-3.4.6-37.fc23.x86_64 

现在假设您的 cuda bin 文件夹位于 /usr/local/cuda/ 中,请按照上述方法制作软链接

sudo ln -s /usr/bin/gcc-34 /usr/local/cuda/bin/gcc
sudo ln -s /usr/bin/g++-34 /usr/local/cuda/bin/g++

您现在应该能够使用nvcc 进行编译,而不会出现 gcc 版本错误。

【讨论】:

【参考方案12】:

对于 CUDA7.5,这些行有效:

sudo ln -s /usr/bin/gcc-4.9 /usr/local/cuda/bin/gcc 
sudo ln -s /usr/bin/g++-4.9 /usr/local/cuda/bin/g++

【讨论】:

【参考方案13】:

$CUDA_HOME/include/host_config.h 中,找到这样的行(在不同的 CUDA 版本之间可能略有不同):

//...
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9)

#error -- unsupported GNU version! gcc versions later than 4.9 are not supported!

#endif [> __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9) <]
//...

删除或更改它们以符合您的条件。

请注意,此方法可能不安全,可能会破坏您的构建。例如,gcc 5 默认使用 C++11,但从 CUDA 7.5 开始,nvcc 并非如此。一种解决方法是添加

--Xcompiler="--std=c++98" 用于 CUDA

--std=c++11 用于 CUDA>=7.0。

【讨论】:

我们在哪里添加--std=c++ 选项?【参考方案14】:

为了在 Ubuntu 16.10 上编译 CUDA 8.0 示例,我做了:

sudo apt-get install gcc-5 g++-5
cd /path/to/NVIDIA_CUDA-8.0_Samples
# Find the path to the library (this should be in NVIDIA's Makefiles)
LIBLOC=`find /usr/lib -name "libnvcuvid.so.*" | head -n1 | perl -pe 's[/usr/lib/(nvidia-\d+)/.*][$1]'`
# Substitute that path into the makefiles for the hard-coded, incorrect one
find . -name "*.mk" | xargs perl -pi -e "s/nvidia-\d+/$LIBLOC/g"
# Make using the supported compiler
HOST_COMPILER=g++-5 make

这样做的好处是不修改整个系统或只对二进制文件进行符号链接(这可能会导致库链接问题。)

【讨论】:

【参考方案15】:

    检查您的 CUDA 版本支持的最大 GCC 版本:

    CUDA version max supported GCC version
    11.4.1+, 11.5, 11.6 11
    11.1, 11.2, 11.3, 11.4.0 10
    11 9
    10.1, 10.2 8
    9.2, 10.0 7
    9.0, 9.1 6
    8 5.3
    7 4.9
    5.5, 6 4.8
    4.2, 5 4.6
    4.1 4.5
    4.0 4.4

    为那个 GCC 版本设置一个环境变量。例如,对于 CUDA 10.2:

    MAX_GCC_VERSION=8
    

    确保您已安装该版本:

    sudo apt install gcc-$MAX_GCC_VERSION g++-$MAX_GCC_VERSION
    

    在 CUDA 文件夹中添加符号链接:

    sudo ln -s /usr/bin/gcc-$MAX_GCC_VERSION /usr/local/cuda/bin/gcc 
    sudo ln -s /usr/bin/g++-$MAX_GCC_VERSION /usr/local/cuda/bin/g++
    

    (或用您的 CUDA 安装路径替换 /usr/local/cuda,如果它不存在)

See this GitHub gist for more information on the CUDA-GCC compatibility table.

【讨论】:

救了我的命大声笑配置噩梦!!!!谢谢。我将它应用于带有 gcc 和 g++ 7 系统链接的 cuda 10。对于遇到此问题的任何人。 我应该自己创建/usr/bin/gcc/usr/bin/g++/usr/local/cuda/bin/gcc 文件夹吗? @JoshDesmond 您提到的文件的符号链接是在第 4 步中创建的。 @bryant1410 当我在第四步中运行命令时,我记得收到类似以下内容的错误:“错误:目录 /usr/local/cuda/bin/gcc 不存在,正在中止”或类似的东西。我现在意识到(在阅读了问题的详细信息之后),您的答案假定 OP 提到了第 0 步:“我已经安装了 CUDA 工具包,最后是 SDK”。我试图使用 NVIDIA 的 cuda_10.2.89_440.33.01_linux.run 向导 thingy 进行安装,它在运行时失败并抱怨 gcc 兼容性。我最终决定卸载 gcc 9:P 如果您使用 [ana|mini]conda(conda-forge 包 cudatoolkit-dev)安装 NVCC,那么您需要在您的环境中链接,例如 ln -s /usr/bin/gcc-8 /home/user/miniconda3/envs/your_env/bin/gccln -s /usr/bin/g++-8 /home/user/miniconda3/envs/your_env/bin/g++【参考方案16】:

如果对我使用cmake,那么编辑文件和链接的技巧都不起作用,所以我使用指定 gcc/g++ 版本的标志进行编译。cmake -DCMAKE_C_COMPILER=gcc-6 -DCMAKE_CXX_COMPILER=g++-6 ..

像魅力一样工作。

【讨论】:

哈哈我打算在这里尝试将您的答案与另一个问题联系起来,因为我认为它需要放在这个线程上。又是好作品!谢谢 应该避免在 SO 上发布重复的答案,但我别无选择。 :)【参考方案17】:

这解决了我的问题:

sudo rm /usr/local/cuda/bin/gcc
sudo rm /usr/local/cuda/bin/g++
sudo apt install gcc-4.4 g++-4.4
sudo ln -s /usr/bin/gcc-4.4 /usr/local/cuda/bin/gcc
sudo ln -s /usr/bin/g++-4.4 /usr/local/cuda/bin/g++

【讨论】:

【参考方案18】:

这是因为您当前的 CUDA 版本不支持您当前的 GCC 版本。您需要执行以下操作:

    找到支持的 GCC 版本(在我的例子中 5 是 CUDA 9)

    CUDA 4.1: GCC 4.5 CUDA 5.0: GCC 4.6 CUDA 6.0: GCC 4.7 CUDA 7.0: GCC 4.8 CUDA 7.5: GCC 4.8 CUDA 8: GCC 5.3 CUDA 9: GCC 5.5 CUDA 9.2: GCC 7 CUDA 10.1: GCC 8

    安装支持的 GCC 版本

    sudo apt-get install gcc-5
    sudo apt-get install g++-5
    

    更改/usr/bin目录中GCC的软链接

    cd /usr/bin
    sudo rm gcc
    sudo rm g++
    sudo ln -s /usr/bin/gcc-5 gcc
    sudo ln -s /usr/bin/g++-5 g++
    

    更改/usr/local/cuda-9.0/bin目录中GCC的软链接

    cd /usr/local/cuda-9.0/bin
    sudo rm gcc
    sudo rm g++
    sudo ln -s /usr/bin/gcc-5 gcc
    sudo ln -s /usr/bin/g++-5 g++
    

    -DCUDA_HOST_COMPILER=/usr/bin/gcc-5 添加到您的setup.py 文件中,用于编译

    if torch.cuda.is_available() and CUDA_HOME is not None:
        extension = CUDAExtension
        sources += source_cuda
        define_macros += [("WITH_CUDA", None)]
        extra_compile_args["nvcc"] = [
            "-DCUDA_HAS_FP16=1",
            "-D__CUDA_NO_HALF_OPERATORS__",
            "-D__CUDA_NO_HALF_CONVERSIONS__",
            "-D__CUDA_NO_HALF2_OPERATORS__",
            "-DCUDA_HOST_COMPILER=/usr/bin/gcc-5"
        ]
    

    删除旧的构建目录

    rm -rd build/
    

    通过设置CUDAHOSTCXX=/usr/bin/gcc-5再次编译

    CUDAHOSTCXX=/usr/bin/gcc-5 python setup.py build develop
    

注意:如果执行这些步骤后仍然出现gcc: error trying to exec 'cc1plus': execvp: no such file or directory 错误,请尝试像这样重新安装 GCC,然后再次编译:

sudo apt-get install --reinstall gcc-5
sudo apt-get install --reinstall g++-5

致谢:https://github.com/facebookresearch/maskrcnn-benchmark/issues/25#issuecomment-433382510

【讨论】:

【参考方案19】:

如果遇到此错误,请阅读日志文件:

$ cat /var/log/cuda-installer.log 
[INFO]: Driver installation detected by command: apt list --installed | grep -e nvidia-driver-[0-9][0-9][0-9] -e nvidia-[0-9][0-9][0-9]
[INFO]: Cleaning up window
[INFO]: Complete
[INFO]: Checking compiler version...
[INFO]: gcc location: /usr/bin/gcc

[INFO]: gcc version: gcc version 9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2) 

[ERROR]: unsupported compiler version: 9.2.1. Use --override to override this check.

只需按照日志文件中的建议进行操作即可:

sudo sh cuda_<version>_linux.run --override

工作完成:)

我刚刚使用 --override 选项在 Kubuntu 19.10 上安装了 CUDA 10.2 和 gcc 9.2。

【讨论】:

【参考方案20】:

对于 CUDA 6.5(显然是 7.0 和 7.5),我创建了一个版本的 gcc 4.8.5 RPM 软件包(在 Fedora Core 30 下),它允许该版本的 gcc 与您系统当前的 GCC 一起安装。

您可以找到所有这些信息here。

【讨论】:

【参考方案21】:

在我的例子中,我已经从 Ubuntu 版本安装了 CUDA,cmake 会使用 NVidia SDK Manager 检测到那个版本,而不是新安装的版本。

我跑了dpkg -l | grep cuda 并且可以看到两个版本。

我必须做的是卸载旧的 CUDA(在我的例子中是 9.1 版)并保留新版本(10.2 版)。我像这样使用清除命令:

sudo apt-get purge libcudart9.1 nvidia-cuda-dev nvidia-cuda-doc \
                                nvidia-cuda-gdb nvidia-cuda-toolkit

请验证软件包名称是否与您要从安装中删除的版本相匹配。

我不得不从空白的BUILD 目录重新运行cmake,以将所有#include 和库重定向到SDK 版本(因为旧路径是在现有构建环境中烘焙的)。

【讨论】:

以上是关于CUDA 与我的 gcc 版本不兼容的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow 和 Cuda 不兼容

CUDA-capability和CUDA版本:兼容?

如何找到与我的 react native 版本兼容的 fbsdk 版本?

为啥 Google Play 商店说我的 Android 应用与我自己的设备不兼容?

驱动程序找不到兼容的图形硬件

如何确定哪个旧版本的 R 包与我的 R 版本兼容