最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

MATLAB アルゴリズムを高速化するための MEX 関数の生成

MATLAB® Coder™ を使用して MATLAB コードから MEX 関数を生成できます。MEX 関数は MATLAB の実行可能ファイルです。生成されたコードは MATLAB 内から呼び出すことができます。MEX 関数を使用すると、MATLAB 環境内での作業において、MATLAB コードの計算量の多い部分を高速化できます。MATLAB コードから MEX 関数を生成するには、MATLAB Coder アプリを使用するか、MATLAB コマンド ラインで codegen を使用します。

このチュートリアルでは、MATLAB Coder codegen コマンドを使用して、MATLAB 関数の MEX 関数を生成します。最初に、固定の既定サイズの入力のみを受け入れる MEX 関数を生成します。その後、複数の異なるサイズの入力を受け入れるもう 1 つの MEX 関数を生成します。

チュートリアル ファイル

チュートリアル ファイルをフォルダー matlabroot\help\toolbox\coder\examples\euclidean からローカルの作業フォルダーにコピーします。ここで、matlabroot は MATLAB のインストール フォルダーです (例: C:\Program Files\MATLAB\R2019a)。これらのファイルを現在のフォルダーにコピーするには、次の MATLAB コマンドを実行します。

copyfile(fullfile(matlabroot,'help','toolbox','coder','examples','euclidean'))
ローカルの作業フォルダーを private フォルダーまたは @ フォルダーにすることはできません。このチュートリアルで使用するファイルは、euclidean_data.mateuclidean.mtest.mtest_2d.mbuild_mex_fixed.m、および build_mex_variable.m です。

  • MATLAB データ ファイル euclidean_data.mat には、3 次元ユークリッド空間の単一の点と 3 次元ユークリッド空間の他の複数の点の 2 つのデータが格納されています。具体的には次のとおりです。

    • x は、3 次元ユークリッド空間の点を表す 31 列の列ベクトルです。

    • cb は、3216 列の配列です。cb の各列が 3 次元ユークリッド空間の点を表します。

  • MATLAB ファイル euclidean.m には、この例の "コア アルゴリズム" を実装する関数 euclidean が含まれています。この関数は xcb を入力として受け取ります。xcb の各点の間のユークリッド距離を計算して次の量を返します。

    • 列ベクトル y_minx に最も近い点を表す cb の列と等しくなります。

    • 列ベクトル y_maxx から最も遠い点を表す cb の列と等しくなります。

    • 2 次元のベクトル idx。ベクトル y_miny_maxcb における列インデックスが格納されます。

    • 2 次元のベクトル distancex との間の計算された最短距離と最長距離が格納されます。

    function [y_min,y_max,idx,distance] = euclidean(x,cb)
    % Initialize minimum distance as distance to first element of cb
    % Initialize maximum distance as distance to first element of cb
    idx(1)=1;
    idx(2)=1;
    
    distance(1)=norm(x-cb(:,1));
    distance(2)=norm(x-cb(:,1));
    
    % Find the vector in cb with minimum distance to x
    % Find the vector in cb with maximum distance to x
    for index=2:size(cb,2)
        d=norm(x-cb(:,index));
        if d < distance(1)
            distance(1)=d;
            idx(1)=index;
        end
        if d > distance(2)
            distance(2)=d;
            idx(2)=index;
        end
    end
    
    % Output the minimum and maximum distance vectors
    y_min=cb(:,idx(1));
    y_max=cb(:,idx(2));
    
    end
  • MATLAB スクリプト test.m は、データ ファイル euclidean_data.mat をワークスペースに読み込みます。関数 euclidean を呼び出して y_miny_maxidx、および distance を計算します。このスクリプトで計算された量がコマンド ラインに表示されます。

    euclidean_data.mat の読み込みは、コア アルゴリズムを呼び出す前に実行される事前処理のステップです。結果の表示は事後処理のステップとなります。

    % Load test data 
    load euclidean_data.mat
    
    % Determine closest and farthest points and corresponding distances
    [y_min,y_max,idx,distance] = euclidean(x,cb);
    
    % Display output for the closest point
    disp('Coordinates of the closest point are: ');
    disp(num2str(y_min'));
    disp(['Index of the closest point is ', num2str(idx(1))]);
    disp(['Distance to the closest point is ', num2str(distance(1))]);
    
    disp(newline);
    
    % Display output for the farthest point
    disp('Coordinates of the farthest point are: ');
    disp(num2str(y_max'));
    disp(['Index of the farthest point is ', num2str(idx(2))]);
    disp(['Distance to the farthest point is ', num2str(distance(2))]);
  • MATLAB スクリプト test_2d.m は、2 次元ユークリッド空間の点を表すために test.m を変更したものです。test_2d.m の内容については、このチュートリアルの後半で MEX 関数の可変サイズ入力のテストに使用するときに説明します。

  • ビルド スクリプト build_mex_fixed.mbuild_mex_variable.m には、MATLAB コードから静的な C ライブラリを生成するためのコマンドが固定サイズの入力を受け入れるものと可変サイズの入力を受け入れるものに分けて格納されています。これらのスクリプトの内容については、このチュートリアルの後半で C コードを生成するときに説明します。

ヒント

MATLAB 関数からのコードの生成には、MATLAB Coder を使用します。MATLAB スクリプトからのコード生成はサポートされていません。

テスト スクリプトを使用して、コア アルゴリズムを実装する関数から事前処理と事後処理のステップを分割します。こうすることで、アルゴリズムを簡単に再利用できます。ここでは、コア アルゴリズムを実装する MATLAB 関数のコードを生成します。テスト スクリプトのコードは生成しません。

MATLAB 関数の MEX 関数の生成

元の MATLAB コードの実行

MATLAB でテスト スクリプト test.m を実行します。yidx、および distance が出力に表示されます。

Coordinates of the closest point are: 
0.8         0.8         0.4
Index of the closest point is 171
Distance to the closest point is 0.080374


Coordinates of the farthest point are: 
0  0  1
Index of the farthest point is 6
Distance to the farthest point is 1.2923

MATLAB コードをコード生成に適したものにする

MATLAB コードをコード生成に適したものにするには、コード アナライザーとコード生成の準備状態ツールを使用します。MATLAB エディターのコード アナライザーは、コードの入力時にそれを常にチェックします。コード アナライザーは、コードの問題を報告し、パフォーマンスと保守性を最大化するための修正方法を提案します。コード生成の準備状態ツールでは、MATLAB コード内にコード生成でサポートされない機能や関数がないかどうかを調べることができます。

C/C++ コード生成でサポートされる MATLAB の一部の組み込み関数とツールボックス関数、クラス、および System object には、特定のコード生成の制限があります。それらの制限と関連する使用上の注意事項については、該当するリファレンス ページの拡張機能のセクションに記載されています。詳細については、C/C++ コードの生成でサポートされている関数およびオブジェクトを参照してください。

  1. MATLAB エディターで、euclidean.m を開きます。MATLAB エディターの右上隅にあるコード アナライザー メッセージ インジケーターは緑色になります。アナライザーは、コード内にエラー、警告または改善すべき点を検出しませんでした。

  2. 関数宣言の後に、%#codegen 命令を追加します。

    function [y,idx,distance] = euclidean(x,cb) %#codegen
    %#codegen 命令により、コード生成に固有の警告やエラーがコード アナライザーで特定されます。

    コード アナライザー メッセージ インジケーターが赤色になり、コード生成の問題が検出されたことが示されます。

  3. 警告メッセージを表示するには、下線が引かれているコード部分にカーソルを移動します。この警告は、コードを生成するには、変数 idxdistance を完全に定義してから添字を付けなければならないことを示しています。この警告が発生するのは、コード ジェネレーターがそれらの変数のサイズをコードにおける最初の出現箇所で決定しなければならないためです。この問題を修正するには、関数 ones を使用して、それらの配列の割り当てと初期化を同時に行います。

    % Initialize minimum distance as distance to first element of cb
    % Initialize maximum distance as distance to first element of cb
    idx = ones(1,2);
    
    distance = ones(1,2)*norm(x-cb(:,1));

    コード アナライザー メッセージ インジケーターが再び緑色になり、コード生成に関する問題がほかに検出されていないことが示されます。

    コード アナライザーの使用の詳細については、エラーと警告についてのコードのチェックを参照してください。

  4. ファイルを保存します。

  5. コード生成の準備状態ツールを実行するには、MATLAB コマンド ラインから関数 coder.screener を呼び出します。

    coder.screener('euclidean')

    euclidean については、ツールでコード生成に関する問題は検出されません。詳細については、コード生成の準備状態ツールを参照してください。

    コード生成の準備状態ツールは、MATLAB Online™ ではサポートされていません。

    メモ

    コード アナライザーとコード生成の準備状態ツールで、コード生成に関するすべての問題を検出できるわけではありません。これらのツールで検出されたエラーや警告を解決したら、MATLAB Coder を使用してコードを生成し、MATLAB コードに準拠違反の問題がほかにないかどうかを調べてください。

これで、MATLAB Coder アプリを使用してコードをコンパイルする準備ができました。"コンパイル" とは、ここでは MATLAB コードから C/C++ コードを生成することを指しています。

メモ

MATLAB コードのコンパイルとは、MATLAB コードから C/C++ コードを生成することを指します。他のコンテキストでは、コンパイルという用語が C/C++ コンパイラのアクションを指す場合もあります。

入力の型の定義

C では静的なデータ型が使用されるため、コード ジェネレーターは MATLAB ファイル内のすべての変数のクラス、サイズ、実数/複素数をコード生成時 ("コンパイル時") に判別しなければなりません。したがって、ファイルのコードを生成するときに、エントリポイント関数に対するすべての入力引数のプロパティを指定しなければなりません。"エントリポイント関数" は、コードを生成する最上位の MATLAB 関数です。

codegen コマンドを使用してコードを生成する場合は、-args オプションを使用してエントリポイント関数に対するサンプル入力パラメーターを指定します。コード ジェネレーターは、この情報を使用して入力引数のプロパティを決定します。

次のステップでは、codegen コマンドを使用して、エントリポイント関数 euclidean から MEX ファイルを生成します。

MEX 関数の生成と検証

ビルド スクリプト build_mex_fixed.meuclidean.m の MEX 関数の生成と検証に使用するコマンドが含まれています。MEX 関数を検証するには、MATLAB 関数 euclidean の呼び出しを生成された MEX 関数の呼び出しに置き換えてテスト スクリプト test を実行します。

% Load the test data
load euclidean_data.mat
% Generate code for euclidean.m with codegen. Use the test data as example input. Validate MEX by using test.m.
codegen -report euclidean.m -args {x, cb} -test test
次の点に注意してください。

  • 既定で、codegen は、現在のフォルダーに euclidean_mex という名前の MEX 関数を生成します。

  • -report オプションは codegen に対して、コード生成の問題をデバッグしたり MATLAB コードがコード生成に適していることを確認したりするために使用できるコード生成レポートを生成するよう指示します。

  • -args オプションは、エントリポイント関数 euclidean に対するサンプル入力パラメーターを指定します。コード ジェネレーターは、この情報を使用して入力引数のクラス、サイズ、実数/複素数を決定します。

  • -test オプションを使用して、テスト ファイル test.m を実行します。このオプションにより、テスト ファイルの euclidean の呼び出しが euclidean_mex の呼び出しに置き換えられます。

コード生成オプションの詳細については、codegen を参照してください。

  1. ビルド スクリプト build_mex_fixed.m を実行します。

    コード ジェネレーターにより、MEX 関数 euclidean_mex が現在の作業フォルダーに生成されます。

    出力は、次のようになります。

    Code generation successful: View report.
    Running test file: 'test' with MEX function 'euclidean_mex'.
    Coordinates of the closest point are: 
    0.8         0.8         0.4
    Index of the closest point is 171
    Distance to the closest point is 0.080374
    
    
    Coordinates of the farthest point are: 
    0  0  1
    Index of the farthest point is 6
    Distance to the farthest point is 1.2923
    この出力が元の MATLAB 関数で生成された出力と一致することから、MEX 関数を確認できます。

  2. レポート ビューアーでコード生成レポートを表示するには、[レポートの表示] をクリックします。

    コード生成中にコード ジェネレーターでエラーや警告が検出された場合は、レポートに問題の説明と問題がある MATLAB コードへのリンクが表示されます。コード生成レポートを参照してください。

ヒント

コマンド ラインでのコードの生成にはビルド スクリプトを使用します。ビルド スクリプトでは、コマンド ラインで繰り返し実行する一連の MATLAB コマンドを自動化できるため、時間の節約となり、入力エラーをなくすことができます。

可変サイズ入力の MEX 関数の生成

生成した euclidean.m の MEX 関数は、コード生成時に指定したサンプル入力と同じサイズの入力のみを受け入れます。ただし、対応する MATLAB 関数への入力配列は任意のサイズにすることができます。チュートリアルのこのパートでは、可変サイズの入力を受け入れる MEX 関数を euclidean.m から生成します。

ここでは、生成される MEX 関数の xcb の次元について、プロパティを次のように設定するとします。

  • xcb の両方の最初の次元を最大サイズ 3 の可変にします。

  • x の 2 番目の次元を値 1 の固定にします。

  • cb の 2 番目の次元を最大サイズ 216 の可変にします。

これらの入力プロパティを指定するには、関数 coder.typeof を使用します。coder.typeof(A,B,1) は、クラスと実数/複素数が A と同じで、上限がサイズ ベクトル B の対応する要素で与えられる可変サイズの入力を指定します。coder.typeof を使用するビルド スクリプト build_mex_variable.m を使用して、生成される MEX 関数の可変サイズ入力のプロパティを指定します。

% Load the test data
load euclidean_data.mat

% Use coder.typeof to specify variable-size inputs
eg_x=coder.typeof(x,[3 1],1);
eg_cb=coder.typeof(cb,[3 216],1);

% Generate code for euclidean.m using coder.typeof to specify
% upper bounds for the example inputs
codegen -report euclidean.m -args {eg_x,eg_cb}

新しい MEX 関数 euclidean_mexx および cb とは異なる次元の入力を受け入れることを確認できます。テスト スクリプト test_2d.m は、xcb の 2 次元のバージョンである入力配列 x2dcb2d を作成します。その後、それらの入力パラメーターを使用して MATLAB 関数 euclidean を呼び出します。

% Load the test data
load euclidean_data.mat

% Create 2-D versions of x and cb
x2d=x(1:2,:);
cb2d=cb(1:2,1:6:216);

% Determine closest and farthest points and corresponding distances
[y_min,y_max,idx,distance] = euclidean(x2d,cb2d);

% Display output for the closest point
disp('Coordinates of the closest point are: ');
disp(num2str(y_min'));
disp(['Index of the closest point is ', num2str(idx(1))]);
disp(['Distance to the closest point is ', num2str(distance(1))]);

disp(newline);

% Display output for the farthest point
disp('Coordinates of the farthest point are: ');
disp(num2str(y_max'));
disp(['Index of the farthest point is ', num2str(idx(2))]);
disp(['Distance to the farthest point is ', num2str(distance(2))]);

test_2d.m を実行すると、次の出力が生成されます。

Coordinates of the closest point are: 
0.8         0.8
Index of the closest point is 29
Distance to the closest point is 0.078672


Coordinates of the farthest point are: 
0  0
Index of the farthest point is 1
Distance to the farthest point is 1.1357

euclidean の呼び出しを euclidean_mex の呼び出しに置き換えてテスト スクリプト test_2d.m を実行するには、coder.runTest を使用します。

coder.runTest('test_2d','euclidean')
この出力は元の MATLAB 関数で生成される出力と一致します。このことから、新しい MEX 関数が x および cb とは異なる次元の入力を受け入れることを確認できます。

次のステップ

目的詳細

コード生成でサポートされる MATLAB の組み込み関数とツールボックス関数、クラス、および System object について学習する

C/C++ コードの生成でサポートされている関数およびオブジェクト

入力の型を対話形式で作成および編集する

コード生成の型エディターを使用した入力の型の作成と編集

生成されたコードの実行速度またはメモリ使用量を最適化する

最適化手法

コード生成レポートについて学習する

コード生成レポート

生成された MEX 関数の実行時間とコード カバレッジを MATLAB プロファイラーで確認する

MATLAB プロファイラーを使用した MEX 関数のプロファイリング

参考

| |