无法使用最新的API CL / cl2.hpp运行任何可用的OpenCL示例

时间:2016-11-15 15:07:26

标签: c++ opencl

我正在尝试使用OpenCL。安装之后,我发现与几乎所有在线教程相比都有点奇怪,没有cl.hpp标题,只有cl2.hpp。我了解到它是一个新版本。一个新版本的API,几乎没有可用的教程。

我发现的教程无法编译。例如,这个(http://github.khronos.org/OpenCL-CLHPP/)由于未定义的变量而无法编译,如果我避免它,它报告我没有OpenCL 2.0设备。我能够通过设备检查(http://simpleopencl.blogspot.cz/2013/06/tutorial-simple-start-with-opencl-and-c.html)得到这个,但是当我尝试创建上下文(找到设备)时崩溃了。

我正在尝试的代码:

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);
}
cl::Platform default_platform=all_platforms[0];
std::cout << "Using platform: "<<default_platform.getInfo<CL_PLATFORM_NAME>()<<"\n";

//get default device of the default platform
std::vector<cl::Device> all_devices;
default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
if(all_devices.size()==0){
    std::cout<<" No devices found. Check OpenCL installation!\n";
    exit(1);
}
cl::Device default_device=all_devices[0];
std::cout<< "Using device: "<<default_device.getInfo<CL_DEVICE_NAME>()<<"\n";


cl::Context context({default_device}); // null pointer read here

cl::Program::Sources sources;

// kernel calculates for each element C=A+B
std::string kernel_code=
        " void kernel simple_add(global const int* A, global const int* B, global int* C){ "
        " C[get_global_id(0)]=A[get_global_id(0)]+B[get_global_id(0)]; "
        " } ";
sources.push_back({kernel_code.c_str(),kernel_code.length()});

cl::Program program(context,sources);
if(program.build({default_device})!=CL_SUCCESS){
    std::cout<<" Error building: "<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device)<<"\n";
    exit(1);
}

// create buffers on the device
cl::Buffer buffer_A(context,CL_MEM_READ_WRITE,sizeof(int)*10);
cl::Buffer buffer_B(context,CL_MEM_READ_WRITE,sizeof(int)*10);
cl::Buffer buffer_C(context,CL_MEM_READ_WRITE,sizeof(int)*10);

int A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int B[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0};

//create queue to which we will push commands for the device.
cl::CommandQueue queue(context,default_device);

//write arrays A and B to the device
queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(int)*10,A);
queue.enqueueWriteBuffer(buffer_B,CL_TRUE,0,sizeof(int)*10,B);


//run the kernel
cl::KernelFunctor simple_add(cl::Kernel(program,"simple_add"),queue,cl::NullRange,cl::NDRange(10),cl::NullRange);
simple_add(buffer_A,buffer_B,buffer_C);

//alternative way to run the kernel
cl::Kernel kernel_add=cl::Kernel(program,"simple_add");
kernel_add.setArg(0,buffer_A);
kernel_add.setArg(1,buffer_B);
kernel_add.setArg(2,buffer_C);
 queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(10),cl::NullRange);
queue.finish();

int C[10];
//read result C from the device to array C
queue.enqueueReadBuffer(buffer_C,CL_TRUE,0,sizeof(int)*10,C);

std::cout<<" result: \n";
for(int i=0;i<10;i++){
    std::cout<<C[i]<<" ";
}

我在Ubuntu 16.04上使用Intel(R)HD Graphics IvyBridge M GT2上的Intel Gen OCL驱动程序。

知道我做错了什么吗?

1 个答案:

答案 0 :(得分:3)

如果驱动程序不支持CL2.0,则需要通过将CL的最小版本和目标版本设置为相关版本(例如1.2)来“降低cl2.hpp的期望值”:

#define CL_HPP_MINIMUM_OPENCL_VERSION 120
#define CL_HPP_TARGET_OPENCL_VERSION 120
#include <CL/cl2.hpp>

这样,cl2.hpp中的代码将为CL1.2环境编译。