OpenCL-Setting
Hello world하나 찍기 참 힘들다.. clinfo깔고 뭔가 드라이버 잡혀있길래 OpenCL-CLHPP바로 clone해서 g++로 빌드는 성공시켰는데, 실행하면 프로그램이 먹통되었다가 gpu커널단에선 죽는거같고 cpu프로그램은 hang되는 문제가 있었다. 자료들도 죄다 outdated된것들 뿐이고 뭐 이런게 다있지; 일단 https://stackoverflow.com/questions/57302414/what-is-difference-between-intel-compute-runtime-intel-opencl-runtime-and-inte 이거로 전체적인 방향은 잡은것 같고, https://github.com/intel/compute-runtime 이거에 나온대로 apt-get install intel-opencl-icd해서 드라이버 업뎃을 먼저 해봤다. 원래 clinfo에서 뭐가 나왔었는데, 이거 하고나서 platform 0개로 나오고 프로그램은 OpenCL error: clGetPlatformIDs(-1001)로 죽는다. 이건 뭐 답도 없는것 같아서 https://github.com/intel/compute-runtime/releases 여기서 'Installation procedure on Ubuntu 22.04'에 나온대로 했더니 잘 된다. clinfo하면 Intel(R) Iris(R) Xe Graphics [0x9a49] 하나 잡히는게 cpu는 다른거 깔아야하는듯? https://www.intel.com/content/www/us/en/developer/articles/tool/opencl-drivers.html 에서 Intel® Graphics Technology Runtimes/Linux* OS 부분 참고하면 도움이 될수도?
g++ -std=c++2a src/cpp/main.cpp -lOpenCL -I./OpenCL-CLHPP/include && ./a.out
#include
#include
#include
#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_TARGET_OPENCL_VERSION 220
#include
// Compute c = a + b.
static const char source[] =
"kernel void add(\n"
" ulong n,\n"
" global const float *a,\n"
" global const float *b,\n"
" global float *c\n"
" )\n"
"{\n"
" size_t i = get_global_id(0);\n"
" printf(\"%d %f %f\\n\",i,a[i],b[i]);\n"
" if (i < n) {\n"
" c[i] = a[i] + b[i];\n"
" }\n"
"}\n";
int main() {
const size_t N = 1 << 0;
try {
// Get list of OpenCL platforms.
std::vector platform;
cl::Platform::get(&platform);
if(platform.empty()) {
std::cerr << "OpenCL platforms not found." << std::endl;
return 1;
}
cl::Context context;
std::vector device;
for(auto p = platform.begin(); device.empty() && p != platform.end(); p++) {
std::vector pldev;
try {
p->getDevices(CL_DEVICE_TYPE_GPU, &pldev);
for(auto d = pldev.begin(); device.empty() && d != pldev.end(); d++) {
if(!d->getInfo()) continue;
device.push_back(*d);
context = cl::Context(device);
}
} catch(...) { std::cout<<"exception"<() << std::endl;
// Create command queue.
cl::CommandQueue queue(context, device[0]);
// Compile OpenCL program for found device.
cl::Program program(context, cl::Program::Sources({cl::string(source)}));
try {
program.build(device);
} catch(const cl::Error &) {
std::cerr << "OpenCL compilation error" << std::endl
<< program.getBuildInfo(device[0])
<< std::endl;
return 1;
}
cl::Kernel add(program, "add");
// Prepare input data.
std::vector a(N, 1);
std::vector b(N, 2);
std::vector c(N);
// Allocate device buffers and transfer input data to device.
cl::Buffer A(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
a.size() * sizeof(float), a.data());
cl::Buffer B(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
b.size() * sizeof(float), b.data());
cl::Buffer C(context, CL_MEM_READ_WRITE, c.size() * sizeof(float));
// Set kernel parameters.
add.setArg(0, static_cast(N));
add.setArg(1, A);
add.setArg(2, B);
add.setArg(3, C);
// Launch kernel on the compute device.
queue.enqueueNDRangeKernel(add, cl::NullRange, N, cl::NullRange);
// Get result back to host.
queue.enqueueReadBuffer(C, CL_TRUE, 0, c.size() * sizeof(float), c.data());
// Should get '3' here.
std::cout << c[0] << std::endl;
} catch(const cl::Error &err) {
std::cerr << "OpenCL error: " << err.what() << "(" << err.err() << ")"
<< std::endl;
return 1;
}
}