2014-09-01 13 views
0
내가 들었

의의 FFT를 일괄/우리는 약간의 m 벡터 각각의 수행 일부 N의 FFT이있는 경우 우리가 cuFFT의 배치 모드를 사용할 수 있음을 읽어 보시기 바랍니다. 그래서 그것을 테스트하기 위해 샘플 프로그램을 만들고 실행했습니다. 내가 사용한 데이터는 1024 부동 소수점 숫자가 같은 1024 숫자가 10 번 반복 된 파일이었습니다. 1024 포인트 FFT에 대해 동일한 결과를 얻어야하지만, 나는 그것을 얻지 못하고있다. 개념적으로 어딘가에 문제가 있다면 저를 바로 잡으십시오. 그리고 제가 만든 오류를 바로 잡을 수 있다면 코드가 아래에 있습니다.1D 실제 배열

참고 : 1D FFT로만 작업하고 있습니다. 여기

는 코드입니다 : 로버트 Crovella에서 언급 한 바와 같이

#include <cuda.h> 
#include <cufft.h> 
#include <stdio.h> 
#include <math.h> 

#define NX 1024 
#define DATASIZE 1024 
#define BATCH 10 

int main (int argc, char* argv[]) 
{ 
     cufftHandle plan; 
     cufftComplex *deviceOutputData, *hostOutputData; 
     cufftReal *hostInputData, *deviceInputData; 
     int i,j; 

     FILE *in; // *out, *fp; 

     cudaMalloc ((void**)&deviceInputData, NX*BATCH*sizeof(cufftReal)); 
     hostInputData = (cufftReal*) malloc (NX*BATCH*sizeof(cufftReal)); 

     cudaMalloc ((void**)&deviceOutputData, NX*BATCH*sizeof(cufftComplex)); 
     hostOutputData = (cufftComplex*) malloc (NX*BATCH*sizeof(cufftComplex)); 

     in = fopen ("InFile.txt", "r"); 

     if (in==NULL) 
     {  fprintf (stderr, "Input file has some issues. Please check."); exit(1);} 

     float data; 
     //Allocate data 

for (i=0; i<BATCH; i++){ 
       for (j=0; j<DATASIZE;j++) 
       { 
         fscanf(in, "%f", &data); 
         hostInputData [j + i*DATASIZE] = data; 
       } 
     } 
     fclose (in); 
     cudaMemcpy (deviceInputData, hostInputData, DATASIZE*BATCH*sizeof(cufftReal), cudaMemcpyHostToDevice); 
     cufftPlan1d (&plan, NX, CUFFT_R2C, BATCH); 
     cufftExecR2C (plan, deviceInputData, deviceOutputData); 
     cudaThreadSynchronize(); 
     cudaMemcpy (hostOutputData, deviceOutputData, DATASIZE*BATCH*sizeof(cufftComplex), cudaMemcpyDeviceToHost); 
     cufftDestroy (plan); 
     cudaFree (deviceOutputData); 
     cudaFree (deviceInputData); 

     #define a hostOutputData[j+i*NX].x 
     #define b hostOutputData[j+i*NX].y 
     float result[NX]; 
     for (i=0; i<BATCH; i++){ 
       printf ("\n*New Batch*\n"); 
       for (j=0; j<=NX/2;j++){ 
         result[j] = sqrt ((a*a)+(b*b)); 
         printf ("%f\n", result[j]); 
       } 

       for (j=1; j<NX/2; j++){ 
         result[j+(NX/2)] = result [(NX/2)-j]; 
         printf ("%f\n", result[j+(NX/2)]); 
       } 
     } 
+0

안녕하세요 @RobertCrovella 선생님, 코드의 일부를 삽입했습니다. 그 부분이 해석하기에 충분하다고 생각했기 때문입니다. 어쨌든, 나는 코드 스 니펫을 수정했다. Jack의 코드로 나를 추천 해 주셔서 감사합니다 :) –

+0

cudaPlanMany()의 hlep로 배치 모드를 실행할 수 있습니다. 고마워요 @ 로버트 크로 베라. –

답변

2

하고 cuFFT 사용 설명서에보고 - CUDA 6.5,

일괄왔다 cufftPlan1d() 1 이외의 다른 크기 더 이상 사용되지 않습니다. 다중 배치 실행에는 cufftPlanMany()을 사용하십시오.

아래 코드는 cufftPlan1d() 대신 cufftPlanMany()을 사용하고 있습니다. 당신이 볼 때,

