2012-11-21 73 views
6

我在嘗試從CUDA站點http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#kernels中測試示例代碼。從示例代碼實現CUDA VecAdd

我只是想補充兩個數組A和大小爲4的B,並將其存儲在陣列C.這是我到目前爲止有:

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

我期待C數組(最後排的輸出)爲2,4,6,8,但它似乎並沒有被添加:

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

我在想什麼?

回答

4

首先,你必須定義指針,將舉行,這將是複製到CUDA數據:

在你的例子中,我們要將數組'a','b'和'c'從CPU複製到CUDA全局內存。

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

定義每個陣列將佔用的大小。

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

然後您將分配的空間將在CUDA中使用的數據:

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

現在我們需要將這些數據從CPU複製到GPU:

從CPU複製到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); 

執行kernell

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

複印結果從GPU到CPU(在我們的實例陣列C):

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

免存儲器:

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

爲了調試運行的目的,我通常保存的功能狀態的陣列上,像這樣:

cudaError_t msg_erro[var]; 

然而,這不是絕對必要的,但如果在分配過程中發生任何錯誤,將節省您的時間或內存轉移。如果你願意,你可以從上面的代碼中取出所有'msg_erro [x] ='。

如果十個分量的「msg_erro [X] =」,如果沒有發生錯誤,您可以使用函數像下面的一個,打印誤差修改:

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

這仍然包含不正確的內核調用 – talonmies

+0

@talonmies謝謝sr。我糾正了錯誤,謝謝指出。 – dreamcrash

3

您需要的內存來回轉移到GPU,像

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 使用命令現在複製內存到設備...但仍然沒有得到正確的結果。 – badjr

+1

@deezy你把它張貼在錯誤的人我猜。在這裏發佈你的代碼pastecode.org/index.php是什麼問題 – dreamcrash

+3

這是正確的*除了內核調用*仍在使用主機指針 – talonmies