最近我一直在我的 Ubuntu 12.04 机器上使用 OpenCL。当我调用 cl::Platform::get
时,我收到错误代码 -1001。经过一些研究,我发现当 c 调用 getPlatformIDs
找不到有效平台时会发生这种情况,并且当/etc/OpenCL/vendors/中没有 .icd 文件时会发生这种情况目录,或者当文件引用的实现无法通过调用 dlopen
打开时。
然而,我已经测试了所有这些可能性。在/etc/OpenCL/vendors/中,我找到了 nvidia.icd,其中包含“libcuda.so”行。然后,我尝试在此文件名上调用 dlopen
,并成功了。然而,我的程序仍然返回错误代码 -1001!我的 nvidia 驱动程序在所有其他方面都运行良好,并且我能够编译该程序。可能有什么问题?
齐斯塔克
编辑:额外信息:我正在使用 nvidia-current-dev 驱动程序。我正在运行 nvidia GeForce GT 540M。
编辑:我最近发现了一些有趣的东西:Here是来自 Khronos 的关于 icd 加载器的规范。它说:
Upon successfully loading a Vendor ICD's library, the ICD Loader queries the following functions from the library: clIcdGetPlatformIDsKHR, clGetPlatformInfo, and clGetExtensionFunctionAddress. If any of these functions are not present then the ICD Loader will close and ignore the library.
和here是一个实现 icd 加载器试图加载 nvidia 平台的人的帖子。它说:
I can get clGetExtensionFunctionAddress and clGetPlatformInfo from libcuda.so using dlsym(), and I can then use clGetExtensionFunctionAddress to retrieve clIcdGetPlatformIDsKHR.
在我的实验中,我只能成功查询 3 个函数中的 2 个 - clGetPlatformInfo
和 clGetExtensionFunctionAddress
。另一个失败了,正如论坛帖子所建议的那样:作者继续说他们使用 clGetExtensionFunctionAddress
来检索 clIcdGetPlatformIDsKHR
。如果 Khronos 实现的 ICD 加载器逐字逐句地遵循规范,那么它会失败是有道理的,因为对 clIcdGetPlatformIDsKHR
的查询将失败,并且库将被忽略。鉴于此,似乎 nvidia 实现似乎并没有完全实现规范,除非有另一个我不知道的更新版本。然而其他人设法让 OpenCL 在他们的 nvidia 平台上工作得很好。我错过了什么吗?
最佳答案
我想通了,这个命令的输出说明了一切:
lspci | grep VGA
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller (rev 09)
01:00.0 VGA compatible controller: NVIDIA Corporation GF108 [GeForce GT 540M] (rev ff)
我有 optimus 技术,因此我的系统默认使用 Intel VGA Controller 。因此,nvidia 平台无效,因为从我的程序的角度来看,软件没有附加硬件。不幸的是,没有简单的方法可以让操作系统忽略 Intel 芯片而只使用 nvidia 芯片,而且 nvidia 不喜欢在 linux 下支持 optimus,所以没有用于此设置的驱动程序。但是,安装 bumblebee 并使用 optirun
运行我的程序非常有效。
关于c++ - clgetPlatformIDs() 返回 -1001 即使 nvidia.icd 存在并包含 'libcuda.so',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10776230/