Last active
February 12, 2019 10:40
-
-
Save JossWhittle/da408dd85951f607ce67fb57eea1d744 to your computer and use it in GitHub Desktop.
Adds to arrays of ints together element-wise.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Compile: nvcc hello.cu -o hello | |
| // Run: ./hello | |
| #include <iostream> | |
| #include <assert.h> | |
| // The GPU kernel | |
| // Computes c[i] = a[i] + b[i] for all i | |
| __global__ | |
| void hello(const int num_elements, int *in_a, int *in_b, int *out_c) { | |
| // Grid stride loop (Google this, it's super important!) | |
| // You often don't have the perfect number of GPU threads for the size of your work | |
| for (int idx = (blockIdx.x * blockDim.x) + threadIdx.x; | |
| idx < num_elements; | |
| idx += (blockDim.x * gridDim.x)) | |
| { | |
| out_c[idx] = in_a[idx] + in_b[idx]; | |
| } | |
| } | |
| int main(int argc, char *argv[]) { | |
| const unsigned int num_elements = 32; | |
| // Allocated CPU arrays | |
| int *a = new int[num_elements]; | |
| int *b = new int[num_elements]; | |
| int *c = new int[num_elements]; | |
| // Fill CPU arrays with input values | |
| for (int i = 0; i < num_elements; ++i) { | |
| a[i] = i; | |
| b[i] = i; | |
| } | |
| // Print inputs | |
| std::cout << "a = [ "; | |
| for (int i = 0; i < num_elements; ++i) std::cout << a[i] << " "; | |
| std::cout << "]" << std::endl; | |
| std::cout << "b = [ "; | |
| for (int i = 0; i < num_elements; ++i) std::cout << b[i] << " "; | |
| std::cout << "]" << std::endl; | |
| // Allocate GPU memory for the inputs and the result | |
| const unsigned int num_bytes = num_elements * sizeof(int); | |
| int *cu_a, *cu_b, *cu_c; | |
| cudaMalloc( (void**) &cu_a, num_bytes); | |
| cudaMalloc( (void**) &cu_b, num_bytes); | |
| cudaMalloc( (void**) &cu_c, num_bytes); | |
| // Copy inputs from CPU memory to GPU memory | |
| cudaMemcpy( cu_a, a, num_bytes, cudaMemcpyHostToDevice ); | |
| cudaMemcpy( cu_b, b, num_bytes, cudaMemcpyHostToDevice ); | |
| // Launch the GPU kernel with 1024 threads | |
| // If the work size is smaller the last threads will terminate immediately | |
| // If the work size is larger than 1024 elements then each thread will loop | |
| // over multiple elements it is responsible for... (Google grid stride loop, see above) | |
| hello<<<1,1024>>>(num_elements, cu_a, cu_b, cu_c); | |
| // Copy the result from the GPU memory to the CPU memory | |
| cudaMemcpy( c, cu_c, num_bytes, cudaMemcpyDeviceToHost ); | |
| // Clean up GPU arrays | |
| cudaFree( cu_a ); | |
| cudaFree( cu_b ); | |
| cudaFree( cu_c ); | |
| // Print result | |
| std::cout << "c[i] = a[i] + b[i]" << std::endl; | |
| std::cout << "c = [ "; | |
| for (int i = 0; i < num_elements; ++i) { | |
| std::cout << c[i] << " "; | |
| assert (c[i] == a[i] + b[i]); // Check the answer is correct | |
| } | |
| std::cout << "]" << std::endl; | |
| // Clean up CPU arrays | |
| delete [] a; | |
| delete [] b; | |
| delete [] c; | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment