生成されたスタンドアロン コードでの FFTW ライブラリ呼び出しを使用した高速フーリエ変換の高速化
次の例は、スタンドアロン コード (スタティック ライブラリ、ダイナミック リンク ライブラリまたは実行可能プログラム) を生成するときに、特定のインストールされた FFTW ライブラリへの呼び出しを生成する方法を示しています。FFTW の詳細については、www.fftw.org を参照してください。
高速フーリエ変換 (FFT) 関数を含む MATLAB® コードから MEX 関数を生成する場合、コード ジェネレーターは MATLAB が FFT アルゴリズムに使用するライブラリを使用します。スタンドアロン C/C++ コードを生成する場合、既定では、コード ジェネレーターは FFT ライブラリ呼び出しを生成するのではなく、FFT アルゴリズムのコードを生成します。生成されたスタンドアロン コードでの高速フーリエ変換を高速化するには、コード ジェネレーターが特定のインストール済み FFTW ライブラリを呼び出すように指定します。
次の条件のすべてが満たされている場合、コード ジェネレーターは FFTW ライブラリ呼び出しを作成します。
MATLAB コードが関数
fft
、fft2
、fftn
、ifft
、ifft2
またはifftn
のいずれかを呼び出している。スタンドアロン C/C++ コードを生成している。
FFTW ライブラリのインストール (Version 3.2 以上) にアクセスできる。
coder.fftw.StandaloneFFTW3Interface
から派生する FFT ライブラリ コールバック クラスで FFTW ライブラリ インストールを指定する。CustomFFTCallback
構成パラメーターをコールバック クラスの名前に設定している。MATLAB Coder™ アプリで、[カスタム FFT ライブラリのコールバック] 設定を使用します。
FFTW 計画の考慮事項
プラン メソッド coder.fftw.StandaloneFFTW3Interface.getPlanMethod
は、FFTW ライブラリのパフォーマンスを最適化するためのワークフローに従って設定する必要があります。ワークフローの必要に応じて、メソッドを次のいずれかの値に設定します。
FFTW_ESTIMATE
:これは既定の設定で、計画フェーズでの FFTW ライブラリによる検討を減らすことができます。この設定は、さまざまなサイズと型からなる複数の FFT がある場合に推奨されます。また、さまざまな型とサイズからなる複数の入力を使用する 1 つの FFT がワークフローに含まれる場合にも推奨されます。計画フェーズに要する時間を短縮できます。FFTW_MEASURE
:この設定では、FFTW ライブラリはワークフローにおける FFT アルゴリズムの使用を積極的に計画できます。この設定は、ワークフローで 1 つの FFT を同じサイズと型からなる複数の入力で実行する場合に推奨されます。計画時間が長くなる可能性がありますが、FFT の実行時間を短縮できます。
その他のプラン メソッド タイプの詳細については、https://www.fftw.org/fftw3_doc/Planner-Flags.htmlを参照してください。
同じサイズと型からなる複数の入力には以前に呼び出した FFT を使用することを検討してください。同じサイズと型からなる複数の入力に同じ FFT 演算を再利用すると、以前に呼び出された FFT のキャッシュされたバージョンがプランナーで使用されます。FFT の実行時間は入力のサイズによっても異なります。入力サイズが 2 のべき乗である FFT アルゴリズムの実行は、入力サイズが 2 のべき乗でない FFT 呼び出しよりも高速になります。https://www.fftw.org/fftw2_doc/fftw_3.htmlを参照してください。
FFTW ライブラリのインストール
Version 3.2 以上の FFTW ライブラリにアクセスできない場合はインストールしなければなりません。Linux® プラットフォームまたは Mac プラットフォームの場合、パッケージ マネージャーを使用した FFTW ライブラリのインストールを検討してください。Windows® プラットフォームの場合、FFTW Web サイトの Windows インストール メモで説明されているように .dll
ファイルに加えて .lib
インポート ライブラリが必要です。
FFTW Web サイトで、ご使用のプラットフォームに対応したインストール手順を参照してください。
FFT コールバック クラスの記述
FFTW ライブラリのインストールを指定するには、FFT コールバック クラスを記述します。スタンドアロン コードで FFTW 呼び出しに FFTW ライブラリを使用するユーザーと、このコールバック クラスを共有します。
コールバック クラスは抽象クラス coder.fftw.StandaloneFFTW3Interface
から派生しなければなりません。このコールバック クラスの例をテンプレートとして使用します。
% copyright 2017 The MathWorks, Inc. classdef useMyFFTW < coder.fftw.StandaloneFFTW3Interface methods (Static) function th = getNumThreads coder.inline('always'); th = int32(coder.const(1)); end function updateBuildInfo(buildInfo, ctx) fftwLocation = '/usr/lib/fftw'; includePath = fullfile(fftwLocation, 'include'); buildInfo.addIncludePaths(includePath); libPath = fullfile(fftwLocation, 'lib'); %Double libName1 = 'libfftw3-3'; [~, libExt] = ctx.getStdLibInfo(); libName1 = [libName1 libExt]; addLinkObjects(buildInfo, libName1, libPath, 1000, true, true); %Single libName2 = 'libfftw3f-3'; [~, libExt] = ctx.getStdLibInfo(); libName2 = [libName2 libExt]; addLinkObjects(buildInfo, libName2, libPath, 1000, true, true); end end end
updateBuildInfo
メソッドと getNumThreads
メソッドの実装。updateBuildInfo
メソッドでは、fftwLocation
をライブラリのインストールの絶対パスに設定します。includePath
を fftw3.h
を格納するフォルダーの絶対パスに設定します。libPath
をライブラリ ファイルが格納されるフォルダーの絶対パスに設定します。FFTW のインストールで複数のスレッドを使用する場合、使用するスレッド数を返すように getNumThreads
メソッドを変更します。
必要に応じて、次のメソッドを実装することができます。
getPlanMethod
(FFTW プラン メソッドを指定する)。coder.fftw.StandaloneFFTW3Interface
を参照してください。lock
およびunlock
(マルチスレッド アクセスを FFTW 計画プロセスと同期する)。生成されたスタンドアロン コードでのマルチスレッド アクセスの FFTW 計画との同期を参照してください。
FFT ライブラリ コールバック クラスの指定による FFTW ライブラリの呼び出しの生成
スタンドアロン C コードでの FFTW ライブラリの呼び出しを生成するには、次を行います。
MATLAB 高速フーリエ変換関数を呼び出す MATLAB 関数を記述します。たとえば、MATLAB 関数
fft
を呼び出す関数myfft
を記述します。function y = myfft() %#codegen t = 0:1/50:10-1/50; x = sin(2*pi*15*t) + sin(2*pi*20*t); y = fft(x); end
スタティック ライブラリ、ダイナミック リンク ライブラリまたは実行可能プログラム向けのコード生成構成オブジェクトを定義します。たとえば、ダイナミック リンク ライブラリの構成オブジェクトを定義します。
cfg = coder.config('dll');
FFTW コールバック クラス
useMyFFTW
を指定します。cfg.CustomFFTCallback = 'useMyFFTW';
コールバック クラスは MATLAB パス上になければなりません。
コードを生成します。
codegen myfft -config cfg -report
実行環境での FFTW ライブラリの検索
実行環境で FFTW ライブラリを利用できなければなりません。FFTW ライブラリが共有されている場合、環境変数またはリンカー オプションを使用して FFTW ライブラリの場所を指定します。
Windows プラットフォームでは、PATH 環境変数を編集します。
Linux プラットフォームでは、LD_LIBRARY_PATH 環境変数を修正するか、
rpath
リンカー オプションを使用します。macOS プラットフォームでは、DYLD_LIBRARY_PATH 環境変数を修正するか、
rpath
リンカー オプションを使用します。
rpath
リンカー オプションを指定するには、coder.fftw.StandaloneFFTW3Interface
クラスの updateBuildInfo
メソッド内のビルド情報 addLinkFlags
メソッドを使用します。たとえば、GCC コンパイラの場合、次のようになります。
buildInfo.addLinkFlags(sprintf('-Wl,-rpath,"%s"',libPath));
FFTW ライブラリ関数によって使用されるメモリのクリーンアップ
呼び出しプロセスがまだ実行されているときに FFTW ライブラリ関数が使用するメモリをクリーンアップするには、生成されたコードを独自のプロジェクトに取り込み、生成されたコードの実行後にクリーンアップ関数を手動で呼び出す必要があります。対照的に、呼び出しプロセスが終了した場合は、FFTW ライブラリ関数が自動的にメモリを解放するため、これらのクリーンアップ関数を呼び出す必要はありません。
使用可能なクリーンアップ関数は次のとおりです。
fftw_cleanup
fftwf_cleanup
fftw_cleanup_threads
fftwf_cleanup_threads
次のルールに従って、使用するクリーンアップ関数を決定します。
FFT 関数の呼び出しで単精度浮動小数点数を使用する場合は、
fftwf
という接頭辞が付いたクリーンアップ関数を使用します。FFT 関数の呼び出しで倍精度浮動小数点数を使用する場合は、
fftw
という接頭辞が付いたクリーンアップ関数を使用します。coder.fftw.StandaloneFFTW3Interface.getNumThreads
メソッドの実装が1
より大きい値を返す場合は、接尾辞threads
が付いているクリーンアップ関数を使用します。
参考
coder.fftw.StandaloneFFTW3Interface