Можно специализировать отдельные функции 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
вызовите, местный вызов более приоритетен.
Можно смешать упорядоченные по столбцам и упорядоченные по строкам функции в том же коде. Генератор кода вставляет, транспонируют или операции преобразования когда передающие данные между упорядоченными по строкам и упорядоченными по столбцам функциями. Эти операции преобразования гарантируют, что элементы массива хранятся как требуется функциями с различными спецификациями размещения массивов. Например, входные параметры к упорядоченной по столбцам функции, вызванной от упорядоченной по строкам функции, преобразованы в упорядоченное по столбцам размещение прежде чем быть переданным упорядоченной по столбцам функции.
Чтобы запросить размещение массивов функции во время компиляции, используйте 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 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
. Методы используют то же размещение массивов в качестве принимающего объекта. Методы не наследовали размещение массивов функции, которая вызывает их. Для статических методов, которые используются так же к обычным функциям, можно задать размещение массивов в методе.
Если вы задаете размещение массивов суперкласса, подкласс наследовал эту спецификацию размещения массивов. Вы не можете задать конфликтные размещения массивов между суперклассами и подклассами.
codegen
| coder.columnMajor
| coder.isColumnMajor
| coder.isRowMajor
| coder.rowMajor