第3章 介绍OpenCL - 3.7 OpenCL C++ Wapper向量加法
优质
小牛编辑
122浏览
2023-12-01
Khronos组织也在后续的OpenCL标准中定义了一套C++
Wapper API。C++
API与C API是对应的(比如,cl::Memory对应cl_mem),不过C++
需要对异常和类进行处理。下面的代码对应的与代码清单3.4中的C代码相对应。
{%ace edit=false, lang=’c_cpp’%}
define __CL_ENABLE_EXCEPTIONS
include
include
include
include
include
int main(){
const int elements = 2048;
size_t datasize = sizeof(int) * elements;
int A = new int[elements];
int B = new int[elements];
int *C = new int[elements];
for (int i = 0; i < elements; i++){
A[i] = i;
B[i] = i;
}
try{
// Query for platforms
std::vector platforms;
cl::Platform::get(&platforms);
// Get a list of devices on this platform
std::vector<cl::Device> devices;
platforms[0].getDevices(CL_DEVICE_TYPE_ALL, &devices);
// Create a context for the devices
cl::Context context(devices);
// Create a command-queue for the first device
cl::CommandQueue queue = cl::CommandQueue(context, devices[0]);
// Create the memory buffers
cl::Buffer bufferA = cl::Buffer(context, CL_MEM_READ_ONLY, datasize);
cl::Buffer bufferB = cl::Buffer(context, CL_MEM_READ_ONLY, datasize);
cl::Buffer bufferC = cl::Buffer(context, CL_MEM_WRITE_ONLY, datasize);
// Copy the input data to the input buffers using the
// command-queue for the first device
queue.enqueueWriteBuffer(bufferA, CL_TRUE, 0, datasize, A);
queue.enqueueWriteBuffer(bufferB, CL_TRUE, 0, datasize, B);
// Read the program source
std::ifstream sourceFile("vector_add_kernel.cl");
std::string sourceCode(std::istreambuf_iterator<char>(sourceFile), (std::istreambuf_iterator<char>()));
cl::Program::Source source(1, std::make_pair(sourceCode.c_str(), sourceCode.length() + 1);
// Create the program from the source code
cl::Program program = cl::Program(context, source);
// Build the program for the devices
program.build(devices);
// Create the kernel
cl::Kernel vecadd_kernel(program, "vecadd");
// Set the kernel arguments
vecadd_kernel.setArg(0, bufferA);
vecadd_kernel.setArg(1, bufferB);
vecadd_kernel.setArg(2, bufferC);
// Execute the kernel
cl::NDRange gloabl(elements);
cl::NDRange local(256);
queue.enqueueNDRangeKernel(vecadd_kernel, cl::NullRange, gloabl, local);
// Copy the output data back to the host
queue.enqueueReadBuffer(bufferC, CL_TRUE, 0, datasize, C);
} catch(cl::Error error){
std::cout << error.what() << “(“ << error.err() << “)” << std::endl;
}
}
{%endace%}
代码清单3.5 使用C++ Wapper实现的OpenCL向量相加