Main Content

Optimize Generated Code by Developing and Using Code Replacement Libraries - MATLAB

Develop and use code replacement libraries to replace functions and operators in generated code. Code replacement is a technique to change the code that the code generator produces for functions and operators to meet application code requirements. For example, you can replace generated code to meet requirements such as:

  • Optimization for a specific run-time environment, including, but not limited to, specific target hardware

  • Integration with existing application code

  • Compliance with a standard, such as AUTOSAR

  • Modification of code behavior, such as enabling or disabling nonfinite or inline support

  • Application- or project-specific code requirements, such as use of BLAS or elimination of math.h, system header files, or calls to memcpy or memset.

You can configure the code generator to use a code replacement library that MathWorks® provides. If you have an Embedded Coder® license, you can develop your own code replacement library interactively with the Code Replacement Tool or programmatically.

This example provides MATLAB® code that shows a variety of ways you can define code replacement mappings. With each example MATLAB function, the example provides MATLAB files that illustrate how to develop function and operator code replacements programmatically.

For more information, see What Is Code Replacement Customization? and Develop a Code Replacement Library.

Create a Registration File

Create and save a registration file. Because an rtwTargetInfo.m file may already exist on the path, this example creates a new file from a file with a different name.

copyfile myRtwTargetInfoCRL.txt rtwTargetInfo.m 

Steps for Developing a Code Replacement Library

  1. Identify your code replacement requirements with respect to function or operating mappings, build information, and registration information.

  2. Prepare for code replacement library development (for example, identify or develop models to test your library).

  3. Define code replacement mappings.

  4. Specify build information for replacement code.

  5. Register code replacement mappings.

  6. Verify code replacements.

  7. Deploy the library.

For more information, see Develop a Code Replacement Library.

Math Function Replacement

This example defines and registers code replacement mappings for math functions. You can define code replacement mappings for a variety of functions. For details, see Code You Can Replace from MATLAB Code.

1. The replace_math_fcns.m file contains this code:

function [y1, y2] = replace_math_fcns(u1, u2) %#codegen

%   Copyright 2008-2010 The MathWorks, Inc.

y1 = single(atan2(u1,u2));
y2 = double(cos(double(u1)) + sin(double(u2)));

2. Configure the code generator to use the code replacement library Function Replacement Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Function Replacement Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

3. Set up the configuration parameters to build and define the function input type.

t = single(2); 

4. Open and explore the code replacement table definition file, crl_table_functions.m.

5. Compile the MATLAB program into a C source file by using the configuration parameters that point to the code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('replace_math_fcns', '-config', cfg, '-args', {t, t});
Code generation successful.

6. The replace_math_fcns.c file contains this generated code:

file = fullfile('codegen','lib','replace_math_fcns','replace_math_fcns.c');
coder.example.extractLines(file,'#include "replace_math_fcns.h','* File trailer for replace_math_fcns.c',1,0)
#include "replace_math_fcns.h"
#include "MyMath.h"

/* Function Definitions */
/*
 * Copyright 2008 The MathWorks, Inc.
 *
 * Arguments    : float u1
 *                float u2
 *                float *b_y1
 *                double *y2
 * Return Type  : void
 */
void replace_math_fcns(float u1, float u2, float *b_y1, double *y2)
{
  *b_y1 = atan2_single(u1, u2);
  *y2 = cos_double(u1) + sin_double(u2);
}

