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