2011-11-22 8 views
9

Tengo un error en un OpenCL núcleo, cuando trato de usar la extensión cl_khr_fp64, el núcleo compila y el registro de generación está vacía, pero cuando llamo clCreateKernel, Tengo CL_INVALID_KERNEL_NAME error.CL_INVALID_KERNEL_NAME error cuando uso cl_khr_fp64 en un núcleo

La fuente que falla:

#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]; 
} 

Esta fuente se compila derecha:

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

estoy usando OpenCL 1.0 con un Tesla C1060 que tienen cl_khr_fp64 en CL_DEVICE_EXTENSIONS, controlador 280.13 y CL_PLATFORM_VERSIO N = OpenCL 1.1 CUDA 4.0.1

+0

Solo para aclarar: usted sabe que su compilación tiene éxito en el primer caso porque está revisando el código de error establecido por clBuildProgram, ¿correcto? – James

+0

Los pasos de compilación devuelven CL_SUCCESS, pero también verifico el registro de compilación – Zhen

+0

¿Está diciendo que si simplemente elimina la línea cl_khr_fp64, clCreateKernel devuelve CL_SUCCESS? – vocaro

Respuesta

2

El problema fue que antes de llamar a clCreateProgramWithSource, eliminamos las nuevas líneas de la fuente. Por ejemplo: la fuente:

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

se convierte en:

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

Esto causa ningún problema hasta que le añadimos la directiva preproccessor.

Es el preprocesador OpenCL que realmente quiere nuevas líneas para estar allí. Por lo tanto, debe escribirse como:

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

Esta es una de las cosas que me ha estado molestando. El problema, creo, es que el código previamente compilado se almacena en la memoria caché y se reutiliza. Entonces tus nuevos cambios dan errores extraños.

Para solucionarlo (NO es una "solución real" pero me funciona) intente cambiar el nombre de su programa (y el nombre del kernel, por ejemplo), p. si el programa es a.out, la próxima vez que lo compile, a2.out y vea si está arreglado. Espero que esto ayude.

si encuentra una solución mejor háganoslo saber.

0

También llegué a cruzar ese error hace unos días y lo resolví. Así que estoy aquí compartiendo mi solución, aunque está bastante cableada y todavía no sé por qué.

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"); 
} 

Este es mi código original que es una función estática llamada por un constructor de alguna clase. El constructor puede ser llamado sin ninguna pregunta. Sin embargo, cada vez que se llama a la función anterior, recibiría el error "nombre de núcleo inválido" que resulta de opencl no puede encontrar el kernel "filterSubsampleUChar4Kernel". Lo he intentado mucho pero ninguno de ellos funcionó. Pero hoy, muy ocasionalmente, trato de cambiar el nombre de la función y tengo éxito. Lo que hago no es más que cambiar "filterSubsampleUChar4Kernel" a "filterSubsampleKernel". También traté de cambiar otros nombres, ej. "filterSubsampleKernel_test", "filterSubsample1Kernel". Pero no funcionaron. Está bastante conectado, ¿no?

Cuestiones relacionadas