coder.gpu.kernelfun

Прагма, которая преобразует функцию в ядра графический процессор

Синтаксис

Описание

пример

coder.gpu.kernelfun() является прагмой глобального уровня, которая пытается сопоставить все расчеты в функции, в которой она находится, с графическим процессором. Циклы в этой функции параллелизируются в ядра графический процессор только в том случае, если они проходят проверку анализа с параллельным циклом. Этот анализ пытается доказать, что каждая итерация цикла независима друг от друга.

Эта прагма не требует никаких входных параметров. Он генерирует ядра, размерности которых вычисляются автоматически на основе параметров цикла.

Эта функция является функцией генерации кода. Это не влияет на MATLAB®.

Примеры

свернуть все

В этом примере показано, как использовать kernelfun pragma в функции и сгенерировать CUDA® код.

В одном файле запишите функцию точки входа scalars который принимает два векторных входов x,y размера 1x4096 и один скалярный вход scale. Функция имеет два for- циклы различных длин итерации, один для сложения векторов и один для нахождения совокупной суммы. Поместите coder.gpu.kernelfun() прагма в scalars функция.

function [vout, sout1] = scalars(x,y,scale)
    coder.gpu.kernelfun;
    sout1 = 0;
    vout = coder.nullcopy(zeros(1,1024));
    
    for i=1:1024
        vout(i) = x(i) + y(i);
    end

    for i=1:4096
        sout1 = (x(i)*scale) + sout1;    
    end
end

Используйте codegen функция для генерации функции MEX CUDA.

codegen -config coder.gpuConfig('mex')...
 -args {ones(1,4096,'double'),ones(1,4096,'double'),coder.typeof(0)}...
 -report scalars

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, чтобы сохранить данные на графическом процессоре.

Введенный в R2017b