Main Content

MATLAB Function ブロックからの生成コード内の行列演算の高速化

MATLAB Function ブロック内の特定の低水準なベクトル演算および行列演算 (行列乗算など) について生成されるコードの実行速度を向上させるには、BLAS 呼び出しをコード ジェネレーターで作成するように指定します。BLAS は、高度に最適化された、マシンに特定的な実装をいくつか持つ、低水準なベクトル計算および行列計算用ソフトウェア ライブラリです。コード ジェネレーターは、BLAS に対して CBLAS C インターフェイスを使用します。BLAS 呼び出しを生成すると指定し、行列関数の入力配列が特定の基準を満たす場合、コード ジェネレーターは BLAS 呼び出しを生成します。それ以外の場合は、コード ジェネレーターは行列関数のコードを生成します。

コード ジェネレーターは指定の BLAS ライブラリを使用します。実行環境に合わせて最適化された BLAS ライブラリを指定します。

BLAS ライブラリの指定

生成されたコードで BLAS 呼び出しを生成するには、BLAS コールバック クラスにアクセスできなければなりません。BLAS コールバック クラスでは BLAS ライブラリ、CBLAS ヘッダー ファイル、特定の CBLAS インターフェイスで使用する C データ型、およびビルドプロアセスのコンパイラとリンカー オプションを指定します。

BLAS 呼び出しを生成して特定の BLAS ライブラリを使用することを指定するには、BLAS コールバック クラスの名前を指定します。[コンフィギュレーションパラメーター] ダイアログ ボックスで、[カスタム BLAS ライブラリのコールバック] を、コールバック クラスの名前に設定します。

BLAS コールバック クラスの記述

生成されたコードで特定の BLAS ライブラリの呼び出しを生成するには、BLAS コールバック クラスを記述します。スタンドアロン コードで BLAS 呼び出しにこの BLAS ライブラリを使用する他のユーザーとコールバック クラスを共有します。

コールバック クラスは抽象クラス coder.BLASCallback から派生しなければなりません。以下に、Windows® プラットフォームで Intel MKL BLAS ライブラリと統合するためのコールバック クラス mklcallback の実装例を示します。

classdef mklcallback < coder.BLASCallback
    methods (Static)
        function updateBuildInfo(buildInfo, ~)
            libPath = fullfile(pwd,'mkl','WIN','lib','intel64');
            libPriority = '';
            libPreCompiled = true;
            libLinkOnly = true;
            libs = {'mkl_intel_ilp64.lib' 'mkl_intel_thread.lib' 'mkl_core.lib'};
            buildInfo.addLinkObjects(libs, libPath, libPriority, libPreCompiled, ...
                                  libLinkOnly);
            buildInfo.addLinkObjects('libiomp5md.lib',fullfile(matlabroot,'bin', ...
                             'win64'), libPriority, libPreCompiled, libLinkOnly);
            buildInfo.addIncludePaths(fullfile(pwd,'mkl','WIN','include'));
            buildInfo.addDefines('-DMKL_ILP64');
        end
        function headerName = getHeaderFilename()
            headerName = 'mkl_cblas.h';
        end
        function intTypeName = getBLASIntTypeName()
            intTypeName = 'MKL_INT';
        end
    end
end

getHeaderFilename メソッド、getBLASIntTypeName メソッド、および updateBuildInfo メソッドを指定しなければなりません。getHeaderFilename メソッドは CBLAS ヘッダー ファイル名を返します。異なる BLAS ライブラリを使用している場合は、mkl_cblas.h を CBLAS ヘッダー ファイルの名前と置き換えます。getBLASIntTypeName メソッドは、CBLAS インターフェイスで使用する整数データ型の名前を返します。異なる BLAS ライブラリを使用する場合は、MKL_INT を使用する CBLAS インターフェイス固有の整数データ型の名前に置き換えます。updateBuildInfo メソッドは BLAS ライブラリにリンクするビルド プロセスに必要な情報を提供します。コールバック クラス例のコードと同様のコードを使用してヘッダー ファイルの場所、BLAS ライブラリの絶対パス名、コンパイラとリンカー オプションを指定します。Intel MKL BLAS ライブラリを使用する場合は、リンク行アドバイザーを使用して、使用例に対して推奨されるライブラリおよびコンパイラのオプションを確認します。

他にも 3 つのメソッドが coder.BLASCallback に既に実装されています。これらのメソッドは、getBLASDoubleComplexTypeNamegetBLASSingleComplexTypeName、および useEnumNameRatherThanTypedef です。既定では、コールバック クラスはこれらの実装を coder.BLASCallback から継承します。特定の状況では、コールバック クラスを定義するときに、これらのメソッドを独自の定義でオーバーライドしなければなりません。

