【问题标题】:Why does a CUDA program work with CMake “FIND_PACKAGE”, but not with “LANGUAGES CUDA”?为什么 CUDA 程序可以与 CMake “FIND_PACKAGE”一起使用,但不能与“LANGUAGES CUDA”一起使用?
【发布时间】:2019-06-06 07:40:40
【问题描述】:

注意:之前的标题是“如何在不使用 FIND_PACKAGE 的情况下使用 CMake 编译 CUDA 程序?”。编辑以更清楚地说明关键问题是什么。

以建议的方式使用 CMake 和 CUDA 时,如果没有 FIND_PACKAGE,它会编译,但是当我运行生成的二进制文件时,会出现以下错误:

CUDA error: CUDA driver version is insufficient for CUDA runtime version

但是,如果我使用nvcc 手动编译,或者如果我在cmake 中使用FIND_PACKAGE,它工作正常。 CUDA 示例也可以编译和运行。我知道 FIND_PACKAGE(CUDA) 已被弃用,因为 cuda 现在是一流的 cmake 语言。这两种不同的方法有什么区别,如何在不使用 find 包的情况下让它工作?


详情:

main.cu:

#include <iostream>

__global__ void helloGPU() {
    printf("Hi globe\n");
}

int main() {
    helloGPU<<<1,2>>>();
    cudaDeviceSynchronize();
    cudaError_t error = cudaGetLastError();
    if(error != cudaSuccess)
    {
        printf("CUDA error: %s\n", cudaGetErrorString(error));
        exit(-1);
    }
}

有效的 CMakeLists.txt:

cmake_minimum_required (VERSION 3.10)
find_package(CUDA REQUIRED)
cuda_add_executable(simple main.cu)

已损坏的 CMakeLists.txt:

cmake_minimum_required (VERSION 3.10)
project(simplecuda LANGUAGES CXX CUDA)
add_executable(simple main.cu)

系统:

Mac OS High Sierra 10.13.6
Cuda 驱动版本:410.130
GPU 驱动程序版本:387.10.10.10.40.105
nvcc 版本:10.0.130
clang++ 版本:9.0.0

编辑:为什么是当前的驱动程序版本

一些 cmets 建议使用不同的驱动程序版本。这就是为什么我有列出的版本:

使用 CUDA 安装程序安装的默认驱动程序,尝试运行 CUDA 示例时出现以下错误:

CUDA driver version is insufficient for CUDA runtime version

