OpenCL 找不到平台?
OpenCL not finding platforms?
我正在尝试将 C++ API 用于 OpenCL。我已经安装了我的 NVIDIA 驱动程序并且我已经测试过我可以 运行 提供的简单矢量加法程序 here。我可以用下面的 gcc 调用和程序 运行s 毫无问题地编译这个程序。
gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include
但是,我更愿意使用 C++ API 而不是 C 所需的非常冗长的主机文件。
我从 here 下载了 Khronos 的 C++ 绑定,并将 cl.hpp
文件放在与我的其他 cl.h
文件相同的位置。该代码使用了一些 C++11,因此我可以使用以下代码编译代码:
g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include
但是当我尝试 运行 程序时出现错误:
clGetPlatformIDs(-1001)
我还尝试了 here 提供的示例,它给出了更有帮助的错误消息。
No platforms found. Check OpenCL installation!
提供此错误的特定代码是:
std::vector<cl::Platform> all_platforms;
cl::Platform::get(&all_platforms);
if(all_platforms.size()==0){
std::cout<<" No platforms found. Check OpenCL installation!\n";
exit(1);
}
考虑到 C 实现 运行 没有问题,这看起来很奇怪。任何见解将不胜感激。
编辑
C 实现实际上 运行 不正确。每次加法都打印为零。检查 ret_num_platforms
也 returns 0。出于某种原因,我的设置无法找到我的 GPU。我错过了什么?我的安装包括分别通过 apt-get
和 .run
文件安装的 nvidia-340 驱动程序和 cuda-6.5。
如果没有 运行 您机器上的特定代码,很难说,但查看您所说的示例 C 代码与 cl.hpp 之间的区别可能会给我们一些线索。特别要注意,C 示例使用以下行来简单地读取单个平台 ID:
cl_platform_id platform_id = NULL;
cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
注意传递 1 作为它的第一个参数。这假定至少存在一个 OpenCL 平台,并要求将找到的第一个放在 platform_id 中。此外,请注意,即使 return 代码分配给 "ret",它是否不会用于实际检查错误是否为 returned。
现在,如果我们查看用于对 cl.hpp 中的平台集进行排队的静态方法的实现,即 cl::Platform::get:
static cl_int get(
VECTOR_CLASS<Platform>* platforms)
{
cl_uint n = 0;
cl_int err = ::clGetPlatformIDs(0, NULL, &n);
if (err != CL_SUCCESS) {
return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
}
cl_platform_id* ids = (cl_platform_id*) alloca(
n * sizeof(cl_platform_id));
err = ::clGetPlatformIDs(n, ids, NULL);
if (err != CL_SUCCESS) {
return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
}
platforms->assign(&ids[0], &ids[n]);
return CL_SUCCESS;
}
我们看到它首先调用
::clGetPlatformIDs(0, NULL, &n);
注意第一个参数是 0,它告诉 OpenCL 运行时 return "n" 中的平台数量。如果成功,它将继续请求实际的 "n" 平台 ID。
所以这里的区别是 C 版本不检查是否存在至少一个平台并简单地假设存在一个,而 cl.hpp 变体是,因此可能是这个调用失败。
造成这一切的最可能原因是 ICD 未正确安装。您可以查看此线程以获取有关如何解决此问题的示例:
ERROR: clGetPlatformIDs -1001 when running OpenCL code (Linux)
希望对您有所帮助。
非常感谢@pasternak 帮助我解决了这个问题。然而,为了解决它,我最终需要避免基本上所有 ubuntu apt-get
调用安装,而只使用 cuda 运行 文件进行完整安装。这是解决问题的方法。
- 清除现有的 nvidia 和 cuda 实现(
sudo apt-get purge cuda* nvidia-*
)
- 从 CUDA toolkit archive
下载 cuda-6.5 工具包
- 重启电脑
- 切换到 ttyl (Ctrl-Alt-F1)
- 停止 X 服务器(sudo stop lightdm)
- 运行 cuda 运行 文件 (
sh cuda_6.5.14_linux_64.run
)
- Select 'yes' 并接受所有默认值
- 需要重启
- 切换到 ttyl,停止 X 服务器和 运行 cuda 运行 文件,select 'yes' 和默认的一切(包括 driver再次)
- 更新
PATH
以包含 /usr/local/cuda-6.5/bin
和 LD_LIBRARY_PATH
包括 /usr/local/cuda-6.5/lib64
- 再次重启
- 编译main.c程序(
gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include
)
- 验证适用于
./vectorAddition
C++ API
- 从 Khronos here 下载
cl.hpp
文件,注意它是版本 1.1
- 将 cl.hpp 文件与其他 cl headers.
一起放入 /usr/local/cuda-6.5/include/CL
- 编译 main.cpp (
g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include
)
- 验证它是否有效 (
./vectorAddition_cpp
)
两个程序的所有输出都显示了向量之间相加的正确输出。
我个人觉得有趣的是 Ubuntu 的 nvidia drivers 似乎不能很好地与 cuda 工具包一起玩。可能只是针对旧版本,但仍然非常出乎意料。
我正在尝试将 C++ API 用于 OpenCL。我已经安装了我的 NVIDIA 驱动程序并且我已经测试过我可以 运行 提供的简单矢量加法程序 here。我可以用下面的 gcc 调用和程序 运行s 毫无问题地编译这个程序。
gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include
但是,我更愿意使用 C++ API 而不是 C 所需的非常冗长的主机文件。
我从 here 下载了 Khronos 的 C++ 绑定,并将 cl.hpp
文件放在与我的其他 cl.h
文件相同的位置。该代码使用了一些 C++11,因此我可以使用以下代码编译代码:
g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include
但是当我尝试 运行 程序时出现错误:
clGetPlatformIDs(-1001)
我还尝试了 here 提供的示例,它给出了更有帮助的错误消息。
No platforms found. Check OpenCL installation!
提供此错误的特定代码是:
std::vector<cl::Platform> all_platforms;
cl::Platform::get(&all_platforms);
if(all_platforms.size()==0){
std::cout<<" No platforms found. Check OpenCL installation!\n";
exit(1);
}
考虑到 C 实现 运行 没有问题,这看起来很奇怪。任何见解将不胜感激。
编辑
C 实现实际上 运行 不正确。每次加法都打印为零。检查 ret_num_platforms
也 returns 0。出于某种原因,我的设置无法找到我的 GPU。我错过了什么?我的安装包括分别通过 apt-get
和 .run
文件安装的 nvidia-340 驱动程序和 cuda-6.5。
如果没有 运行 您机器上的特定代码,很难说,但查看您所说的示例 C 代码与 cl.hpp 之间的区别可能会给我们一些线索。特别要注意,C 示例使用以下行来简单地读取单个平台 ID:
cl_platform_id platform_id = NULL;
cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
注意传递 1 作为它的第一个参数。这假定至少存在一个 OpenCL 平台,并要求将找到的第一个放在 platform_id 中。此外,请注意,即使 return 代码分配给 "ret",它是否不会用于实际检查错误是否为 returned。
现在,如果我们查看用于对 cl.hpp 中的平台集进行排队的静态方法的实现,即 cl::Platform::get:
static cl_int get(
VECTOR_CLASS<Platform>* platforms)
{
cl_uint n = 0;
cl_int err = ::clGetPlatformIDs(0, NULL, &n);
if (err != CL_SUCCESS) {
return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
}
cl_platform_id* ids = (cl_platform_id*) alloca(
n * sizeof(cl_platform_id));
err = ::clGetPlatformIDs(n, ids, NULL);
if (err != CL_SUCCESS) {
return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
}
platforms->assign(&ids[0], &ids[n]);
return CL_SUCCESS;
}
我们看到它首先调用
::clGetPlatformIDs(0, NULL, &n);
注意第一个参数是 0,它告诉 OpenCL 运行时 return "n" 中的平台数量。如果成功,它将继续请求实际的 "n" 平台 ID。
所以这里的区别是 C 版本不检查是否存在至少一个平台并简单地假设存在一个,而 cl.hpp 变体是,因此可能是这个调用失败。
造成这一切的最可能原因是 ICD 未正确安装。您可以查看此线程以获取有关如何解决此问题的示例:
ERROR: clGetPlatformIDs -1001 when running OpenCL code (Linux)
希望对您有所帮助。
非常感谢@pasternak 帮助我解决了这个问题。然而,为了解决它,我最终需要避免基本上所有 ubuntu apt-get
调用安装,而只使用 cuda 运行 文件进行完整安装。这是解决问题的方法。
- 清除现有的 nvidia 和 cuda 实现(
sudo apt-get purge cuda* nvidia-*
) - 从 CUDA toolkit archive 下载 cuda-6.5 工具包
- 重启电脑
- 切换到 ttyl (Ctrl-Alt-F1)
- 停止 X 服务器(sudo stop lightdm)
- 运行 cuda 运行 文件 (
sh cuda_6.5.14_linux_64.run
) - Select 'yes' 并接受所有默认值
- 需要重启
- 切换到 ttyl,停止 X 服务器和 运行 cuda 运行 文件,select 'yes' 和默认的一切(包括 driver再次)
- 更新
PATH
以包含/usr/local/cuda-6.5/bin
和LD_LIBRARY_PATH
包括/usr/local/cuda-6.5/lib64
- 再次重启
- 编译main.c程序(
gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include
) - 验证适用于
./vectorAddition
C++ API
- 从 Khronos here 下载
cl.hpp
文件,注意它是版本 1.1 - 将 cl.hpp 文件与其他 cl headers. 一起放入
- 编译 main.cpp (
g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include
) - 验证它是否有效 (
./vectorAddition_cpp
)
/usr/local/cuda-6.5/include/CL
两个程序的所有输出都显示了向量之间相加的正确输出。
我个人觉得有趣的是 Ubuntu 的 nvidia drivers 似乎不能很好地与 cuda 工具包一起玩。可能只是针对旧版本,但仍然非常出乎意料。