OpenCL 1.2 C++ Wrapper - 对 clReleaseDevice 的未定义引用
Posted
技术标签:
【中文标题】OpenCL 1.2 C++ Wrapper - 对 clReleaseDevice 的未定义引用【英文标题】:OpenCL 1.2 C++ Wrapper - undefined reference to clReleaseDevice 【发布时间】:2013-03-29 03:46:19 【问题描述】:我正在尝试将 OpenCL C++ 包装 API 用于以下程序:
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <cstdio>
#include <cstdlib>
#include <iostream>
const char helloStr [] = "__kernel void "
"hello(void) "
" "
" "
" ";
int
main(void)
cl_int err = CL_SUCCESS;
try
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
if (platforms.size() == 0)
std::cout << "Platform size 0\n";
return -1;
cl_context_properties properties[] =
CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0;
cl::Context context(CL_DEVICE_TYPE_CPU, properties);
std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
cl::Program::Sources source(1,
std::make_pair(helloStr,strlen(helloStr)));
cl::Program program_ = cl::Program(context, source);
program_.build(devices);
cl::Kernel kernel(program_, "hello", &err);
cl::Event event;
cl::CommandQueue queue(context, devices[0], 0, &err);
queue.enqueueNDRangeKernel(
kernel,
cl::NullRange,
cl::NDRange(4,4),
cl::NullRange,
NULL,
&event);
event.wait();
catch (cl::Error err)
std::cerr
<< "ERROR: "
<< err.what()
<< "("
<< err.err()
<< ")"
<< std::endl;
return EXIT_SUCCESS;
我使用该博客文章中的相同内核文件,无论如何这不是问题,因为我无法通过编译。
我正在使用以下命令编译程序:
g++ example.cpp -o example -l OpenCL
我收到以下错误消息:
/tmp/ccbUf7dB.o: In function `cl::detail::ReferenceHandler<_cl_device_id*>::release(_cl_device_id*)':
example.cpp:(.text._ZN2cl6detail16ReferenceHandlerIP13_cl_device_idE7releaseES3_[_ZN2cl6detail16ReferenceHandlerIP13_cl_device_idE7releaseES3_]+0x14): undefined reference to `clReleaseDevice'
collect2: error: ld returned 1 exit status
我读过有关 clReleaseDevice 不适用于旧设备的资料(例如,请参阅 this question),但我的显卡是相当新的(NVidia GTX 660 Ti,支持 OpenCL 1.2)。我可以从那里去哪里?
我在 Ubuntu 13.04 x64 上运行它,并从 ubuntu 存储库安装了 nvidia-opencl-dev 和 opencl-headers。
【问题讨论】:
尝试将-DCL_USE_DEPRECATED_OPENCL_1_1_APIS
添加到您的makefile。
没有改变任何东西。我浏览了 CL/cl.hpp 文件,与此定义捆绑的代码似乎与此函数调用无关。
如果你输入#define CL_USE_DEPRECATED_OPENCL_1_1_APIS; #include "CL/cl.h"; #undef CL_VERSION_1_2; #define __CL_ENABLE_EXCEPTIONS; #include "cl-1.2.hpp"
会怎样?我在 Amazon AWS nvidia 上用 ubuntu 14.04 试了一下,好像还可以?
【参考方案1】:
根本原因
问题是您链接的 OpenCL 库不支持 OpenCL 1.2。笼统地说,在支持您要使用的版本的 OpenCL 实现可用于特定平台之前,当链接到随它提供的 OpenCL 共享库时,您将遇到这个问题。有两种解决方案:
从 Khronos 下载与所选硬件提供的 OpenCL 版本相匹配的 cl.hpp 版本,并继续使用设备制造商提供的库。 链接到实现最新 OpenCL 标准的 OpenCL 共享库,但编写多个代码路径 - 每个 OpenCL 版本一个,确保每个代码路径仅使用该版本支持的 OpenCL 功能。 这条路线更难,我不知道如何使用 C++ 包装器来实现。如果您尝试在不支持 OpenCL 1.2 的平台上调用 OpenCL 1.2 函数,您将收到段错误,这就是为什么需要不同的代码路径。英伟达专用
Nvidia 在提供 OpenCL 1.2 支持方面一直非常缓慢。结果,他们的 OpenCL 库没有提供链接器正在寻找的 OpenCL 1.2 函数,从而导致错误。
2015 年 5 月,Nvidia 发布了支持 OpenCL 1.2 的驱动程序,请参阅下面 Z Boson 的 cmets。更新驱动程序应该可以解决链接器错误。 GeForce GTX 6xx 和更高版本的显卡(前几代的更名除外)支持 OpenCL 1.2。您可以检查 Khronos OpenCL 站点上的conformant products list 以确保。列出了 GTX 660 Ti,所以你很幸运。
【讨论】:
我通过谷歌搜索得到了 OpenCL 1.2 支持,但似乎我错了!谢谢。 谢谢你 - 刚刚遇到同样的问题! Nvidia 现在在 Linux 和 Windows 上支持 OpenCL 1.2 phoronix.com/… “最近,NVIDIA 也终于在其专有的 Linux 驱动程序中添加了 OpenCL 1.2 支持。”和 devtalk.nvidia.com/default/topic/540773/… “是的,NVIDIA 352.84 和 352.63 的最新 Win10 驱动程序包括 OpenCL 1.2 支持。”【参考方案2】:是的。我从未在 Nvidia 设备上看到过 OpenCL 1.2。在您的系统上编译它,然后查看“OpenCL C 版本”:
#include <iostream>
#include <vector>
#include <CL/cl.hpp>
int main()
// Get the platforms
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
// Loop over the number of platforms
for ( size_t i = 0; i < platforms.size(); ++i )
// Display the platform information
std::cout << "Platform " << i+1 << ": "
<< platforms[i].getInfo<CL_PLATFORM_NAME>()
<< "\n----------------------------------------------"
<< "\nVendor : " << platforms[i].getInfo<CL_PLATFORM_VENDOR>()
<< "\nVersion : " << platforms[i].getInfo<CL_PLATFORM_VERSION>();
// Get the devices on the current platform
std::vector <cl::Device> devices;
platforms[i].getDevices( CL_DEVICE_TYPE_ALL , & devices);
// Loop over the devices
std::cout << "\n----------------------------------------------\n";
for ( size_t j = 0; j < devices.size(); ++j )
// Display the device information
std::cout
<< "\n Device " << j+1 << ": "
<< devices[j].getInfo< CL_DEVICE_NAME >()
<< "\n\t Device Version : "
<< devices[j].getInfo< CL_DEVICE_VERSION >()
<< "\n\t OpenCL C Version : "
<< devices[j].getInfo< CL_DEVICE_OPENCL_C_VERSION >()
<< "\n\t Compute Units : "
<< devices[j].getInfo< CL_DEVICE_MAX_COMPUTE_UNITS >()
<< "\n\t Max Work Group Size: "
<< devices[j].getInfo< CL_DEVICE_MAX_WORK_GROUP_SIZE >()
<< "\n\t Clock Frequency : "
<< devices[j].getInfo< CL_DEVICE_MAX_CLOCK_FREQUENCY >()
<< "\n\t Local Memory Size : "
<< devices[j].getInfo< CL_DEVICE_LOCAL_MEM_SIZE >()
<< "\n\t Global Memory Size : "
<< devices[j].getInfo< CL_DEVICE_GLOBAL_MEM_SIZE >();
// Check if the device supports double precision
std::string str = devices[j].getInfo<CL_DEVICE_EXTENSIONS>();
size_t found = str.find("cl_khr_fp64");
std::cout << "\n\t Double Precision : ";
if ( found != std::string::npos ) std::cout << "yes\n";
else std::cout << "no\n";
std::cout << "\n----------------------------------------------\n";
// std::cin.ignore();
return 0;
【讨论】:
以上是关于OpenCL 1.2 C++ Wrapper - 对 clReleaseDevice 的未定义引用的主要内容,如果未能解决你的问题,请参考以下文章
OpenCL 1.2:mem_fence() 或 barrier() 或两者兼有
在 NVIDIA GEFORCE GTX 1050 上下载适用于 windows 10 的 openCL 1.2 [关闭]