Поддержка функций языка MATLAB для GPU Coder

GPU Coder™ поддерживает многие из MATLAB® функции языка, поддерживаемые MATLAB Coder™, см. «Функции языка MATLAB, поддерживаемые для генерации кода C/C + +». Однако некоторые функции могут поддерживаться в ограниченном режиме, а другие не поддерживаться. В следующих разделах мы выделяем некоторые важные функции, которые влияют на генерацию кода GPU, а затем перечисляем функции, которые не поддерживаются GPU Coder.

Общим и важным фактором является поддержка матриц переменного размера. Эта функция может действительно повлиять на способ CUDA® создаются ядра, и следующее обсуждение описывает функцию и факторы для генерации кода GPU.

Генерация кода для массивов переменного размера

Для генерации кода измерение массива равно fixed-size или variable-size. Если генератор кода может определить размер массива и что размер массива не меняется во время выполнения, то размерность является фиксированным. Когда все размерности массива имеют фиксированный размер, массив является fixed-size массивом. В следующем примере Z является массивом фиксированного размера.

function Z = myfcn()
Z = zeros(1,4);
end

Если генератор кода не может определить размер массива или генератор кода определяет, что размер изменяется, то размерность является переменным. Когда по крайней мере одна из его размерностей имеет переменный размер, массив является variable-size массивом.

Размер размерности либо bounded, либо unbounded. Ограниченная размерность имеет фиксированный верхний размер. Неограниченная размерность не имеет фиксированного верхнего размера.

В следующем примере второе измерение Z ограничен, переменный размер. Она имеет верхнюю границу 32.

function s = myfcn(n)
if (n > 0)
    Z = zeros(1,4);
else
    Z = zeros(1,32);
end
s = length(Z);

В следующем примере, если значение n неизвестен во время компиляции, затем второе измерение Z неограниченно.

function s = myfcn(n)
Z = rand(1,n);
s = sum(Z);
end

Можно задать массивы переменного размера путем:

  • Использование конструкторов, таких как zeros или ones, с неконстантным значением размера

  • Присвоение нескольких, постоянных размеров одной и той же переменной перед использованием

  • Использование циклов для увеличения размерностей переменных

  • Объявление всех образцов переменной переменным размером при помощи coder.typeof или coder.varsize функций. Для примера, coder.typeof(1, [12,1],[true, false]) и coder.varsize(1, [Inf,1], [true, false]).

Для получения дополнительной информации смотрите Задать данные переменного размера для генерации кода.

Включение и отключение поддержки массивов переменного размера

Поведение генерации кода

Для ограниченных массивов переменного размера GPU Coder сопоставляет эти ограниченные переменные с ядрами GPU и CUDA. Чтобы задать верхние границы для массивов переменного размера, смотрите Задать верхние границы для массивов переменного размера.

Для неограниченных массивов переменного размера и массивов переменного размера, размер которых больше или равен DynamicMemoryAllocation порог, GPU Coder не сопоставляет эти переменные с графическим процессором, и ядра не создаются. Генератор кода динамически выделяет память на куче центрального процессора. GPU Coder выдает предупреждение для неограниченных переменных в журнале сборки и отчете генерации кода.

По умолчанию генератор кода настраивает динамическое выделение памяти для массивов переменного размера, размер которых больше или равен порогу с пороговым значением 2 ГБ. Чтобы изменить эти настройки:

  • В объекте строения установите DynamicMemoryAllocation на Threshold и DynamicMemoryAllocationThreshold в неотрицательное целое число.

  • В приложении GPU Coder, в настройках Memory, установите Dynamic memory allocation на For arrays with max size at or above threshold и Dynamic memory allocation threshold к неотрицательному целому числу.

Массивы переменного размера в отчете генерации кода

Можно определить, имеет ли массив фиксированный или переменный размер, посмотрев на Size столбец вкладки Variables в отчете генерации кода.

Двоеточие (:) указывает, что размерность переменного размера. Вопросительный знак (?) указывает, что размер неограниченен. Для примера, размер 1-by-:? указывает, что размер первой размерности имеет фиксированный размер 1, а размер второго измерения неограниченный, переменный размер. Звездочка (*) указывает, что генератор кода произвел массив переменного размера, но размер массива не меняется во время выполнения.

Определение структуры для генерации кода

Чтобы сгенерировать эффективный автономный код для структур, необходимо задать и использовать структуры по-другому, чем обычно при запуске кода в среде MATLAB. Для генерации кода необходимо сначала создать скалярную версию шаблона структуры, прежде чем превращать ее в массив. Механизм вывода генерации кода использует тип этого скалярного значения в качестве базового типа массива. Чтобы сгенерировать автономный код для структур MATLAB, вы ограничены следующими операциями:

  • Определите структуры как локальные и постоянные переменные путем назначения и использования struct функция

  • Индексируйте поля структуры с помощью записи через точку

  • Задайте входные параметры первичной функции или функции точки входа как структуры

  • Передайте структуры в локальные функции

Для получения дополнительной информации смотрите Определение структуры для Генерации кода.

Примечание

GPU Coder генерирует более эффективный код, когда вы используете struct массивов вместо массива структур.

Пример

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

tempS = struct('a',0,'b',0);
numE = 2000;
AofS = repmat(tempS,numE,1);

В MATLAB, при построении массива структур, вы обычно добавляете поля, как вы идете. Этот «динамический» стиль строительных конструкций не поддерживается для генерации кода. Одной из причин является то, что в MATLAB возможно иметь отличную структуру поля для двух различных элементов массива структур, что конфликтует с более статическим подходом вывода типов. Поэтому сначала необходимо задать базовый скалярный элемент, а затем вырастить массив структур из этого полностью заданного элемента. Этот метод гарантирует, что два элемента массива структур всегда совместно используют тип (поля).

for ind = 1:numE
 AofS(ind).a = rand;
 AofS(ind).b = rand;
end

Теперь можно задать функцию точки входа mStructSupport который принимает AofS как вход. Локальная функция arrayOp в двойном разряде AofS.b и сохраняет результат в AofS.a.

function [V] = mStructSupport(AofS)
 V = arrayOp(AofS);

end

function AofS = arrayOp(AofS)
 n = numel(AofS);

 for i = 1:n
  AofS(i).a  = AofS(i).b * 2;    
 end  

end

Можно использовать любой из методов, описанных в Генерации кода, Используя Приложение GPU Coder для генерации кода CUDA для этого примера.

Неподдерживаемые функции

В следующем списке перечислены функции, которые в данный момент не поддерживаются.

  • Проверки целостности памяти, см. «Проверки во время выполнения управления».

  • Проверки границ массивов и размерностей.

  • break операторы.

  • Указатели на функцию поддерживаются только тогда, когда они заданы в другой функции, а не как параметр точки входа.

  • Анонимные функции поддерживаются только тогда, когда они заданы внутри другой функции, а не как параметр точки входа.

  • Классы MATLAB.