JASPL  0.2
Just Another Signal Processing Library
linearconvolution.tpp
1 
2 template <typename T>
3 LinearConvolution<T>::LinearConvolution( T& convolution_kernel ) {
4 
5  static_assert( is_stdlib_container< T >::value, "LinearConvolution can only accept pointers or container-like objects." );
6  static_assert( std::is_arithmetic<typename T::value_type>::value, "LinearConvolution must be made with arithmetic type" );
7 
8  // std::string source_directory = SOURCE_DIR;
9  // std::string kernel_name = "/linearconvolve.cl";
10 
11  // kernel_path = source_directory + kernel_name;
12 
13  // LoadCLKernel<typename T::value_type>( "LinearConvolve" );
14  std::string kernel_str = R"END(
15  __kernel void LinearConvolve( __global TYPE* input, __constant TYPE* filter_kernel, __global TYPE* output, const uint signal_size, const uint kernel_size )
16  {
17 
18  int half_k_size = (signal_size%2 == 0)?( kernel_size/2 ):( (kernel_size - 1)/2 );
19  int signal_max_index = signal_size - 1;
20 
21  int i = get_global_id(0);
22 
23  TYPE conv_elem = 0.0;
24 
25  int k_max = ( ( i + half_k_size ) > signal_max_index )?( signal_max_index + half_k_size - i ):(kernel_size);
26  int k_min = ( ( i - half_k_size ) < 0 )?( half_k_size - i ):(0);
27 
28  for ( int j = k_min ; j < k_max ; j++ ) {
29 
30  conv_elem += input[ i + j - half_k_size ]*filter_kernel[ j ];
31 
32  }
33 
34  //Left side mirroring
35  for ( int j = 0 ; j < k_min ; j++ ) {
36 
37  conv_elem += input[ -i - j + half_k_size ]*filter_kernel[ j ];
38  }
39 
40  //Right side mirroring
41  for ( int j = k_max ; j < kernel_size ; j++ ) {
42 
43  conv_elem += input[ 2*signal_max_index - i - j + half_k_size ]*filter_kernel[ j ];
44 
45  }
46 
47  output[i] = conv_elem;
48 
49  }
50 
51  )END";
52 
53  std::string kernel_name = "LinearConvolve";
54 
55  LoadCLKernel<typename T::value_type>( kernel_str, kernel_name );
56 
57  uint kernel_size = convolution_kernel.size();
58  size_t kernel_bytes = kernel_size*sizeof( typename T::value_type );
59  auto kernel_ptr = convolution_kernel.data();
60 
61  kernel_buff = cl::Buffer ( context, CL_MEM_READ_ONLY, kernel_bytes );
62  command_queue.enqueueWriteBuffer( kernel_buff, CL_TRUE, 0, kernel_bytes, kernel_ptr );
63 
64  cl_int err;
65  err = kernel.setArg(1, kernel_buff);
66  OCL_DEBUG( err );
67  err = kernel.setArg(4, kernel_size);
68  OCL_DEBUG( err );
69 }
70 
71 template <typename T>
72 LinearConvolution<T>::LinearConvolution( T* convolution_kernel ) {
73 
74  static_assert( std::is_arithmetic<T>::value, "LinearConvolution must be made with arithmetic pointer type" );
75  std::string source_directory = SOURCE_DIR;
76  std::string kernel_name = "/linearconvolve.cl";
77 
78  kernel_path = source_directory + kernel_name;
79 
80  LoadCLKernel<T>( "LinearConvolve" );
81 
82  uint kernel_size = convolution_kernel.size();
83  size_t kernel_bytes = kernel_size*sizeof( T );
84  auto kernel_ptr = convolution_kernel.data();
85 
86  kernel_buff = cl::Buffer ( context, CL_MEM_READ_ONLY, kernel_bytes );
87  command_queue.enqueueWriteBuffer( kernel_buff, CL_TRUE, 0, kernel_bytes, kernel_ptr );
88 
89  cl_int err;
90  err = kernel.setArg(1, kernel_buff);
91  OCL_DEBUG( err );
92  err = kernel.setArg(3, kernel_size);
93  OCL_DEBUG( err );
94 }
95 
96 template <typename T>
97 LinearConvolution<T>::~LinearConvolution() {}
98 
99 template <typename T>
100 void LinearConvolution<T>::Trigger() {
101 
102  cl_int err;
103  err = command_queue.enqueueNDRangeKernel( kernel,cl::NullRange, cl::NDRange( signal_size ) );
104  OCL_DEBUG( err );
105 }
106 
107 template <typename T>
108 void LinearConvolution<T>::SetSignal( cl::Buffer& signal_buff, uint sig_size ) {
109 
110  signal_size = sig_size;
111 
112  cl_int* err_ptr = NULL;
113  scratch_buff = cl::Buffer ( context, CL_MEM_READ_WRITE, sig_size*sizeof(typename T::value_type), err_ptr );
114  OCL_DEBUG( err_ptr );
115 
116  cl_int err = kernel.setArg(2, scratch_buff);
117  OCL_DEBUG( err );
118 
119  err = kernel.setArg(0, signal_buff);
120  err = kernel.setArg(3, sig_size);
121  OCL_DEBUG( err );
122 }
123 
124 template <typename T>
125 cl::Buffer& LinearConvolution<T>::ProcessedSignal() {
126  return scratch_buff;
127 }
128 
129 template <typename T>
130 size_t LinearConvolution<T>::ProcessedSignalBytes() {
131  return signal_size*sizeof( typename T::value_type );
132 }
133 
134 template <typename T>
135 size_t LinearConvolution<T>::ProcessedSignalSize() {
136  return signal_size;
137 }
138 
139 template <typename T>
140 bool LinearConvolution<T>::NeedsToReknew() {
141  return true;
142 }
143