像这样的网站让我相信尝试不同的驱动程序版本会有所帮助:(https://devtalk.nvidia.com/default/topic/1027922/cuda-setup-and-installation/-solved-code-35-cudaerrorinsufficientdriver-error-on-mac-version-10-13-2-17c88-with-nvidia-geforce-gt-/)。

经过一些不成功的尝试和错误,我发现了这个脚本:https://www.tonymacx86.com/threads/nvidia-update-simple-way-to-install-nvidia-web-drivers.244987/

这会自动搜索并安装驱动程序,这就是我获得 387.10.10.10.40.105 的方式。

在这个版本中,CUDA 示例第一次可以正常工作,使用 nvcc 手动编译源代码可以正常工作,并且使用 FIND_PACKAGE 可以正常工作。我相对确定我的驱动程序版本现在是正确的。当我使用 NVIDIA Driver Manager 首选项窗格检查新版本时,它说我有最新的,并且根据http://www.macvidcards.com/drivers.html,我有正确的驱动程序版本。

编辑:深入研究构建命令

我通过使用make VERBOSE=1 进一步研究了 CMake 正在做什么。我删除了尽可能多的行和标志,以仍然获得相同的行为,并简化了路径、tmp 目录等。这是生成错误二进制文件的命令的最小示例,取自带有LANGUAGES CXX CUDA 的 CMake (如果我在与main.cu 相同的文件夹中运行这些,然后运行./simple,它会给出上面的CUDA 错误):

/Developer/NVIDIA/CUDA-10.0/bin/nvcc  -c main.cu -o main.cu.o
/Developer/NVIDIA/CUDA-10.0/bin/nvcc  -dlink main.cu.o -o cmake_device_link.o
/usr/bin/clang++  main.cu.o cmake_device_link.o -o simple  -L"/Developer/NVIDIA/CUDA-10.0/lib" "/Developer/NVIDIA/CUDA-10.0/lib/libcudart_static.a"

这是来自 CMake 的类似最小版本的命令,带有FIND_PACKAGE(CUDA)

/Developer/NVIDIA/CUDA-10.0/bin/nvcc main.cu -c -o main.cu.o -I/Developer/NVIDIA/CUDA-10.0/include
/usr/bin/clang++   main.cu.o  -o simple /Developer/NVIDIA/CUDA-10.0/lib/libcudart_static.a -Wl,-rpath,/usr/local/cuda/lib

关键部分似乎是最后一个标志,-Wl,-rpath,/usr/local/cuda/lib。我可以通过设置环境变量来使损坏的 CMake 版本正常工作:

export LD_LIBRARY_PATH=/usr/local/cuda/lib

或通过如下方式更新 CMake 文件:

SET_TARGET_PROPERTIES(simple PROPERTIES LINK_FLAGS -Wl,-rpath,/usr/local/cuda/lib)

我的系统是否有问题需要我执行此操作?或者 CMake 在 Mac 上的 cuda 兼容性被破坏了?

注意:官方博客中提到了Apple和rpaths的一些东西:https://devblogs.nvidia.com/building-cuda-applications-cmake/

但如果我将此部分添加到CMakeLists.txt,它没有帮助:

if(APPLE)
  # We need to add the path to the driver (libcuda.dylib) as an rpath, 
  # so that the static cuda runtime can find it at runtime.
  set_property(TARGET simple
               PROPERTY
               BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
endif()

【问题讨论】:

  • 原生 CUDA 支持似乎可以检查更多内容或激活更高的运行时版本。您的目标运行时版本是什么?
  • 我真的不确定,我是新手。我应该定位哪个运行时版本?如何针对不同的运行时版本?
  • 我看到这个问题被否决了。有没有我可以提供的更多信息,或者重新措辞可以使我的要求更清楚?
  • 很奇怪,发行说明说它应该可以工作:docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html 奇怪的是 GPU 驱动程序比 CUDA 驱动程序旧得多,也许这就是问题所在?您可以使用更新的 GPU 驱动程序吗?此外,当 CMake 运行这些检查时,它可以确保代码确实有效。手工构建后运行吗?
  • 一般建议:如果确实应该起作用的东西不起作用,那么找出它不起作用的原因通常比尝试找到解决方法更有效率。可能会有更深层次的问题,至少你会以一种不完整的方法来处理更难维护的事情。即,问题应该是“为什么find_package 不起作用”,而不是“我该如何使用它”。 ;-)

标签: c++ cmake cuda


【解决方案1】:

我必须不同意并同意@MatthieuBrucher:

  • CUDA 10 需要 410+ 个驱动程序,您似乎有 387 个用于显示,它与 CUDA 9.0 兼容。另外,我不建议混合使用 CUDA 和显示驱动程序版本。在 Linux 和 Windows 上,CUDA 驱动程序会与显示驱动程序一起自动安装,因此您总能获得良好的组合。

  • CMake 将尝试构建一个小型测试程序(在 Linux 上从 /usr/share/cmake-3.10/Modules/CMakeCUDACompilerId.cu.in 生成)并尝试运行它。这就是您收到兼容性错误消息的地方。

升级您的显示驱动程序,一切正常。如果较新的驱动程序不支持您的 GPU(在 mac 上不应该是这种情况),那么您将不得不降级您的 CUDA 驱动程序和工具包。

您可以找到更多信息here,尤其是前两行:

CUDA 工具包正在过渡到更快的发布节奏,以提供新功能、性能改进和关键错误修复。然而,CUDA 运行时与显示驱动程序的紧密耦合(特别是 libcuda.so — Linux 系统上的 CUDA 驱动程序),意味着客户需要更新整个驱动程序堆栈以使用最新的 CUDA 软件(包括编译器、库和工具)。

(已添加重点)

【讨论】:

  • 谢谢。我花了一段时间试图让其他驱动程序版本工作,并认为我终于用当前版本破解了它。我在解释细节的问题文本中添加了更多注释。我会尝试回去尝试其他版本。
  • 至少根据这个站点:macvidcards.com/drivers.html,我有正确的驱动程序版本。 (我有 Mac OS 10.13.6 build 17G65,其正确的驱动程序列为 387.10.10.10.40.105)。
  • 也许故事是这样的:我的 GPU 和操作系统需要驱动程序版本 387.10.10.40.105,但 CUDA 10.0 需要版本 410+,所以我不应该在我的机器上运行 CUDA 版本 10.0。这有点道理,但我仍然很想知道为什么它使用大多数编译方法都有效。
  • 如何解释代码在以一种方式构建而不是在以另一种方式构建时如何运行而没有错误?驱动程序不匹配应该与代码的构建方式无关
  • 我敢打赌安装多个 CUDA 版本并且编译器(甚至可能使用不同的编译器版本)不针对同一版本,具体取决于从 cmake 调用或手动调用
猜你喜欢
  • 2020-12-16
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 2021-11-15
相关资源
最近更新 更多