Функция Opencl cl :: Kernel всегда выдает ошибку -46 - PullRequest
0 голосов
/ 25 марта 2020

Я пытаюсь скомпилировать ядро ​​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

Любая идея будет принята с благодарностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...