Этот пример показывает, как задать заменяющие отображения кода, которые заменяют нескалярные маленькие операции над матрицей на специфичные для процессора встроенные функции. Пример задает таблицу, содержащую две заменяющих записи матричного оператора для +
(сложение) оператор и тип данных double
. Пример задает функцию, сопоставляющую программно. Также можно использовать Code Replacement Tool, чтобы задать то же отображение.
Создайте табличный файл определения, который содержит функциональное определение. Например:
function hTable = crl_table_matrix_add_double
В теле функции составьте таблицу путем вызова функционального RTW.TflTable
.
hTable = RTW.TflTable;
Создайте запись для первого отображения оператора с вызовом функции RTW.TflCOperationEntry
.
% Create table entry for matrix_sum_2x2_double
op_entry = RTW.TflCOperationEntry;
Установите параметры записи оператора с вызовом функции setTflCOperationEntryParameters
. Генератор кода игнорирует насыщение и округление режимов для нескалярного сложения с плавающей точкой и вычитания. Для заменяющих записей кода для нескалярного сложения и операций вычитания, которые не включают данные фиксированной точки в вызове setTflCOperationEntryParameters
, задают 'RTW_SATURATE_UNSPECIFIED'
для свойства SaturationMode
и {'RTW_ROUND_UNSPECIFIED'}
для RoundingModes
.
setTflCOperationEntryParameters(op_entry, ... 'Key', 'RTW_OP_ADD', ... 'Priority', 30, ... 'SaturationMode', 'RTW_WRAP_ON_OVERFLOW', ... 'ImplementationName', 'matrix_sum_2x2_double', ... 'ImplementationHeaderFile', 'MatrixMath.h', ... 'ImplementationSourceFile', 'MatrixMath.c', ... 'ImplementationHeaderPath', LibPath, ... 'ImplementationSourcePath', LibPath, ... 'AdditionalIncludePaths', {LibPath}, ... 'GenCallback', 'RTW.copyFileToBuildDir', ... 'SideEffects', true);
Создайте концептуальные аргументы y1
, u1
и u2
. Существует несколько способов настроить концептуальные аргументы. Этот пример использует вызовы функции createAndAddConceptualArg
, чтобы создать и добавить аргумент с одним вызовом функции. Чтобы задать матричный аргумент в вызове функции, используйте класс аргумента RTW.TflArgMatrix
. Задайте базовый тип и размерности, для которых аргумент допустим. Первая запись таблицы задает [2 2]
, и вторая запись таблицы задает [3 3]
.
% Specify operands and result createAndAddConceptualArg(op_entry, 'RTW.TflArgMatrix', ... 'Name', 'y1', ... 'IOType', 'RTW_IO_OUTPUT', ... 'BaseType', 'double', ... 'DimRange', [2 2]); createAndAddConceptualArg(op_entry, 'RTW.TflArgMatrix',... 'Name', 'u1', ... 'BaseType', 'double', ... 'DimRange', [2 2]); createAndAddConceptualArg(op_entry, 'RTW.TflArgMatrix',... 'Name', 'u2', ... 'BaseType', 'double', ... 'DimRange', [2 2]);
Создайте аргументы реализации. Существует несколько способов настроить аргументы реализации. Этот пример использует вызовы getTflArgFromString
, чтобы создать аргументы. setReturn
удобных методов и addArgument
задают, является ли аргумент возвращаемым значением или аргументом и добавляет аргумент в массив записи аргументов реализации.
arg = getTflArgFromString(hTable, 'y2', 'void'); arg.IOType = 'RTW_IO_OUTPUT'; op_entry.Implementation.setReturn(arg); arg = getTflArgFromString(hTable, 'u1', ['double' '*']); op_entry.Implementation.addArgument(arg); arg = getTflArgFromString(hTable, 'u2', ['double' '*']); op_entry.Implementation.addArgument(arg); arg = getTflArgFromString(hTable, 'y1', ['double' '*']); arg.IOType = 'RTW_IO_OUTPUT'; op_entry.Implementation.addArgument(arg);
Добавьте запись в заменяющую таблицу кода с вызовом функции addEntry
.
addEntry(hTable, op_entry);
Создайте запись для второго отображения оператора.
% Create table entry for matrix_sum_3x3_double op_entry = RTW.TflCOperationEntry; setTflCOperationEntryParameters(op_entry, ... 'Key', 'RTW_OP_ADD', ... 'Priority', 30, ... 'SaturationMode', 'RTW_WRAP_ON_OVERFLOW', ... 'ImplementationName', 'matrix_sum_3x3_double', ... 'ImplementationHeaderFile', 'MatrixMath.h', ... 'ImplementationSourceFile', 'MatrixMath.c', ... 'ImplementationHeaderPath', LibPath, ... 'ImplementationSourcePath', LibPath, ... 'AdditionalIncludePaths', {LibPath}, ... 'GenCallback', 'RTW.copyFileToBuildDir', ... 'SideEffects', true); % Specify operands and result createAndAddConceptualArg(op_entry, 'RTW.TflArgMatrix', ... 'Name', 'y1', ... 'IOType', 'RTW_IO_OUTPUT', ... 'BaseType', 'double', ... 'DimRange', [3 3]); createAndAddConceptualArg(op_entry, 'RTW.TflArgMatrix',... 'Name', 'u1', ... 'BaseType', 'double', ... 'DimRange', [3 3]); createAndAddConceptualArg(op_entry, 'RTW.TflArgMatrix',... 'Name', 'u2', ... 'BaseType', 'double', ... 'DimRange', [3 3]); % Specify replacement function signature arg = getTflArgFromString(hTable, 'y2', 'void'); arg.IOType = 'RTW_IO_OUTPUT'; op_entry.Implementation.setReturn(arg); arg = getTflArgFromString(hTable, 'u1', ['double' '*']); op_entry.Implementation.addArgument(arg); arg = getTflArgFromString(hTable, 'u2', ['double' '*']); op_entry.Implementation.addArgument(arg); arg = getTflArgFromString(hTable, 'y1', ['double' '*']); arg.IOType = 'RTW_IO_OUTPUT'; op_entry.Implementation.addArgument(arg); addEntry(hTable, op_entry);
Сохраните табличный файл определения. Используйте имя табличной функции определения, чтобы назвать файл.
Протестировать этот пример:
Укажите заменяющее отображение кода.
Создайте модель, которая включает блок Add.
Сконфигурируйте модель со следующими настройками:
На панели Solver выберите фиксированный шаг, дискретный решатель с размером фиксированного шага, таким как 0.1
.
На панели Code Generation выберите ERT-based system target file.
На Code Generation> панель Interface, выберите заменяющую библиотеку кода, которая содержит вашу запись операции сложения.
В Model Explorer сконфигурируйте Signal Attributes для исходных блоков In2
и In1
. Для каждого исходного блока, набор Port dimensions к [3,3]
и набор Data type к double
. Примените изменения. Сохраните модель.
Сгенерируйте код и отчет генерации кода.
Рассмотрите замены кода. Генератор кода заменяет оператор +
на matrix_sum_3x3_double
в сгенерированном коде.
Реконфигурируйте Port dimensions для In1
и In2
к [2 2]
, регенерируйте код. Заметьте, что код, содержащий оператор +
, заменяется matrix_sum_2x2_double
.