示例#1
0
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.");
}
示例#2
0
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;


}