Main Content

生成されたスタンドアロン コードでの BLAS 呼び出しを使用した行列演算の高速化

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

スタンドアロン コード内での BLAS の呼び出しについては、MATLAB Coder は指定する BLAS ライブラリを使用します。実行環境に合わせて最適化された BLAS ライブラリを指定します。

BLAS ライブラリの指定

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

  • コマンド ラインで、コード構成オブジェクトのプロパティ CustomBLASCallback をコールバック クラスの名前に設定します。

  • MATLAB Coder アプリで、[カスタム 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

getHeaderFilenamegetBLASIntTypeName、および 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. 基本的な行列演算の関数を呼び出す MATLAB 関数を記述します。たとえば、2 つの行列 AB を乗算する関数 myMultiply を記述します。

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

  2. スタティック ライブラリ、ダイナミック リンク ライブラリまたは実行可能プログラム向けのコード構成オブジェクトを定義します。たとえば、Windows プラットフォーム上のダイナミック リンク ライブラリの構成オブジェクトを定義します。

    cfg = coder.config('dll');
  3. BLAS コールバック クラス useMyBLAS を指定します。

    cfg.CustomBLASCallback = 'useMyBLAS';

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

  4. コードを生成します。入力 AB が 1000 行 1000 列の double の配列であることを指定します。

    codegen myMultiply -args {zeros(1000),zeros(1000)} -config cfg -report

    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 サイト