3 PowerSpectrum<T>::PowerSpectrum() {
6 std::string kernel_str = R"END(
7 __kernel void PowerSpectrum( __global TYPE* input, __global TYPE* scratch, const unsigned int signal_size )
10 int i = get_global_id(0);
11 //Do not use sqrt(), you -will- get round-off errors for large FFT sizes
12 scratch[i] = input[2*i]*input[2*i] + input[2*i+1]*input[2*i+1];
13 //Normalize by number of elements
14 scratch[i] /= (TYPE)signal_size * (TYPE)signal_size;
19 std::string kernel_name = "PowerSpectrum";
21 // std::string source_directory = SOURCE_DIR;
22 // std::string kernel_name = "/powerspectrum.cl";
24 // FFT<T>::kernel_path = source_directory + kernel_name;
26 // TaskItem::LoadCLKernel< typename T::value_type >( "PowerSpectrum" );
28 TaskItem::LoadCLKernel<typename T::value_type>( kernel_str, kernel_name );
32 void PowerSpectrum<T>::Trigger() {
35 //Since this is a two-step process we need to explictly call CommandQueue::finish() between steps
36 TaskItem::command_queue.finish();
38 FFT<T>::err = TaskItem::command_queue.enqueueNDRangeKernel( TaskItem::kernel,cl::NullRange, cl::NDRange( TaskItem::signal_size ) );
39 OCL_DEBUG( FFT<T>::err );
40 TaskItem::command_queue.finish();
42 TaskItem::signal_size = (TaskItem::signal_size%2 == 0)?( TaskItem::signal_size/2 ):( (TaskItem::signal_size - 1)/2 );
47 void PowerSpectrum<T>::SetSignal( cl::Buffer& signal_buff, uint sig_size ) {
49 FFT<T>::err = TaskItem::kernel.setArg(0, signal_buff);
50 OCL_DEBUG( FFT<T>::err );
51 //std::cout << __func__ << "(setKernelArgs[0]) OpenCL Status: " << CLErrorToString( FFT<T>::err ) << std::endl;
53 TaskItem::signal_size = sig_size;
54 FFT<T>::local_buff = signal_buff;
56 size_t scratch_bytes = (sig_size%2 == 0)?( sizeof(typename T::value_type)*sig_size/2 ):( sizeof(typename T::value_type)*(sig_size - 1)/2 );
57 output_buff = cl::Buffer ( OpenCLBase::context, CL_MEM_READ_WRITE, scratch_bytes );
59 FFT<T>::err = TaskItem::kernel.setArg(1, output_buff);
60 OCL_DEBUG( FFT<T>::err );
62 FFT<T>::err = TaskItem::kernel.setArg(2, sig_size);
63 OCL_DEBUG( FFT<T>::err );
65 size_t clLengths[1] = { sig_size };
67 /* Create a default plan for a complex FFT. */
68 FFT<T>::err = clfftCreateDefaultPlan(&(FFT<T>::planHandle), OpenCLBase::context(), FFT<T>::dim, clLengths);
69 OCL_DEBUG( FFT<T>::err );
71 /* Set plan parameters. */
72 if ( boost::is_same< typename T::value_type, float>::value ) {
73 FFT<T>::err = clfftSetPlanPrecision(FFT<T>::planHandle, CLFFT_SINGLE);
75 FFT<T>::err = clfftSetPlanPrecision(FFT<T>::planHandle, CLFFT_DOUBLE);
78 OCL_DEBUG( FFT<T>::err );
80 FFT<T>::err = clfftSetLayout(FFT<T>::planHandle, CLFFT_REAL, CLFFT_HERMITIAN_INTERLEAVED );
81 OCL_DEBUG( FFT<T>::err );
83 FFT<T>::err = clfftSetResultLocation(FFT<T>::planHandle, CLFFT_INPLACE);
84 OCL_DEBUG( FFT<T>::err );
87 FFT<T>::err = clfftBakePlan(FFT<T>::planHandle, 1, &OpenCLBase::command_queue(), NULL, NULL);
92 cl::Buffer& PowerSpectrum<T>::ProcessedSignal() {
97 size_t PowerSpectrum<T>::ProcessedSignalBytes() {
98 return TaskItem::signal_size*sizeof( typename T::value_type );
101 template <typename T>
102 size_t PowerSpectrum<T>::ProcessedSignalSize() {
103 return TaskItem::signal_size;