Implementing CUDA VecAdd from sample code

You need to transfer the memory back and forth from/to the GPU, something like

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

First, you have to define the pointers that will hold the data that will be copied to GPU:

In your example, we want to copy the arrays 'a','b' and 'c' from CPU to the GPU's global memory.

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

define the size that each array will occupy.

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

Then you will allocate the space to the data that will be used in cuda:

Cuda memory allocation:

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

Now we need to copy this data from CPU to the GPU:

Copy from CPU to 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);

Execute the kernel

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

Copy the results from GPU to CPU (in our example array C):

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

Free Memory:

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

For debugging purposes, I normally save the status of the functions on an array, like this:

cudaError_t msg_erro[var];

However, this is not strictly necessary but it will save you time if an error occurs during the allocation or memory transference. You can take out all the 'msg_erro[x] =' from the code above if you wish.

If you mantain the 'msg_erro[x] =', and if a error does occur you can use a function like the one that follows, to print these erros:

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