ViennaCL - The Vienna Computing Library  1.7.0
Free open-source GPU-accelerated linear algebra and solver library.
vector_proxy.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_VECTOR_PROXY_HPP_
2 #define VIENNACL_VECTOR_PROXY_HPP_
3 
4 /* =========================================================================
5  Copyright (c) 2010-2015, 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 manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
25 #include "viennacl/forwards.h"
26 #include "viennacl/range.hpp"
27 #include "viennacl/slice.hpp"
28 #include "viennacl/vector.hpp"
30 
31 namespace viennacl
32 {
33 
38 template<typename VectorType>
39 class vector_range : public vector_base<typename VectorType::cpu_value_type>
40 {
41  typedef vector_range<VectorType> self_type;
42  typedef vector_base<typename VectorType::cpu_value_type> base_type;
43 
44 public:
45  typedef typename VectorType::value_type value_type;
48  typedef value_type reference;
49  typedef const value_type & const_reference;
50  typedef typename VectorType::const_iterator const_iterator;
51  typedef typename VectorType::iterator iterator;
53 
54  typedef typename VectorType::cpu_value_type cpu_value_type;
55 
56  vector_range(VectorType const & v, range const & entry_range)
57  : base_type(const_cast<handle_type &>(v.handle()),
58  entry_range.size(), v.start() + v.stride() * entry_range.start(), v.stride()) {}
59 
60  vector_range(self_type const & v, range const & entry_range)
61  : base_type(const_cast<handle_type &>(v.handle()),
62  entry_range.size(), v.start() + v.stride() * entry_range.start(), v.stride()) {}
63 
64  vector_range(self_type const & other)
65  : base_type(const_cast<handle_type &>(other.handle()),
66  other.size(), other.start(), other.stride()) {}
67 
68  using base_type::operator=;
69 
70  // the following are needed for Visual Studio:
71  template<typename OtherNumericT>
72  base_type & operator=(viennacl::vector<OtherNumericT> const & v) { return base_type::operator=(static_cast<viennacl::vector_base<OtherNumericT> const &>(v)); }
73 
74  template<typename OtherNumericT>
76 
77  template<typename OtherNumericT>
79 };
80 
81 template<typename VectorType>
82 class vector_range<vector_range<VectorType> > : public vector_base<typename VectorType::cpu_value_type>
83 {
85 
86 public:
88 
89  vector_range(VectorType const & v, range const & entry_range)
90  : base_type(const_cast<handle_type &>(v.handle()),
91  entry_range.size(), v.start() + v.stride() * entry_range.start(), v.stride()) {}
92 
93  vector_range(vector_range<VectorType> const & v, range const & entry_range)
94  : base_type(const_cast<handle_type &>(v.handle()),
95  entry_range.size(), v.start() + v.stride() * entry_range.start(), v.stride()) {}
96 };
97 
101 
102 template<typename VectorType, typename NumericT>
103 void copy(const VectorType & cpu_vector,
104  vector_range<vector<NumericT> > & gpu_vector_range )
105 {
106  assert(cpu_vector.end() - cpu_vector.begin() >= 0 && bool("Range must have nonnegative length!"));
107 
108  if (cpu_vector.end() - cpu_vector.begin() > 0)
109  {
110  //we require that the size of the gpu_vector is larger or equal to the cpu-size
111  std::vector<NumericT> temp_buffer(static_cast<vcl_size_t>(cpu_vector.end() - cpu_vector.begin()));
112  std::copy(cpu_vector.begin(), cpu_vector.end(), temp_buffer.begin());
113  viennacl::backend::memory_write(gpu_vector_range.handle(), sizeof(NumericT)*gpu_vector_range.start(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
114  }
115 }
116 
117 
123 template<typename CPUVECTOR, typename VectorType>
124 void fast_copy(const CPUVECTOR & cpu_vec, vector_range<VectorType> & gpu_vec)
125 {
126  viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
127 }
128 
132 
133 
134 template<typename NumericT, typename VectorType>
135 void copy(vector_range<vector<NumericT> > const & gpu_vector_range,
136  VectorType & cpu_vector)
137 {
138  assert(cpu_vector.end() - cpu_vector.begin() >= 0 && bool("Range must have nonnegative length!"));
139 
140  if (cpu_vector.end() > cpu_vector.begin())
141  {
142  std::vector<NumericT> temp_buffer(static_cast<vcl_size_t>(cpu_vector.end() - cpu_vector.begin()));
143  viennacl::backend::memory_read(gpu_vector_range.handle(), sizeof(NumericT)*gpu_vector_range.start(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
144 
145  //now copy entries to cpu_vec:
146  std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_vector.begin());
147  }
148 }
149 
150 
156 template<typename VectorType, typename CPUVECTOR>
158  CPUVECTOR & cpu_vec )
159 {
160  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
161 }
162 
163 
164 
165 //
166 // Convenience function
167 //
168 template<typename VectorType>
169 vector_range<VectorType> project(VectorType const & vec, viennacl::range const & r1)
170 {
171  return vector_range<VectorType>(vec, r1);
172 }
173 
174 template<typename VectorType>
176 {
177  assert(r1.size() <= vec.size() && bool("Size of range invalid!"));
178  return vector_range<VectorType>(vec, r1);
179 }
180 
181 //
182 //
183 //
185 //
186 //
187 //
188 
189 
190 
195 template<typename VectorType>
196 class vector_slice : public vector_base<typename VectorType::cpu_value_type>
197 {
198  typedef vector_slice<VectorType> self_type;
199  typedef vector_base<typename VectorType::cpu_value_type> base_type;
200 
201 public:
202  typedef typename VectorType::value_type value_type;
205  typedef value_type reference;
206  typedef const value_type & const_reference;
207  typedef typename VectorType::const_iterator const_iterator;
208  typedef typename VectorType::iterator iterator;
210 
211  typedef typename VectorType::cpu_value_type cpu_value_type;
212 
213  vector_slice(VectorType const & v, slice const & entry_slice)
214  : base_type(const_cast<handle_type &>(v.handle()),
215  entry_slice.size(), v.start() + v.stride() * entry_slice.start(), v.stride() * entry_slice.stride()) {}
216 
217  vector_slice(self_type const & v, slice const & entry_slice)
218  : base_type(const_cast<handle_type &>(v.handle()),
219  entry_slice.size(), v.start() + v.stride() * entry_slice.start(), v.stride() * entry_slice.stride()) {}
220 
221  vector_slice(self_type const & other)
222  : base_type(const_cast<handle_type &>(other.handle()),
223  other.size(), other.start(), other.stride()) {}
224 
225  using base_type::operator=;
226 
227  // the following are needed for Visual Studio:
228  template<typename OtherNumericT>
230 
231  template<typename OtherNumericT>
233 
234  template<typename OtherNumericT>
236 };
237 
238 
239 template<typename VectorType>
240 class vector_slice<vector_slice<VectorType> > : public vector_base<typename VectorType::cpu_value_type>
241 {
243 
244 public:
246 
247  vector_slice(VectorType const & v, slice const & entry_slice)
248  : base_type(const_cast<handle_type &>(v.handle()),
249  entry_slice.size(), v.start() + v.stride() * entry_slice.start(), entry_slice.stride() * v.stride()) {}
250 
251  vector_slice(vector_slice<VectorType> const & v, slice const & entry_slice)
252  : base_type(const_cast<handle_type &>(v.handle()),
253  entry_slice.size(), v.start() + v.stride() * entry_slice.start(), entry_slice.stride() * v.stride()) {}
254 };
255 
259 
260 template<typename VectorType, typename NumericT>
261 void copy(const VectorType & cpu_vector,
262  vector_slice<vector<NumericT> > & gpu_vector_slice )
263 {
264  if (cpu_vector.size() > 0)
265  {
266  std::vector<NumericT> temp_buffer(gpu_vector_slice.stride() * gpu_vector_slice.size());
267 
268  viennacl::backend::memory_read(gpu_vector_slice.handle(), sizeof(NumericT)*gpu_vector_slice.start(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
269 
270  for (vcl_size_t i=0; i<cpu_vector.size(); ++i)
271  temp_buffer[i * gpu_vector_slice.stride()] = cpu_vector[i];
272 
273  viennacl::backend::memory_write(gpu_vector_slice.handle(), sizeof(NumericT)*gpu_vector_slice.start(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
274  }
275 }
276 
277 
278 
282 
283 
284 template<typename VectorType, typename NumericT>
285 void copy(vector_slice<vector<NumericT> > const & gpu_vector_slice,
286  VectorType & cpu_vector)
287 {
288  assert(gpu_vector_slice.end() - gpu_vector_slice.begin() >= 0 && bool("Range must have nonnegative length!"));
289 
290  if (gpu_vector_slice.end() - gpu_vector_slice.begin() > 0)
291  {
292  std::vector<NumericT> temp_buffer(gpu_vector_slice.stride() * gpu_vector_slice.size());
293  viennacl::backend::memory_read(gpu_vector_slice.handle(), sizeof(NumericT)*gpu_vector_slice.start(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
294 
295  for (vcl_size_t i=0; i<cpu_vector.size(); ++i)
296  cpu_vector[i] = temp_buffer[i * gpu_vector_slice.stride()];
297  }
298 }
299 
300 
301 
302 
303 
304 //
305 // Convenience functions
306 //
307 template<typename VectorType>
308 vector_slice<VectorType> project(VectorType const & vec, viennacl::slice const & s1)
309 {
310  assert(s1.size() <= vec.size() && bool("Size of slice larger than vector size!"));
311  return vector_slice<VectorType>(vec, s1);
312 }
313 
314 template<typename VectorType>
316 {
317  assert(s1.size() <= vec.size() && bool("Size of slice larger than vector proxy!"));
318  return vector_slice<VectorType>(vec, s1);
319 }
320 
321 // interaction with range and vector_range:
322 
323 template<typename VectorType>
325 {
326  assert(r1.size() <= vec.size() && bool("Size of slice larger than vector proxy!"));
327  return vector_slice<VectorType>(vec, viennacl::slice(r1.start(), 1, r1.size()));
328 }
329 
330 template<typename VectorType>
332 {
333  assert(s1.size() <= vec.size() && bool("Size of slice larger than vector proxy!"));
334  return vector_slice<VectorType>(vec, s1);
335 }
336 
337 
338 }
339 
340 #endif
viennacl::tools::shared_ptr< char > handle_type
Definition: cpu_ram.hpp:40
void memory_write(mem_handle &dst_buffer, vcl_size_t dst_offset, vcl_size_t bytes_to_write, const void *ptr, bool async=false)
Writes data from main RAM identified by 'ptr' to the buffer identified by 'dst_buffer'.
Definition: memory.hpp:220
VectorType::handle_type handle_type
slice::difference_type difference_type
A proxy class for entries in a vector.
size_type size() const
Definition: slice.hpp:56
size_type size() const
Definition: range.hpp:56
This file provides the forward declarations for the main types used within ViennaCL.
vector_slice(VectorType const &v, slice const &entry_slice)
void memory_read(mem_handle const &src_buffer, vcl_size_t src_offset, vcl_size_t bytes_to_read, void *ptr, bool async=false)
Reads data from a buffer back to main RAM.
Definition: memory.hpp:261
base_type & operator=(viennacl::vector_slice< viennacl::vector< OtherNumericT > > const &v)
VectorType::value_type value_type
viennacl::scalar< float > s1
VectorType::const_iterator const_iterator
float NumericT
Definition: bisect.cpp:40
size_type stride() const
Returns the stride within the buffer (in multiples of sizeof(NumericT))
Definition: vector_def.hpp:124
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:34
base_type & operator=(viennacl::vector< OtherNumericT > const &v)
vector_range(vector_range< VectorType > const &v, range const &entry_range)
VectorType::value_type value_type
Class for representing non-strided subvectors of a bigger vector x.
Definition: forwards.h:434
vector_range(VectorType const &v, range const &entry_range)
size_type start() const
Definition: range.hpp:55
const value_type & const_reference
Class for representing strided subvectors of a bigger vector x.
Definition: forwards.h:437
Common base class for dense vectors, vector ranges, and vector slices.
Definition: vector_def.hpp:104
matrix_range< MatrixType > project(MatrixType const &A, viennacl::range const &r1, viennacl::range const &r2)
self_type & operator=(const self_type &vec)
Assignment operator. Other vector needs to be of the same size, or this vector is not yet initialized...
Definition: vector.hpp:356
base_type & operator=(viennacl::vector< OtherNumericT > const &v)
std::size_t vcl_size_t
Definition: forwards.h:75
void copy(vector_slice< vector< NumericT > > const &gpu_vector_slice, VectorType &cpu_vector)
VectorType::iterator iterator
base_type & operator=(viennacl::vector_range< viennacl::vector< OtherNumericT > > const &v)
VectorType::const_iterator const_iterator
vector_slice(self_type const &v, slice const &entry_slice)
VectorType::iterator iterator
vector_range(self_type const &other)
vector_range(self_type const &v, range const &entry_range)
DistanceT difference_type
Definition: range.hpp:43
basic_slice slice
Definition: forwards.h:429
VectorType::cpu_value_type cpu_value_type
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
void copy(std::vector< NumericT > &cpu_vec, circulant_matrix< NumericT, AlignmentV > &gpu_mat)
Copies a circulant matrix from the std::vector to the OpenCL device (either GPU or multi-core CPU) ...
Implementation of a slice object for use with proxy objects.
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector_def.hpp:118
vector_range(VectorType const &v, range const &entry_range)
A range class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:424
vector_slice(VectorType const &v, slice const &entry_slice)
range::size_type size_type
slice::size_type size_type
Implementation of a range object for use with proxy objects.
base_type & operator=(viennacl::vector_range< viennacl::vector< OtherNumericT > > const &v)
VectorType::handle_type handle_type
size_type start() const
Returns the offset within the buffer.
Definition: vector_def.hpp:122
A slice class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:429
const value_type & const_reference
DistanceT difference_type
Definition: slice.hpp:43
range::difference_type difference_type
const handle_type & handle() const
Returns the memory handle.
Definition: vector_def.hpp:128
base_type & operator=(viennacl::vector_slice< viennacl::vector< OtherNumericT > > const &v)
vector_slice(vector_slice< VectorType > const &v, slice const &entry_slice)
VectorType::cpu_value_type cpu_value_type
vector_slice(self_type const &other)
void fast_copy(const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_begin, const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_end, CPU_ITERATOR cpu_begin)