2015-07-10 15 views
5

Ho implementato un progetto con opencl. Ho un file che contiene la funzione del kernel e le funzioni che sono usate dal kernel sono incluse in un file di intestazione separato ma quando cambio il file che è incluso, a volte le modifiche vengono applicate e talvolta non lo sono e mi fa confondere se l'applicazione ha un bug o no.OpenCL clBuildProgram memorizza nella cache l'origine e non ricompila se # include'd modifiche di origine

Ho controllato gli altri post nello stackoverflow e vedo nvidia ha seri problemi con il passaggio di -I{include directory}, quindi l'ho modificato e ho dato esplicitamente l'indirizzo dei file di intestazione, ma il compilatore opencl non è ancora in grado di trovare gli errori nel file di intestazione è incluso nel nome del file del kernel.

Inoltre, sto usando nvidia gtx 980 e ho installato CUDA 7.0 sul mio computer.

Chiunque ha la stessa esperienza? come posso ripararlo?

Quindi, assumere ho un kernel come questo:

#include "../../src/cl/test_kernel_include.cl" 

void __kernel test_kernel(
    __global int* result, 
    int n 
) 
{ 
    int thread_idx = get_global_id(0); 
    result[thread_idx] = test_func(); 
} 

cui il test_kernel_include.cl è la seguente:

int test_func() 
{ 
    return 1; 
} 

Poi ho eseguito il codice e ottengo un array che tutti i membri sono uguale a 1 come previsto. Ora, a cambiare il test_kernel_include.cl a:

int test_func() 
{ 
    return 2; 
} 

ma il risultato è ancora una matrice cui tutti i membri sono uguali a 1 che dovrebbe cambiare a 2, ma non lo sono.

risposta

6

Per migliorare i tempi di compilazione del kernel, NVIDIA implementa uno schema di caching, in base al quale un file binario compilato viene archiviato su disco e caricato la volta successiva che viene compilato lo stesso kernel. Alcuni hash sono calcolati sul codice sorgente del kernel che viene poi utilizzato come indice nella cache del kernel compilata.

Sfortunatamente, questi hash non includono alcun file di intestazione che è incluso dal sorgente del kernel principale. Ciò significa che quando si modifica qualcosa in un file di intestazione incluso, il driver ignorerà essenzialmente la modifica e ricaricherà il precedente binario del kernel dal disco (a meno che qualcosa non sia cambiato anche nell'origine del kernel principale).

Su sistemi Linux, la cache del kernel può essere trovata in ~/.nv/ComputeCache. Se elimini questa directory dopo aver apportato una modifica a uno dei tuoi file di inclusione, allora dovrebbe forzare il driver a ricompilare effettivamente il kernel di OpenCL.

+0

Inoltre, in Windows è possibile trovare% AppData% \ NVIDIA \ ComputeCache'. Questa stupida cosa è applicata anche ad AMD e Intel o è specifica del compilatore nvidia? – mmostajab

+1

Ho notato questo problema solo con NVIDIA. Gli altri possono implementare anche schemi di cache, ma forse prendono in considerazione intestazioni incluse. – jprice

+0

Ho semplicemente aggiunto 'del/Q/S% APPDATA% \ NVIDIA \ ComputeCache *' al mio evento di prebuild in visual studio, ora si elimina sempre la cache del compilatore prima di rieseguire l'applicazione :) – mmostajab

8

fare questo prima di inizializzazione piattaforma:

setenv("CUDA_CACHE_DISABLE", "1", 1); 

Sarà disabilitare meccanismo di caching per la compilazione. Funziona anche per la piattaforma OpenCL, anche se dice CUDA.

+0

Funziona anche in Windows? perché l'ho provato, ma 'setenv' non è stato definito. – mmostajab

+2

@mmostajab L'equivalente di Windows sarebbe '_putenv_s (" CUDA_CACHE_DISABLE "," 1 ");' – jprice

Problemi correlati