Ansi C CUDA

0

Witam

Jestem nowym uzytko0wnikiem tego forum. Bardzo proszę o pomoc z programem do splotu maski z obrazem tiff z wykorzystaniem technologi CUDA.
Ten sam program działający na procesorze działa poprawnie. Podczas prób przerobienia go na GPU występuje problem. Program kompiluje się prawidłowo uruchamia się również ale niestety błędnie liczy.

Poniżej funkcja obliczeniowa dla CPU:

char splotCPU(unsigned char *wejscie,int rozmiar, int *maska)
    {
////////////////////////////////////////////////////////////////////////////////
//  Funkcja nakładająca maske na tablicę. Na wejsciu otrzymuje    //
//  zestaw pikseli (9) oraz maskę do nałozenia, zwraca wartość    //
//  piksela                                       //
////////////////////////////////////////////////////////////////////////////////
    char wynik;                         //wartość piksela po nałozeniu maski
    wynik=( wejscie[0]* maska[0]+
            wejscie[1]* maska[1]+
            wejscie[2]* maska[2]+
            wejscie[3]* maska[3]+
            wejscie[4]* maska[4]+
            wejscie[5]* maska[5]+
            wejscie[6]* maska[6]+
            wejscie[7]* maska[7]+
            wejscie[8]* maska[8])/9 ;
    return wynik;
    }

podobna funkcja dla GPU:

__global__ void splotGPU(unsigned char *wejscie,int rozmiar, int *maska,unsigned char *wynik)
    {
////////////////////////////////////////////////////////////////////////////////
//  Funkcja nakładająca maske na tablicę. Na wejsciu otrzymuje    //
//  zestaw pikseli (9) oraz maskę do nałozenia, zwraca wartość    //
//  piksela                                      //
///////////////////////////////////////////////////////////////////////////////

    //int id = blockIdx.x * blockDim.x + threadIdx.x;
    wynik[0]=(  wejscie[0]* maska[0]+
            wejscie[1]* maska[1]+
            wejscie[2]* maska[2]+
            wejscie[3]* maska[3]+
            wejscie[4]* maska[4]+
            wejscie[5]* maska[5]+
            wejscie[6]* maska[6]+
            wejscie[7]* maska[7]+
            wejscie[8]* maska[8])/9 ;

    }

Poniżej użycie funkcji dla CPU:

            wyR[i]=splotCPU(tabR,3, wekM);
            wyG[i]=splotCPU(tabG,3, wekM);
            wyB[i]=splotCPU(tabB,3, wekM);

gdzie:
wyR[i] - wektor wynikowy dla wartość R (czerwonych)
wyG[i] - wektor wynikowy dla wartość G (zielonych)
wyB[i] - wektor wynikowy dla wartość B (niebieskich)
wekM - wektor jednowymiarowy zawierający wartości maski Laplaca
tabR, tabG, tabG - wektory wejściowe dla poszczególnych kolorów

Program działa poprawnie wylicza odpowiednio dane.

Dla GPU:

cudaMemcpy(wynGR, tabGPU_R, size, cudaMemcpyHostToDevice);
splotGPU<<<dimGrid , dimBlock>>>(tabGPU_R , 3 , wekM , rezultat_Device_R);
cudaThreadSynchronize();   // synchronizacja
cudaMemcpy(rezultat_Device_R,temp_R, size_resultat, cudaMemcpyDeviceToHost);

gdzie:
wynGR - wektor z wejściowy dla GPU(Device) dla R(czerwony)
tabGPU_R - wektor z wejściowy dla CPU(Host) dla R(czerwony)
size - wielkość wynGR czyli "size_t size = sizeof(unsigned char) * 9;"
wekM - wektor jednowymiarowy zawierający wartości maski Laplaca
rezultat_Device_R - wektor wyjściowy dla GPU(Device) dla R(czerwony)
temp_R - wektor wyjściowy dla CPU(Host) dla R(czerwony)
size_resultat - wielkość rezultat_Device_R czyli "size_t size_resultat = sizeof(unsigned char);"

Identycznie postępuje z innymi kolorami.

Niestety ale temp_R , temp_G oraz temp_B czyli wartości zwracane z funkcji są zawsze stałe niezależnie od danych wejściowych. Są równe dla wszystkich kolorów chociaż wartości poszczególnych kolorów dla piksla są różne.

Bardzo proszę o pomoc.

0

splotCPU - wynik jest jako char
splotGPU - wynik jest jako unsigned char

O to cho?

1
 wejscie[0]* maska[0]+
                        wejscie[1]* maska[1]+
                        wejscie[2]* maska[2]+
                        wejscie[3]* maska[3]+
                        wejscie[4]* maska[4]+
                        wejscie[5]* maska[5]+
                        wejscie[6]* maska[6]+
                        wejscie[7]* maska[7]+
                        wejscie[8]* maska[8]

Hmmm, a pętle ukradli na poczcie?

0

Czy ma ktoś może jakiś pomysł z czym może być problem??

Czekam na opinie.

0

No tak, masz int maska i podajesz mu 3. Usuń

0

Ta 3 tyczy się rozmiaru a nie maski.

0

To twój pierwszy program w CUDA?

W OpenCL trzeba wziąć id wątku, grupy itp przed pobraniem wartości z tablicy wejściowej. Każdy wątek dostaje te same parametry oprócz wspomnianych id. Zresztą widzę, że w kodzie dla GPU masz wykomentowane liczenie numeru wątku: "//int id = blockIdx.x * blockDim.x + threadIdx.x;". Nie wiesz do czego to służy?

0

Tak to mój pierwszy program w CUDA.

Nie wiem do końca tak dokładnie

*int id = blockIdx.x blockDim.x + threadIdx.x;**

Z tego co wiem to ten zapis powoduje tak jakby obliczenia przechodziły przez pętle po przez bloki i wątki bloków w GPU.

0

Nie wiesz co to są grupy wątków, nie wiesz że scheduler może rozmieszczać wątki w 1D, 2D i 3D, a zadajesz pytania na forum? Idź poszukaj jakiegoś tutoriala CUDA dla początkujących.

http://developer.amd.com/gpu/[...]ion/pages/TutorialOpenCL.aspx
Tu masz tutorial jak w OpenCL zrobić Hello World'a. Przerób go, zrozum i możesz wtedy zadawać pytania na forum.

0
Wibowit napisał(a)

Nie wiesz co to są grupy wątków, nie wiesz że scheduler może rozmieszczać wątki w 1D, 2D i 3D, a zadajesz pytania na forum? Idź poszukaj jakiegoś tutoriala CUDA dla początkujących.

http://developer.amd.com/gpu/[...]ion/pages/TutorialOpenCL.aspx
Tu masz tutorial jak w OpenCL zrobić Hello World'a. Przerób go, zrozum i możesz wtedy zadawać pytania na forum.

Dzięki wielkie za pomoc.
Jako pomoc podsyłasz tutorial w OpenCL ale niestety ja mam napisać w CUDA. Kwestie Hello World już przerobiłem w CUDA.

Może dla niektórych problem który mam jest błahy ale myślałem że po to są fora aby osoby o wielkiej wiedzy w danym segmencie nauki pomagały tym którzy się uczą.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0