2012-11-21 9 views
6

Próbuję przetestować przykładowy kod z witryny CUDA http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#kernels.Implementacja CUDA VecAdd z kodu przykładowego

ja po prostu chcesz dodać dwóch macierzy A i B o rozmiarze 4 i przechowywać je w tablicy C. Oto co mam do tej pory:

#include <stdio.h> 
#include "util.h" 
void print_array(int* array, int size) { 
int i; 
for (i = 0; i < size; i++) { 
    printf("%d ", array[i]); 
} 
printf("\n"); 
} 

__global__ void VecAdd(int* A, int* B, int* C) { 
int i = threadIdx.x; 
C[i] = A[i] + B[i]; 
} 

int main(int argc , char **argv) { 
int N = 4; 
    int i; 
int *A = (int *) malloc(N * sizeof(int)); 
int *B = (int *) malloc(N * sizeof(int)); 
int *C = (int *) malloc(N * sizeof(int)); 

for (i = 0; i < N; i++) { 
    A[i] = i + 1; 
    B[i] = i + 1; 
} 

print_array(A, N); 
print_array(B, N); 


VecAdd<<<1, N>>>(A, B, C); 
print_array(C, N); 
    return 0; 
} 

Czekam macierz C (ostatnia wiersz wyjścia) na 2, 4, 6, 8, ale nie wydaje się, aby dodać:

1 2 3 4 
1 2 3 4 
0 0 0 0 

Czego mi brakuje?

Odpowiedz

4

najpierw trzeba zdefiniowanie wskaźników, które trzymają dane, które zostaną skopiowane do CUDA:

W twoim przykładzie możemy skopiować tablicę "a", "b" i "c" z CPU do CUDA pamięci globalnej.

int a[array_size], b[array_size],c[array_size]; // your original arrays 
int *a_cuda,*b_cuda,*c_cuda;     // defining the "cuda" pointers 

zdefiniuj rozmiar, który zajmie każda z tablic.

int size = array_size * sizeof(int); // Is the same for the 3 arrays 

Wtedy będzie można przydzielić miejsca na dane, które zostaną wykorzystane w CUDA:

alokacji pamięci Cuda:

msg_erro[0] = cudaMalloc((void **)&a_cuda,size); 
msg_erro[1] = cudaMalloc((void **)&b_cuda,size); 
msg_erro[2] = cudaMalloc((void **)&c_cuda,size); 

Teraz musimy skopiować te dane z CPU GPU:

Kopiowanie z procesora na GPU:

msg_erro[3] = cudaMemcpy(a_cuda, a,size,cudaMemcpyHostToDevice); 
msg_erro[4] = cudaMemcpy(b_cuda, b,size,cudaMemcpyHostToDevice); 
msg_erro[5] = cudaMemcpy(c_cuda, c,size,cudaMemcpyHostToDevice); 

Wykonaj kernell

int blocks = //; 
int threads_per_block = //; 
VecAdd<<<blocks, threads_per_block>>>(a_cuda, b_cuda, c_cuda); 

skopiować wyniki z GPU CPU (w naszym przykładzie macierzy C):

msg_erro[6] = cudaMemcpy(c,c_cuda,size,cudaMemcpyDeviceToHost); 

wolnej pamięci:

cudaFree(a_cuda); 
cudaFree(b_cuda); 
cudaFree(c_cuda); 

Dla celów debuging, ja normalnie zachować status funkcji na tablicy, tak:

cudaError_t msg_erro[var]; 

Jednak nie jest to bezwzględnie konieczne, ale będzie to zaoszczędzić czas, jeśli jakiś błąd występuje podczas przydzielania lub przeniesienie pamięci. Jeśli chcesz, możesz wyjąć cały kod "msg_erro [x] =" z powyższego kodu.

Jeśli mantain do 'msg_erro [x] =', a jeśli występuje błąd nie można użyć funkcji, jak ten, który następuje, aby wydrukować erros:

void printErros(cudaError_t *erros,int size) 
{ 
for(int i = 0; i < size; i++) 
     printf("{%d} => %s\n",i ,cudaGetErrorString(erros[i])); 
} 
+1

To nadal zawiera nieprawidłowe wywołanie jądra – talonmies

+0

@talonmies Thanks sr. Poprawiam erro, dzięki za wskazanie tego. – dreamcrash

3

Trzeba przenieść pamięć iz powrotem do GPU, coś

int *a_GPU, *b_GPU, *c_GPU; 

    cudaMalloc(&a_GPU, N*sizeof(int)); 
    cudaMalloc(&b_GPU, N*sizeof(int)); 
    cudaMalloc(&c_GPU, N*sizeof(int)); 

    cudaMemcpy(a_GPU, A, N*sizeof(int), cudaMemcpyHostToDevice); 
    cudaMemcpy(b_GPU, B, N*sizeof(int), cudaMemcpyHostToDevice); 

    VecAdd<<<1, N>>>(a_GPU, b_GPU, c_GPU); 

    cudaMemcpy(C, c_GPU, N*sizeof(int), cudaMemcpyDeviceToHost); 

    print_array(C, N); 

    cudaFree(a_GPU); 
    cudaFree(b_GPU); 
    cudaFree(c_GPU); 
+0

@dreamcrash Używanie Polecenia do kopiowania pamięci do i od urządzenia teraz ... ale nadal nie uzyskują poprawnego wyniku. – badjr

+1

@Deezy możesz opublikować go w niewłaściwej osoby. Opublikuj swój kod tutaj: pastecode.org/index.php na czym jest problem. – dreamcrash

+3

To jest poprawne * z wyjątkiem wywołania jądra *, które wciąż używa wskaźników hosta – talonmies

Powiązane problemy