Main Content

Specify Array Layout in Functions and Classes

You can specialize individual MATLAB®functions for row-major layout or column-major layout by insertingcoder.rowMajororcoder.columnMajorcalls 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 foraddMatrixRMby using thecodegencommand.

codegenaddMatrixRM-args{ones(20,10),ones(20,10)}-config:lib-launchreport

Because of thecoder.rowMajorcall, 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.rowMajororcoder.columnMajorcall, 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.isRowMajororcoder.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. WhenaddMatrixRoutedis row-major, it calls theaddMatrixRMfunction, which has efficient memory access for row-major data. When the function is column-major, it calls a version of theaddMatrixRMfunction 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 theaddMatrixRMfunction.

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 foraddMatrixRoutedprovides 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.rowMajororcoder.columnMajorcall 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 classrowMatsas 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.rowMajorin 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 convertsin1andin2to row-major layout. Similarly, it converts thedoMathfunction 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 usingcoder.rowMajororcoder.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

||||

Related Topics