coder.gpu.kernel

Прагма, которая сопоставляет for- циклы к ядрам графического процессора

Описание

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

Примечание

coder.gpu.kernel прагма заменяет все аналитические проверки параллельного цикла, которые выполняет программное обеспечение. Рекомендуется использовать coder.gpu.kernelfun сначала перед использованием большей передовой функциональности coder.gpu.kernel прагма.

coder.gpu.kernel(B,T) прагма уровня цикла, которую необходимо сразу поместить перед циклом for. Это генерирует ядро с размерностями, заданными B и T. B[Bx,By,1] массив, который задает количество блоков в сетке по измерениям x и y Z не используемый). T[Tx,Ty,Tz] массив, который задает количество потоков в блоке по измерениям xY, и z.

Значение-1 для B и T указывает, что GPU Coder™ должен вывести сетку и наибольшие главные размерения автоматически. coder.gpu.kernel прагма генерирует ошибки для недопустимой сетки и наибольших главных размерений.

пример

coder.gpu.kernel(B,T,M,name) ожидает тот же B и T аргументы. Можно задать дополнительные аргументы M и nameM положительное целое число, задающее минимальное количество блоков на потоковую передачу многопроцессорной системы. Иногда, увеличение M может уменьшать использование регистра в ядре и улучшить заполнение ядра. Значение-1 для M указывает, что GPU Coder должен использовать значение по умолчанию 1. name символьный массив, который позволяет вам настраивать имя сгенерированного ядра.

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

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

Примеры

свернуть все

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

В одном файле запишите функции точки входа scalars это признает, что два вектора вводят x,y из размера 1x4096 и один скалярный вход scale. Функция имеет два for- циклы различных длин итерации, один для векторного сложения и один для нахождения совокупной суммы. Поместите coder.gpu.kernel(1,1024) прагма вне первого цикла. Эта прагма создает ядро с одним блоком, имеющим 1 024 потока. Поместите coder.gpu.kernel(8,512,512,'reduction') прагма вне второго цикла. Эта прагма создает ядро с восемью блоками, имеющими 512 потоков на блок. Ядро, созданное для этого блока, называют сокращением.

function [vout, sout1] = scalars(x,y,scale)
    sout1 = 0;
    vout = coder.nullcopy(zeros(size(x)));
    
    coder.gpu.kernel(1,1024);
    for i=1:1024
        vout(i) = x(i) + y(i);
    end
    
    coder.gpu.kernel(8,512,512,'reduction');
    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 для векторного сложения и scalarsreduction ядро за совокупную сумму. Никакое ядро не необходимо для инициализации sout1=0.

  cudaMemcpy(gpu_y, y, 32768U, cudaMemcpyHostToDevice);
  cudaMemcpy(gpu_x, x, 32768U, cudaMemcpyHostToDevice);  
  scalars_kernel1<<<dim3(1U, 1U, 1U), dim3(1024U, 1U, 1U)>>>(gpu_y, gpu_x, gpu_vout);
  cudaMemcpy(gpu_sout1, sout1, 8U, cudaMemcpyHostToDevice);
  scalarsreduction<<<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_kernel1 имеет один блок с 1 024 потоками на блок, один для добавления каждого элемента. scalarsreduction ядро имеет восемь блоков с 512 потоками на блок, приводящий к в общей сложности 4 096 потокам.

Можно использовать переменные или выражения при определении размерностей ядра. Например, можно переписать scalars функция точки входа, таким образом, что сетка и наибольшие главные размерения заданы во время компиляции.

function [vout, sout1] = scalars(x,y,scale, a, b)
    sout1 = 0;
    vout = zeros(size(x));
    
    coder.gpu.kernel(1,1024);
    for i=1:1024
        vout(i) = x(i) + y(i);
    end
    
    coder.gpu.kernel([a,a*b,1], [a*b, 1, 1], 'reduction');
    for i=1:length(x)
        sout1 = (x(i)*scale) + sout1;    
    end
end

Используйте codegen функция, чтобы сгенерировать MEX-функцию CUDA.

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

Введенный в R2017b