JASPL  0.2
Just Another Signal Processing Library
powerspectrum.tpp
1 
2 template<typename T>
3 PowerSpectrum<T>::PowerSpectrum() {
4 
5 
6  std::string kernel_str = R"END(
7  __kernel void PowerSpectrum( __global TYPE* input, __global TYPE* scratch, const unsigned int signal_size )
8  {
9 
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;
15 
16  }
17  )END";
18 
19  std::string kernel_name = "PowerSpectrum";
20 
21 // std::string source_directory = SOURCE_DIR;
22 // std::string kernel_name = "/powerspectrum.cl";
23 
24 // FFT<T>::kernel_path = source_directory + kernel_name;
25 
26 // TaskItem::LoadCLKernel< typename T::value_type >( "PowerSpectrum" );
27 
28  TaskItem::LoadCLKernel<typename T::value_type>( kernel_str, kernel_name );
29 }
30 
31 template<typename T>
32 void PowerSpectrum<T>::Trigger() {
33 
34  FFT<T>::Trigger();
35  //Since this is a two-step process we need to explictly call CommandQueue::finish() between steps
36  TaskItem::command_queue.finish();
37 
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();
41 
42  TaskItem::signal_size = (TaskItem::signal_size%2 == 0)?( TaskItem::signal_size/2 ):( (TaskItem::signal_size - 1)/2 );
43 
44 }
45 
46 template <typename T>
47 void PowerSpectrum<T>::SetSignal( cl::Buffer& signal_buff, uint sig_size ) {
48 
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;
52 
53  TaskItem::signal_size = sig_size;
54  FFT<T>::local_buff = signal_buff;
55 
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 );
58 
59  FFT<T>::err = TaskItem::kernel.setArg(1, output_buff);
60  OCL_DEBUG( FFT<T>::err );
61 
62  FFT<T>::err = TaskItem::kernel.setArg(2, sig_size);
63  OCL_DEBUG( FFT<T>::err );
64 
65  size_t clLengths[1] = { sig_size };
66 
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 );
70 
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);
74  } else {
75  FFT<T>::err = clfftSetPlanPrecision(FFT<T>::planHandle, CLFFT_DOUBLE);
76  }
77 
78  OCL_DEBUG( FFT<T>::err );
79 
80  FFT<T>::err = clfftSetLayout(FFT<T>::planHandle, CLFFT_REAL, CLFFT_HERMITIAN_INTERLEAVED );
81  OCL_DEBUG( FFT<T>::err );
82 
83  FFT<T>::err = clfftSetResultLocation(FFT<T>::planHandle, CLFFT_INPLACE);
84  OCL_DEBUG( FFT<T>::err );
85 
86  /* Bake the plan. */
87  FFT<T>::err = clfftBakePlan(FFT<T>::planHandle, 1, &OpenCLBase::command_queue(), NULL, NULL);
88 
89 }
90 
91 template <typename T>
92 cl::Buffer& PowerSpectrum<T>::ProcessedSignal() {
93  return output_buff;
94 }
95 
96 template <typename T>
97 size_t PowerSpectrum<T>::ProcessedSignalBytes() {
98  return TaskItem::signal_size*sizeof( typename T::value_type );
99 }
100 
101 template <typename T>
102 size_t PowerSpectrum<T>::ProcessedSignalSize() {
103  return TaskItem::signal_size;
104 }