第3章 介绍OpenCL - 3.7 OpenCL C++ Wapper向量加法

优质
小牛编辑
119浏览
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);

  1. // Get a list of devices on this platform
  2. std::vector<cl::Device> devices;
  3. platforms[0].getDevices(CL_DEVICE_TYPE_ALL, &devices);
  4. // Create a context for the devices
  5. cl::Context context(devices);
  6. // Create a command-queue for the first device
  7. cl::CommandQueue queue = cl::CommandQueue(context, devices[0]);
  8. // Create the memory buffers
  9. cl::Buffer bufferA = cl::Buffer(context, CL_MEM_READ_ONLY, datasize);
  10. cl::Buffer bufferB = cl::Buffer(context, CL_MEM_READ_ONLY, datasize);
  11. cl::Buffer bufferC = cl::Buffer(context, CL_MEM_WRITE_ONLY, datasize);
  12. // Copy the input data to the input buffers using the
  13. // command-queue for the first device
  14. queue.enqueueWriteBuffer(bufferA, CL_TRUE, 0, datasize, A);
  15. queue.enqueueWriteBuffer(bufferB, CL_TRUE, 0, datasize, B);
  16. // Read the program source
  17. std::ifstream sourceFile("vector_add_kernel.cl");
  18. std::string sourceCode(std::istreambuf_iterator<char>(sourceFile), (std::istreambuf_iterator<char>()));
  19. cl::Program::Source source(1, std::make_pair(sourceCode.c_str(), sourceCode.length() + 1);
  20. // Create the program from the source code
  21. cl::Program program = cl::Program(context, source);
  22. // Build the program for the devices
  23. program.build(devices);
  24. // Create the kernel
  25. cl::Kernel vecadd_kernel(program, "vecadd");
  26. // Set the kernel arguments
  27. vecadd_kernel.setArg(0, bufferA);
  28. vecadd_kernel.setArg(1, bufferB);
  29. vecadd_kernel.setArg(2, bufferC);
  30. // Execute the kernel
  31. cl::NDRange gloabl(elements);
  32. cl::NDRange local(256);
  33. queue.enqueueNDRangeKernel(vecadd_kernel, cl::NullRange, gloabl, local);
  34. // Copy the output data back to the host
  35. 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向量相加