/*

For more information on math function replacement, see Math Function Code Replacement.

Addition and Subtraction Operator Replacement

This example shows how to define and register code replacement mappings for addition (+) and subtraction (-) operations. When defining entries for addition and subtraction operations, you can specify which of the following algorithms (EntryInfoAlgorithm) your library functions implement:

  • Cast-before-operation (CBO) (RTW_CAST_BEFORE_OP), the default

  • Cast-after-operation (CAO) (RTW_CAST_AFTER_OP)

1. The addsub_two_int16.m file contains this code:

function [y1, y2] = addsub_two_int16(u1, u2) %#codegen

%   Copyright 2008-2010 The MathWorks, Inc.

y1 = int16(u1 + u2);
y2 = int16(u1 - u2);

Note, the code uses the default algorithm, CBO.

2. Configure the code generator to use a code replacement library Addition & Subtraction Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Addition & Subtraction Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

3. Set up the configuration parameters to build and define the operation input type.

t = int16(2); 

4. Open and explore the code replacement table definition file, addsub_two_int16(u1, u2).m.

5. Compile the MATLAB program into a C source file by using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('addsub_two_int16','-config', cfg, '-args', {t, t});
Code generation successful.

6. The addsub_two_int16.c file contains this generated code.

file = fullfile('codegen','lib','addsub_two_int16','addsub_two_int16.c');
coder.example.extractLines(file,'#include "addsub_two_int16.h','* File trailer for addsub_two_int16.c',1,0);
#include "addsub_two_int16.h"
#include "MyMath.h"

/* Function Definitions */
/*
 * Copyright 2008 The MathWorks, Inc.
 *
 * Arguments    : short u1
 *                short u2
 *                short *b_y1
 *                short *y2
 * Return Type  : void
 */
void addsub_two_int16(short u1, short u2, short *b_y1, short *y2)
{
  *b_y1 = s16_add_s16_s16(u1, u2);
  *y2 = s16_sub_s16_s16(u1, u2);
}

/*

For more information on addition and subtraction operator replacement, see Scalar Operator Code Replacement and Addition and Subtraction Operator Code Replacement.

Matrix Operator Replacement

This example defines and registers code replacement mappings for matrix operations: addition, subtraction, multiplication, transposition, conjugate, and Hermitian.

Supported types include:

  • single, double

  • int8, uint8

  • int16, uint16

  • int32, uint32

  • csingle, cdouble

  • cint8, cuint8

  • cint16, cuint16

  • cint32, cuint32

  • fixed-point integers

  • mixed types (different type on each input)

1. The replace_matrix_ops.m file contains this code:

function [y1, y2, y3] = replace_matrix_ops(u1, u2) %#codegen
% This block supports the Embedded MATLAB subset.
% See the help menu for details. 

%   Copyright 2010 The MathWorks, Inc.

y1 = u1 + u2;
y2 = u1 - u2;
y3 = y2';

2. Configure the code generator to use a code replacement library Matrix Op Replacement Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Matrix Op Replacement Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

3. Set up the configuration parameters to build and define the operation input type.

t = [1.0 2.0; 3.0, 4.0]; 

4. Open and explore the code replacement table definition file, crl_table_matops.m.

5. Compile the MATLAB program using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('replace_matrix_ops', '-config', cfg, '-args', {t, t});
Code generation successful.

6. The replace_matrix_ops.c file contains this generated code:

file = fullfile('codegen','lib','replace_matrix_ops','replace_matrix_ops.c');
coder.example.extractLines(file,'#include "replace_matrix_ops.h','* File trailer for replace_matrix_ops.c',1,0);
#include "replace_matrix_ops.h"
#include "MatrixMath.h"

/* Function Definitions */
/*
 * This block supports the Embedded MATLAB subset.
 *  See the help menu for details.
 *
 * Arguments    : const double u1[4]
 *                const double u2[4]
 *                double b_y1[4]
 *                double y2[4]
 *                double y3[4]
 * Return Type  : void
 */
void replace_matrix_ops(const double u1[4], const double u2[4], double b_y1[4],
                        double y2[4], double y3[4])
{
  /*    Copyright 2015 The MathWorks, Inc. */
  matrix_sum_2x2_double((double *)&u1[0], (double *)&u2[0], &b_y1[0]);
  matrix_sub_2x2_double((double *)&u1[0], (double *)&u2[0], &y2[0]);
  y3[0] = y2[0];
  y3[1] = y2[1];
  y3[2] = y2[2];
  y3[3] = y2[3];
}

