コード置換ライブラリの開発と使用による生成コードの最適化 - MATLAB
コード置換ライブラリを開発し使用して、生成コード内の関数および演算子を置換します。コード置換とは、アプリケーション コードの要件を満たすためにコード ジェネレーターが生成するコードの関数と演算子を変更する手法です。たとえば、生成コードを置き換えて次のような要件を満たすことができます。
特定のターゲット ハードウェアを含むがこれに限定されない、特定のランタイム環境向けの最適化
既存のアプリケーション コードとの統合
AUTOSAR などの規格への準拠
非有限数またはインラインのサポートを有効または無効にするなどのコードの動作の変更
BLAS の使用または
math.h
、システム ヘッダー ファイル、memcpy
やmemset
の呼び出しの排除などの、アプリケーションまたはプロジェクト固有のコード要件
MathWorks® が提供するコード置換ライブラリを使用するようにコード ジェネレーターを構成できます。Embedded Coder® ライセンスがある場合は、コード置換ツールまたはプログラムによって、対話的に独自のコード置換ライブラリを開発できます。
この例には、コード置換マッピングを定義するさまざまな方法について説明する MATLAB® コードが含まれています。それぞれの MATLAB 関数の例に加えて、関数および演算子のコード置換をプログラムによって開発する方法について説明する MATLAB ファイルが含まれています。
詳細については、What Is Code Replacement Customization?およびコード置換ライブラリの開発を参照してください。
登録ファイルの作成
登録ファイルを作成して保存します。既に rtwTargetInfo.m
ファイルがパス上に存在する可能性があるため、この例ではファイルから別の名前で新しいファイルを作成します。
copyfile myRtwTargetInfoCRL.txt rtwTargetInfo.m
コード置換ライブラリの開発手順
関数または演算のマッピング、ビルド情報、登録情報に関するコード置換要件を特定します。
コード置換ライブラリの開発の準備をします (たとえばライブラリをテストするモデルの特定または開発)。
コード置換マッピングを定義します。
コード置換のビルド情報を指定します。
コード置換マッピングを登録します。
コード置換を検証します。
ライブラリを展開します。
詳細については、コード置換ライブラリの開発を参照してください。
数学関数の置換
この例では、数学関数のコード置換マッピングの定義と登録を行います。さまざまな関数についてコード置換マッピングを定義できます。詳細については、Code You Can Replace from MATLAB Codeを参照してください。
1. replace_math_fcns.m
ファイルには次のコードが含まれています。
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. コード置換ライブラリ 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. ビルドする構成パラメーターを設定し、関数の入力データ型を定義します。
t = single(2);
4. コード置換テーブル定義ファイル crl_table_functions.m
を開いて確認します。
5. コード置換ライブラリを指定する構成パラメーターと、codegen
コマンドへの入力パラメーターとして手順 3 で定義した入力クラスの例を使用して、MATLAB プログラムを C ソース ファイルにコンパイルします。
codegen('replace_math_fcns', '-config', cfg, '-args', {t, t});
Code generation successful.
6. replace_math_fcns.c
ファイルには次の生成コードが含まれています。
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); } /*
数学関数の置換の詳細については、Math Function Code Replacementを参照してください。
加算および減算演算子の置換
この例では、加算 (+) および減算 (-) の演算用のコード置換マッピングを定義および登録する方法について説明します。加算および減算の演算用のエントリを定義するときに、ライブラリ関数が次のどちらのアルゴリズム (EntryInfoAlgorithm
) を実装するかを指定できます。
演算前にキャスト (CBO) (
RTW_CAST_BEFORE_OP
)、既定値演算後にキャスト (CAO) (
RTW_CAST_AFTER_OP
)
1. addsub_two_int16.m
ファイルには次のコードが含まれています。
function [y1, y2] = addsub_two_int16(u1, u2) %#codegen % Copyright 2008-2010 The MathWorks, Inc. y1 = int16(u1 + u2); y2 = int16(u1 - u2);
コードで既定のアルゴリズムの CBO が使用されていることに注意してください。
2. コード置換ライブラリ "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. ビルドする構成パラメーターを設定し、演算入力データ型を定義します。
t = int16(2);
4. コード置換テーブル定義ファイル addsub_two_int16(u1, u2).m
を開いて確認します。
5. 目的のコード置換ライブラリを指定する構成パラメーターと、codegen
コマンドへの入力パラメーターとして手順 3 で定義した入力クラスの例を使用して MATLAB プログラムを C ソース ファイルにコンパイルします。
codegen('addsub_two_int16','-config', cfg, '-args', {t, t});
Code generation successful.
6. addsub_two_int16.c
ファイルには次の生成コードが含まれています。
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); } /*
加算および減算演算子の置換の詳細については、スカラー演算子のコード置換およびAddition and Subtraction Operator Code Replacementを参照してください。
行列演算子の置換
この例では、行列演算 (加算、減算、乗算、転置、共役、エルミート) のコード置換マッピングの定義と登録を行います。
サポートされているデータ型は、以下のとおりです。
single
,double
int8
,uint8
int16
,uint16
int32
,uint32
csingle
,cdouble
cint8
,cuint8
cint16
,cuint16
cint32
,cuint32
固定小数点整数
混合データ型 (入力ごとに異なるデータ型)
1. replace_matrix_ops.m
ファイルには次のコードが含まれています。
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. コード置換ライブラリ 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. ビルドする構成パラメーターを設定し、演算入力データ型を定義します。
t = [1.0 2.0; 3.0, 4.0];
4. コード置換テーブル定義ファイル crl_table_matops.m を開いて確認します。
5. 目的のコード置換ライブラリを指定する構成パラメーターと、codegen
コマンドへの入力パラメーターとして手順 3 で定義した入力クラスの例を使用して MATLAB プログラムをコンパイルします。
codegen('replace_matrix_ops', '-config', cfg, '-args', {t, t});
Code generation successful.
6. replace_matrix_ops.c
ファイルには次の生成コードが含まれています。
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]; } /*
行列演算子の置換の詳細については、Small Matrix Operation to Processor Code Replacementを参照してください。
行列乗算の BLAS 用の置換
この例では、Basic Linear Algebra Subroutines (BLAS) サブルーチンである xGEMM
および xGEMV
用のコード置換マッピングの定義と登録を行います。次の演算を BLAS サブルーチンにマッピングできます。
行列の乗算
1 つまたは両方の入力の転置を伴う行列の乗算
1 つまたは両方の入力のエルミート演算を伴う行列の乗算
1. replace_matrix_ops_blas.m
ファイルには次のコードが含まれています。
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. コード置換ライブラリ 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. ビルドする構成パラメーターを設定し、関数の入力データ型を定義します。
t = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0];
4. コード置換テーブル定義ファイルの crl_table_blas.m
ファイルを開いて確認します。
5. 目的のコード置換ライブラリを指定する構成パラメーターと、codegen
コマンドへの入力パラメーターとして手順 3 で定義した入力クラスの例を使用して MATLAB プログラムをコンパイルします。
codegen('replace_matrix_ops_blas', '-config', cfg, '-args', {t, t});
Code generation successful.
6. replace_matrix_ops_blas.c
ファイルには次の生成コードが含まれています。
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)); } /*
行列乗算の BLAS 用の置換の詳細については、Matrix Multiplication Operation to MathWorks BLAS Code Replacementを参照してください。
行優先および列優先の行列演算の置換
この例では、行優先および列優先の行列演算のコード置換マッピングの定義と登録を行います。
1. replace_mixed_row_column_ops.m
ファイルには次のコードが含まれています。
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. コード置換ライブラリ "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. ビルドする構成パラメーターを設定し、関数の入力データ型を定義します。
t = [1 2; 3 4];
4. コード置換テーブル定義ファイル crl_table_row_major_op.m
および crl_table_column_major_op.m
を開いて確認します。
5. 目的のコード置換ライブラリを指定する構成パラメーターと、codegen
コマンドへの入力パラメーターとして手順 3 で定義した入力クラスの例を使用して MATLAB プログラムをコンパイルします。
codegen('replace_mixed_row_column_ops.m', '-config', cfg, '-args', {t, t, t});
Code generation successful.
6. replace_matrix_row_column_ops.c
ファイルには次の生成コードが含まれています。
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); } /*
coder.replace を使用した MATLAB 関数の置換
コード置換ライブラリは、組み込みデータ型、複素数データ型、固定小数点データ型のスカラーおよび行列の入出力を備えた MATLAB 関数の置換をサポートします。
1. coder_replace_fcn.m ファイルには次のコードが含まれています。
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. コード置換ライブラリ 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. ビルドする構成パラメーターを設定し、関数の入力データ型を定義します。
t = [1 2; 3 4];
4. コード置換テーブル定義ファイル crl_table_coder_replace.m
を確認します。
5. 目的のコード置換ライブラリを指定する構成パラメーターと、codegen
コマンドへの入力パラメーターとして手順 3 で定義した入力クラスの例を使用して MATLAB プログラムをコンパイルします。
codegen('coder_replace_fcn', '-config', cfg, '-args', {t, t});
Code generation successful.
6. coder_replace_fcn.c
ファイルには次の生成コードが含まれています。
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]); } /*
詳細については、Replace MATLAB Functions with Custom Code by Using the coder.replace Functionを参照してください。
ビルド情報
コード置換テーブルの各エントリでは、置換関数用に次のようなビルド情報を指定できます。
ヘッダー ファイルの依存関係
ソース ファイルの依存関係
追加のインクルード パス
追加のソース パス
追加のリンク フラグ
また、置換コードを生成するために必要なヘッダー、ソースまたはオブジェクト ファイルをコード生成前にビルド フォルダーにコピーするために、RTW.copyFileToBuildDir
を指定できます。RTW.copyFileToBuildDir
は次の値として設定することで指定できます。
setTflCFunctionEntryParameters
、setTflCOperationEntryParameters
またはsetTflCSemaphoreEntryParameters
呼び出しのGenCallback
プロパティ。registerCFunctionEntry
、registerCOperationEntry
またはregisterCSemaphoreEntry
呼び出しの引数genCallback
。
メモ: 置換関数の実装は提供されないため、この例の .m
スクリプトではコード生成のみが構成されています。
置換コードのビルド情報の指定の詳細については、コード置換ライブラリの開発を参照してください。
クリーンアップ
現在の MATLAB セッション内のライブラリ登録情報を更新します。
RTW.TargetRegistry.getInstance('reset');