Main Content

生成されたスタンドアロン コードでの FFTW ライブラリ呼び出しを使用した高速フーリエ変換の高速化

次の例は、スタンドアロン コード (スタティック ライブラリ、ダイナミック リンク ライブラリまたは実行可能プログラム) を生成するときに、特定のインストールされた FFTW ライブラリへの呼び出しを生成する方法を示しています。FFTW の詳細については、www.fftw.org を参照してください。

高速フーリエ変換 (FFT) 関数を含む MATLAB® コードから MEX 関数を生成する場合、コード ジェネレーターは MATLAB が FFT アルゴリズムに使用するライブラリを使用します。スタンドアロン C/C++ コードを生成する場合、既定では、コード ジェネレーターは FFT ライブラリ呼び出しを生成するのではなく、FFT アルゴリズムのコードを生成します。生成されたスタンドアロン コードでの高速フーリエ変換を高速化するには、コード ジェネレーターが特定のインストール済み FFTW ライブラリを呼び出すように指定します。

次の条件のすべてが満たされている場合、コード ジェネレーターは FFTW ライブラリ呼び出しを作成します。

  • MATLAB コードが関数 fftfft2fftnifftifft2 または 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 をライブラリのインストールの絶対パスに設定します。includePathfftw3.h を格納するフォルダーの絶対パスに設定します。libPath をライブラリ ファイルが格納されるフォルダーの絶対パスに設定します。FFTW のインストールで複数のスレッドを使用する場合、使用するスレッド数を返すように getNumThreads メソッドを変更します。

必要に応じて、次のメソッドを実装することができます。

FFT ライブラリ コールバック クラスの指定による FFTW ライブラリの呼び出しの生成

スタンドアロン C コードでの FFTW ライブラリの呼び出しを生成するには、次を行います。

  1. 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

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

    cfg = coder.config('dll');

  3. FFTW コールバック クラス useMyFFTW を指定します。

    cfg.CustomFFTCallback = 'useMyFFTW';

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

  4. コードを生成します。

    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 が付いているクリーンアップ関数を使用します。

参考

関連するトピック

外部の Web サイト