このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
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
は MATLAB のインストール フォルダーです (例: matlabroot
C:\Program Files\MATLAB\R2019a
)。これらのファイルを現在のフォルダーにコピーするには、次の MATLAB コマンドを実行します。
copyfile(fullfile(matlabroot,'help','toolbox','coder','examples','euclidean'))
euclidean_data.mat
、euclidean.m
、test.m
、test_2d.m
、build_mex_fixed.m
、および build_mex_variable.m
です。
MATLAB データ ファイル
euclidean_data.mat
には、3 次元ユークリッド空間の単一の点と 3 次元ユークリッド空間の他の複数の点の 2 つのデータが格納されています。具体的には次のとおりです。x
は、3 次元ユークリッド空間の点を表す3
行1
列の列ベクトルです。cb
は、3
行216
列の配列です。cb
の各列が 3 次元ユークリッド空間の点を表します。
MATLAB ファイル
euclidean.m
には、この例の "コア アルゴリズム" を実装する関数euclidean
が含まれています。この関数はx
とcb
を入力として受け取ります。x
とcb
の各点の間のユークリッド距離を計算して次の量を返します。列ベクトル
y_min
。x
に最も近い点を表すcb
の列と等しくなります。列ベクトル
y_max
。x
から最も遠い点を表すcb
の列と等しくなります。2 次元のベクトル
idx
。ベクトルy_min
とy_max
のcb
における列インデックスが格納されます。2 次元のベクトル
distance
。x
との間の計算された最短距離と最長距離が格納されます。
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_min
、y_max
、idx
、および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.m
とbuild_mex_variable.m
には、MATLAB コードから静的な C ライブラリを生成するためのコマンドが固定サイズの入力を受け入れるものと可変サイズの入力を受け入れるものに分けて格納されています。これらのスクリプトの内容については、このチュートリアルの後半で C コードを生成するときに説明します。
ヒント
MATLAB 関数からのコードの生成には、MATLAB Coder を使用します。MATLAB スクリプトからのコード生成はサポートされていません。
テスト スクリプトを使用して、コア アルゴリズムを実装する関数から事前処理と事後処理のステップを分割します。こうすることで、アルゴリズムを簡単に再利用できます。ここでは、コア アルゴリズムを実装する MATLAB 関数のコードを生成します。テスト スクリプトのコードは生成しません。
MATLAB 関数の MEX 関数の生成
元の MATLAB コードの実行
MATLAB でテスト スクリプト test.m
を実行します。y
、idx
、および 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++ コードの生成でサポートされている関数およびオブジェクトを参照してください。
MATLAB エディターで、
euclidean.m
を開きます。MATLAB エディターの右上隅にあるコード アナライザー メッセージ インジケーターは緑色になります。アナライザーは、コード内にエラー、警告または改善すべき点を検出しませんでした。関数宣言の後に、
%#codegen
命令を追加します。function [y,idx,distance] = euclidean(x,cb) %#codegen
%#codegen
命令により、コード生成に固有の警告やエラーがコード アナライザーで特定されます。コード アナライザー メッセージ インジケーターが赤色になり、コード生成の問題が検出されたことが示されます。
警告メッセージを表示するには、下線が引かれているコード部分にカーソルを移動します。この警告は、コードを生成するには、変数
idx
とdistance
を完全に定義してから添字を付けなければならないことを示しています。この警告が発生するのは、コード ジェネレーターがそれらの変数のサイズをコードにおける最初の出現箇所で決定しなければならないためです。この問題を修正するには、関数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));
コード アナライザー メッセージ インジケーターが再び緑色になり、コード生成に関する問題がほかに検出されていないことが示されます。
コード アナライザーの使用の詳細については、コード アナライザーを使用したエラーと警告についてのコードのチェックを参照してください。
ファイルを保存します。
コード生成の準備状態ツールを実行するには、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.m
に euclidean.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
を参照してください。
ビルド スクリプト
build_mex_fixed.m
を実行します。コード ジェネレーターにより、MEX 関数
euclidean_mex
が現在の作業フォルダーに生成されます。出力は、次のようになります。
この出力が元の MATLAB 関数で生成された出力と一致することから、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 コードへのリンクが表示されます。コード生成レポートを参照してください。
ヒント
コマンド ラインでのコードの生成にはビルド スクリプトを使用します。ビルド スクリプトでは、コマンド ラインで繰り返し実行する一連の MATLAB コマンドを自動化できるため、時間の節約となり、入力エラーをなくすことができます。
可変サイズ入力の MEX 関数の生成
生成した euclidean.m
の MEX 関数は、コード生成時に指定したサンプル入力と同じサイズの入力のみを受け入れます。ただし、対応する MATLAB 関数への入力配列は任意のサイズにすることができます。チュートリアルのこのパートでは、可変サイズの入力を受け入れる MEX 関数を euclidean.m
から生成します。
ここでは、生成される MEX 関数の x
と cb
の次元について、プロパティを次のように設定するとします。
x
とcb
の両方の最初の次元を最大サイズ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_mex
が x
および cb
とは異なる次元の入力を受け入れることを確認できます。テスト スクリプト test_2d.m
は、x
と cb
の 2 次元のバージョンである入力配列 x2d
と cb2d
を作成します。その後、それらの入力パラメーターを使用して 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')
x
および cb
とは異なる次元の入力を受け入れることを確認できます。次のステップ
目的 | 詳細 |
---|---|
コード生成でサポートされる MATLAB の組み込み関数とツールボックス関数、クラス、および System object について学習する | |
C++ MEX コードを生成する | |
入力の型を対話形式で作成および編集する | |
生成されたコードの実行速度またはメモリ使用量を最適化する | |
コード生成レポートについて学習する | |
生成された MEX 関数の実行時間とコード カバレッジを MATLAB プロファイラーで確認する |