/*

For more information on matrix operator replacement, see Small Matrix Operation to Processor Code Replacement.

Matrix Multiplication Replacement for BLAS

This example defines and registers code replacement mappings for Basic Linear Algebra Subroutines (BLAS) subroutines xGEMM and xGEMV. You can map the following operations to a BLAS subroutine:

  • Matrix multiplication

  • Matrix multiplication with transpose on single or both inputs

  • Matrix multiplication with Hermitian operation on single or both inputs

1. The replace_matrix_ops_blas.m file contains this code:

function [y1, y2] = replace_matrix_ops_blas(u1, u2) %#codegen
% This block supports the MATLAB Coder subset.
% See the help menu for details. 

%   Copyright 2010 The MathWorks, Inc.

y1 = u1 * u2;
y2 = u1 * u2;

2. Configure the code generator to use a code replacement library BLAS Replacement Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'BLAS Replacement Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

3. Set up the configuration parameters to build and define the function input type.

t = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]; 

4. Open and explore the code replacement table definition file, crl_table_blas.m file.

5. Compile the MATLAB program using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('replace_matrix_ops_blas', '-config', cfg, '-args', {t, t});
Code generation successful.

6. The replace_matrix_ops_blas.c file contains this generated code.

file = fullfile('codegen','lib','replace_matrix_ops_blas','replace_matrix_ops_blas.c');
coder.example.extractLines(file,'#include "replace_matrix_ops_blas.h','* File trailer for replace_matrix_ops_blas.c',1,0);
#include "replace_matrix_ops_blas.h"
#include "blascompat32.h"
#include <string.h>

/* Function Definitions */
/*
 * This block supports the MATLAB Coder subset.
 *  See the help menu for details.
 *
 * Arguments    : const double u1[9]
 *                const double u2[9]
 *                double b_y1[9]
 *                double y2[9]
 * Return Type  : void
 */
void replace_matrix_ops_blas(const double u1[9], const double u2[9],
                             double b_y1[9], double y2[9])
{
  double ALPHA;
  double BETA;
  int K;
  int LDA;
  int LDB;
  int LDC;
  int M;
  int N;
  char TRANSA;
  char TRANSB;
  /*    Copyright 2015 The MathWorks, Inc. */
  TRANSA = 'N';
  TRANSB = 'N';
  M = 3;
  N = 3;
  K = 3;
  ALPHA = 1.0;
  LDA = 3;
  LDB = 3;
  BETA = 0.0;
  LDC = 3;
  dgemm32(&TRANSA, &TRANSB, &M, &N, &K, &ALPHA, &u1[0], &LDA, &u2[0], &LDB,
          &BETA, &b_y1[0], &LDC);
  memcpy(&y2[0], &b_y1[0], 9U * sizeof(double));
}

/*

For more information on matrix multiplication replacement for BLAS, see Matrix Multiplication Operation to MathWorks BLAS Code Replacement.

Replacements for Row-Major and Column-Major Matrix Operations

This example defines and registers code replacement mappings for row-major and column-major matrix operations.

1. The replace_mixed_row_column_ops.m file contains this code:

function [y1, y2 , y3, y4] = replace_mixed_row_column_ops( u1,u2, u3)
    coder.rowMajor;
    [y1,y2] = Child_Op(u1,u2,u3);
    y3 = u1*u2;
    y4 = u1+u3;
end

function [b1, b2] = Child_Op( a1,a2,a3)
    coder.columnMajor;
    coder.inline('never');
    b1 = a1*a2;
    b2 = a1+a3;
end

2. Configure the code generator to use a code replacement library Row Major CRL Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Row Major CRL Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

3. Set up the configuration parameters to build and define the function input type.

t = [1 2; 3 4]; 

4. Open and explore the code replacement table definition files, crl_table_row_major_op.m and crl_table_column_major_op.m.

5. Compile the MATLAB program using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('replace_mixed_row_column_ops.m', '-config', cfg, '-args', {t, t, t});
Code generation successful.

6. The replace_matrix_row_column_ops.c file contains this generated code.

file = fullfile('codegen','lib','replace_mixed_row_column_ops','replace_mixed_row_column_ops.c');
coder.example.extractLines(file,'#include "replace_mixed_row_column_ops.h','* File trailer for replace_mixed_row_column_ops.c',1,0);
#include "replace_mixed_row_column_ops.h"
#include "CRL_Multiplication.h"

/* Function Declarations */
static void Child_Op(const double a1[4], const double a2[4], const double a3[4],
                     double b1[4], double b2[4]);

