CUDA与我的gcc版本不兼容

CUDA incompatible with my gcc version

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

最初,它根本没有编译:

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

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

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

从那时起,我只编译了几个示例,其结尾为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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将整个系统作为依赖项...


如前所述,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


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

您唯一的解决方案是安装gcc 4.4版本作为第二个编译器(大多数发行版都允许这样做)。 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版本开始,在Ubuntu 16.04,Ubuntu 17.04和Fedora 25上完全支持gcc 6。
  • CUDA 9.2版本增加了对gcc 7的支持
  • CUDA 10.1版本增加了对gcc 8的支持

当前(从CUDA 10.1开始)在CUDA中不支持gcc 9。

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     | CUDA version | max supported GCC version |
     |--------------|---------------------------|
     |      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:

    1
     MAX_GCC_VERSION=8
  • 确保已安装该版本:

    1
     sudo apt install gcc-$MAX_GCC_VERSION g++-$MAX_GCC_VERSION
  • 在CUDA文件夹中添加符号链接:

    1
    2
     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++

    (如果不存在,则用/usr/local/cuda替换为CUDA安装路径)

  • 有关CUDA-GCC兼容性表的更多信息,请参见GitHub要点。


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

    1
    2
    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++

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

    1
    2
    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++

    查看如何使用"更新替代"来解决此问题:

    ... If you install gcc 4.6 you can also use the update-alternatives
    command to allow for easily switching between versions. This can be
    configured with:

    1
    2
    3
    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

    如果对我使用cmake,则没有编辑文件和链接的技巧,因此我使用指定gcc / g ++版本的标志进行了编译。
    cmake -DCMAKE_C_COMPILER=gcc-6 -DCMAKE_CXX_COMPILER=g++-6 ..

    像魅力一样工作。


    在大多数发行版中,除了最新的编译器(例如gcc-4.7)之外,您还可以安装其他gcc和g ++版本。此外,大多数构建系统都知道CCCXX环境变量,它们可以分别指定其他C和C ++编译器。所以我建议类似:

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

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


    这适用于fedora23。compated gcc存储库将根据您的fedora版本而稍有不同。

    如果安装以下存储库:

    1
    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/

    1
    2
    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版本错误。


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

    1
    2
    3
    4
    5
    6
    7
    //...
    #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 <= 6.5

    要么

    CUDA的--std=c++11 = 7.0。


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


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


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

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

    1
    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手册用于用户配置,但这是最适合我的解决方案。


    Gearoid Murphy的解决方案就像一个魅力。对我来说,我有两个cuda目录-

    1
    2
    /usr/local/cuda
    /usr/local/cuda-5.0

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

    1
    /usr/local/cuda

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


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

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

    检查gcc-4.4是否在/ usr / bin /中,并且与g ++相同
    然后我可以使用上面的解决方案:

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ 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.

    只需遵循日志文件中的建议即可:

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

    任务完成 :)

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


    就我而言,我已经从Ubuntu版本安装了CUDA,而cmake将使用NVidia SDK Manager来检测该版本而不是新安装的版本。

    我运行了dpkg -l | grep cuda,可以看到两个版本。

    我要做的是卸载旧的CUDA(在我的情况下为9.1版),而单独保留新版本(10.2版)。 我像这样使用purge命令:

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

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

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    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

    这样的优点是,无需修改整个系统或仅对二进制文件进行符号链接(这可能会导致库链接问题。)


    这解决了我的问题:

    1
    2
    3
    4
    5
    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++

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

    您可以在此处找到所有这些信息。


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

  • 查找受支持的GCC版本(在我的情况下为CUDA 9,为5)

    • 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版本

    1
    2
    sudo apt-get install gcc-5
    sudo apt-get install g++-5
  • 更改/usr/bin目录中GCC的软链接

    1
    2
    3
    4
    5
    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的软链接

    1
    2
    3
    4
    5
    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文件中,用于编译

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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"
        ]
  • 删除旧的构建目录

    1
    rm -rd build/
  • 通过设置CUDAHOSTCXX=/usr/bin/gcc-5重新编译

    1
    CUDAHOSTCXX=/usr/bin/gcc-5 python setup.py build develop
  • 注意:如果按照以下步骤操作后仍然出现gcc: error trying to exec 'cc1plus': execvp: no such file or directory错误,请尝试像这样重新安装GCC,然后重新编译:

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

    积分:https://github.com/facebookresearch/maskrcnn-benchmark/issues/25#issuecomment-433382510