coder.gpu.kernelfun

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

Синтаксис

coder.gpu.kernelfun()

Описание

пример

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

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

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

Примеры

свернуть все

Этот пример показывает, как использовать прагму kernelfun в функции и сгенерировать код 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(size(x)));
    
    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 потоками на блок для в общей сложности 1 024 потоков, один для добавления каждого элемента. Точно так же scalars_kernel3 имеет восемь блоков с 512 потоками на блок, приводящий к в общей сложности 4 096 потокам. GPU Coder также выполняет оптимизацию, которая минимизирует количество вызовов функции cudamMemcpy. В этом примере копия входа x находится в графическом процессоре, никакой дополнительный cudamMemcpy не требуется между scalars_kernel2 и scalars_kernel3. В дополнение к оптимизации памяти любой последовательный код между ядрами сопоставлен с потоками CUDA, чтобы сохранить данные по графическому процессору.

Введенный в R2017b