Specify Array Layout in Functions and Classes
You can specialize individual MATLAB®functions for row-major layout or column-major layout by insertingcoder.rowMajor
orcoder.columnMajor
calls into the function body. Using these function specializations, you can combine row-major data and column-major data in your generated code. You can also specialize classes for one specific array layout. Function and class specializations allow you to:
Incrementally modify your code for row-major layout or column-major layout.
Define array layout boundaries for applications that require different layouts in different components.
结构数组的产业布局many different functions and classes.
ForMATLAB Coder™entry-point (top-level) functions, all inputs and outputs must use the same array layout. In the generated C/C++ code, the entry-point function interface accepts and returns data with the same array layout as the function array layout specification.
Note
By default, code generation uses column-major array layout.
Specify Array Layout in a Function
For an example of a specialized function, consideraddMatrixRM
:
function[S] = addMatrixRM(A,B)%#codegenS = zeros(size(A)); coder.rowMajor;% specify row-major codeforrow = 1:size(A,1)forcol = 1:size(A,2) S(row,col) = A(row,col) + B(row,col);endend
ForMATLAB Coder, you can generate code foraddMatrixRM
by using thecodegen
command.
codegenaddMatrixRM-args{ones(20,10),ones(20,10)}-config:lib-launchreport
Because of thecoder.rowMajor
call, the code generator produces code that uses data stored in row-major layout.
Other functions called from a row-major function or column-major function inherit the same array layout. If a called function has its own distinctcoder.rowMajor
orcoder.columnMajor
call, the local call takes precedence.
You can mix column-major and row-major functions in the same code. The code generator inserts transpose or conversion operations when passing data between row-major and column-major functions. These conversion operations ensure that array elements are stored as required by functions with different array layout specifications. For example, the inputs to a column-major function, called from a row-major function, are converted to column-major layout before being passed to the column-major function.
Query Array Layout of a Function
To query the array layout of a function at compile time, usecoder.isRowMajor
orcoder.isColumnMajor
. This query can be useful for specializing your generated code when it involves row-major and column-major functions. For example, consider this function:
function[S] = addMatrixRouted(A,B)ifcoder.isRowMajor%execute this code if row-majorS = addMatrixRM(A,B);elseifcoder.isColumnMajor%execute this code if column-majorS = addMatrix_OptimizedForColumnMajor(A,B);end
This function behaves differently depending on whether it is row-major or column-major. WhenaddMatrixRouted
is row-major, it calls theaddMatrixRM
function, which has efficient memory access for row-major data. When the function is column-major, it calls a version of theaddMatrixRM
function optimized for column-major data.
For example, consider this function definition. The algorithm iterates through the columns in the outer loop and the rows in the inner loop, in contrast to theaddMatrixRM
function.
function[S] = addMatrix_OptimizedForColumnMajor(A,B)%#codegenS = zeros(size(A));forcol = 1:size(A,2)forrow = 1:size(A,1) S(row,col) = A(row,col) + B(row,col);endend
Code generation for this function yields:
... /* 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]; } } ...
The generated code has a stride length of only one element. Due to the specializing queries, the generated code foraddMatrixRouted
provides efficient memory access for either choice of array layout.
Specify Array Layout in a Class
You can specify array layout for a class so that object property variables are stored with a specific array layout. To specify the array layout, place acoder.rowMajor
orcoder.columnMajor
call in the class constructor. If you assign an object with a specified array layout to the property of another object, the array layout of the assigned object takes precedence.
Consider the row-major classrowMats
as an example. This class contains matrix properties and a method that consists of an element-wise addition algorithm. The algorithm in the method performs more efficiently for data stored in row-major layout. By specifyingcoder.rowMajor
in the class constructor, the generated code uses row-major layout for the property data.
classdefrowMatsproperties(Access = public) A; B; C;endmethodsfunctionobj = rowMats(A,B) coder.rowMajor;ifnargin == 0 obj.A = 0; obj.B = 0; obj.C = 0;elseobj.A = A; obj.B = B; obj.C = zeros(size(A));endendfunctionobj = add(obj)forrow = 1:size(obj.A,1)forcol = 1:size(obj.A,2) obj.C(row,col) = obj.A(row,col) + obj.B(row,col);endendendendend
Use the class in a simple functiondoMath
. The inputs and outputs of the entry-point function must all use the same array layout.
function[out] = doMath(in1,in2)%#codegenout = zeros(size(in1)); myMats = rowMats(in1,in2); myMats = myMats.add; out = myMats.C;end
ForMATLAB Coder, you can generate code by entering:
A = rand(20,10); B = rand(20,10); cfg = coder.config('lib'); codegen-configcfgdoMath-args{A,B}-launchreport
With default settings, the code generator assumes that the entry-point function inputs and outputs use column-major layout, because you do not specify row-major layout for the functiondoMath
. Therefore, before calling the class constructor, the generated code convertsin1
andin2
to row-major layout. Similarly, it converts thedoMath
function output back to column-major layout.
When designing a class for a specific array layout, consider:
If you do not specify the array layout in a class constructor, objects inherit their array layout from the function that calls the class constructor, or from code generation configuration settings.
You cannot specify the array layout in a nonstatic method by using
coder.rowMajor
orcoder.columnMajor
. Methods use the same array layout as the receiving object. Methods do not inherit the array layout of the function that calls them. For static methods, which are used similarly to ordinary functions, you can specify the array layout in the method.If you specify the array layout of a superclass, the subclass inherits this array layout specification. You cannot specify conflicting array layouts between superclasses and subclasses.
See Also
coder.columnMajor
|coder.rowMajor
|coder.isRowMajor
|coder.isColumnMajor
|codegen