/* Function Definitions */
/*
 * Arguments    : const double a1[4]
 *                const double a2[4]
 *                const double a3[4]
 *                double b1[4]
 *                double b2[4]
 * Return Type  : void
 */
static void Child_Op(const double a1[4], const double a2[4], const double a3[4],
                     double b1[4], double b2[4])
{
  MyMul_CUSTOM_COL((double *)&a1[0], (double *)&a2[0], &b1[0], 2U, 2U, 2U, 2U);
  MyAdd_CUSTOM_COL((double *)&a1[0], (double *)&a3[0], &b2[0], 2U, 2U, 2U, 2U);
}

/*
 * Arguments    : const double u1[4]
 *                const double u2[4]
 *                const double u3[4]
 *                double b_y1[4]
 *                double y2[4]
 *                double y3[4]
 *                double y4[4]
 * Return Type  : void
 */
void replace_mixed_row_column_ops(const double u1[4], const double u2[4],
                                  const double u3[4], double b_y1[4],
                                  double y2[4], double y3[4], double y4[4])
{
  double b_u1[4];
  double b_u2[4];
  double b_u3[4];
  double dv[4];
  double dv1[4];
  b_u1[0] = u1[0];
  b_u2[0] = u2[0];
  b_u3[0] = u3[0];
  b_u1[1] = u1[2];
  b_u2[1] = u2[2];
  b_u3[1] = u3[2];
  b_u1[2] = u1[1];
  b_u2[2] = u2[1];
  b_u3[2] = u3[1];
  b_u1[3] = u1[3];
  b_u2[3] = u2[3];
  b_u3[3] = u3[3];
  Child_Op(b_u1, b_u2, b_u3, dv, dv1);
  y2[0] = dv1[0];
  b_y1[0] = dv[0];
  y2[1] = dv1[2];
  b_y1[1] = dv[2];
  y2[2] = dv1[1];
  b_y1[2] = dv[1];
  y2[3] = dv1[3];
  b_y1[3] = dv[3];
  MyMul_CUSTOM_ROW((double *)&u1[0], (double *)&u2[0], &y3[0], 2U, 2U, 2U, 2U);
  MyAdd_CUSTOM_ROW((double *)&u1[0], (double *)&u3[0], &y4[0], 2U, 2U, 2U, 2U);
}

