Я пытаюсь скомпилировать ядро OpenCL, используя привязку c ++, довольно стандартные вещи. Тем не менее, функция cl::Kernel
всегда выдает ошибку -46 ( CL_INVALID_KERNEL_NAME )
Мой код кажется чистым, поэтому я много раз искал, в чем может быть ошибка ... Я пытался чтобы убедиться, что и файл CPP, и кодировка файла ядра совпадают, попытались убедиться, что все они используют один и тот же случай, но не повезло.
Вот код:
#include <iostream>
#include <random>
#include <vector>
#include <fstream>
#include <sstream>
#include <memory>
#include <map>
#include <filesystem>
#include <string>
#include <sstream>
#include <CL/cl.hpp>
int main()
{
/*
* Initialize OPENCL
*/
std::vector<cl::Platform> g_opencl_platforms;
cl::Platform::get(&g_opencl_platforms);
if(g_opencl_platforms.size()==0)
{
std::cout << "[Main] Error initializing OpenCL : No platform available" << std::endl;
return -1;
}
cl::Platform g_opencl_default_platform = g_opencl_platforms[0];
std::cout << "[Main] Using OpenCL platform [" << g_opencl_default_platform.getInfo<CL_PLATFORM_NAME>() << "]" << std::endl;
std::vector<cl::Device> g_opencl_default_platform_devices;
g_opencl_default_platform.getDevices(CL_DEVICE_TYPE_ALL, &g_opencl_default_platform_devices);
if(g_opencl_default_platform_devices.size()==0)
{
std::cout << "[Main] Error initializing OpenCL : No device found for platoform [" << g_opencl_default_platform.getInfo<CL_PLATFORM_NAME>() << "]" << std::endl;
return -1;
}
cl::Device g_opencl_default_device = g_opencl_default_platform_devices[0];
std::cout << "[Main] Using OpenCL device [" << g_opencl_default_device.getInfo<CL_DEVICE_NAME>() << "]" << std::endl;
cl::Context g_opencl_default_context({g_opencl_default_device});
std::string g_current_working_directory = std::filesystem::current_path();
/*
* std::filesystem::current_path() returns the working directory with double quotes, remove thoses.
*/
g_current_working_directory.erase(std::remove(g_current_working_directory.begin(),g_current_working_directory.end(),'\"'),g_current_working_directory.end());
std::stringstream tmpFileNameStringStream;
tmpFileNameStringStream << g_current_working_directory << "/Include/OpenCL";
std::string g_opencl_kernels_directory = tmpFileNameStringStream.str();
cl::Program::Sources g_opencl_kernels_sources;
std::cout << "[Main] Checking for OpenCL kernel(s) to compile in directory [" << g_opencl_kernels_directory << "]" << std::endl ;
for (const auto & entry : std::filesystem::directory_iterator(g_opencl_kernels_directory))
{
std::string tmpFilePath = entry.path();
tmpFilePath.erase(std::remove(tmpFilePath.begin(),tmpFilePath.end(),'\"'),tmpFilePath.end());
std::cout << "[Main] Loading OpenCL kernel [" << tmpFilePath << "]" << std::endl ;
std::fstream kernel_file(tmpFilePath, std::ios_base::in | std::ios_base::binary);
std::string tmp_kernel_source( (std::istreambuf_iterator<char>(kernel_file)),std::istreambuf_iterator<char>() );
std::cout << tmp_kernel_source << std::endl;
g_opencl_kernels_sources.push_back({tmp_kernel_source.c_str(),tmp_kernel_source.size()});
}
std::cout << "[Main] Compiling [" << g_opencl_kernels_sources.size() << "] OpenCL source(s)" << std::endl ;
cl::Program g_opencl_default_program(g_opencl_default_context,g_opencl_kernels_sources);
cl_int build_result = g_opencl_default_program.build({g_opencl_default_device});
if(build_result != CL_SUCCESS)
{
std::cout << "[Main] Error compiling OpenCL source(s) :" << g_opencl_default_program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(g_opencl_default_device) << std::endl ;
return -1;
}
cl::CommandQueue g_opencl_default_command_queue(g_opencl_default_context,g_opencl_default_device);
cl_uchar A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
cl_uchar B[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0};
cl::Buffer buffer_A(g_opencl_default_context,CL_MEM_READ_ONLY,sizeof(cl_uchar)*10);
cl::Buffer buffer_B(g_opencl_default_context,CL_MEM_READ_ONLY,sizeof(cl_uchar)*10);
cl::Buffer buffer_C(g_opencl_default_context,CL_MEM_READ_WRITE,sizeof(cl_uchar)*10);
g_opencl_default_command_queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(cl_uchar)*10,A);
g_opencl_default_command_queue.enqueueWriteBuffer(buffer_B,CL_TRUE,0,sizeof(cl_uchar)*10,B);
cl_int kernel_creation_result = 0;
cl::Kernel kernel_add = cl::Kernel(g_opencl_default_program,"rien",&kernel_creation_result);
if(kernel_creation_result != CL_SUCCESS)
{
std::cout << "[Main] Error creating kernel [" << kernel_creation_result << "]" << std::endl ;
return -1;
}
return 1;
}
Вот файл rien.cl (находится в текущем рабочем каталоге Include / OpenCL / rien.cl)
__kernel void rien()
{
}
Вот вывод:
[Main] Using OpenCL platform [NVIDIA CUDA]
[Main] Using OpenCL device [GeForce GTX 1050]
[Main] Checking for OpenCL kernel(s) to compile in directory [/mnt/Data/Temporary/test/Include/OpenCL]
[Main] Loading OpenCL kernel [/mnt/Data/Temporary/test/Include/OpenCL/simple.cl]
#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
__kernel void rien()
{
}
[Main] Compiling [1] OpenCL source(s)
[Main] Error creating kernel [-46]
Код составлен со следующим:
g++ --std=c++2a -O3 -Wall main.cpp -lOpenCL
Любая идея будет принята с благодарностью.