exponenta event banner

coder.gpu.kernelfun

Прагматика, отображающая функцию на ядра GPU

Синтаксис

Описание

пример

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

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

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

Примеры

свернуть все

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

В одном файле запишите функцию точки входа scalars который принимает два векторных входа x,y размера 1x4096 и один скалярный вход scale. Функция имеет два for- петли различной длины итерации, одна для векторного сложения и одна для нахождения кумулятивной суммы. Разместить coder.gpu.kernelfun() pragma в пределах 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 для создания функции CUDA MEX.

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 потоков. Кодер графического процессора также выполняет оптимизацию, которая минимизирует количество cudamMemcpy вызовы функций. В этом примере копия входных данных x находится в GPU, никаких дополнительных cudamMemcpy требуется между scalars_kernel2 и scalars_kernel3. В дополнение к оптимизации памяти, любой последовательный код между ядрами сопоставляется с потоками CUDA для хранения данных на GPU.

Представлен в R2017b