ViennaCL - The Vienna Computing Library  1.6.0
Free open-source GPU-accelerated linear algebra and solver library.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fft_operations.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_LINALG_OPENCL_FFT_OPERATIONS_HPP_
2 #define VIENNACL_LINALG_OPENCL_FFT_OPERATIONS_HPP_
3 
4 /* =========================================================================
5  Copyright (c) 2010-2014, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8  Portions of this software are copyright by UChicago Argonne, LLC.
9 
10  -----------------
11  ViennaCL - The Vienna Computing Library
12  -----------------
13 
14  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15 
16  (A list of authors and contributors can be found in the PDF manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19  ============================================================================= */
20 
25 #include "viennacl/forwards.h"
26 #include "viennacl/ocl/device.hpp"
27 #include "viennacl/ocl/kernel.hpp"
32 
33 #include <viennacl/vector.hpp>
34 #include <viennacl/matrix.hpp>
35 
36 #include <cmath>
37 #include <stdexcept>
38 
39 namespace viennacl
40 {
41 namespace linalg
42 {
43 namespace detail
44 {
45 namespace fft
46 {
47 
49 
54  {
55  vcl_size_t bits_datasize = 0;
56  vcl_size_t ds = 1;
57 
58  while (ds < size)
59  {
60  ds = ds << 1;
61  bits_datasize++;
62  }
63 
64  return bits_datasize;
65  }
66 
71  {
72  n = n - 1;
73 
74  vcl_size_t power = 1;
75 
76  while (power < sizeof(vcl_size_t) * 8)
77  {
78  n = n | (n >> power);
79  power *= 2;
80  }
81 
82  return n + 1;
83  }
84 
85 } //namespce fft
86 } //namespace detail
87 
88 namespace opencl
89 {
90 
97 template<typename NumericT>
100  vcl_size_t size, vcl_size_t stride, vcl_size_t batch_num, NumericT sign = NumericT(-1),
102 {
103  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(in.context());
105 
108  {
110  program_string =
112  } else
114 
115  viennacl::ocl::kernel & k = ctx.get_kernel(program_string, "fft_direct");
116  viennacl::ocl::enqueue(k(in, out,
117  static_cast<cl_uint>(size),
118  static_cast<cl_uint>(stride),
119  static_cast<cl_uint>(batch_num),
120  sign)
121  );
122 }
123 
124 /*
125  * This function performs reorder of input data. Indexes are sorted in bit-reversal order.
126  * Such reordering should be done before in-place FFT.
127  */
128 template<typename NumericT>
130  vcl_size_t size, vcl_size_t stride,
131  vcl_size_t bits_datasize, vcl_size_t batch_num,
133 {
134  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(in.context());
136 
139  {
142  } else
144 
145  viennacl::ocl::kernel& k = ctx.get_kernel(program_string, "fft_reorder");
147  static_cast<cl_uint>(bits_datasize), static_cast<cl_uint>(size),
148  static_cast<cl_uint>(stride), static_cast<cl_uint>(batch_num))
149  );
150 }
151 
159 template<typename NumericT>
161  vcl_size_t size, vcl_size_t stride,
162  vcl_size_t batch_num, NumericT sign = NumericT(-1),
164 {
165  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(in.context());
167 
168  assert(batch_num != 0 && bool("batch_num must be larger than 0"));
169 
172  {
175  } else
177 
180  {
181  viennacl::ocl::kernel & k = ctx.get_kernel(program_string, "fft_radix2_local");
183  viennacl::ocl::local_mem((size * 4) * sizeof(NumericT)),
184  static_cast<cl_uint>(bits_datasize), static_cast<cl_uint>(size),
185  static_cast<cl_uint>(stride), static_cast<cl_uint>(batch_num), sign));
186 
187  }
188  else
189  {
190  viennacl::linalg::opencl::reorder<NumericT>(in, size, stride, bits_datasize, batch_num);
191 
192  for (vcl_size_t step = 0; step < bits_datasize; step++)
193  {
194  viennacl::ocl::kernel & k = ctx.get_kernel(program_string, "fft_radix2");
196  static_cast<cl_uint>(step), static_cast<cl_uint>(bits_datasize),
197  static_cast<cl_uint>(size), static_cast<cl_uint>(stride),
198  static_cast<cl_uint>(batch_num), sign));
199  }
200  }
201 }
202 
210 template<typename NumericT, unsigned int AlignmentV>
213 {
214  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(in).context());
216 
217  vcl_size_t size = in.size() >> 1;
219 
223 
224  {
226  viennacl::ocl::enqueue(k(A, B, static_cast<cl_uint>(ext_size)));
227  }
228  {
230  viennacl::ocl::enqueue(k(in, A, B, static_cast<cl_uint>(size), static_cast<cl_uint>(ext_size)));
231  }
232 
234 
235  {
237  viennacl::ocl::enqueue(k(Z, out, static_cast<cl_uint>(size)));
238  }
239 }
240 
244 template<typename NumericT, unsigned int AlignmentV>
248 {
249  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(input1).context());
251  vcl_size_t size = input1.size() >> 1;
253  viennacl::ocl::enqueue(k(input1, input2, output, static_cast<cl_uint>(size)));
254 }
255 
259 template<typename NumericT, unsigned int AlignmentV>
261 {
262  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(input).context());
264 
266 
267  vcl_size_t size = input.size() >> 1;
268  NumericT norm_factor = static_cast<NumericT>(size);
269  viennacl::ocl::enqueue(k(input, static_cast<cl_uint>(size), norm_factor));
270 }
271 
275 template<typename NumericT, unsigned int AlignmentV>
277 {
278  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(input).context());
280 
282  viennacl::ocl::enqueue(k(input, static_cast<cl_uint>(input.internal_size1() >> 1),
283  static_cast<cl_uint>(input.internal_size2()) >> 1));
284 }
285 
289 template<typename NumericT, unsigned int AlignmentV>
292 {
293  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(input).context());
295 
297  viennacl::ocl::enqueue(k(input, output, static_cast<cl_uint>(input.internal_size1() >> 1),
298  static_cast<cl_uint>(input.internal_size2() >> 1)));
299 }
300 
304 template<typename NumericT>
307 {
308  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(in).context());
310 
312  viennacl::ocl::enqueue(k(in, out, static_cast<cl_uint>(size)));
313 }
314 
318 template<typename NumericT>
321 {
322  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(in).context());
324 
326  viennacl::ocl::enqueue(k(in, out, static_cast<cl_uint>(size)));
327 }
328 
332 template<typename NumericT>
334 {
335  viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(in).context());
337 
338  vcl_size_t size = in.size();
339 
341  viennacl::ocl::enqueue(k(in, static_cast<cl_uint>(size)));
342 }
343 
344 } //namespace opencl
345 } //namespace linalg
346 } //namespace viennacl
347 
348 #endif /* FFT_OPERATIONS_HPP_ */
349 
void reorder(viennacl::ocl::handle< cl_mem > const &in, vcl_size_t size, vcl_size_t stride, vcl_size_t bits_datasize, vcl_size_t batch_num, viennacl::linalg::host_based::detail::fft::FFT_DATA_ORDER::DATA_ORDER data_order=viennacl::linalg::host_based::detail::fft::FFT_DATA_ORDER::ROW_MAJOR)
OpenCL kernel file for FFT operations.
vcl_size_t next_power_2(vcl_size_t n)
Find next power of two.
Represents an OpenCL device within ViennaCL.
void complex_to_real(viennacl::vector_base< NumericT > const &in, viennacl::vector_base< NumericT > &out, vcl_size_t size)
Create real vector from complex vector (even elements(2*k) = real part, odd elements(2*k+1) = imagina...
Represents an OpenCL kernel within ViennaCL.
Definition: kernel.hpp:58
Implementation of the dense matrix class.
Main kernel class for generating OpenCL kernels for the fast Fourier transform.
Definition: fft.hpp:243
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:54
result_of::size_type< viennacl::vector_base< T > >::type stride(viennacl::vector_base< T > const &s)
Definition: stride.hpp:45
This file provides the forward declarations for the main types used within ViennaCL.
endcode *Final step
A dense matrix class.
Definition: forwards.h:374
Determines row and column increments for matrices and matrix proxies.
void transpose(viennacl::matrix< NumericT, viennacl::row_major, AlignmentV > &input)
Inplace_transpose matrix.
viennacl::ocl::context const & context() const
Definition: handle.hpp:191
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:144
A class representing local (shared) OpenCL memory. Typically used as kernel argument.
Definition: local_mem.hpp:33
viennacl::ocl::kernel & get_kernel(std::string const &program_name, std::string const &kernel_name)
Convenience function for retrieving the kernel of a program directly from the context.
Definition: context.hpp:607
static void init(viennacl::ocl::context &ctx)
Definition: matrix.hpp:775
void radix2(viennacl::ocl::handle< cl_mem > const &in, vcl_size_t size, vcl_size_t stride, vcl_size_t batch_num, NumericT sign=NumericT(-1), viennacl::linalg::host_based::detail::fft::FFT_DATA_ORDER::DATA_ORDER data_order=viennacl::linalg::host_based::detail::fft::FFT_DATA_ORDER::ROW_MAJOR)
Radix-2 algorithm for computing Fourier transformation.
void reverse(viennacl::vector_base< NumericT > &in)
Reverse vector to oposite order and save it in input vector.
void real_to_complex(viennacl::vector_base< NumericT > const &in, viennacl::vector_base< NumericT > &out, vcl_size_t size)
Create complex vector from real vector (even elements(2*k) = real part, odd elements(2*k+1) = imagina...
std::size_t vcl_size_t
Definition: forwards.h:74
void convolve_i(viennacl::vector< SCALARTYPE, ALIGNMENT > &input1, viennacl::vector< SCALARTYPE, ALIGNMENT > &input2, viennacl::vector< SCALARTYPE, ALIGNMENT > &output)
const vcl_size_t MAX_LOCAL_POINTS_NUM
void enqueue(KernelType &k, viennacl::ocl::command_queue const &queue)
Enqueues a kernel in the provided queue.
Definition: enqueue.hpp:50
Representation of an OpenCL kernel in ViennaCL.
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
void multiply_complex(viennacl::vector< NumericT, AlignmentV > const &input1, viennacl::vector< NumericT, AlignmentV > const &input2, viennacl::vector< NumericT, AlignmentV > &output)
Mutiply two complex vectors and store result in output.
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector_def.hpp:118
void direct(viennacl::ocl::handle< cl_mem > const &in, viennacl::ocl::handle< cl_mem > const &out, vcl_size_t size, vcl_size_t stride, vcl_size_t batch_num, NumericT sign=NumericT(-1), viennacl::linalg::host_based::detail::fft::FFT_DATA_ORDER::DATA_ORDER data_order=viennacl::linalg::host_based::detail::fft::FFT_DATA_ORDER::ROW_MAJOR)
Direct algorithm for computing Fourier transformation.
vcl_size_t num_bits(vcl_size_t size)
Get number of bits.
size_type internal_size2() const
Returns the internal number of columns. Usually required for launching OpenCL kernels only...
Definition: matrix_def.hpp:231
size_type internal_size1() const
Returns the internal number of rows. Usually required for launching OpenCL kernels only...
Definition: matrix_def.hpp:229
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
static void init(viennacl::ocl::context &ctx)
Definition: fft.hpp:250
void normalize(viennacl::vector< NumericT, AlignmentV > &input)
Normalize vector on with his own size.
void bluestein(viennacl::vector< NumericT, AlignmentV > &in, viennacl::vector< NumericT, AlignmentV > &out, vcl_size_t)
Bluestein's algorithm for computing Fourier transformation.
Runtime generation of OpenCL kernels for matrix operations.
ScalarType fft(std::vector< ScalarType > &in, std::vector< ScalarType > &out, unsigned int, unsigned int, unsigned int batch_size)
Definition: fft_1d.cpp:719
SCALARTYPE sign(SCALARTYPE val)