コード置換ライブラリの開発と使用による生成コードの最適化 - MATLAB
コード置換ライブラリを開発し使用して、生成コード内の関数および演算子を置換します。コード置換とは、アプリケーション コードの要件を満たすためにコード ジェネレーターが生成するコードの関数と演算子を変更する手法です。たとえば、生成コードを置き換えて次のような要件を満たすことができます。
特定のターゲット ハードウェアを含むがこれに限定されない、特定のランタイム環境向けの最適化
既存のアプリケーション コードとの統合
AUTOSAR などの規格への準拠
非有限数またはインラインのサポートを有効または無効にするなどのコードの動作の変更
BLAS の使用または
math.h、システム ヘッダー ファイル、memcpyやmemsetの呼び出しの排除などの、アプリケーションまたはプロジェクト固有のコード要件
MathWorks® が提供するコード置換ライブラリを使用するようにコード ジェネレーターを構成できます。Embedded Coder® ライセンスがある場合は、コード置換ツールまたはプログラムによって、対話的に独自のコード置換ライブラリを開発できます。
この例には、コード置換マッピングを定義するさまざまな方法について説明する MATLAB® コードが含まれています。それぞれの MATLAB 関数の例に加えて、関数および演算子のコード置換をプログラムによって開発する方法について説明する MATLAB ファイルが含まれています。
詳細については、コード置換のカスタマイズとはおよびコード置換ライブラリの開発を参照してください。
登録ファイルの作成
登録ファイルを作成して保存します。既に 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);
}
/*
数学関数の置換の詳細については、数学関数のコード置換を参照してください。
加算および減算演算子の置換
この例では、加算 (+) および減算 (-) の演算用のコード置換マッピングを定義および登録する方法について説明します。加算および減算の演算用のエントリを定義するときに、ライブラリ関数が次のどちらのアルゴリズム (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,doubleint8,uint8int16,uint16int32,uint32csingle,cdoublecint8,cuint8cint16,cuint16cint32,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');