3 LinearConvolution<T>::LinearConvolution( T& convolution_kernel ) {
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" );
8 // std::string source_directory = SOURCE_DIR;
9 // std::string kernel_name = "/linearconvolve.cl";
11 // kernel_path = source_directory + kernel_name;
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 )
18 int half_k_size = (signal_size%2 == 0)?( kernel_size/2 ):( (kernel_size - 1)/2 );
19 int signal_max_index = signal_size - 1;
21 int i = get_global_id(0);
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);
28 for ( int j = k_min ; j < k_max ; j++ ) {
30 conv_elem += input[ i + j - half_k_size ]*filter_kernel[ j ];
35 for ( int j = 0 ; j < k_min ; j++ ) {
37 conv_elem += input[ -i - j + half_k_size ]*filter_kernel[ j ];
40 //Right side mirroring
41 for ( int j = k_max ; j < kernel_size ; j++ ) {
43 conv_elem += input[ 2*signal_max_index - i - j + half_k_size ]*filter_kernel[ j ];
47 output[i] = conv_elem;
53 std::string kernel_name = "LinearConvolve";
55 LoadCLKernel<typename T::value_type>( kernel_str, kernel_name );
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();
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 );
65 err = kernel.setArg(1, kernel_buff);
67 err = kernel.setArg(4, kernel_size);
72 LinearConvolution<T>::LinearConvolution( T* convolution_kernel ) {
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";
78 kernel_path = source_directory + kernel_name;
80 LoadCLKernel<T>( "LinearConvolve" );
82 uint kernel_size = convolution_kernel.size();
83 size_t kernel_bytes = kernel_size*sizeof( T );
84 auto kernel_ptr = convolution_kernel.data();
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 );
90 err = kernel.setArg(1, kernel_buff);
92 err = kernel.setArg(3, kernel_size);
97 LinearConvolution<T>::~LinearConvolution() {}
100 void LinearConvolution<T>::Trigger() {
103 err = command_queue.enqueueNDRangeKernel( kernel,cl::NullRange, cl::NDRange( signal_size ) );
107 template <typename T>
108 void LinearConvolution<T>::SetSignal( cl::Buffer& signal_buff, uint sig_size ) {
110 signal_size = sig_size;
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 );
116 cl_int err = kernel.setArg(2, scratch_buff);
119 err = kernel.setArg(0, signal_buff);
120 err = kernel.setArg(3, sig_size);
124 template <typename T>
125 cl::Buffer& LinearConvolution<T>::ProcessedSignal() {
129 template <typename T>
130 size_t LinearConvolution<T>::ProcessedSignalBytes() {
131 return signal_size*sizeof( typename T::value_type );
134 template <typename T>
135 size_t LinearConvolution<T>::ProcessedSignalSize() {
139 template <typename T>
140 bool LinearConvolution<T>::NeedsToReknew() {