int Lucas::fft_setup (int length) { clAmdFftSetupData fftSetupData; OPENCL_V_THROW(clAmdFftInitSetupData (&fftSetupData),"Failed to clAmdFftInitSetupData."); fftSetupData.debugFlags = CLFFT_DUMP_PROGRAMS; // Dumps the FFT kernels // Setup the AMD FFT library. OPENCL_V_THROW(clAmdFftSetup (&fftSetupData),"Failed to clAmdFftSetup."); // Create FFT Plan const size_t logicalDimensions[1] = { length }; // Create default plan. OPENCL_V_THROW(clAmdFftCreateDefaultPlan(&plan, context(), CLFFT_1D, logicalDimensions),"Failed to clAmdFftCreateDefaultPlan."); // Set double precision. OPENCL_V_THROW(clAmdFftSetPlanPrecision(plan, CLFFT_DOUBLE),"Failed to clAmdFftSetPlanPrecision."); // Set layout. OPENCL_V_THROW(clAmdFftSetLayout(plan, CLFFT_COMPLEX_INTERLEAVED,CLFFT_COMPLEX_INTERLEAVED),"Failed to clAmdFftSetLayout."); // Normalize forward transformation. OPENCL_V_THROW(clAmdFftSetPlanScale(plan, CLFFT_FORWARD, 1.0f/static_cast<cl_float>(length)),"Failed to clAmdFftSetPlanScale."); // Normalize backward transformation. OPENCL_V_THROW(clAmdFftSetPlanScale(plan, CLFFT_BACKWARD, 1.0f),"Failed to clAmdFftSetPlanScale."); // In-place FFT. OPENCL_V_THROW(clAmdFftSetResultLocation(plan, CLFFT_INPLACE),"Failed to clAmdFftSetResultLocation."); // Set number of transformations per plan. OPENCL_V_THROW(clAmdFftSetPlanBatchSize(plan, 1),"Failed to clAmdFftSetPlanBatchSize."); // BakePlan OPENCL_V_THROW(clAmdFftBakePlan(plan, 1, &commandQueue(), NULL, NULL),"Failed to clAmdFftBakePlan."); }
clAmdFftPlanHandle CreateFFTPlan(clLabviewDevice *d, int FFTType, int Dimension, int Width, int Height, int Depth, int StrideW, int StrideH, int StrideD, int StrideT, int PaddingW, int PaddingH, int PaddingD, size_t *OutputWidthFloat, int SingleOrDouble, int *Error){ clAmdFftPlanHandle plHandle = 0; #ifndef NO_OPENCL *Error = clLabviewDevice::Error(clLabviewDevice::SanitizeDevice(d)); if(*Error != 0) return NULL; clAmdFftResultLocation place = CLFFT_OUTOFPLACE; //INPLACE NOT SUPPORTED size_t clStridesIn[ 4 ]; size_t clStridesOut[ 4 ]; clAmdFftLayout inLayout; clAmdFftLayout outLayout; size_t batchSize; clAmdFftDim dim; size_t clLengths[ 3 ]; clAmdFftStatus status; int DistanceIn, DistanceOut; int OutputWidth; int FFTSize; if(FFTType == 1){ //Needed to the FFT does the proper size on the inverse FFTSize = (Width - 1)*2; }else{ FFTSize = Width; } switch(Dimension){ case 0: //1D FFT batchSize = Depth*Height; dim = CLFFT_1D; clLengths[0] = FFTSize; clLengths[1] = 1; clLengths[2] = 1; break; case 1: //2D FFT batchSize = Depth; dim = CLFFT_2D; clLengths[0] = FFTSize; clLengths[1] = Height; clLengths[2] = 1; break; case 2: //3D FFT batchSize = 1; dim = CLFFT_3D; clLengths[0] = FFTSize; clLengths[1] = Height; clLengths[2] = Depth; break; } switch(FFTType){ //These cases are defined by the labview Type Def case 0: inLayout = CLFFT_REAL; outLayout = CLFFT_HERMITIAN_PLANAR; //*BufferSize = clLengths[2]*clLengths[1]*(clLengths[0]/2 + 1)*batchSize*sizeof(std::complex<float>)/sizeof(float); OutputWidth = FFTSize/2 + 1; *OutputWidthFloat = OutputWidth; DistanceIn = Width*clLengths[1]*clLengths[2]; DistanceOut = OutputWidth*clLengths[1]*clLengths[2]; break; case 1: inLayout = CLFFT_HERMITIAN_PLANAR; outLayout = CLFFT_REAL; //*BufferSize = clLengths[2]*clLengths[1]*(clLengths[0] - 1)*2*batchSize; OutputWidth = FFTSize; *OutputWidthFloat = OutputWidth; DistanceIn = Width*clLengths[1]*clLengths[2]; DistanceOut = OutputWidth*clLengths[1]*clLengths[2]; break; case 2: inLayout = CLFFT_COMPLEX_PLANAR; outLayout = CLFFT_COMPLEX_PLANAR; //*BufferSize = clLengths[2]*clLengths[1]*(clLengths[0])*batchSize*sizeof(std::complex<float>)/sizeof(float); OutputWidth = FFTSize; *OutputWidthFloat = OutputWidth; DistanceIn = Width*clLengths[1]*clLengths[2]; DistanceOut = OutputWidth*clLengths[1]*clLengths[2]; place = CLFFT_INPLACE; break; } size_t fftVectorSize= 0, fftVectorSizePadded = 0, fftBatchSize = 0; clStridesIn[0] = 1; clStridesIn[ 1 ] = (clStridesIn[ 0 ])*(Width + PaddingW); clStridesIn[ 2 ] = (clStridesIn[ 1 ])*(clLengths[ 1 ] + PaddingH); clStridesIn[ 3 ] = (clStridesIn[ 2 ])*(clLengths[ 2 ] + PaddingD); clStridesOut[0] = 1; clStridesOut[ 1 ] = (clStridesOut[ 0 ])*(OutputWidth + PaddingW); clStridesOut[ 2 ] = (clStridesOut[ 1 ])*(clLengths[ 1 ] + PaddingH); clStridesOut[ 3 ] = (clStridesOut[ 2 ])*(clLengths[ 2 ] + PaddingD); fftVectorSize = clLengths[ 0 ] * clLengths[ 1 ] * clLengths[ 2 ]; fftVectorSizePadded = clStridesIn[ 3 ]; fftBatchSize = fftVectorSizePadded * batchSize; status = clAmdFftCreateDefaultPlan( &plHandle, d->GetContext(), dim, clLengths ); if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_DEFAULT_PLAN_FAILED); return NULL; } status = clAmdFftSetResultLocation( plHandle, place ); if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_SET_RESULT_FAILED); return NULL; } status = clAmdFftSetLayout( plHandle, inLayout, outLayout ); if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_SET_LAYOUT_FAILED); return NULL; } if(SingleOrDouble == 0){ status = clAmdFftSetPlanPrecision(plHandle, CLFFT_SINGLE); }else{ status = clAmdFftSetPlanPrecision(plHandle, CLFFT_DOUBLE); } if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_SET_PRECISION_FAILED); return NULL; } status = clAmdFftSetPlanBatchSize( plHandle, batchSize ); if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_SET_BATCHSIZE_FAILED); return NULL; } status = clAmdFftSetPlanInStride ( plHandle, dim, clStridesIn ); if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_SET_STRIDES_IN_FAILED); return NULL; } status = clAmdFftSetPlanOutStride ( plHandle, dim, clStridesOut ); if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_SET_STRIDES_OUT_FAILED); return NULL; } status = clAmdFftSetPlanDistance ( plHandle, DistanceIn, DistanceOut); if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_SET_PLAN_DIST_FAILED); return NULL; } status = clAmdFftBakePlan( plHandle, 0, d->GetQueuePtr(), NULL, NULL ); if(status != 0){ *Error = clLabviewDevice::Error(OPENCLV_FFT_BAKE_PLAN_FAILED); return NULL; } #endif return plHandle; }