2015-07-10 19 views
5

Zaimplementowałem projekt z opencl. Mam plik, który zawiera funkcję jądra, a funkcje używane przez jądro są zawarte w osobnym pliku nagłówkowym, ale kiedy zmieniam dołączony plik, czasami zmiany są stosowane, a czasami nie są i to powoduje, że jestem zdezorientowany jeśli aplikacja ma błąd lub nie.OpenCL clBuildProgram buforuje źródło i nie rekompiluje, jeśli # include'd zmiany źródła

Sprawdziłem inne posty w stackoverflow i zobacz, jak nvidia ma poważny problem z przekazaniem -I{include directory}, więc zmieniłem go i wyraźnie podałem adres plików nagłówkowych, ale nadal kompilator opencl nie jest w stanie znaleźć błędów w pliku nagłówkowym, który jest zawarty w nazwie pliku jądra.

Również używam nvidia gtx 980 i mam zainstalowany CUDA 7.0 na moim komputerze.

Ktoś ma takie samo doświadczenie? jak mogę to naprawić?

Więc załóżmy, że mam kernel tak:

#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(); 
} 

których test_kernel_include.cl jest następujący:

int test_func() 
{ 
    return 1; 
} 

Potem uruchomić kod i uzyskać tablicę której wszyscy członkowie są równa się 1 zgodnie z naszymi oczekiwaniami. Teraz mogę zmienić test_kernel_include.cl do:

int test_func() 
{ 
    return 2; 
} 

ale wynik jest nadal tablicą której wszyscy członkowie są równe 1 który powinien zmienić się 2 ale one nie są.

Odpowiedz

6

Aby poprawić czas kompilacji jądra, NVIDIA implementuje schemat buforowania, w którym skompilowany plik binarny jądra jest zapisywany na dysku i ładowany przy następnym kompilacji tego samego jądra. Niektóre skróty są obliczane na podstawie kodu źródłowego jądra, który jest następnie używany jako indeks w skompilowanej pamięci podręcznej jądra.

Niestety, te skróty nie zawierają żadnych plików nagłówkowych, które są zawarte w głównym źródle jądra. Oznacza to, że gdy coś zmienisz w dołączonym pliku nagłówkowym, sterownik zignoruje zmianę i ponownie załaduje poprzednią wersję binarną jądra z dysku (chyba, że ​​coś zmieni się również w głównym źródle jądra).

W systemach Linux pamięć podręczną jądra można znaleźć pod numerem ~/.nv/ComputeCache. Jeśli usuniesz ten katalog po wprowadzeniu zmiany do jednego z plików dołączania, to powinieneś zmusić sterownik do ponownego przekompilowania jądra OpenCL.

+0

Również w oknach można znaleźć '% AppData% \ NVIDIA \ ComputeCache'. Czy ta głupia rzecz dotyczy również AMD i intel, czy też jest specyficzna dla kompilatora nvidia? – mmostajab

+1

Zauważyłem tylko ten problem z NVIDIA. Inni mogą również implementować schematy buforowania, ale być może biorą pod uwagę nagłówki. – jprice

+0

Po prostu dodałem 'del/Q/S% APPDATA% \ NVIDIA \ ComputeCache *' do mojego zdarzenia prebuild w visual studio, teraz jest to zawsze usuwanie pamięci podręcznej kompilatora przed ponownym uruchomieniem aplikacji :) – mmostajab

8

Zrób to przed inicjalizacji platformy:

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

To spowoduje wyłączenie mechanizmu buforowania dla kompilacji. Działa również na platformie OpenCL, mimo że mówi CUDA.

+0

Czy działa również w systemie Windows? ponieważ próbowałem, ale 'setenv' nie został zdefiniowany. – mmostajab

+2

@mmostajab Odpowiednikiem Windows byłoby '_putenv_s (" CUDA_CACHE_DISABLE "," 1 ");' – jprice