3

FFTW / CUFFT (同様の API を持っています) を使用して、多次元配列の特定の軸に対して fft を実行する効率的な方法はありますか?

形状 (2, 3, 4) の 3D 配列があるとします。ストライドは (12, 4, 1) です。つまり、最後の軸に沿って 1 単位移動するには、フラット配列で 1 単位移動しますが、最初の軸に沿って 1 単位移動するには、ステップ オーバーする必要があります。 3 * 4 = 12 単位。(配列は、軸が転置されたときに他のストライドを持つことができるnumpy ndarrayですが、与えられたストライドでこの特定の3Dケースだけに対処する答えに満足しています)

ここで、中央の軸に沿って1D fftを計算したいとしましょう。CUFFT は次の関数を公開します。

cufftResult cufftPlanMany(
    cufftHandle *plan,        // Plan to be initialized
    int rank,                 // Rank = 1 for 1D fft
    int *n,                   // shape of the fft = 3
    int *inembed,
    int istride,
    int idist,
    int *onembed,
    int ostride,
    int odist,
    cufftType type,           // e.g. 64 bit float to 128 bit complex
    int batch                 // Could use batch = 2 for the first axis
);

変換を行うには、、、パラメーターが必要nembedだと思います。それらはここに文書化されています: http://docs.nvidia.com/cuda/cufft/index.html#advanced-data-layoutstridedist

デュメンテーションは、1D fft の場合、位置 x のバッチ b の要素が次から取得されることを示しています。 input[b * idist + x * istride]

ただし、位置 [b][x][z] の要素は次の場所に格納されます。

input[b * 12 + x * 4 + z]

そのため、CUFFT を 3 番目 (z) 軸でループさせる方法が明確ではありません。

私が設定した場合:

  • idist と odist を 3*4=12 にします (b をインクリメントすると、最初の軸に沿って移動します)。
  • istride と ostride を 4 にします (x の増分は、fft したい軸である 2 番目の軸に沿って移動します)。
  • バッチ = 2
  • inembed と onembed を 3 に (ただし、ドキュメントによると、これらは 1D 変換では無視されます)

次に、最後の軸インデックスが 0 である 2 つのバッチのそれぞれについて正しい fft を計算しますが、最後のインデックスが 1、2、または 3 であるサブ配列はそのままにします。

これは一般的なユースケースのように思えますが、複数の呼び出し (GPU ではコストがかかります) を実行したり、異なるメモリ レイアウトでコピーを作成したりせずに、指定されたパラメーターでこれを行う方法を理解できないようです。

4

0 に答える 0