/*

MATLAB Function Replacement Using Coder.Replace

Code replacement libraries support the replacement of MATLAB functions with scalar and matrix inputs and outputs for built-in, complex, and fixed-point data types.

1. The coder_replace_fcn.m file contains this code:

function [y1, y2, y3] = coder_replace_fcn(u1, u2) %#codegen
%   Copyright 2012 The MathWorks, Inc.

y1 = myScalarFunction(u1(1),u1(2));
y2 = myMatrixFunction(u1, u2);
complexValue = u1 + 1i;
y3 = myComplexFunction(complexValue, u2(1));
end


%-----------------------------------------
% Lookup this function for CRL replacement
% Function: myScalarFunction
% Inputs:  u1: double scalar
%          u2: double scalar
% Outputs: y1: double scalar
%----------------------------------------
function y1 = myScalarFunction(u1, u2)

% Trigger CRL lookup 
coder.replace('-errorifnoreplacement');
y1 = sin(u1) + cos(u2);
end

%-----------------------------------------
% Lookup this function for CRL replacement
% Function: myMatrixFunction
% Inputs:  u1: 2x2 double matrix
%          u2: 2x2 double matrix
% Outputs: y1: 2x2 double matrix
%----------------------------------------
function y1 = myMatrixFunction(u1, u2)

% Trigger CRL lookup 
coder.replace('-errorifnoreplacement');
y1 = u1 + u2;
end


%-----------------------------------------
% Lookup this function for CRL replacement
% Function: myComplexFunction
% Inputs:  u1: 2x2 complex double matrix
%          u2: double scalar
% Outputs: y1: 2x2 complex double matrix
%-----------------------------------------
function y1 = myComplexFunction(u1, u2)

% Trigger CRL lookup 
coder.replace('-errorifnoreplacement');
y1 = u1 + u2;
end

2. Configure the code generator to use a code replacement library Coder Replace Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Coder Replace Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

3. Set up the configuration parameters to build and define the function input type.

t = [1 2; 3 4];

4. Explore the code replacement table definition file, crl_table_coder_replace.m.

5. Compile the MATLAB program using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('coder_replace_fcn', '-config', cfg, '-args', {t, t});
Code generation successful.

6. The coder_replace_fcn.c file contains this generated code.

file = fullfile('codegen','lib','coder_replace_fcn','coder_replace_fcn.c');
coder.example.extractLines(file,'#include "coder_replace_fcn.h','* File trailer for coder_replace_fcn.c',1,0)
#include "coder_replace_fcn.h"
#include "MyMath.h"

/* Function Definitions */
/*
 * Copyright 2012 The MathWorks, Inc.
 *
 * Arguments    : const double u1[4]
 *                const double u2[4]
 *                double *b_y1
 *                double y2[4]
 *                creal_T y3[4]
 * Return Type  : void
 */
void coder_replace_fcn(const double u1[4], const double u2[4], double *b_y1,
                       double y2[4], creal_T y3[4])
{
  creal_T dcv[4];
  *b_y1 = myScalarFunction_impl(u1[0], u1[1]);
  myMatrixFunction_impl(&y2[0], (double *)&u1[0], (double *)&u2[0]);
  dcv[0].re = u1[0];
  dcv[0].im = 1.0;
  dcv[1].re = u1[1];
  dcv[1].im = 1.0;
  dcv[2].re = u1[2];
  dcv[2].im = 1.0;
  dcv[3].re = u1[3];
  dcv[3].im = 1.0;
  myComplexFunction_impl(&y3[0], &dcv[0], u2[0]);
}

/*

For more information, see Replace MATLAB Functions with Custom Code by Using the coder.replace Function.

Build Information

For each entry in a code replacement table, you can specify build information such as the following, for replacement functions:

  • Header file dependencies

  • Source file dependencies

  • Additional include paths

  • Additional source paths

  • Additional link flags

Additionally, you can specify RTW.copyFileToBuildDir to copy header, source, or object files, which are required to generate replacement code, to the build folder before code generation. You can specify RTW.copyFileToBuildDir by setting it as the value of:

  • Property GenCallback in a call to setTflCFunctionEntryParameters, setTflCOperationEntryParameters, or setTflCSemaphoreEntryParameters.

  • Argument genCallback in a call to registerCFunctionEntry, registerCOperationEntry, or registerCSemaphoreEntry.

Note: The .m scripts in this example are configured for code generation only because the implementations for the replacement functions are not provided.

For more information on specifying build information for replacement code, see Develop a Code Replacement Library.

Cleanup

Refresh the library registration information within the current MATLAB session.

RTW.TargetRegistry.getInstance('reset');