【发布时间】:2015-12-28 13:08:14
【问题描述】:
问题
我有一个使用 FFTW3 的基于 FFT 的应用程序。我正在使用 CUFFT 将应用程序移植到基于 CUDA 的实现。在 Nsight 中独立编译和运行应用程序的 FFT 核心工作正常。我已经从那里转移到将设备代码集成到我的应用程序中。
当我使用集成到我的应用程序中的 CUFFT 核心代码运行时,cudaGetDeviceCount 返回一个 cudaErrorInsufficientDriver 错误,尽管我在 Nsight 独立运行时没有得到它。这个调用是在我初始化 GPU 时在运行开始时进行的。
背景
我在 CentOS 6 上运行,在 GeForce GTX 750 上使用 CUDA 7.0,icpc 12.1.5。我还成功地测试了一个使用 GT 610 的小示例。这两种卡都可以在 Nsight 中运行(而且我还可以毫无问题地编译和运行命令行,尽管不如 Nsight 中那样广泛)。
为了将 FFT 内核的 CUFFT 实现集成到我的应用程序中,我使用 nvcc 编译和设备链接,然后使用 icpc(英特尔 C++ 编译器)编译主机代码并链接设备和主机创建 .so 的代码。我终于在没有错误或警告的情况下完成了该步骤(依赖于this tutorial)。
(关于我为什么使用 .so 的原因有相当多的历史和额外的背景。只要说我的应用程序需要制作 .so 就够了。)
本教程指出,生成独立可执行文件(就像我在 Nsight 中所做的那样)和生成设备链接库以包含在 .so 中的编译步骤不同。为了完成编译,我必须按照教程中的描述添加-lcudart,以及-lcuda,到我的icpc链接调用(以及-L以添加.../cuda-7.0/lib64和.../cuda-7.0/lib64/stubs作为这些库的路径)。
注意:nvcc 默认链接到 libcudart。我假设它对libcuda 执行相同的操作,因为 Nsight 没有在任何编译和链接步骤中包含这些库中的任何一个。顺便说一句,我确实觉得很奇怪,尽管 nvcc 将它们链接到默认情况下,它们不会在可执行文件上调用 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
这是我传递给设备链接步骤的标志:
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
最后,这是我的链接标志:
-pthread
-shared
关于如何解决这个问题的任何想法?
【问题讨论】:
-
你是在g++兼容模式下编译和链接intel编译器吗?
-
@talonmies 我的印象是英特尔默认编译 g++ 兼容模式,您必须使用 --no-gcc 标志显式关闭它。话虽如此,我将更新我的帖子以显示我的编译和链接标志。
-
根据我遇到的所有情况,“驱动程序不足”意味着相对于正在使用的 CUDA 运行时版本,您的驱动程序太旧了。将您的驱动程序包更新到适用于您的平台的最新版本。由于现代 CUDA 版本附带了匹配的驱动程序包,因此不清楚您是如何使用过时的驱动程序结束的。
-
我的建议是简单地安装最新的驱动程序包(只需几分钟的工作)来检查是否可以解决问题,而不是进一步假设。我从未见过 CUDA 运行时发出的误报“驱动程序不足”错误,这并不意味着这样的错误是不可能的,只是看起来不太可能。
-
这在我的脑海中没有加起来。较旧的 CUDA 运行时应该可以与较新的 CUDA 驱动程序一起正常工作,相反的情况不起作用并导致“驱动程序不足”错误。换句话说,您应该能够在不更新 CUDA 运行时的情况下安装 never 驱动程序。您可能需要咨询您的 IT 部门,看看他们到底在做什么。