使用 nvcc、icpc 编译时来自 cudaGetDeviceCount 的运行时 cudaErrorInsufficientDriver 错误

Runtime cudaErrorInsufficientDriver error from cudaGetDeviceCount when compiling with nvcc, icpc

问题

我有一个使用 FFTW3 的基于 FFT 的应用程序。我正在使用 CUFFT 将应用程序移植到基于 CUDA 的实现。在 Nsight 中独立编译和 运行 应用程序的 FFT 核心工作正常。我已经从那里转移到将设备代码集成到我的应用程序中。

当我 运行 使用集成到我的应用程序中的 CUFFT 核心代码时, cudaGetDeviceCount returns 一个 cudaErrorInsufficientDriver 错误,虽然我没有用 Nsight 得到它独立 运行。此调用是在 运行 开始时进行的,当时我正在初始化 GPU。

背景

我 运行 正在使用 CentOS 6,在 GeForce GTX 750 和 icpc 12.1.5 上使用 CUDA 7.0。我还使用 GT 610 成功地测试了一个小示例。两张卡都在 Nsight 中工作(而且我也编译 运行 命令行没有问题,尽管没有 Nsight 中的那么广泛)。

为了将 FFT 核心的 CUFFT 实现集成到我的应用程序中,我使用 nvcc 编译和设备linked,然后使用 icpc(英特尔 C++ 编译器)来编译主机代码并link 设备和主机代码创建.so。我终于在没有错误或警告的情况下完成了那一步(依赖this tutorial)。

(关于我为什么使用 .so 的原因有相当多的历史和额外的背景。足以说明我的应用程序需要制作 .so。)

本教程指出编译步骤在生成独立可执行文件(就像我在 Nsight 中所做的那样)和生成设备-linked 库以包含在 .so 中是不同的。为了完成编译,我必须按照教程中的描述添加 -lcudart 以及 -lcuda 到我的 icpc linking 调用(以及 -L 添加 .../cuda-7.0/lib64.../cuda-7.0/lib64/stubs 作为这些库的路径。

注意:默认情况下 libcudart 中的 nvcc links。我假设它对 libcuda 做同样的事情,因为 Nsight 在任何编译和 linking 步骤中都不包含这些库中的任何一个。顺便说一句,我确实觉得很奇怪,虽然nvcc link 默认情况下,它们不会出现在对可执行文件 ldd 的调用中。

我还必须将 --compiler-options '-fPIC' 添加到我的 nvcc 命令中以避免 here.

中描述的错误

我看到一些关于 Intel/NVCC 兼容性的讨论(例如,参见 this post),但看起来它们出现在旧版本 NVCC 的编译时,所以...我 认为 在这方面我没问题。

最后是编译三个.cu文件的编译命令(除了.cu文件名和.o文件名外完全相同):

nvcc
-ccbin g++
-Iinc
-I/path/to/cuda/samples/common/inc
-m64
-O3
-gencode arch=compute_20,code=sm_20
-gencode arch=compute_30,code=sm_30
-gencode arch=compute_35,code=sm_35
-gencode arch=compute_37,code=sm_37
-gencode arch=compute_50,code=sm_50
-gencode arch=compute_52,code=sm_52
-gencode arch=compute_52,code=compute_52
--relocatable-device-code=true
--compile
--compiler-options '-fPIC'
-o my_object_file1.o
-c my_source_code_file1.cu

这是我传递给设备的标志 linking 步骤:

nvcc
-ccbin g++
-Iinc
-I/path/to/cuda/samples/common/inc
-m64
-O3
-gencode arch=compute_20,code=sm_20
-gencode arch=compute_30,code=sm_30
-gencode arch=compute_35,code=sm_35
-gencode arch=compute_37,code=sm_37
-gencode arch=compute_50,code=sm_50
-gencode arch=compute_52,code=sm_52
-gencode arch=compute_52,code=compute_52
--compiler-options '-fPIC'
--device-link
my_object_file1.o
my_object_file2.o
my_object_file3.o
-o my_device_linked_object_file.o

我可能不需要 30、37 和 52 的 -gencode 标志,至少目前是这样,但它们应该不会造成任何问题,最终,我可能会那样编译。

这是我用于调用我的 CUDA 库的 .cc 文件的编译标志(减去 -o 标志和所有 -I 标志):

-c
-fpic
-D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64
-fno-operator-names
-D_REENTRANT
-D_POSIX_PTHREAD_SEMANTICS
-DM2KLITE -DGCC_
-std=gnu++98
-O2
-fp-model source
-gcc
-wd1881
-vec-report0

最后,这是我的 linking 标志:

-pthread
-shared

关于如何解决这个问题有什么想法吗?

不要添加到 LD_LIBRARY_PATH .../cuda7.0/lib64/stubs。如果你这样做,你将从那里拿起 libcuda.so 而不是从 driver。 (参见 this post)。