exponenta event banner

Задание макета массива в функциях и классах

Отдельные функции MATLAB ® можно специализировать на компоновке строки или столбца путем вставкиcoder.rowMajor или coder.columnMajor вызывает тело функции. Эти функциональные специализации позволяют объединять основные данные строк и основные данные столбцов в созданном коде. Можно также специализировать классы для одного конкретного макета массива. Специализации функций и классов позволяют:

  • Инкрементное изменение кода для макета основной строки или макета основной строки.

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

  • Структурировать наследование макета массива между множеством различных функций и классов.

Для функций MATLAB Coder™ начального уровня (верхнего уровня) все входы и выходы должны иметь одинаковую структуру массива. В сгенерированном коде C/C + + интерфейс функции начального уровня принимает и возвращает данные с той же компоновкой массива, что и спецификация компоновки массива функций.

Примечание

По умолчанию при создании кода используется макет основного массива столбца.

Задание макета массива в функции

Пример специализированной функции: addMatrixRM:

function [S] = addMatrixRM(A,B) 
%#codegen
S = zeros(size(A));
coder.rowMajor; % specify row-major code
for row = 1:size(A,1) 
   for col = 1:size(A,2)  
       S(row,col) = A(row,col) + B(row,col);
   end
end

Для кодера MATLAB можно создать код для addMatrixRM с помощью codegen команда.

codegen addMatrixRM -args {ones(20,10),ones(20,10)} -config:lib -launchreport

Из-за coder.rowMajor вызов, генератор кода создает код, который использует данные, хранящиеся в главной строке.

Другие функции, вызываемые из основной функции строки или основной функции столбца, наследуют тот же макет массива. Если вызываемая функция имеет свои собственные отличия coder.rowMajor или coder.columnMajor вызов, локальный вызов имеет приоритет.

Функции «основной столбец» и «основная строка» можно смешивать в одном и том же коде. Генератор кода вставляет операции транспонирования или преобразования при передаче данных между основными функциями строки и основными функциями столбца. Эти операции преобразования обеспечивают сохранение элементов массива в соответствии с требованиями функций с различными спецификациями компоновки массива. Например, входные данные основной функции столбца, вызываемые из основной функции строки, преобразуются в основную структуру столбца перед передачей основной функции столбца.

Структура массива запросов функции

Чтобы запросить макет массива функции во время компиляции, используйте coder.isRowMajor или coder.isColumnMajor. Этот запрос может быть полезен для специализации созданного кода при использовании основных функций строк и столбцов. Например, рассмотрим эту функцию:

function [S] = addMatrixRouted(A,B)
 if coder.isRowMajor
     %execute this code if row-major
     S = addMatrixRM(A,B); 
 elseif coder.isColumnMajor
     %execute this code if column-major
     S = addMatrix_OptimizedForColumnMajor(A,B);
 end

Эта функция ведет себя по-разному в зависимости от того, является ли она основной строкой или основной строкой. Когда addMatrixRouted является строкой-мажором, он вызывает addMatrixRM функция, которая имеет эффективный доступ к памяти для основных данных строки. Когда функция является основной для столбца, она вызывает версию addMatrixRM функция оптимизирована для основных данных столбцов.

Например, рассмотрим это определение функции. Алгоритм выполняет итерацию через столбцы во внешнем цикле и строки во внутреннем цикле, в отличие от addMatrixRM функция.

function [S] = addMatrix_OptimizedForColumnMajor(A,B) 
%#codegen
S = zeros(size(A));
for col = 1:size(A,2) 
   for row = 1:size(A,1)  
       S(row,col) = A(row,col) + B(row,col);
   end
end

Создание кода для этой функции дает:

... 
/* column-major layout */
for (col = 0; col < 10; col++) {
  for (row = 0; row < 20; row++) {
     S[row + 20 * col] = A[row + 20 * col] + B[row + 20 * col];  
  }
}
...

Сгенерированный код имеет длину шага только одного элемента. Из-за специализированных запросов созданный код для addMatrixRouted обеспечивает эффективный доступ к памяти для любого варианта компоновки массива.

Задание макета массива в классе

Можно задать макет массива для класса, чтобы переменные свойств объекта сохранялись с определенным макетом массива. Чтобы задать макет массива, разместите coder.rowMajor или coder.columnMajor вызов в конструкторе класса. При назначении объекта с указанным макетом массива свойству другого объекта приоритет имеет макет массива назначенного объекта.

Рассмотрим основной класс строк rowMats в качестве примера. Этот класс содержит свойства матрицы и метод, состоящий из алгоритма сложения элементов. Алгоритм в способе работает более эффективно для данных, хранящихся в макете основной строки. Путем указания coder.rowMajor в конструкторе класса созданный код использует макет основной строки для данных свойства.

classdef rowMats
    properties (Access = public)
        A;
        B;
        C;
    end
    methods
        function obj = rowMats(A,B)
            coder.rowMajor;
            if nargin == 0
                obj.A = 0;
                obj.B = 0;
                obj.C = 0;
            else
                obj.A = A;
                obj.B = B;
                obj.C = zeros(size(A));
            end
        end
        function obj = add(obj)
            for row = 1:size(obj.A,1)
                for col = 1:size(obj.A,2)
                    obj.C(row,col) = obj.A(row,col) + obj.B(row,col);
                end
            end
        end
    end
end

Использование класса в простой функции doMath. Входы и выходы функции точки входа должны иметь одинаковую структуру массива.

function [out] = doMath(in1,in2)
%#codegen
out = zeros(size(in1));
myMats = rowMats(in1,in2);
myMats = myMats.add;
out = myMats.C;
end

Для кодера MATLAB можно создать код путем ввода:

A = rand(20,10);
B = rand(20,10);
cfg = coder.config('lib');
codegen -config cfg doMath -args {A,B} -launchreport

При использовании настроек по умолчанию генератор кода предполагает, что входы и выходы функции точки входа используют компоновку «основной столбец», поскольку для функции не задается компоновка «основная строка». doMath. Поэтому перед вызовом конструктора класса генерируемый код преобразует in1 и in2 в основной макет строки. Аналогично, он преобразует doMath вывод функции обратно в компоновку «основной столбец».

При проектировании класса для определенной компоновки массива необходимо учитывать следующее:

  • Если макет массива не указан в конструкторе класса, объекты наследуют свой макет массива из функции, вызывающей конструктор класса, или из настроек конфигурации генерации кода.

  • Невозможно указать макет массива в нестатическом методе с помощью coder.rowMajor или coder.columnMajor. Методы используют тот же макет массива, что и принимающий объект. Методы не наследуют структуру массива вызывающей их функции. Для статических методов, которые используются аналогично обычным функциям, можно указать макет массива в методе.

  • Если задан макет массива суперкласса, подкласс наследует эту спецификацию макета массива. Нельзя указывать конфликтующие макеты массивов между суперклассами и подклассами.

См. также

| | |

Связанные темы