0

cuda fft(R2C)の結果であるcufftcomplexデータブロックがあります。データは、実数の後に画像番号が続く構造として保存されることを知っています。今、私は各複雑な要素の振幅= sqrt(R * R + I * I)、および位相= arctan(I / R)を高速な方法で(ループではなく)取得したいと考えています。それを行う良い方法はありますか?または任意のライブラリがそれを行うことができますか?

4

1 に答える 1

3

GPU 上のデータを操作するためcufftExecR2C、結果は既に GPU 上にあります (ホストにコピーする前に、そうしている場合)。

これを実現するために独自の cuda カーネルを作成するのは簡単です。あなたが説明している振幅は、cuCabsまたはヘッダーファイルcuCabsfで返される値です。cuComplex.hそのヘッダー ファイル内の関数を見ることで、位相角を計算する独自の関数を作成する方法を理解できるはずです。の typedef にすぎないcufftComplexことに注意してください。 cuComplex

あなたの cufftExecR2C 呼び出しが type のいくつかの結果をsize のcufftComplex配列に残したとしましょう。カーネルは次のようになります。datasz

#include <math.h>
#include <cuComplex.h>
#include <cufft.h>
#define nTPB 256    // threads per block for kernel
#define sz 100000   // or whatever your output data size is from the FFT
...

__host__ __device__ float carg(const cuComplex& z) {return atan2(cuCimagf(z), cuCrealf(z));} // polar angle

__global__ void magphase(cufftComplex *data, float *mag, float *phase, int dsz){
  int idx = threadIdx.x + blockDim.x*blockIdx.x;
  if (idx < dsz){
    mag[idx]   = cuCabsf(data[idx]);
    phase[idx] = carg(data[idx]);
  }
}

...
int main(){
...
    /* Use the CUFFT plan to transform the signal in place. */
    /* Your code might be something like this already:      */
    if (cufftExecR2C(plan, (cufftReal*)data, data) != CUFFT_SUCCESS){
      fprintf(stderr, "CUFFT error: ExecR2C Forward failed");
      return;   
    }
    /* then you might add:                                  */
    float *h_mag, *h_phase, *d_mag, *d_phase;
    // malloc your h_ arrays using host malloc first, then...
    cudaMalloc((void **)&d_mag, sz*sizeof(float));
    cudaMalloc((void **)&d_phase, sz*sizeof(float));
    magphase<<<(sz+nTPB-1)/nTPB, nTPB>>>(data, d_mag, d_phase, sz);
    cudaMemcpy(h_mag, d_mag, sz*sizeof(float), cudaMemcpyDeviceToHost);
    cudaMemcpy(h_phase, d_phase, sz*sizeof(float), cudaMemcpyDeviceToHost);

これは、マグニチュード関数とフェーズ関数のファンクターを作成し、これらのファンクターを,およびthrow ::transformに渡すことで、推力を使用して行うこともできます。datamagphase

ベクトル加算演算とベクトル乗算演算の組み合わせを使用して、おそらくCUBLASでも同様に実行できると確信しています。

この質問/回答も興味深いかもしれません。そこからフェーズ機能を持ち上げcargました。

于 2013-08-29T14:18:03.737 に答える