2

次のような基本的な C++ FFTW 実装があります。

for (int i = 0; i < N; i++){
     // declare pointers and plan
     fftw_complex *in, *out;
     fftw_plan p;

     // allocate 
     in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
     out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);

     // initialize "in"
     ...

     // create plan
     p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);

     // execute plan
     fftw_execute(p);

     // clean up
     fftw_destroy_plan(p);
     fftw_free(in); fftw_free(out);
}

for ループで N fft を実行しています。FFTW で一度に多くのプランを実行できることはわかっていますが、私の実装ではループごとに inoutが異なります。ポイントは、FFTWパイプライン全体をforループの内側で実行していることです。

これを高速化するために CUDA の使用に移行したいと考えています。CUDA には独自の FFT ライブラリ CUFFT があることを理解しています。構文は非常に似ています:オンラインドキュメントから:

#define NX 64
#define NY 64
#define NZ 128

cufftHandle plan;
cufftComplex *data1, *data2;
cudaMalloc((void**)&data1, sizeof(cufftComplex)*NX*NY*NZ);
cudaMalloc((void**)&data2, sizeof(cufftComplex)*NX*NY*NZ);
/* Create a 3D FFT plan. */
cufftPlan3d(&plan, NX, NY, NZ, CUFFT_C2C);

/* Transform the first signal in place. */
cufftExecC2C(plan, data1, data1, CUFFT_FORWARD);

/* Transform the second signal using the same plan. */
cufftExecC2C(plan, data2, data2, CUFFT_FORWARD);

/* Destroy the cuFFT plan. */
cufftDestroy(plan);
cudaFree(data1); cudaFree(data2);

ただし、これらの「カーネル」(Nvida が呼ぶように) (cufftPlan3d、cufftExecC2C など) のそれぞれは、GPU との間の呼び出しです。CUDA 構造を正しく理解していれば、これらの各メソッド呼び出しは個別に並列化された操作です。

#define NX 64
#define NY 64
#define NZ 128

cufftHandle plan;
cufftComplex *data1, *data2;
cudaMalloc((void**)&data1, sizeof(cufftComplex)*NX*NY*NZ);
cudaMalloc((void**)&data2, sizeof(cufftComplex)*NX*NY*NZ);
/* Create a 3D FFT plan. */
cufftPlan3d(&plan, NX, NY, NZ, CUFFT_C2C); // DO THIS IN PARALLEL ON GPU, THEN COME BACK TO CPU

/* Transform the first signal in place. */
cufftExecC2C(plan, data1, data1, CUFFT_FORWARD); // DO THIS IN PARALLEL ON GPU, THEN COME BACK TO CPU

/* Transform the second signal using the same plan. */
cufftExecC2C(plan, data2, data2, CUFFT_FORWARD); // DO THIS IN PARALLEL ON GPU, THEN COME BACK TO CPU

/* Destroy the cuFFT plan. */
cufftDestroy(plan);
cudaFree(data1); cudaFree(data2);

GPU で各 FFT ステップを実行することにより、コードがどのように高速化されるかを理解しています。しかし、for ループ全体を並列化したい場合はどうすればよいでしょうか。元の N for ループのそれぞれで FFTW パイプライン全体を GPU で実行したい場合はどうすればよいですか? カスタム「カーネル」を作成して、デバイス (GPU) から FFTW メソッドを呼び出すことはできますか?

4

1 に答える 1