我正在尝试使用OpenCL的C ++ API。我已经安装了我的NVIDIA驱动程序,并且测试过我可以运行here提供的简单向量添加程序。我可以使用以下gcc调用编译该程序,程序运行没有问题。
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
也会返回0.由于某种原因,我的设置无法找到我的GPU。我能错过什么?我的安装包括分别通过apt-get
和.run
文件安装的nvidia-340驱动程序和cuda-6.5。
答案 0 :(得分:4)
我最诚挚的感谢@pasternak帮助我解决了这个问题。为了解决它,我最终需要避免基本上所有ubuntu apt-get
调用安装,只需使用cuda运行文件进行完整安装。以下是解决问题的方法。
sudo apt-get purge cuda* nvidia-*
)sh cuda_6.5.14_linux_64.run
)PATH
以包含/usr/local/cuda-6.5/bin
和LD_LIBRARY_PATH
包括/usr/local/cuda-6.5/lib64
gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include
)./vectorAddition
C ++ API
cl.hpp
文件,注意它是版本1.1 /usr/local/cuda-6.5/include/CL
和其他cl标题中。g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include
)./vectorAddition_cpp
)两个程序的所有输出都显示了矢量之间相加的正确输出。
我个人觉得有趣的是,Ubuntu的nvidia驱动程序似乎与cuda工具包不太匹配。可能仅适用于旧版本,但仍然非常出乎意料。
答案 1 :(得分:2)
很难说没有在你的机器上运行特定的代码,但是看看你说的工作的示例C代码和cl.hpp之间的区别可能会给我们一个线索。特别要注意的是,C示例使用以下行来简单地读取单个平台ID:
cl_platform_id platform_id = NULL;
cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
请注意,它是第一个参数传递1。这假设至少存在一个OpenCL平台,并请求找到的第一个OpenCL平台放在platform_id中。另外,请注意,即使将返回代码分配给“ret”,也不会用于实际检查是否返回错误。
现在,如果我们看一下用于对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运行时返回“n”中的平台数。如果成功,则继续请求实际的“n”平台ID。
所以这里的区别在于C版本没有检查是否存在至少一个平台而只是假设存在一个平台,而cl.hpp变体就是这样,也许这个调用失败了。
所有这一切的最可能原因是未正确安装ICD。您可以查看此主题以获取解决此问题的示例:
ERROR: clGetPlatformIDs -1001 when running OpenCL code (Linux)
我希望这会有所帮助。