Вы можете специализироваться на отдельных 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 Coder можно сгенерировать код для addMatrixRM
при помощи codegen
команда.
codegen addMatrixRM -args {ones(20,10),ones(20,10)} -config:lib -launchreport
Из-за coder.rowMajor
генератор кода создает код, который использует данные, сохраненные в размещении.
Другие функции, вызываемые из функции основной строки или функции основной столбца, наследуют то же размещение массива. Если вызываемая функция имеет свое собственное различие coder.rowMajor
или coder.columnMajor
вызов, локальный вызов имеет приоритет.
Можно смешать функции основной и основной строк в том же коде. Генератор кода вставляет операции транспонирования или преобразования при передаче данных между функциями основной строки и основной строки. Эти операции преобразования гарантируют, что элементы массива хранятся в соответствии с требованиями функций с различными спецификациями размещения массива. Для примера входные параметры функции column-major, вызываемые из функции row-major, преобразуются в размещение column-major перед передачей в функцию column-major.
Чтобы запросить размещение массива функции во время компиляции, используйте 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
обеспечивает эффективный доступ к памяти для любого выбора размещения массива.
Можно задать размещение массива для класса, чтобы переменные свойств объектов хранились с определенным размещением массива. Чтобы задать размещение массива, поместите a 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 Coder можно сгенерировать код, введя:
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
. Методы используют то же размещение массива, что и принимающий объект. Методы не наследуют размещение массива функции, которая вызывает их. Для статических методов, которые используются аналогично обычным функциям, можно задать размещение массива в методе.
Если вы задаете размещение массива суперкласса, подкласс наследует эту спецификацию размещения массива. Вы не можете задать конфликтующие размещения массивов между суперклассами и подклассами.
coder.columnMajor
| coder.isColumnMajor
| coder.isRowMajor
| coder.rowMajor