int rank = 1;       // --- 1D FFTs 
int n[] = { DATASIZE };     // --- Size of the Fourier transform 
int istride = 1, ostride = 1;   // --- Distance between two successive input/output elements 
int idist = DATASIZE, odist = (DATASIZE/2 + 1); // --- Distance between batches 
int inembed[] = { 0 };     // --- Input size with pitch (ignored for 1D transforms) 
int onembed[] = { 0 };     // --- Output size with pitch (ignored for 1D transforms) 
int batch = BATCH;      // --- Number of batched executions 
cufftPlanMany(&handle, rank, n, 
       inembed, istride, idist, 
       onembed, ostride, odist, CUFFT_R2C, batch); 

cufftPlan1d(&handle, DATASIZE, CUFFT_R2C, BATCH); 

이 예제는 사실을 고려하지 않는 것을주의 할은 "구식"에 완전히 동일합니다 그 길이 DATASIZEcufftReal 배열의 1D FFT DATASIZE/2 + 1 요소의 cufftComplex 배열입니다.

#include <cuda.h> 
#include <cufft.h> 
#include <stdio.h> 
#include <math.h> 

#define DATASIZE 8 
#define BATCH 2 

/********************/ 
/* CUDA ERROR CHECK */ 
/********************/ 
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } 
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) 
{ 
    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); 
     if (abort) exit(code); 
    } 
} 

/********/ 
/* MAIN */ 
/********/ 
int main() 
{ 
    // --- Host side input data allocation and initialization 
    cufftReal *hostInputData = (cufftReal*)malloc(DATASIZE*BATCH*sizeof(cufftReal)); 
    for (int i=0; i<BATCH; i++) 
     for (int j=0; j<DATASIZE; j++) hostInputData[i*DATASIZE + j] = (cufftReal)(i + 1); 

    // --- Device side input data allocation and initialization 
    cufftReal *deviceInputData; gpuErrchk(cudaMalloc((void**)&deviceInputData, DATASIZE * BATCH * sizeof(cufftReal))); 
    cudaMemcpy(deviceInputData, hostInputData, DATASIZE * BATCH * sizeof(cufftReal), cudaMemcpyHostToDevice); 

    // --- Host side output data allocation 
    cufftComplex *hostOutputData = (cufftComplex*)malloc((DATASIZE/2 + 1) * BATCH * sizeof(cufftComplex)); 

    // --- Device side output data allocation 
    cufftComplex *deviceOutputData; gpuErrchk(cudaMalloc((void**)&deviceOutputData, (DATASIZE/2 + 1) * BATCH * sizeof(cufftComplex))); 

    // --- Batched 1D FFTs 
    cufftHandle handle; 
    int rank = 1;       // --- 1D FFTs 
    int n[] = { DATASIZE };     // --- Size of the Fourier transform 
    int istride = 1, ostride = 1;   // --- Distance between two successive input/output elements 
    int idist = DATASIZE, odist = (DATASIZE/2 + 1); // --- Distance between batches 
    int inembed[] = { 0 };     // --- Input size with pitch (ignored for 1D transforms) 
    int onembed[] = { 0 };     // --- Output size with pitch (ignored for 1D transforms) 
    int batch = BATCH;      // --- Number of batched executions 
    cufftPlanMany(&handle, rank, n, 
        inembed, istride, idist, 
        onembed, ostride, odist, CUFFT_R2C, batch); 

    //cufftPlan1d(&handle, DATASIZE, CUFFT_R2C, BATCH); 
    cufftExecR2C(handle, deviceInputData, deviceOutputData); 

    // --- Device->Host copy of the results 
    gpuErrchk(cudaMemcpy(hostOutputData, deviceOutputData, (DATASIZE/2 + 1) * BATCH * sizeof(cufftComplex), cudaMemcpyDeviceToHost)); 

    for (int i=0; i<BATCH; i++) 
     for (int j=0; j<(DATASIZE/2 + 1); j++) 
      printf("%i %i %f %f\n", i, j, hostOutputData[i*(DATASIZE/2 + 1) + j].x, hostOutputData[i*(DATASIZE/2 + 1) + j].y); 

    cufftDestroy(handle); 
    gpuErrchk(cudaFree(deviceOutputData)); 
    gpuErrchk(cudaFree(deviceInputData)); 

} 

, 자신의 cuFFT 오류가 CUFFT error handling에 따라 검사를 추가하십시오 :

다음은 전체 예제입니다.