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/gcc
和 sudo 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++ 版本。此外,大多数构建系统都知道CC
和CXX
环境变量,它们可以分别指定其他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/gcc
和 ln -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 版本不兼容的主要内容,如果未能解决你的问题,请参考以下文章
如何找到与我的 react native 版本兼容的 fbsdk 版本?