2011-11-22 5 views
9

ho un errore in un kernel OpenCL, quando si tenta di utilizzare l'estensione cl_khr_fp64, il kernel compila e il log di compilazione è vuota, ma quando chiamo clCreateKernel, Ho l'errore CL_INVALID_KERNEL_NAME.CL_INVALID_KERNEL_NAME errore quando uso cl_khr_fp64 in un kernel

La fonte che non riesce:

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

Questa fonte compila destra:

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

sto usando OpenCL 1.0 con un Tesla C1060 che hanno cl_khr_fp64 in CL_DEVICE_EXTENSIONS, driver 280.13 e CL_PLATFORM_VERSIO N = OpenCL 1.1 CUDA 4.0.1

+0

Giusto per chiarire: si sa che la compilazione riesce nel primo caso perché si sta verificando il codice di errore impostato da clBuildProgram, corretto? – James

+0

I passaggi di compilazione restituiscono CL_SUCCESS, ma controllo anche il log di build – Zhen

+0

Stai dicendo che se rimuovi semplicemente la riga cl_khr_fp64, clCreateKernel restituisce CL_SUCCESS? – vocaro

risposta

2

Il problema era che prima di chiamare clCreateProgramWithSource, rimuoveremo le newline dall'origine. Per esempio: la fonte:

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

diventa:

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

Essa provoca nessun problema fino a quando si aggiunge la direttiva preproccessor.

È il preprocessore OpenCL che in realtà vuole che le nuove linee siano presenti. Quindi, dovrebbe essere scritto come:

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

Questa è una delle cose che mi ha infastidito. Il problema che penso sia il codice precedentemente compilato è memorizzato in cache da qualche parte e viene riutilizzato. Quindi le tue nuove modifiche danno strani errori.

Per risolvere il problema (NON è una "soluzione reale" ma funziona per me) provare a cambiare il nome del programma (e il nome del kernel, forse) ad es. se il programma è a.out, la prossima volta che lo compili lo fai a2.out e vedi se è corretto. Spero che aiuti.

se trovate una soluzione migliore fatecelo sapere.

0

Ho anche venuto attraversare tale bug pochi giorni fa e ho appena lavorare fuori. Quindi sono qui per condividere la mia soluzione sebbene sia abbastanza cablata e non so ancora perché.

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

Questo è il mio codice originale che è una funzione statica chiamata da un costruttore di una classe. Il costruttore può essere chiamato senza alcuna domanda. Tuttavia, ogni volta che viene richiamata la funzione precedente, avrei ricevuto il bug "nome del kernel non valido" risultante da opencl, impossibile trovare il kernel "filterSubsampleUChar4Kernel". Ho provato molto ma nessuno di loro ha funzionato. Ma oggi, ogni tanto, provo a cambiare il nome della funzione e ci riesco. Quello che faccio è nient'altro che cambiare "filterSubsampleUChar4Kernel" in "filterSubsampleKernel". Ho anche provato a cambiare altri nomi, ad es. "filterSubsampleKernel_test", "filterSubsample1Kernel". Ma loro non hanno funzionato. È abbastanza cablato, non è vero?

Problemi correlati