2013-08-29 5 views
-1

나는 cuffacomplex 데이터 블록을 가지고 있는데 이것은 cuda fft (R2C)의 결과입니다. 나는 데이터가 실제 번호와 이미지 번호 뒤에 구조체로 저장된다는 것을 안다. 이제는 각 복잡한 요소의 진폭 = sqrt (R * R + I * I) 및 위상 = arctan (I/R)을 빠른 방법 (루프가 아님)으로 가져 오려고합니다. 거기에 좋은 방법이 있습니까? 또는 어떤 도서관이 그렇게 할 수 있습니까? cufftExecR2C 이후cufftcomplex 크기와 위상을 빨리 얻는 방법

+0

이것은 매우 명확하게 쓰여진 질문이 아닙니다. "나는 cofftcomplex | sic"블록 데이터가 무엇을 의미합니까? 이것은 공유 메모리에있는 어떤 데이터를 블록 스코프로 가지고 있고 위상과 크기를 계산하기위한 디바이스 기능을 원한다는 것을 의미합니까? 또는 다른 것? – talonmies

+0

죄송합니다. 이것은 cuda fft (R2C)의 결과 인 장치 메모리의 cufftcomplex 데이터 블록입니다. 위상과 크기를 계산하고 싶습니다. – jiangstonybrook

답변

1

는, 결과는 GPU에 이미있는 GPU에 데이터를 작동 (호스트로 다시 복사하기 전에 그 일을하는 경우.) 쓸 간단합니다

자신의 cuda 커널이이를 수행합니다. 설명하는 진폭은 cuCabs 또는 cuCabsf에 의해 반환 된 값이며 cuComplex.h 헤더 파일에 있습니다. 헤더 파일의 함수를 살펴보면 위상 각을 계산하는 자체 작성 방법을 이해할 수 있어야합니다. cufftComplexjust a typedef ofcuComplex입니다.

귀하의 cufftExecR2C 호출이 배열 datacufftComplex 유형의 결과를 남겼다고 가정 해 봅시다. 커널은 다음과 같습니다

#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); 

당신은 또한 크기와 위상 기능 펑터를 생성하고 thrust::transformdata, magphase와 함께이 펑를 전달하여이 사용 thrust을 할 수 있습니다.

벡터 덧셈 연산과 벡터 곱셈 연산의 조합을 사용하여 CUBLAS으로도 처리 할 수 ​​있습니다.

question/answer도 중요 할 수 있습니다. 나는 거기에서 나의 위상 기능 carg을 들었다.

+0

호기심. 실제 함수의 푸리에 변환은 허미 시안입니다. 이러한 simmetry를 이용하기 위해'cufftExecR2C' 함수는 출력 배열에 비 중복 푸리에 변환만을 저장합니다. 커널 시작 크기'sz'에서 이것을 설명해야합니까? 아마 – JackOLantern

+0

. 그것은 설명되지 않습니까? 어디에서 FFT의 입력 크기와 출력 크기 사이의 관계를 식별 할 수있는 커프 계획의 세부 사항을 지정하지 않았습니다. 간단히 말해서 "데이터"에 sz라는 크기의 결과가 남았습니다. 어떻게 말씀 하시겠습니까? '#define sz' 줄을 지워서 명확하게해야합니까? 내 대답을 자유롭게 편집하십시오. –

+0

정말 고맙습니다. 정말 도움이됩니다. – jiangstonybrook

관련 문제