В этом примере показано, как использовать kernelfun
pragma в функции и сгенерировать CUDA® код.
В одном файле запишите функцию точки входа scalars
который принимает два векторных входов x,y
размера 1x4096
и один скалярный вход scale
. Функция имеет два for
- циклы различных длин итерации, один для сложения векторов и один для нахождения совокупной суммы. Поместите coder.gpu.kernelfun()
прагма в scalars
функция.
Используйте codegen
функция для генерации функции MEX CUDA.
GPU Coder создает три ядра: scalars_kernel1
для инициализации sout1=0
, scalars_kernel2
для сложения векторов и scalars_kernel3
- ядро восстановления для совокупной суммы.
scalars_kernel1<<<dim3(1U, 1U, 1U), dim3(32U, 1U, 1U)>>>(gpu_sout1);
cudaMemcpy(gpu_y, y, 32768U, cudaMemcpyHostToDevice);
cudaMemcpy(gpu_x, x, 32768U, cudaMemcpyHostToDevice);
scalars_kernel2<<<dim3(2U, 1U, 1U), dim3(512U, 1U, 1U)>>>(gpu_y, gpu_x, gpu_vout);
scalars_kernel3<<<dim3(8U, 1U, 1U), dim3(512U, 1U, 1U)>>>(scale, gpu_x, gpu_sout1);
cudaMemcpy(vout, gpu_vout, 32768U, cudaMemcpyDeviceToHost);
cudaMemcpy(sout1, gpu_sout1, 8U, cudaMemcpyDeviceToHost);
scalars_kernel2
имеет два блока с 512 потоками на блок для в общей сложности 1024 потоков, по одному для добавления каждого элемента. Точно так же scalars_kernel3
имеет восемь блоков с 512 потоками на блок, в результате чего в общей сложности 4096 потоков. GPU Coder также выполняет оптимизацию, которая минимизирует количество cudamMemcpy
вызовы функций. В этом примере копия входа x
находится в графическом процессоре, никаких дополнительных cudamMemcpy
требуется между scalars_kernel2
и scalars_kernel3
. В дополнение к оптимизации памяти любой последовательный код между ядрами сопоставляется с потоками CUDA, чтобы сохранить данные на графическом процессоре.