Customize Code Match and Replacement for Matrix Operations
This example shows how to create custom code replacement entries that add logic to the code match and replacement process for a nonscalar operation. Custom entries specify additional match criteria or modify the replacement function signature to meet application needs.
This example restricts the match criteria for an element-wise multiplication replacement to entries with a specific dimension range. When a match occurs, the custom do_match method modifies the replacement signature to pass the number of elements into the function.
Open the model CRLMultiplicationDivision.slx, which will use the code replacement library.
model = "CRLMultiplicationDivision";
open_system(model)The model contains the block MultiplyElements, which has:
Two Input ports with Data type
Int32and Port dimensions set to[3 3]Integer rounding mode set to
FloorSaturate on integer overflow de-selected
Create the replacement function source and header files. For this example, use the directory named src, which contains myMulImplLib.c and myMulImplLib.h.
type src/myMulImplLib.c#include "myMulImplLib.h"
void myElemMul_s32(int32_T* u1, int32_T* u2, int32_T* y1, uint32_T numElements)
{
int idx;
for(idx = 0; idx<numElements; ++idx)
{
y1[idx] = u1[idx] * u2[idx];
}
}
type src/myMulImplLib.h#ifndef __myMulImplLib_h #define __myMulImplLib_h #include "rtwtypes.h" void myElemMul_s32(int32_T* u1, int32_T* u2, int32_T* y1, uint32_T numElements); #endif /*__myMulImplLib_h*/
Create a class that is derived from the base class RTW.TflCOperationEntryML. For this example, use the pre-written class MyElemMultEntry.
type MyElemMultEntry.mclassdef MyElemMultEntry < RTW.TflCOperationEntryML
methods
function ent = do_match(hThis, ...
hCSO, ... %#ok
targetBitPerChar, ... %#ok
targetBitPerShort, ... %#ok
targetBitPerInt, ... %#ok
targetBitPerLong, ... %#ok
targetBitPerLongLong ) %#ok
% Fourth implementation arg represents number of elements for producing matches.
assert(strcmp(hThis.Implementation.Arguments(4).Name,'numElements'));
ent = RTW.TflCOperationEntry(hThis);
% Calculate number of elements and set value of injected constant.
ent.Implementation.Arguments(4).Value = prod(hCSO.ConceptualArgs(1).DimRange(1,:));
end
end
end
The derived class defines a do_match method with the following signature:
function ent = do_match(hThis, ...
hCSO, ...
targetBitPerChar, ...
targetBitPerShort, ...
targetBitPerInt, ...
targetBitPerLong, ...
targetBitPerLongLong)
In the do_match signature:
entis the return handle. If the match succeeds,entis returned as aTflCOperationEntryhandle. If the match fails,entis returned as empty or as an error message that you specify by callingerrorin the entry.hThisis the handle to the derived instance.hCSOis a handle to an object that the code generator creates for querying the library for a replacement.Remaining arguments are the number of bits for various data types of the current target.
The do_match method:
Creates a copy of an existing type of code replacement entry.
Adds match criteria that the base class does not provide.
Makes changes to the implementation signature.
The do_match method relies on the base class for checking data types and dimension ranges. If the code generator finds a match, do_match:
Sets the return handle.
Uses the conceptual arguments to compute the number of elements in the array. In the replacement entry returned, sets the value of the constant implementation argument as the number of elements of the array.
Create a code replacement table definition file. For example, use the file myElemMultCrlTable.m.
open("myElemMultCrlTable.m")This file defines a code replacement table that contains an operator entry generator for element-wise multiplication. The table entry:
Instantiates the derived class
myElemMultEntryfrom the previous step.Sets operator entry parameters with the call to the
setTflCOperationEntryParametersfunction.Creates conceptual arguments
y1,u1, andu2. The argument classRTW.TflArgMatrixspecifies matrix arguments to match. The three arguments are set up to match 2-dimensional matrices with at least two elements in each dimension.Calls the
getTflArgFromStringfunction to create a return value and four implementation arguments. Argumentsu1andu2are the operands,y1is the product, and the fourth argument is the number of elements. Alternatively, thedo_matchmethod of the derived classmyElemMultEntrycan create and add the implementation arguments. When the number of additional implementation arguments required can vary based on compile-time information, use the alternative approach.Calls
addEntryto add the entry to a code replacement table.
Check the validity of the code replacement table entry. At the command prompt, invoke the table definition file.
tbl = myElemMultCrlTable
tbl =
TflTable with properties:
Version: '1.0'
ReservedSymbols: []
StringResolutionMap: []
AllEntries: [1×1 MyElemMultEntry]
EnableTrace: 1
In the Code Replacement Viewer, view the table definition file.
crviewer(myElemMultCrlTable)
Register the code replacement library. Create a file named rtwTargetInfo.m. For this example, copy the contents from the example text file to rtwTargetInfo.m.
delete ("rtwTargetInfo.m") copyfile CRLCustomEntriesRtwTargetInfo.txt rtwTargetInfo.m type rtwTargetInfo.m
function rtwTargetInfo(cm)
cm.registerTargetInfo(@loc_register_crl);
end
function this = loc_register_crl
% Register a code replacement library for use with CRLMath
this(1) = RTW.TflRegistry;
this(1).Name = 'My Sin CRL';
this(1).TableList = {'crl_table_custom_sinfcn_double'};
this(1).BaseTfl = '';
this(1).TargetHWDeviceType = {'*'};
this(1).Description = '';
% Register a code replacement library for use with CRLMultiplicationDivision
this(2) = RTW.TflRegistry;
this(2).Name = 'My Element-Wise Multiplication CRL';
this(2).TableList = {'myElemMultCrlTable'};
this(2).BaseTfl = '';
this(2).TargetHWDeviceType = {'*'};
this(2).Description = '';
end
Refresh your current MATLAB session by using the command sl_refresh_customizations.
sl_refresh_customizations;
Set these configuration parameters for the model:
System target file —
ert.tlcCode replacement libraries —
My CRL Lib
set_param(model,"SystemTargetFile","ert.tlc"); set_param(model,"CodeReplacementLibrary",'My Element-Wise Multiplication CRL'); sl_refresh_customizations;
When you generate code from the model, the generated code calls the replacement source code.
slbuild(model);
### Searching for referenced models in model 'CRLMultiplicationDivision'. ### Total of 1 models to build. ### Starting build procedure for: CRLMultiplicationDivision ### Successful completion of code generation for: CRLMultiplicationDivision Build Summary Top model targets: Model Build Reason Status Build Duration =============================================================================================================== CRLMultiplicationDivision Information cache folder or artifacts were missing. Code generated. 0h 0m 21.836s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 23.365s
cfile = fullfile("CRLMultiplicationDivision_ert_rtw","CRLMultiplicationDivision.c"); coder.example.extractLines(cfile, ' rtY.Out8 = (int16_T)(rtU.In15 / rtU.In16);','/* Model initialize function */',1, 0);
rtY.Out8 = (int16_T)(rtU.In15 / rtU.In16); /* Outport: '<Root>/Out9' incorporates: * Inport: '<Root>/In17' * Inport: '<Root>/In18' * Product: '<Root>/MultiplyElements' */ myElemMul_s32(&rtU.In17[0], &rtU.In18[0], &rtY.Out9[0], 9U); }