Ошибка CL_INVALID_KERNEL_NAME, когда я использую cl_khr_fp64 в ядре

У меня есть ошибка в ядре OpenCL, когда я пытаюсь использовать расширение cl_khr_fp64, компиляция ядра и журнал сборки пуст, но когда я вызываю clCreateKernel У меня есть CL_INVALID_KERNEL_NAME ошибка.

Источник, который не работает:

#pragma OPENCL EXTENSION cl_khr_fp64 : enable

__kernel void simple( __global char *x, __global char *y ){
int id = get_global_id(0);
y[id]=2*x[id];
}

Этот источник компилируется правильно:

__kernel void simple( __global char *x, __global char *y ){
int id = get_global_id(0);
y[id]=2*x[id];
}

Я использую OpenCL 1.0 с Tesla C1060, которые имеют cl_khr_fp64 в CL_DEVICE_EXTENSIONS, драйвер 280.13 и CL_PLATFORM_VERSION= OpenCL 1.1 CUDA 4.0.1

Ответ 1

Проблема заключалась в том, что перед вызовом clCreateProgramWithSource мы удаляем новые строки из исходного кода. Например: источник:

"__kernel void f( __global char *x ){\nint id = get_global_id(0);\nx[id]=2;\n}"

становится:

"__kernel void simple( __global char *x, __global char *y ){"
"int id = get_global_id(0);"
"x[id]=2;}"

Это не вызывает проблем, пока мы не добавим директиву preproccessor.

Это препроцессор OpenCL, который на самом деле хочет, чтобы новые строки были там. Поэтому он должен быть записан как:

"__kernel void simple( __global char *x, __global char *y ){\n"
"int id = get_global_id(0);\n"
"x[id]=2;}\n"

Ответ 2

Это одна из тех вещей, которые меня беспокоили. Проблема, о которой я думаю, это ранее скомпилированный код, где-то кэшируется и повторно используется. Таким образом, ваши новые изменения приносят странные ошибки.

Чтобы исправить это (НЕ "реальное решение", но оно работает для меня) попробуйте изменить название своей программы (и, возможно, имя ядра), например. если программа a.out, то в следующий раз, когда вы скомпилируете make, сделайте a2.out и посмотрите, исправлено ли это. Надеюсь, это поможет.

если вы найдете лучшее решение, сообщите нам.

Ответ 3

Я тоже наткнулся на такую ​​ошибку несколько дней назад, и я просто ее проработал. Таким образом, я здесь, разделяя свое решение, хотя он вполне подключен, и я до сих пор не знаю, почему.

static inline void CreateOCLKernels()
{
    std::cout << "ocl lowlevelengine: Creating ocl kernels ...\n";
    filterSubsample_ocl_kernel = clCreateKernel(program, "filterSubsampleUChar4Kernel", &clError);
    checkErr(clError, "clCreateKernel0");
    filterSubsampleWithHoles_float4_ocl_kernel = clCreateKernel(program, "filterSubsampleWithHolesFloat4Kernel", &clError);
    checkErr(clError, "clCreateKernel1");
    filterSubsampleWithHoles_float_ocl_kernel = clCreateKernel(program, "filterSubsampleWithHolesFloatKernel", &clError);
    checkErr(clError, "clCreateKernel2");
    gradientX_ocl_kernel = clCreateKernel(program, "gradientXKernel", &clError);
    checkErr(clError, "clCreateKernel3");
    gradientY_ocl_kernel = clCreateKernel(program, "gradientYKernel", &clError);
    checkErr(clError, "clCreateKernel4");
    //type-dependent ocl memset kernels
    memset_ocl_kernel_Vector4s = clCreateKernel(program, "memsetKernelVector4s", &clError);
    checkErr(clError, "clCreateKernel5");
}

Это мой исходный код, который является статической функцией, вызываемой конструктором некоторого класса. Конструктор можно вызвать без каких-либо вопросов. Тем не менее, каждый раз, когда вызывается вышеупомянутая функция, я получал ошибку "недопустимое имя ядра", полученное из opencl, не может найти ядро ​​ "filterSubsampleUChar4Kernel". Я много пробовал, но никто из них не работал. Но сегодня, очень редко, я пытаюсь изменить имя функции, и мне это удается. Что я делаю, это не что иное, как изменение "filterSubsampleUChar4Kernel" на "filterSubsampleKernel". Я также пытался изменить другие имена, например. "filterSubsampleKernel_test", "filterSubsample1Kernel". Но они не сработали. Это довольно проводной, не так ли?

Ответ 4

Я предполагаю, что вы компилируете код, используя строку ex

std::string code =
"#pragma OPENCL EXTENSION cl_khr_fp64 : enable"
"__kernel void simple( __global char *x, __global char *y )"
"{"
"int id = get_global_id(0);"
"y[id]=2*x[id];"
"}"

просто добавьте " \n " в конце строки #pragma

std::string code =
"#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n"
"__kernel void simple( __global char *x, __global char *y )"
"{"
"int id = get_global_id(0);"
"y[id]=2*x[id];"
"}"