Created
November 13, 2016 19:01
-
-
Save Sinitca-Aleksandr/e5118bb4605cd39984083e8cc8b9afff to your computer and use it in GitHub Desktop.
This file contains 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
#include "cuda_runtime.h" | |
#include "device_launch_parameters.h" | |
#include <stdio.h> | |
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size); | |
__global__ void addKernel(int *c, const int *a, const int *b) | |
{ | |
int i = threadIdx.x; | |
c[i] = a[i] + b[i]; | |
} | |
int main() | |
{ | |
const int arraySize = 5; | |
const int a[arraySize] = { 1, 2, 3, 4, 5 }; | |
const int b[arraySize] = { 10, 20, 30, 40, 50 }; | |
int c[arraySize] = { 0 }; | |
// Сложение векторов на GPU. | |
cudaError_t cudaStatus = addWithCuda(c, a, b, arraySize); | |
//Если запуск прошел не успешно выводим сообщение | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "addWithCuda failed!"); | |
return 1; | |
} | |
printf("{1,2,3,4,5} + {10,20,30,40,50} = {%d,%d,%d,%d,%d}\n", | |
c[0], c[1], c[2], c[3], c[4]); | |
// cudaDeviceReset должен вызываться перед выходом для того, чтобы | |
// инструменты профилирования и отслеживания показали полные данные. | |
cudaStatus = cudaDeviceReset(); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaDeviceReset failed!"); | |
return 1; | |
} | |
system("pause"); | |
return 0; | |
} | |
// Вспомогательная функция использования CUDA для параллельного сложения векторов. | |
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size) | |
{ | |
//Указатели на данные в памяти GPU | |
int *dev_a = 0; | |
int *dev_b = 0; | |
int *dev_c = 0; | |
cudaError_t cudaStatus; | |
// Выбор GPU для запуска, можно менять в системах с несколькими GPU. | |
cudaStatus = cudaSetDevice(0); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?"); | |
goto Error; | |
} | |
// Выделение GPU памяти для трех векторов (два входных, один выходной) . | |
cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int)); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaMalloc failed!"); | |
goto Error; | |
} | |
cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int)); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaMalloc failed!"); | |
goto Error; | |
} | |
cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(int)); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaMalloc failed!"); | |
goto Error; | |
} | |
// Копировние исходных векторов из оперативной памяти в память GPU. | |
cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaMemcpy failed!"); | |
goto Error; | |
} | |
cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaMemcpy failed!"); | |
goto Error; | |
} | |
// Запуск GPU с одним потоком на каждый элемент вектора. | |
addKernel<<<1, size>>>(dev_c, dev_a, dev_b); | |
// Проверка на ошибки при запуске | |
cudaStatus = cudaGetLastError(); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus)); | |
goto Error; | |
} | |
// cudaDeviceSynchronize ждет окончания работы всехъ потоков, и возвращает | |
// любые ошибки, возникающие во время запуска. | |
cudaStatus = cudaDeviceSynchronize(); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus); | |
goto Error; | |
} | |
// Копирование результирующих данных из памяти GPU (device)в оперативную память (host). | |
cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost); | |
if (cudaStatus != cudaSuccess) { | |
fprintf(stderr, "cudaMemcpy failed!"); | |
goto Error; | |
} | |
Error: | |
//Освобождение памяти на видеокарте | |
cudaFree(dev_c); | |
cudaFree(dev_a); | |
cudaFree(dev_b); | |
return cudaStatus; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment