coder.gpu.kernel

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

Синтаксис

coder.gpu.kernel()
coder.gpu.kernel(B,T)
coder.gpu.kernel(B,T,M,name)

Описание

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] является массивом, который задает количество потоков в блоке по измерениям x, y и z.

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

пример

coder.gpu.kernel(B,T,M,name) ожидает те же аргументы B и T. Можно задать дополнительные аргументы M и name. M является положительным целым числом, задающим минимальное количество блоков на потоковую передачу многопроцессорной системы. Иногда, увеличение 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 потокам.

Введенный в R2017b