【发布时间】: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不起作用”,而不是“我该如何使用它”。 ;-)