c++ - clgetPlatformIDs() 返回 -1001 即使 nvidia.icd 存在并包含 'libcuda.so'

标签 c++ ubuntu opencl nvidia dlopen

最近我一直在我的 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 个 - clGetPlatformInfoclGetExtensionFunctionAddress。另一个失败了,正如论坛帖子所建议的那样:作者继续说他们使用 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/

相关文章:

c++ - boost 线程死锁,任何人都可以检查为什么?

c++ - 将大于 long 类型最大值的值传递给 C 中的 fseek

c++ - 结构化绑定(bind)中的 const 引用是否会延长分解对象的生命周期?

c++ - opencl clCreateImage clCreateImage2D

c++ - 如何使用 OpenCL C++ API 获取设备 cl_device_id

c++ - 在 Visual C++ 2010 Windows 窗体项目中使用 HTML Tidy

eclipse - 无法安装 EclipseFP,因为无法安装 scion-browser,因为无法安装 terminfo

java - 如何在 ubuntu 中运行一个有很多 jars 依赖的 java 文件

bash - 在 Ubuntu 18.04 上使用 bash 编写 "sudo apt upgrade"脚本时,如何自动绕过 "package configuration"屏幕?

macos - OpenCL:如何优化缩减内核(列总和),目前 CPU 速度更快