getBLASDoubleComplexTypeName メソッドは、生成コードの倍精度複素変数に使用する型を返します。BLAS ライブラリが倍精度複素数配列引数に double* および void* 以外の型を取る場合は、このメソッドをコールバック クラスの定義に含めます。

function doubleComplexTypeName = getBLASDoubleComplexTypeName()
doubleComplexTypeName = 'my_double_complex_type';
end

my_double_complex_type を、BLAS ライブラリが倍精度複素数配列引数に取る型で置き換えます。

getBLASSingleComplexTypeName メソッドは、生成コードの単精度複素変数に使用する型を返します。BLAS ライブラリが単精度複素数配列引数に float* および void* 以外の型を取る場合は、このメソッドをコールバック クラスの定義に含めます。

function singleComplexTypeName = getBLASSingleComplexTypeName()
doubleComplexTypeName = 'my_single_complex_type';
end

my_single_complex_type を、BLAS ライブラリが単精度複素数配列引数に取る型で置き換えます。

useEnumNameRatherThanTypedef メソッドは既定で false を返します。BLAS ライブラリの列挙の型に enum キーワードが含まれる場合は、コールバック クラス定義で true を返すようにこのメソッドを再定義します。

function p = useEnumNameRatherThanTypedef()
p = true;
end

以下は、enum キーワードを含む生成された C ソース コードの抜粋です。

enum CBLAS_SIDE t;
enum CBLAS_UPLO b_t;
double temp;
enum CBLAS_TRANSPOSE c_t;
enum CBLAS_DIAG d_t;

BLAS コールバック クラスの指定による BLAS 呼び出しの生成

この例では、特定の BLAS ライブラリの BLAS 関数を呼び出すコードを生成する方法を示します。BLAS コールバック クラス useMyBLAS は、この例で使用する BLAS ライブラリを指定します。

  1. Simulink® モデルを作成します。

  2. MATLAB Function ブロックをモデルに追加します。

  3. MATLAB Function ブロックに、基本的な行列演算の関数を呼び出すコードを追加します。たとえば、2 つの行列 AB を乗算する関数 myMultiply を追加します。

    function C = myMultiply(A,B) %#codegen
    C = A*B;
    end

  4. MATLAB Function ブロックの左に 2 つの Constant ブロックを追加します。それらの値を zeros(1000) に設定します。

  5. MATLAB Function ブロックの右に Outport ブロックを追加します。

  6. ブロックを結線します。

  7. [コンフィギュレーションパラメーター] ダイアログ ボックスで、[カスタム BLAS ライブラリのコールバック] を、コールバック クラスの名前 useMyBLAS に設定します。

    コールバック クラスは MATLAB® パス上になければなりません。

  8. モデルを作成します。

    AB が十分な大きさである場合、コード ジェネレーターは行列乗算関数の BLAS 呼び出しを生成します。

実行環境での BLAS ライブラリの場所の指定

BLAS ライブラリは実行環境で利用できなければなりません。BLAS ライブラリが共有されている場合、環境変数またはリンカー オプションを使用して BLAS ライブラリの場所を指定します。

  • Windows プラットフォームでは、PATH 環境変数を編集します。

  • Linux® プラットフォームでは、LD_LIBRARY_PATH 環境変数を修正するか、rpath リンカー オプションを使用します。

  • macOS プラットフォームでは、DYLD_LIBRARY_PATH 環境変数を修正するか、rpath リンカー オプションを使用します。

rpath リンカー オプションを指定するには、BLAS コールバック クラスの updateBuildInfo メソッド内のビルド情報 addLinkFlags メソッドを使用します。たとえば、GCC コンパイラの場合、次のようになります。

buildInfo.addLinkFlags(sprintf('-Wl,-rpath,"%s"',libPath));

OpenBLAS ライブラリの使用上の注意および制限事項

OpenBLAS ライブラリ関数の呼び出しを含むコードを生成する場合は、次のガイドラインと制限に従います。

  • OpenBLAS ライブラリ関数の呼び出しを含む C++ コードを生成する場合、-pedantic オプションでコードをコンパイルすると警告が生成されます。-pedantic コンパイラ オプションを無効にするには、以下の行を updateBuildInfo メソッドに含めます。

    if ctx.getTargetLang() == 'C++'
        buildInfo.addCompileFlags('-Wno-pedantic');
    end
  • OpenBLAS は C89/C90 規格をサポートしません。

参考

関連するトピック

外部の Web サイト