Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

コード置換ライブラリの開発と使用による生成コードの最適化 - MATLAB

コード置換ライブラリを開発し使用して、生成コード内の関数および演算子を置換します。コード置換とは、アプリケーション コードの要件を満たすためにコード ジェネレーターが生成するコードの関数と演算子を変更する手法です。たとえば、生成コードを置き換えて次のような要件を満たすことができます。

  • 特定のターゲット ハードウェアを含むがこれに限定されない、特定のランタイム環境向けの最適化

  • 既存のアプリケーション コードとの統合

  • AUTOSAR などの規格への準拠

  • 非有限数またはインラインのサポートを有効または無効にするなどのコードの動作の変更

  • BLAS の使用または math.h、システム ヘッダー ファイル、memcpymemset の呼び出しの排除などの、アプリケーションまたはプロジェクト固有のコード要件

MathWorks® が提供するコード置換ライブラリを使用するようにコード ジェネレーターを構成できます。Embedded Coder® ライセンスがある場合は、コード置換ツールまたはプログラムによって、対話的に独自のコード置換ライブラリを開発できます。

この例には、コード置換マッピングを定義するさまざまな方法について説明する MATLAB® コードが含まれています。それぞれの MATLAB 関数の例に加えて、関数および演算子のコード置換をプログラムによって開発する方法について説明する MATLAB ファイルが含まれています。

詳細については、What Is Code Replacement Customization?およびコード置換ライブラリの開発を参照してください。

登録ファイルの作成

登録ファイルを作成して保存します。既に rtwTargetInfo.m ファイルがパス上に存在する可能性があるため、この例ではファイルから別の名前で新しいファイルを作成します。

copyfile myRtwTargetInfoCRL.txt rtwTargetInfo.m 

コード置換ライブラリの開発手順

  1. 関数または演算のマッピング、ビルド情報、登録情報に関するコード置換要件を特定します。

  2. コード置換ライブラリの開発の準備をします (たとえばライブラリをテストするモデルの特定または開発)。

  3. コード置換マッピングを定義します。

  4. コード置換のビルド情報を指定します。

  5. コード置換マッピングを登録します。

  6. コード置換を検証します。

  7. ライブラリを展開します。

詳細については、コード置換ライブラリの開発を参照してください。

数学関数の置換

この例では、数学関数のコード置換マッピングの定義と登録を行います。さまざまな関数についてコード置換マッピングを定義できます。詳細については、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 は次の値として設定することで指定できます。

  • setTflCFunctionEntryParameterssetTflCOperationEntryParameters または setTflCSemaphoreEntryParameters 呼び出しの GenCallback プロパティ。

  • registerCFunctionEntryregisterCOperationEntry または registerCSemaphoreEntry 呼び出しの引数 genCallback

メモ: 置換関数の実装は提供されないため、この例の .m スクリプトではコード生成のみが構成されています。

置換コードのビルド情報の指定の詳細については、コード置換ライブラリの開発を参照してください。

クリーンアップ

現在の MATLAB セッション内のライブラリ登録情報を更新します。

RTW.TargetRegistry.getInstance('reset');