生成されたスタンドアロン コードでの LAPACK 呼び出しを使用した線形代数の高速化
スタンドアロン コード (ライブラリまたは実行可能プログラム) で特定の線形代数関数に対して生成されたコードの実行速度を向上させるために、MATLAB® Coder™ が LAPACK 呼び出しを生成するように指定します。LAPACK は数値的線形代数のソフトウェア ライブラリです。MATLAB Coder は LAPACK への LAPACKE C インターフェイスを使用します。LAPACK 呼び出しを生成すると指定し、線形代数関数の入力配列が特定の基準を満たす場合、コード ジェネレーターは LAPACK 呼び出しを生成します。それ以外の場合は、コード ジェネレーターは線形代数関数のコードを生成します。
スタンドアロン コードでの LAPACK 呼び出しの場合、MATLAB Coder は指定の LAPACK ライブラリを使用します。実行環境に合わせて最適化された LAPACK ライブラリを指定します。https://netlib.org/lapack/faq.html#_what_and_where_are_the_lapack_vendors_implementationsを参照してください。
MathWorks® では、さまざまなプラットフォーム向けの BLAS と LAPACK の一連のコールバック クラスを提供しています。これらのコールバック クラスは、この GitHub リポジトリからダウンロードできます。
これらのコールバックを使用してコードを生成する方法の詳細については、Speed Up of Standalone Generated Code Using Preconfigured BLAS and LAPACK Callbacksを参照してください。
LAPACK ライブラリの指定
スタンドアロン コードで LAPACK 呼び出しを生成するには、LAPACK コールバック クラスにアクセスできなければなりません。LAPACK コールバック クラスは、LAPACK 呼び出しの LAPACK ライブラリと LAPACKE ヘッダー ファイルを指定します。LAPACK 呼び出しを生成して、特定の LAPACK ライブラリを使用することを示すには、LAPACK コールバック クラスの名前を指定します。
コマンド ラインで、コード構成オブジェクトのプロパティ
CustomLAPACKCallbackをコールバック クラスの名前に設定します。MATLAB Coder アプリで、[カスタム LAPACK ライブラリのコールバック] をコールバック クラスの名前に設定します。
LAPACK コールバック クラスの記述
特定の LAPACK ライブラリと LAPACKE ヘッダー ファイルの場所を指定するには、LAPACK コールバック クラスを記述します。スタンドアロン コードで LAPACK 呼び出しに LAPACK ライブラリを使用するユーザーと、このコールバック クラスを共有します。
コールバック クラスは抽象クラス coder.LAPACKCallback から派生しなければなりません。次のコールバック クラスの例をテンプレートとして使用してください。
classdef useMyLAPACK < coder.LAPACKCallback methods (Static) function hn = getHeaderFilename() hn = 'mylapacke_custom.h'; end function updateBuildInfo(buildInfo, buildctx) buildInfo.addIncludePaths(fullfile(pwd,'include')); libName = 'mylapack'; libPath = fullfile(pwd,'lib'); [~,linkLibExt] = buildctx.getStdLibInfo(); buildInfo.addLinkObjects([libName linkLibExt], libPath, ... '', true, true); buildInfo.addDefines('HAVE_LAPACK_CONFIG_H'); buildInfo.addDefines('LAPACK_COMPLEX_STRUCTURE'); buildInfo.addDefines('LAPACK_ILP64'); end end end
getHeaderFilename および updateBuildInfo メソッドを指定しなければなりません。getHeaderFilename メソッドは LAPACKE ヘッダー ファイル名を返します。コールバック クラスの例では、mylapacke_custom.h を使用する LAPACKE ヘッダー ファイルの名前に置き換えます。updateBuildInfo メソッドは LAPACK ライブラリにリンクするビルド プロセスに必要な情報を提供します。テンプレートにあるコードと同様のコードを使用して、ヘッダー ファイルの場所と LAPACK ライブラリの絶対パス名を指定します。コールバック クラスの例では、mylapack を使用する LAPACK ライブラリの名前に置き換えます。
コンパイラが構造体として表される複素数データ型のみをサポートしている場合は、updateBuildInfo メソッドに次の行を含めます。
buildInfo.addDefines('HAVE_LAPACK_CONFIG_H'); buildInfo.addDefines('LAPACK_COMPLEX_STRUCTURE');
LAPACK ライブラリで使用される整数型を指定しなければなりません。この整数型を指定しないと、結果として不正確な動作やクラッシュが生じる可能性があります。次のいずれかを行います。
updateBuildInfoメソッドに次の行を含めます。buildInfo.addDefines('HAVE_LAPACK_CONFIG_H'); buildInfo.addDefines('LAPACK_ILP64');
あるいは、LAPACK ライブラリで使用される整数型を直接指定することもできます。たとえば、整数型が
long longの場合、updateBuildInfoメソッドに次の行を含めます。buildInfo.addDefines('lapack_int=long long');
LAPACK コールバック クラスを指定した LAPACK 呼び出しの生成
この例では、特定の LAPACK ライブラリの LAPACK 関数を呼び出すコードを生成する方法を示します。この例では、LAPACK コールバック クラス useMyLAPACK で使用する LAPACK ライブラリを指定すると仮定します。
線形代数関数を呼び出す MATLAB 関数を記述します。たとえば、MATLAB 関数
svdを呼び出す関数mysvdを記述します。function s = mysvd(A) %#codegen s = svd(A); end
スタティック ライブラリ、ダイナミック リンク ライブラリまたは実行可能プログラム向けのコード構成オブジェクトを定義します。たとえば、Windows® プラットフォーム上のダイナミック リンク ライブラリの構成オブジェクトを定義します。
cfg = coder.config('dll');LAPACK コールバック クラス
useMyLAPACKを指定します。cfg.CustomLAPACKCallback = 'useMyLAPACK';コールバック クラスは MATLAB パス上になければなりません。
コードを生成します。入力
Aには 500 行 500 列の double の配列を指定します。codegen mysvd -args {zeros(500)} -config cfg -report
A が十分に大きい場合、コード ジェネレーターは svd の LAPACK 呼び出しを生成します。次に、svd の LAPACK ライブラリ関数の呼び出しの例を示します。
info_t = LAPACKE_dgesvd(LAPACK_COL_MAJOR, 'N', 'N', (lapack_int)500,
(lapack_int)500, &A[0], (lapack_int)500, &S[0], NULL, (lapack_int)1, NULL,
(lapack_int)1, &superb[0]);実行環境での LAPACK ライブラリの場所指定
実行環境で LAPACK ライブラリを利用できなければなりません。LAPACK ライブラリが共有されている場合、環境変数またはリンカー オプションを使用して LAPACK ライブラリの場所を指定します。
Windows プラットフォームでは、PATH 環境変数を編集します。
Linux® プラットフォームでは、LD_LIBRARY_PATH 環境変数を修正するか、
rpathリンカー オプションを使用します。macOS プラットフォームでは、DYLD_LIBRARY_PATH 環境変数を修正するか、
rpathリンカー オプションを使用します。
rpath リンカー オプションを指定するには、coder.LAPACKCallback クラスの updateBuildInfo メソッド内のビルド情報 addLinkFlags メソッドを使用します。たとえば、GCC コンパイラの場合、次のようになります。
buildInfo.addLinkFlags(sprintf('-Wl,-rpath,"%s"',libPath));