ViennaCL - The Vienna Computing Library: viennacl/vector.hpp Source File

ViennaCL - The Vienna Computing Library 1.7.1 Free open-source GPU-accelerated linear algebra and solver library. |

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vector.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_VECTOR_HPP_
2 #define VIENNACL_VECTOR_HPP_
3
4 /* =========================================================================
5 Copyright (c) 2010-2016, 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
26 #include "viennacl/forwards.h"
27 #include "viennacl/detail/vector_def.hpp"
28 #include "viennacl/backend/memory.hpp"
29 #include "viennacl/scalar.hpp"
30 #include "viennacl/tools/tools.hpp"
31 #include "viennacl/tools/entry_proxy.hpp"
32 #include "viennacl/linalg/detail/op_executor.hpp"
33 #include "viennacl/linalg/vector_operations.hpp"
34 #include "viennacl/meta/result_of.hpp"
35 #include "viennacl/context.hpp"
36 #include "viennacl/traits/handle.hpp"
37
38 namespace viennacl
39 {
40
41 //
42 // Vector expression
43 //
44
57 template<typename LHS, typename RHS, typename OP>
58 class vector_expression
59 {
60 typedef typename viennacl::result_of::reference_if_nonscalar<LHS>::type lhs_reference_type;
61 typedef typename viennacl::result_of::reference_if_nonscalar<RHS>::type rhs_reference_type;
62
63 public:
64 enum { alignment = 1 };
65
68 typedef vcl_size_t size_type;
69
70 vector_expression(LHS & l, RHS & r) : lhs_(l), rhs_(r) {}
71
74 lhs_reference_type lhs() const { return lhs_; }
77 rhs_reference_type rhs() const { return rhs_; }
78
80 size_type size() const { return viennacl::traits::size(*this); }
81
82 private:
84 lhs_reference_type lhs_;
86 rhs_reference_type rhs_;
87 };
88
107 template<class NumericT, unsigned int AlignmentV>
108 class const_vector_iterator
109 {
110 typedef const_vector_iterator<NumericT, AlignmentV> self_type;
111 public:
112 typedef scalar<NumericT> value_type;
113 typedef vcl_size_t size_type;
114 typedef vcl_ptrdiff_t difference_type;
115 typedef viennacl::backend::mem_handle handle_type;
116
117 //const_vector_iterator() {}
118
125 const_vector_iterator(vector_base<NumericT> const & vec,
126 size_type index,
127 size_type start = 0,
128 size_type stride = 1) : elements_(vec.handle()), index_(index), start_(start), stride_(stride) {}
129
136 const_vector_iterator(handle_type const & elements,
137 size_type index,
138 size_type start = 0,
139 size_type stride = 1) : elements_(elements), index_(index), start_(start), stride_(stride) {}
140
142 value_type operator*(void) const
143 {
144 value_type result;
145 result = const_entry_proxy<NumericT>(start_ + index_ * stride(), elements_);
146 return result;
147 }
148 self_type operator++(void) { ++index_; return *this; }
149 self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
150
151 bool operator==(self_type const & other) const { return index_ == other.index_; }
152 bool operator!=(self_type const & other) const { return index_ != other.index_; }
153
154 // self_type & operator=(self_type const & other)
155 // {
156 // index_ = other._index;
157 // elements_ = other._elements;
158 // return *this;
159 // }
160
161 difference_type operator-(self_type const & other) const
162 {
163 assert( (other.start_ == start_) && (other.stride_ == stride_) && bool("Iterators are not from the same vector (proxy)!"));
164 return static_cast<difference_type>(index_) - static_cast<difference_type>(other.index_);
165 }
166 self_type operator+(difference_type diff) const { return self_type(elements_, size_type(difference_type(index_) + diff), start_, stride_); }
167
168 //vcl_size_t index() const { return index_; }
170 size_type offset() const { return start_ + index_ * stride(); }
171
173 size_type stride() const { return stride_; }
174 handle_type const & handle() const { return elements_; }
175
176 protected:
178 handle_type const & elements_;
179 size_type index_; //offset from the beginning of elements_
180 size_type start_;
181 size_type stride_;
182 };
183
184
204 template<class NumericT, unsigned int AlignmentV>
205 class vector_iterator : public const_vector_iterator<NumericT, AlignmentV>
206 {
207 typedef const_vector_iterator<NumericT, AlignmentV> base_type;
208 typedef vector_iterator<NumericT, AlignmentV> self_type;
209 public:
210 typedef typename base_type::handle_type handle_type;
211 typedef typename base_type::size_type size_type;
212 typedef typename base_type::difference_type difference_type;
213
214 vector_iterator(handle_type const & elements,
215 size_type index,
216 size_type start = 0,
217 size_type stride = 1) : base_type(elements, index, start, stride), elements_(elements) {}
224 vector_iterator(vector_base<NumericT> & vec,
225 size_type index,
226 size_type start = 0,
227 size_type stride = 1) : base_type(vec, index, start, stride), elements_(vec.handle()) {}
228 //vector_iterator(base_type const & b) : base_type(b) {}
229
230 entry_proxy<NumericT> operator*(void)
231 {
232 return entry_proxy<NumericT>(base_type::start_ + base_type::index_ * base_type::stride(), elements_);
233 }
234
235 difference_type operator-(self_type const & other) const { difference_type result = base_type::index_; return (result - static_cast<difference_type>(other.index_)); }
236 self_type operator+(difference_type diff) const { return self_type(elements_, static_cast<vcl_size_t>(static_cast<difference_type>(base_type::index_) + diff), base_type::start_, base_type::stride_); }
237
238 handle_type & handle() { return elements_; }
239 handle_type const & handle() const { return base_type::elements_; }
240
241 //operator base_type() const
242 //{
243 // return base_type(base_type::elements_, base_type::index_, base_type::start_, base_type::stride_);
244 //}
245 private:
246 handle_type elements_;
247 };
248
249
250 template<class NumericT, typename SizeT, typename DistanceT>
251 vector_base<NumericT, SizeT, DistanceT>::vector_base() : size_(0), start_(0), stride_(1), internal_size_(0) { /* Note: One must not call ::init() here because a vector might have been created globally before the backend has become available */ }
252
253 template<class NumericT, typename SizeT, typename DistanceT>
254 vector_base<NumericT, SizeT, DistanceT>::vector_base(viennacl::backend::mem_handle & h,
255 size_type vec_size, size_type vec_start, size_type vec_stride)
256 : size_(vec_size), start_(vec_start), stride_(vec_stride), internal_size_(vec_size), elements_(h) {}
257
258 template<class NumericT, typename SizeT, typename DistanceT>
259 vector_base<NumericT, SizeT, DistanceT>::vector_base(size_type vec_size, viennacl::context ctx)
260 : size_(vec_size), start_(0), stride_(1), internal_size_(viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size))
261 {
262 if (size_ > 0)
263 {
264 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), ctx);
265 clear();
266 }
267 }
268
269 // CUDA or host memory:
270 template<class NumericT, typename SizeT, typename DistanceT>
271 vector_base<NumericT, SizeT, DistanceT>::vector_base(NumericT * ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, vcl_size_t start, size_type stride)
272 : size_(vec_size), start_(start), stride_(stride), internal_size_(vec_size)
273 {
274 if (mem_type == viennacl::CUDA_MEMORY)
275 {
276 #ifdef VIENNACL_WITH_CUDA
277 elements_.switch_active_handle_id(viennacl::CUDA_MEMORY);
278 elements_.cuda_handle().reset(reinterpret_cast<char*>(ptr_to_mem));
279 elements_.cuda_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
280 #else
281 throw cuda_not_available_exception();
282 #endif
283 }
284 else if (mem_type == viennacl::MAIN_MEMORY)
285 {
286 elements_.switch_active_handle_id(viennacl::MAIN_MEMORY);
287 elements_.ram_handle().reset(reinterpret_cast<char*>(ptr_to_mem));
288 elements_.ram_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
289 }
290
291 elements_.raw_size(sizeof(NumericT) * vec_size);
292
293 }
294
295 #ifdef VIENNACL_WITH_OPENCL
296 template<class NumericT, typename SizeT, typename DistanceT>
297 vector_base<NumericT, SizeT, DistanceT>::vector_base(cl_mem existing_mem, size_type vec_size, size_type start, size_type stride, viennacl::context ctx)
298 : size_(vec_size), start_(start), stride_(stride), internal_size_(vec_size)
299 {
300 elements_.switch_active_handle_id(viennacl::OPENCL_MEMORY);
301 elements_.opencl_handle() = existing_mem;
302 elements_.opencl_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
303 elements_.opencl_handle().context(ctx.opencl_context());
304 elements_.raw_size(sizeof(NumericT) * vec_size);
305 }
306 #endif
307
308
309 template<class NumericT, typename SizeT, typename DistanceT>
310 template<typename LHS, typename RHS, typename OP>
311 vector_base<NumericT, SizeT, DistanceT>::vector_base(vector_expression<const LHS, const RHS, OP> const & proxy)
312 : size_(viennacl::traits::size(proxy)), start_(0), stride_(1), internal_size_(viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size))
313 {
314 if (size_ > 0)
315 {
316 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(proxy));
317 clear();
318 }
319 self_type::operator=(proxy);
320 }
321
322 // Copy CTOR:
323 template<class NumericT, typename SizeT, typename DistanceT>
324 vector_base<NumericT, SizeT, DistanceT>::vector_base(const vector_base<NumericT, SizeT, DistanceT> & other) :
325 size_(other.size_), start_(0), stride_(1),
326 internal_size_(viennacl::tools::align_to_multiple<size_type>(other.size_, dense_padding_size))
327 {
328 elements_.switch_active_handle_id(viennacl::traits::active_handle_id(other));
329 if (internal_size() > 0)
330 {
331 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(other));
332 clear();
333 self_type::operator=(other);
334 }
335 }
336
337 // Conversion CTOR:
338 template<typename NumericT, typename SizeT, typename DistanceT>
339 template<typename OtherNumericT>
340 vector_base<NumericT, SizeT, DistanceT>::vector_base(const vector_base<OtherNumericT> & other) :
341 size_(other.size()), start_(0), stride_(1),
342 internal_size_(viennacl::tools::align_to_multiple<size_type>(other.size(), dense_padding_size))
343 {
344 elements_.switch_active_handle_id(viennacl::traits::active_handle_id(other));
345 if (internal_size() > 0)
346 {
347 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(other));
348 clear();
349 self_type::operator=(other);
350 }
351 }
352
353
354
355 template<class NumericT, typename SizeT, typename DistanceT>
356 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator=(const self_type & vec)
357 {
358 assert( ( (vec.size() == size()) || (size() == 0) )
359 && bool("Incompatible vector sizes!"));
360
361 if (&vec==this)
362 return *this;
363
364 if (vec.size() > 0)
365 {
366 if (size_ == 0)
367 {
368 size_ = vec.size();
369 internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
370 elements_.switch_active_handle_id(vec.handle().get_active_handle_id());
371 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(vec));
372 pad();
373 }
374
375 viennacl::linalg::av(*this,
376 vec, cpu_value_type(1.0), 1, false, false);
377 }
378
379 return *this;
380 }
381
382
387 template<class NumericT, typename SizeT, typename DistanceT>
388 template<typename LHS, typename RHS, typename OP>
389 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator=(const vector_expression<const LHS, const RHS, OP> & proxy)
390 {
391 assert( ( (viennacl::traits::size(proxy) == size()) || (size() == 0) )
392 && bool("Incompatible vector sizes!"));
393
394 // initialize the necessary buffer
395 if (size() == 0)
396 {
397 size_ = viennacl::traits::size(proxy);
398 internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
399 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(proxy));
400 pad();
401 }
402
403 linalg::detail::op_executor<self_type, op_assign, vector_expression<const LHS, const RHS, OP> >::apply(*this, proxy);
404
405 return *this;
406 }
407
408 // convert from vector with other numeric type
409 template<class NumericT, typename SizeT, typename DistanceT>
410 template<typename OtherNumericT>
411 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>:: operator = (const vector_base<OtherNumericT> & v1)
412 {
413 assert( ( (v1.size() == size()) || (size() == 0) )
414 && bool("Incompatible vector sizes!"));
415
416 if (size() == 0)
417 {
418 size_ = v1.size();
419 if (size_ > 0)
420 {
421 internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
422 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(v1));
423 pad();
424 }
425 }
426
427 viennacl::linalg::convert(*this, v1);
428
429 return *this;
430 }
431
433 template<class NumericT, typename SizeT, typename DistanceT>
434 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator = (unit_vector<NumericT> const & v)
435 {
436 assert( ( (v.size() == size()) || (size() == 0) )
437 && bool("Incompatible vector sizes!"));
438
439 if (size() == 0)
440 {
441 size_ = v.size();
442 internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
443 if (size_ > 0)
444 {
445 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
446 clear();
447 }
448 }
449 else
450 viennacl::linalg::vector_assign(*this, NumericT(0));
451
452 if (size_ > 0)
453 this->operator()(v.index()) = NumericT(1);
454
455 return *this;
456 }
457
459 template<class NumericT, typename SizeT, typename DistanceT>
460 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator = (zero_vector<NumericT> const & v)
461 {
462 assert( ( (v.size() == size()) || (size() == 0) )
463 && bool("Incompatible vector sizes!"));
464
465 if (size() == 0)
466 {
467 size_ = v.size();
468 internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
469 if (size_ > 0)
470 {
471 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
472 clear();
473 }
474 }
475 else
476 viennacl::linalg::vector_assign(*this, NumericT(0));
477
478 return *this;
479 }
480
482 template<class NumericT, typename SizeT, typename DistanceT>
483 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator = (scalar_vector<NumericT> const & v)
484 {
485 assert( ( (v.size() == size()) || (size() == 0) )
486 && bool("Incompatible vector sizes!"));
487
488 if (size() == 0)
489 {
490 size_ = v.size();
491 internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
492 if (size_ > 0)
493 {
494 viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
495 pad();
496 }
497 }
498
499 if (size_ > 0)
500 viennacl::linalg::vector_assign(*this, v[0]);
501
502 return *this;
503 }
504
505
506
508
509 //Note: The following operator overloads are defined in matrix_operations.hpp, compressed_matrix_operations.hpp and coordinate_matrix_operations.hpp
510 //This is certainly not the nicest approach and will most likely by changed in the future, but it works :-)
511
512 //matrix<>
513 template<class NumericT, typename SizeT, typename DistanceT>
514 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator=(const viennacl::vector_expression< const matrix_base<NumericT>, const vector_base<NumericT>, viennacl::op_prod> & proxy)
515 {
516 assert(viennacl::traits::size1(proxy.lhs()) == size() && bool("Size check failed for v1 = A * v2: size1(A) != size(v1)"));
517
518 // check for the special case x = A * x
519 if (viennacl::traits::handle(proxy.rhs()) == viennacl::traits::handle(*this))
520 {
521 viennacl::vector<NumericT> result(viennacl::traits::size1(proxy.lhs()));
522 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
523 *this = result;
524 }
525 else
526 {
527 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
528 }
529 return *this;
530 }
531
532
533 //transposed_matrix_proxy:
534 template<class NumericT, typename SizeT, typename DistanceT>
535 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator=(const vector_expression< const matrix_expression< const matrix_base<NumericT>, const matrix_base<NumericT>, op_trans >,
536 const vector_base<NumericT>,
537 op_prod> & proxy)
538 {
539 assert(viennacl::traits::size1(proxy.lhs()) == size() && bool("Size check failed in v1 = trans(A) * v2: size2(A) != size(v1)"));
540
541 // check for the special case x = trans(A) * x
542 if (viennacl::traits::handle(proxy.rhs()) == viennacl::traits::handle(*this))
543 {
544 viennacl::vector<NumericT> result(viennacl::traits::size1(proxy.lhs()));
545 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
546 *this = result;
547 }
548 else
549 {
550 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
551 }
552 return *this;
553 }
554
556
557
559 //read-write access to an element of the vector
560
561 template<class NumericT, typename SizeT, typename DistanceT>
562 entry_proxy<NumericT> vector_base<NumericT, SizeT, DistanceT>::operator()(size_type index)
563 {
564 assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
565 assert( index < size() && bool("Index out of bounds!") );
566
567 return entry_proxy<NumericT>(start_ + stride_ * index, elements_);
568 }
569
570 template<class NumericT, typename SizeT, typename DistanceT>
571 entry_proxy<NumericT> vector_base<NumericT, SizeT, DistanceT>::operator[](size_type index)
572 {
573 assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
574 assert( index < size() && bool("Index out of bounds!") );
575
576 return entry_proxy<NumericT>(start_ + stride_ * index, elements_);
577 }
578
579 template<class NumericT, typename SizeT, typename DistanceT>
580 const_entry_proxy<NumericT> vector_base<NumericT, SizeT, DistanceT>::operator()(size_type index) const
581 {
582 assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
583 assert( index < size() && bool("Index out of bounds!") );
584
585 return const_entry_proxy<NumericT>(start_ + stride_ * index, elements_);
586 }
587
588 template<class NumericT, typename SizeT, typename DistanceT>
589 const_entry_proxy<NumericT> vector_base<NumericT, SizeT, DistanceT>::operator[](size_type index) const
590 {
591 assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
592 assert( index < size() && bool("Index out of bounds!") );
593
594 return const_entry_proxy<NumericT>(start_ + stride_ * index, elements_);
595 }
596
598
599
600 //
601 // Operator overloads with implicit conversion (thus cannot be made global without introducing additional headache)
602 //
603 template<class NumericT, typename SizeT, typename DistanceT>
604 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator += (const self_type & vec)
605 {
606 assert(vec.size() == size() && bool("Incompatible vector sizes!"));
607
608 if (size() > 0)
609 viennacl::linalg::avbv(*this,
610 *this, NumericT(1.0), 1, false, false,
611 vec, NumericT(1.0), 1, false, false);
612 return *this;
613 }
614
615 template<class NumericT, typename SizeT, typename DistanceT>
616 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator -= (const self_type & vec)
617 {
618 assert(vec.size() == size() && bool("Incompatible vector sizes!"));
619
620 if (size() > 0)
621 viennacl::linalg::avbv(*this,
622 *this, NumericT(1.0), 1, false, false,
623 vec, NumericT(-1.0), 1, false, false);
624 return *this;
625 }
626
628 template<class NumericT, typename SizeT, typename DistanceT>
629 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (char val)
630 {
631 if (size() > 0)
632 viennacl::linalg::av(*this,
633 *this, NumericT(val), 1, false, false);
634 return *this;
635 }
637 template<class NumericT, typename SizeT, typename DistanceT>
638 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (short val)
639 {
640 if (size() > 0)
641 viennacl::linalg::av(*this,
642 *this, NumericT(val), 1, false, false);
643 return *this;
644 }
646 template<class NumericT, typename SizeT, typename DistanceT>
647 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (int val)
648 {
649 if (size() > 0)
650 viennacl::linalg::av(*this,
651 *this, NumericT(val), 1, false, false);
652 return *this;
653 }
655 template<class NumericT, typename SizeT, typename DistanceT>
656 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (long val)
657 {
658 if (size() > 0)
659 viennacl::linalg::av(*this,
660 *this, NumericT(val), 1, false, false);
661 return *this;
662 }
664 template<class NumericT, typename SizeT, typename DistanceT>
665 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (float val)
666 {
667 if (size() > 0)
668 viennacl::linalg::av(*this,
669 *this, NumericT(val), 1, false, false);
670 return *this;
671 }
673 template<class NumericT, typename SizeT, typename DistanceT>
674 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator *= (double val)
675 {
676 if (size() > 0)
677 viennacl::linalg::av(*this,
678 *this, NumericT(val), 1, false, false);
679 return *this;
680 }
681
682
684 template<class NumericT, typename SizeT, typename DistanceT>
685 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (char val)
686 {
687 if (size() > 0)
688 viennacl::linalg::av(*this,
689 *this, NumericT(val), 1, true, false);
690 return *this;
691 }
693 template<class NumericT, typename SizeT, typename DistanceT>
694 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (short val)
695 {
696 if (size() > 0)
697 viennacl::linalg::av(*this,
698 *this, NumericT(val), 1, true, false);
699 return *this;
700 }
702 template<class NumericT, typename SizeT, typename DistanceT>
703 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (int val)
704 {
705 if (size() > 0)
706 viennacl::linalg::av(*this,
707 *this, NumericT(val), 1, true, false);
708 return *this;
709 }
711 template<class NumericT, typename SizeT, typename DistanceT>
712 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (long val)
713 {
714 if (size() > 0)
715 viennacl::linalg::av(*this,
716 *this, NumericT(val), 1, true, false);
717 return *this;
718 }
720 template<class NumericT, typename SizeT, typename DistanceT>
721 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (float val)
722 {
723 if (size() > 0)
724 viennacl::linalg::av(*this,
725 *this, NumericT(val), 1, true, false);
726 return *this;
727 }
729 template<class NumericT, typename SizeT, typename DistanceT>
730 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::operator /= (double val)
731 {
732 if (size() > 0)
733 viennacl::linalg::av(*this,
734 *this, NumericT(val), 1, true, false);
735 return *this;
736 }
737
738
740 template<class NumericT, typename SizeT, typename DistanceT>
741 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
742 vector_base<NumericT, SizeT, DistanceT>::operator * (char value) const
743 {
744 return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
745 }
747 template<class NumericT, typename SizeT, typename DistanceT>
748 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
749 vector_base<NumericT, SizeT, DistanceT>::operator * (short value) const
750 {
751 return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
752 }
754 template<class NumericT, typename SizeT, typename DistanceT>
755 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
756 vector_base<NumericT, SizeT, DistanceT>::operator * (int value) const
757 {
758 return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
759 }
761 template<class NumericT, typename SizeT, typename DistanceT>
762 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
763 vector_base<NumericT, SizeT, DistanceT>::operator * (long value) const
764 {
765 return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
766 }
768 template<class NumericT, typename SizeT, typename DistanceT>
769 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
770 vector_base<NumericT, SizeT, DistanceT>::operator * (float value) const
771 {
772 return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
773 }
775 template<class NumericT, typename SizeT, typename DistanceT>
776 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
777 vector_base<NumericT, SizeT, DistanceT>::operator * (double value) const
778 {
779 return vector_expression< const self_type, const NumericT, op_mult>(*this, NumericT(value));
780 }
781
782
784 template<class NumericT, typename SizeT, typename DistanceT>
785 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
786 vector_base<NumericT, SizeT, DistanceT>::operator / (char value) const
787 {
788 return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
789 }
791 template<class NumericT, typename SizeT, typename DistanceT>
792 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
793 vector_base<NumericT, SizeT, DistanceT>::operator / (short value) const
794 {
795 return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
796 }
798 template<class NumericT, typename SizeT, typename DistanceT>
799 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
800 vector_base<NumericT, SizeT, DistanceT>::operator / (int value) const
801 {
802 return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
803 }
805 template<class NumericT, typename SizeT, typename DistanceT>
806 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
807 vector_base<NumericT, SizeT, DistanceT>::operator / (long value) const
808 {
809 return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
810 }
812 template<class NumericT, typename SizeT, typename DistanceT>
813 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
814 vector_base<NumericT, SizeT, DistanceT>::operator / (float value) const
815 {
816 return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
817 }
819 template<class NumericT, typename SizeT, typename DistanceT>
820 vector_expression< const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_div>
821 vector_base<NumericT, SizeT, DistanceT>::operator / (double value) const
822 {
823 return vector_expression< const self_type, const NumericT, op_div>(*this, NumericT(value));
824 }
825
826
828 template<class NumericT, typename SizeT, typename DistanceT>
829 vector_expression<const vector_base<NumericT, SizeT, DistanceT>, const NumericT, op_mult>
830 vector_base<NumericT, SizeT, DistanceT>::operator-() const
831 {
832 return vector_expression<const self_type, const NumericT, op_mult>(*this, NumericT(-1.0));
833 }
834
835 //
837 //
838
840 template<class NumericT, typename SizeT, typename DistanceT>
841 typename vector_base<NumericT, SizeT, DistanceT>::iterator vector_base<NumericT, SizeT, DistanceT>::begin()
842 {
843 return iterator(*this, 0, start_, stride_);
844 }
845
847 template<class NumericT, typename SizeT, typename DistanceT>
848 typename vector_base<NumericT, SizeT, DistanceT>::iterator vector_base<NumericT, SizeT, DistanceT>::end()
849 {
850 return iterator(*this, size(), start_, stride_);
851 }
852
854 template<class NumericT, typename SizeT, typename DistanceT>
855 typename vector_base<NumericT, SizeT, DistanceT>::const_iterator vector_base<NumericT, SizeT, DistanceT>::begin() const
856 {
857 return const_iterator(*this, 0, start_, stride_);
858 }
859
860 template<class NumericT, typename SizeT, typename DistanceT>
861 typename vector_base<NumericT, SizeT, DistanceT>::const_iterator vector_base<NumericT, SizeT, DistanceT>::end() const
862 {
863 return const_iterator(*this, size(), start_, stride_);
864 }
865
866 template<class NumericT, typename SizeT, typename DistanceT>
867 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::swap(self_type & other)
868 {
869 viennacl::linalg::vector_swap(*this, other);
870 return *this;
871 }
872
873
874 template<class NumericT, typename SizeT, typename DistanceT>
875 void vector_base<NumericT, SizeT, DistanceT>::clear()
876 {
877 viennacl::linalg::vector_assign(*this, cpu_value_type(0.0), true);
878 }
879
880 template<class NumericT, typename SizeT, typename DistanceT>
881 vector_base<NumericT, SizeT, DistanceT> & vector_base<NumericT, SizeT, DistanceT>::fast_swap(self_type & other)
882 {
883 assert(this->size_ == other.size_ && bool("Vector size mismatch"));
884 this->elements_.swap(other.elements_);
885 return *this;
886 }
887
888 template<class NumericT, typename SizeT, typename DistanceT>
889 void vector_base<NumericT, SizeT, DistanceT>::pad()
890 {
891 if (internal_size() != size())
892 {
893 std::vector<NumericT> pad(internal_size() - size());
894 viennacl::backend::memory_write(elements_, sizeof(NumericT) * size(), sizeof(NumericT) * pad.size(), &(pad[0]));
895 }
896 }
897
898 template<class NumericT, typename SizeT, typename DistanceT>
899 void vector_base<NumericT, SizeT, DistanceT>::switch_memory_context(viennacl::context new_ctx)
900 {
901 viennacl::backend::switch_memory_context<NumericT>(elements_, new_ctx);
902 }
903
904 //TODO: Think about implementing the following public member functions
905 //void insert_element(unsigned int i, NumericT val){}
906 //void erase_element(unsigned int i){}
907
908 template<class NumericT, typename SizeT, typename DistanceT>
909 void vector_base<NumericT, SizeT, DistanceT>::resize(size_type new_size, bool preserve)
910 {
911 resize_impl(new_size, viennacl::traits::context(*this), preserve);
912 }
913
914 template<class NumericT, typename SizeT, typename DistanceT>
915 void vector_base<NumericT, SizeT, DistanceT>::resize(size_type new_size, viennacl::context ctx, bool preserve)
916 {
917 resize_impl(new_size, ctx, preserve);
918 }
919
920 template<class NumericT, typename SizeT, typename DistanceT>
921 void vector_base<NumericT, SizeT, DistanceT>::resize_impl(size_type new_size, viennacl::context ctx, bool preserve)
922 {
923 assert(new_size > 0 && bool("Positive size required when resizing vector!"));
924
925 if (new_size != size_)
926 {
927 vcl_size_t new_internal_size = viennacl::tools::align_to_multiple<vcl_size_t>(new_size, dense_padding_size);
928
929 std::vector<NumericT> temp(size_);
930 if (preserve && size_ > 0)
931 fast_copy(*this, temp);
932 temp.resize(new_size); //drop all entries above new_size
933 temp.resize(new_internal_size); //enlarge to fit new internal size
934
935 if (new_internal_size != internal_size())
936 {
937 viennacl::backend::memory_create(elements_, sizeof(NumericT)*new_internal_size, ctx, NULL);
938 }
939
940 fast_copy(temp, *this);
941 size_ = new_size;
942 internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
943 pad();
944 }
945
946 }
947
948
949 template<class NumericT, unsigned int AlignmentV>
950 class vector : public vector_base<NumericT>
951 {
952 typedef vector<NumericT, AlignmentV> self_type;
953 typedef vector_base<NumericT> base_type;
954
955 public:
956 typedef typename base_type::size_type size_type;
957 typedef typename base_type::difference_type difference_type;
958
961 explicit vector() : base_type() { /* Note: One must not call ::init() here because the vector might have been created globally before the backend has become available */ }
962
967 explicit vector(size_type vec_size) : base_type(vec_size) {}
968
969 explicit vector(size_type vec_size, viennacl::context ctx) : base_type(vec_size, ctx) {}
970
971 explicit vector(NumericT * ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start = 0, size_type stride = 1)
972 : base_type(ptr_to_mem, mem_type, vec_size, start, stride) {}
973
974 #ifdef VIENNACL_WITH_OPENCL
975
983 explicit vector(cl_mem existing_mem, size_type vec_size, size_type start = 0, size_type stride = 1) : base_type(existing_mem, vec_size, start, stride) {}
984
990 explicit vector(size_type vec_size, viennacl::ocl::context const & ctx) : base_type(vec_size, ctx) {}
991 #endif
992
993 template<typename LHS, typename RHS, typename OP>
994 vector(vector_expression<const LHS, const RHS, OP> const & proxy) : base_type(proxy) {}
995
996 vector(const base_type & v) : base_type(v.size(), viennacl::traits::context(v))
997 {
998 if (v.size() > 0)
999 base_type::operator=(v);
1000 }
1001
1002 vector(const self_type & v) : base_type(v.size(), viennacl::traits::context(v))
1003 {
1004 if (v.size() > 0)
1005 base_type::operator=(v);
1006 }
1007
1009 vector(unit_vector<NumericT> const & v) : base_type(v.size())
1010 {
1011 if (v.size() > 0)
1012 this->operator()(v.index()) = NumericT(1);;
1013 }
1014
1016 vector(zero_vector<NumericT> const & v) : base_type(v.size(), v.context())
1017 {
1018 if (v.size() > 0)
1019 viennacl::linalg::vector_assign(*this, NumericT(0.0));
1020 }
1021
1023 vector(scalar_vector<NumericT> const & v) : base_type(v.size(), v.context())
1024 {
1025 if (v.size() > 0)
1026 viennacl::linalg::vector_assign(*this, v[0]);
1027 }
1028
1029 // the following is used to circumvent an issue with Clang 3.0 when 'using base_type::operator=;' directly
1030 template<typename T>
1031 self_type & operator=(T const & other)
1032 {
1033 base_type::operator=(other);
1034 return *this;
1035 }
1036
1037 using base_type::operator+=;
1038 using base_type::operator-=;
1039
1040 //enlarge or reduce allocated memory and set unused memory to zero
1046 void resize(size_type new_size, bool preserve = true)
1047 {
1048 base_type::resize(new_size, preserve);
1049 }
1050
1051 void resize(size_type new_size, viennacl::context ctx, bool preserve = true)
1052 {
1053 base_type::resize(new_size, ctx, preserve);
1054 }
1055
1058 self_type & fast_swap(self_type & other)
1059 {
1060 base_type::fast_swap(other);
1061 return *this;
1062 }
1063
1064 void switch_memory_context(viennacl::context new_ctx)
1065 {
1066 base_type::switch_memory_context(new_ctx);
1067 }
1068
1069 }; //vector
1070
1072 template<typename ScalarT>
1073 class vector_tuple
1074 {
1075 typedef vector_base<ScalarT> VectorType;
1076
1077 public:
1078 // 2 vectors
1079
1080 vector_tuple(VectorType const & v0, VectorType const & v1) : const_vectors_(2), non_const_vectors_()
1081 {
1082 const_vectors_[0] = &v0;
1083 const_vectors_[1] = &v1;
1084 }
1085 vector_tuple(VectorType & v0, VectorType & v1) : const_vectors_(2), non_const_vectors_(2)
1086 {
1087 const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1088 const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1089 }
1090
1091 // 3 vectors
1092
1093 vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2) : const_vectors_(3), non_const_vectors_()
1094 {
1095 const_vectors_[0] = &v0;
1096 const_vectors_[1] = &v1;
1097 const_vectors_[2] = &v2;
1098 }
1099 vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2) : const_vectors_(3), non_const_vectors_(3)
1100 {
1101 const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1102 const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1103 const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
1104 }
1105
1106 // 4 vectors
1107
1108 vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2, VectorType const & v3) : const_vectors_(4), non_const_vectors_()
1109 {
1110 const_vectors_[0] = &v0;
1111 const_vectors_[1] = &v1;
1112 const_vectors_[2] = &v2;
1113 const_vectors_[3] = &v3;
1114 }
1115 vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2, VectorType & v3) : const_vectors_(4), non_const_vectors_(4)
1116 {
1117 const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1118 const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1119 const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
1120 const_vectors_[3] = &v3; non_const_vectors_[3] = &v3;
1121 }
1122
1123 // add more overloads here
1124
1125 // generic interface:
1126
1127 vector_tuple(std::vector<VectorType const *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_()
1128 {
1129 for (vcl_size_t i=0; i<vecs.size(); ++i)
1130 const_vectors_[i] = vecs[i];
1131 }
1132
1133 vector_tuple(std::vector<VectorType *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_(vecs.size())
1134 {
1135 for (vcl_size_t i=0; i<vecs.size(); ++i)
1136 {
1137 const_vectors_[i] = vecs[i];
1138 non_const_vectors_[i] = vecs[i];
1139 }
1140 }
1141
1142 vcl_size_t size() const { return non_const_vectors_.size(); }
1143 vcl_size_t const_size() const { return const_vectors_.size(); }
1144
1145 VectorType & at(vcl_size_t i) const { return *(non_const_vectors_.at(i)); }
1146 VectorType const & const_at(vcl_size_t i) const { return *(const_vectors_.at(i)); }
1147
1148 private:
1149 std::vector<VectorType const *> const_vectors_;
1150 std::vector<VectorType *> non_const_vectors_;
1151 };
1152
1153 // 2 args
1154 template<typename ScalarT>
1155 vector_tuple<ScalarT> tie(vector_base<ScalarT> const & v0, vector_base<ScalarT> const & v1) { return vector_tuple<ScalarT>(v0, v1); }
1156
1157 template<typename ScalarT>
1158 vector_tuple<ScalarT> tie(vector_base<ScalarT> & v0, vector_base<ScalarT> & v1) { return vector_tuple<ScalarT>(v0, v1); }
1159
1160 // 3 args
1161 template<typename ScalarT>
1162 vector_tuple<ScalarT> tie(vector_base<ScalarT> const & v0, vector_base<ScalarT> const & v1, vector_base<ScalarT> const & v2) { return vector_tuple<ScalarT>(v0, v1, v2); }
1163
1164 template<typename ScalarT>
1165 vector_tuple<ScalarT> tie(vector_base<ScalarT> & v0, vector_base<ScalarT> & v1, vector_base<ScalarT> & v2) { return vector_tuple<ScalarT>(v0, v1, v2); }
1166
1167 // 4 args
1168 template<typename ScalarT>
1169 vector_tuple<ScalarT> tie(vector_base<ScalarT> const & v0, vector_base<ScalarT> const & v1, vector_base<ScalarT> const & v2, vector_base<ScalarT> const & v3)
1170 {
1171 return vector_tuple<ScalarT>(v0, v1, v2, v3);
1172 }
1173
1174 template<typename ScalarT>
1175 vector_tuple<ScalarT> tie(vector_base<ScalarT> & v0, vector_base<ScalarT> & v1, vector_base<ScalarT> & v2, vector_base<ScalarT> & v3)
1176 {
1177 return vector_tuple<ScalarT>(v0, v1, v2, v3);
1178 }
1179
1180 // 5 args
1181 template<typename ScalarT>
1182 vector_tuple<ScalarT> tie(vector_base<ScalarT> const & v0,
1183 vector_base<ScalarT> const & v1,
1184 vector_base<ScalarT> const & v2,
1185 vector_base<ScalarT> const & v3,
1186 vector_base<ScalarT> const & v4)
1187 {
1188 typedef vector_base<ScalarT> const * VectorPointerType;
1189 std::vector<VectorPointerType> vec(5);
1190 vec[0] = &v0;
1191 vec[1] = &v1;
1192 vec[2] = &v2;
1193 vec[3] = &v3;
1194 vec[4] = &v4;
1195 return vector_tuple<ScalarT>(vec);
1196 }
1197
1198 template<typename ScalarT>
1199 vector_tuple<ScalarT> tie(vector_base<ScalarT> & v0,
1200 vector_base<ScalarT> & v1,
1201 vector_base<ScalarT> & v2,
1202 vector_base<ScalarT> & v3,
1203 vector_base<ScalarT> & v4)
1204 {
1205 typedef vector_base<ScalarT> * VectorPointerType;
1206 std::vector<VectorPointerType> vec(5);
1207 vec[0] = &v0;
1208 vec[1] = &v1;
1209 vec[2] = &v2;
1210 vec[3] = &v3;
1211 vec[4] = &v4;
1212 return vector_tuple<ScalarT>(vec);
1213 }
1214
1215 // TODO: Add more arguments to tie() here. Maybe use some preprocessor magic to accomplish this.
1216
1217 //
1219 //
1220
1221
1233 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1234 void fast_copy(const const_vector_iterator<NumericT, AlignmentV> & gpu_begin,
1235 const const_vector_iterator<NumericT, AlignmentV> & gpu_end,
1236 CPU_ITERATOR cpu_begin )
1237 {
1238 if (gpu_begin != gpu_end)
1239 {
1240 if (gpu_begin.stride() == 1)
1241 {
1242 viennacl::backend::memory_read(gpu_begin.handle(),
1243 sizeof(NumericT)*gpu_begin.offset(),
1244 sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(gpu_end - gpu_begin),
1245 &(*cpu_begin));
1246 }
1247 else
1248 {
1249 vcl_size_t gpu_size = static_cast<vcl_size_t>(gpu_end - gpu_begin);
1250 std::vector<NumericT> temp_buffer(gpu_begin.stride() * gpu_size);
1251 viennacl::backend::memory_read(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
1252
1253 for (vcl_size_t i=0; i<gpu_size; ++i)
1254 {
1255 (&(*cpu_begin))[i] = temp_buffer[i * gpu_begin.stride()];
1256 }
1257 }
1258 }
1259 }
1260
1266 template<typename NumericT, typename CPUVECTOR>
1267 void fast_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1268 {
1269 viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1270 }
1271
1272
1283 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1284 void async_copy(const const_vector_iterator<NumericT, AlignmentV> & gpu_begin,
1285 const const_vector_iterator<NumericT, AlignmentV> & gpu_end,
1286 CPU_ITERATOR cpu_begin )
1287 {
1288 if (gpu_begin != gpu_end)
1289 {
1290 if (gpu_begin.stride() == 1)
1291 {
1292 viennacl::backend::memory_read(gpu_begin.handle(),
1293 sizeof(NumericT)*gpu_begin.offset(),
1294 sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(gpu_end - gpu_begin),
1295 &(*cpu_begin),
1296 true);
1297 }
1298 else // no async copy possible, so fall-back to fast_copy
1299 fast_copy(gpu_begin, gpu_end, cpu_begin);
1300 }
1301 }
1302
1308 template<typename NumericT, typename CPUVECTOR>
1309 void async_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1310 {
1311 viennacl::async_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1312 }
1313
1314
1321 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1322 void copy(const const_vector_iterator<NumericT, AlignmentV> & gpu_begin,
1323 const const_vector_iterator<NumericT, AlignmentV> & gpu_end,
1324 CPU_ITERATOR cpu_begin )
1325 {
1326 assert(gpu_end - gpu_begin >= 0 && bool("Iterators incompatible"));
1327 if (gpu_end - gpu_begin != 0)
1328 {
1329 std::vector<NumericT> temp_buffer(static_cast<vcl_size_t>(gpu_end - gpu_begin));
1330 fast_copy(gpu_begin, gpu_end, temp_buffer.begin());
1331
1332 //now copy entries to cpu_vec:
1333 std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_begin);
1334 }
1335 }
1336
1343 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1344 void copy(const vector_iterator<NumericT, AlignmentV> & gpu_begin,
1345 const vector_iterator<NumericT, AlignmentV> & gpu_end,
1346 CPU_ITERATOR cpu_begin )
1347
1348 {
1349 viennacl::copy(const_vector_iterator<NumericT, AlignmentV>(gpu_begin),
1350 const_vector_iterator<NumericT, AlignmentV>(gpu_end),
1351 cpu_begin);
1352 }
1353
1359 template<typename NumericT, typename CPUVECTOR>
1360 void copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1361 {
1362 viennacl::copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1363 }
1364
1365
1366
1367 #ifdef VIENNACL_WITH_EIGEN
1368 template<typename NumericT, unsigned int AlignmentV>
1369 void copy(vector<NumericT, AlignmentV> const & gpu_vec,
1370 Eigen::Matrix<NumericT, Eigen::Dynamic, 1> & eigen_vec)
1371 {
1372 viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
1373 }
1374
1375 template<typename NumericT, unsigned int AlignmentV, int EigenMapTypeV, typename EigenStrideT>
1376 void copy(vector<NumericT, AlignmentV> const & gpu_vec,
1377 Eigen::Map<Eigen::Matrix<NumericT, Eigen::Dynamic, 1>, EigenMapTypeV, EigenStrideT> & eigen_vec)
1378 {
1379 viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
1380 }
1381 #endif
1382
1383
1384 //
1386 //
1387
1399 template<typename CPU_ITERATOR, typename NumericT, unsigned int AlignmentV>
1400 void fast_copy(CPU_ITERATOR const & cpu_begin,
1401 CPU_ITERATOR const & cpu_end,
1402 vector_iterator<NumericT, AlignmentV> gpu_begin)
1403 {
1404 if (cpu_end - cpu_begin > 0)
1405 {
1406 if (gpu_begin.stride() == 1)
1407 {
1408 viennacl::backend::memory_write(gpu_begin.handle(),
1409 sizeof(NumericT)*gpu_begin.offset(),
1410 sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(cpu_end - cpu_begin), &(*cpu_begin));
1411 }
1412 else //writing to slice:
1413 {
1414 vcl_size_t cpu_size = static_cast<vcl_size_t>(cpu_end - cpu_begin);
1415 std::vector<NumericT> temp_buffer(gpu_begin.stride() * cpu_size);
1416
1417 viennacl::backend::memory_read(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
1418
1419 for (vcl_size_t i=0; i<cpu_size; ++i)
1420 temp_buffer[i * gpu_begin.stride()] = (&(*cpu_begin))[i];
1421
1422 viennacl::backend::memory_write(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
1423 }
1424 }
1425 }
1426
1427
1433 template<typename CPUVECTOR, typename NumericT>
1434 void fast_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
1435 {
1436 viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1437 }
1438
1449 template<typename CPU_ITERATOR, typename NumericT, unsigned int AlignmentV>
1450 void async_copy(CPU_ITERATOR const & cpu_begin,
1451 CPU_ITERATOR const & cpu_end,
1452 vector_iterator<NumericT, AlignmentV> gpu_begin)
1453 {
1454 if (cpu_end - cpu_begin > 0)
1455 {
1456 if (gpu_begin.stride() == 1)
1457 {
1458 viennacl::backend::memory_write(gpu_begin.handle(),
1459 sizeof(NumericT)*gpu_begin.offset(),
1460 sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(cpu_end - cpu_begin), &(*cpu_begin),
1461 true);
1462 }
1463 else // fallback to blocking copy. There's nothing we can do to prevent this
1464 fast_copy(cpu_begin, cpu_end, gpu_begin);
1465 }
1466 }
1467
1468
1474 template<typename CPUVECTOR, typename NumericT>
1475 void async_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
1476 {
1477 viennacl::async_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1478 }
1479
1480 //from cpu to gpu. Safe assumption: cpu_vector does not necessarily occupy a linear memory segment, but is not larger than the allocated memory on the GPU
1487 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1488 void copy(CPU_ITERATOR const & cpu_begin,
1489 CPU_ITERATOR const & cpu_end,
1490 vector_iterator<NumericT, AlignmentV> gpu_begin)
1491 {
1492 assert(cpu_end - cpu_begin > 0 && bool("Iterators incompatible"));
1493 if (cpu_begin != cpu_end)
1494 {
1495 //we require that the size of the gpu_vector is larger or equal to the cpu-size
1496 std::vector<NumericT> temp_buffer(static_cast<vcl_size_t>(cpu_end - cpu_begin));
1497 std::copy(cpu_begin, cpu_end, temp_buffer.begin());
1498 viennacl::fast_copy(temp_buffer.begin(), temp_buffer.end(), gpu_begin);
1499 }
1500 }
1501
1502 // for things like copy(std_vec.begin(), std_vec.end(), vcl_vec.begin() + 1);
1503
1509 template<typename HostVectorT, typename T>
1510 void copy(HostVectorT const & cpu_vec, vector_base<T> & gpu_vec)
1511 {
1512 viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1513 }
1514
1520 template<typename HostVectorT, typename T, unsigned int AlignmentV>
1521 void copy(HostVectorT const & cpu_vec, vector<T, AlignmentV> & gpu_vec)
1522 {
1523 if (gpu_vec.size() == 0)
1524 gpu_vec.resize(static_cast<vcl_size_t>(cpu_vec.end() - cpu_vec.begin()));
1525 viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1526 }
1527
1528
1529 #ifdef VIENNACL_WITH_EIGEN
1530 template<typename NumericT, unsigned int AlignmentV>
1531 void copy(Eigen::Matrix<NumericT, Eigen::Dynamic, 1> const & eigen_vec,
1532 vector<NumericT, AlignmentV> & gpu_vec)
1533 {
1534 viennacl::fast_copy(eigen_vec.data(), eigen_vec.data() + eigen_vec.size(), gpu_vec.begin());
1535 }
1536
1537 template<typename NumericT, int EigenMapTypeV, typename EigenStrideT, unsigned int AlignmentV>
1538 void copy(Eigen::Map<Eigen::Matrix<NumericT, Eigen::Dynamic, 1>, EigenMapTypeV, EigenStrideT> const & eigen_vec,
1539 vector<NumericT, AlignmentV> & gpu_vec)
1540 {
1541 viennacl::fast_copy(eigen_vec.data(), eigen_vec.data() + eigen_vec.size(), gpu_vec.begin());
1542 }
1543 #endif
1544
1545
1546
1547 //
1549 //
1556 template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
1557 void copy(const_vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_begin,
1558 const_vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_end,
1559 vector_iterator<NumericT, AlignmentV_DEST> gpu_dest_begin)
1560 {
1561 assert(gpu_src_end - gpu_src_begin >= 0);
1562 assert(gpu_src_begin.stride() == 1 && bool("ViennaCL ERROR: copy() for GPU->GPU not implemented for slices! Use operator= instead for the moment."));
1563
1564 if (gpu_src_begin.stride() == 1 && gpu_dest_begin.stride() == 1)
1565 {
1566 if (gpu_src_begin != gpu_src_end)
1567 viennacl::backend::memory_copy(gpu_src_begin.handle(), gpu_dest_begin.handle(),
1568 sizeof(NumericT) * gpu_src_begin.offset(),
1569 sizeof(NumericT) * gpu_dest_begin.offset(),
1570 sizeof(NumericT) * (gpu_src_end.offset() - gpu_src_begin.offset()));
1571 }
1572 else
1573 {
1574 assert( false && bool("not implemented yet"));
1575 }
1576 }
1577
1584 template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
1585 void copy(vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_begin,
1586 vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_end,
1587 vector_iterator<NumericT, AlignmentV_DEST> gpu_dest_begin)
1588 {
1589 viennacl::copy(static_cast<const_vector_iterator<NumericT, AlignmentV_SRC> >(gpu_src_begin),
1590 static_cast<const_vector_iterator<NumericT, AlignmentV_SRC> >(gpu_src_end),
1591 gpu_dest_begin);
1592 }
1593
1599 template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
1600 void copy(vector<NumericT, AlignmentV_SRC> const & gpu_src_vec,
1601 vector<NumericT, AlignmentV_DEST> & gpu_dest_vec )
1602 {
1603 viennacl::copy(gpu_src_vec.begin(), gpu_src_vec.end(), gpu_dest_vec.begin());
1604 }
1605
1606
1607
1608
1609
1610
1611 //global functions for handling vectors:
1616 template<typename T>
1617 std::ostream & operator<<(std::ostream & os, vector_base<T> const & val)
1618 {
1619 std::vector<T> tmp(val.size());
1620 viennacl::copy(val.begin(), val.end(), tmp.begin());
1621 os << "[" << val.size() << "](";
1622 for (typename std::vector<T>::size_type i=0; i<val.size(); ++i)
1623 {
1624 if (i > 0)
1625 os << ",";
1626 os << tmp[i];
1627 }
1628 os << ")";
1629 return os;
1630 }
1631
1632 template<typename LHS, typename RHS, typename OP>
1633 std::ostream & operator<<(std::ostream & os, vector_expression<LHS, RHS, OP> const & proxy)
1634
1635 {
1636 typedef typename viennacl::result_of::cpu_value_type<typename LHS::value_type>::type ScalarType;
1637 viennacl::vector<ScalarType> result = proxy;
1638 os << result;
1639 return os;
1640 }
1641
1647 template<typename T>
1648 void swap(vector_base<T> & vec1, vector_base<T> & vec2)
1649 {
1650 viennacl::linalg::vector_swap(vec1, vec2);
1651 }
1652
1658 template<typename NumericT, unsigned int AlignmentV>
1659 vector<NumericT, AlignmentV> & fast_swap(vector<NumericT, AlignmentV> & v1,
1660 vector<NumericT, AlignmentV> & v2)
1661 {
1662 return v1.fast_swap(v2);
1663 }
1664
1665
1666
1667
1668
1669 //
1670 //
1672 //
1673 //
1674
1675
1676 //
1677 // operator *=
1678 //
1679
1682 template<typename T, typename S1>
1683 typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
1684 vector_base<T> &
1685 >::type
1686 operator *= (vector_base<T> & v1, S1 const & gpu_val)
1687 {
1688 bool flip_sign = viennacl::is_flip_sign_scalar<S1>::value;
1689 if (v1.size() > 0)
1690 viennacl::linalg::av(v1,
1691 v1, gpu_val, 1, false, flip_sign);
1692 return v1;
1693 }
1694
1695
1696 //
1697 // operator /=
1698 //
1699
1700
1703 template<typename T, typename S1>
1704 typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
1705 vector_base<T> &
1706 >::type
1707 operator /= (vector_base<T> & v1, S1 const & gpu_val)
1708 {
1709 bool flip_sign = viennacl::is_flip_sign_scalar<S1>::value;
1710 if (v1.size() > 0)
1711 viennacl::linalg::av(v1,
1712 v1, gpu_val, 1, true, flip_sign);
1713 return v1;
1714 }
1715
1716
1717 //
1718 // operator +
1719 //
1720
1721
1727 template<typename LHS1, typename RHS1, typename OP1,
1728 typename LHS2, typename RHS2, typename OP2>
1729 vector_expression< const vector_expression< LHS1, RHS1, OP1>,
1730 const vector_expression< LHS2, RHS2, OP2>,
1731 viennacl::op_add>
1732 operator + (vector_expression<LHS1, RHS1, OP1> const & proxy1,
1733 vector_expression<LHS2, RHS2, OP2> const & proxy2)
1734 {
1735 assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
1736 return vector_expression< const vector_expression<LHS1, RHS1, OP1>,
1737 const vector_expression<LHS2, RHS2, OP2>,
1738 viennacl::op_add>(proxy1, proxy2);
1739 }
1740
1746 template<typename LHS, typename RHS, typename OP, typename T>
1747 vector_expression< const vector_expression<LHS, RHS, OP>,
1748 const vector_base<T>,
1749 viennacl::op_add>
1750 operator + (vector_expression<LHS, RHS, OP> const & proxy,
1751 vector_base<T> const & vec)
1752 {
1753 assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1754 return vector_expression< const vector_expression<LHS, RHS, OP>,
1755 const vector_base<T>,
1756 viennacl::op_add>(proxy, vec);
1757 }
1758
1764 template<typename T, typename LHS, typename RHS, typename OP>
1765 vector_expression< const vector_base<T>,
1766 const vector_expression<LHS, RHS, OP>,
1767 viennacl::op_add>
1768 operator + (vector_base<T> const & vec,
1769 vector_expression<LHS, RHS, OP> const & proxy)
1770 {
1771 assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1772 return vector_expression< const vector_base<T>,
1773 const vector_expression<LHS, RHS, OP>,
1774 viennacl::op_add>(vec, proxy);
1775 }
1776
1779 template<typename T>
1780 vector_expression< const vector_base<T>, const vector_base<T>, op_add>
1781 operator + (const vector_base<T> & v1, const vector_base<T> & v2)
1782 {
1783 return vector_expression< const vector_base<T>, const vector_base<T>, op_add>(v1, v2);
1784 }
1785
1786
1787
1788 //
1789 // operator -
1790 //
1791
1797 template<typename LHS1, typename RHS1, typename OP1,
1798 typename LHS2, typename RHS2, typename OP2>
1799 vector_expression< const vector_expression< LHS1, RHS1, OP1>,
1800 const vector_expression< LHS2, RHS2, OP2>,
1801 viennacl::op_sub>
1802 operator - (vector_expression<LHS1, RHS1, OP1> const & proxy1,
1803 vector_expression<LHS2, RHS2, OP2> const & proxy2)
1804 {
1805 assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
1806 return vector_expression< const vector_expression<LHS1, RHS1, OP1>,
1807 const vector_expression<LHS2, RHS2, OP2>,
1808 viennacl::op_sub>(proxy1, proxy2);
1809 }
1810
1811
1817 template<typename LHS, typename RHS, typename OP, typename T>
1818 vector_expression< const vector_expression<LHS, RHS, OP>,
1819 const vector_base<T>,
1820 viennacl::op_sub>
1821 operator - (vector_expression<LHS, RHS, OP> const & proxy,
1822 vector_base<T> const & vec)
1823 {
1824 assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1825 return vector_expression< const vector_expression<LHS, RHS, OP>,
1826 const vector_base<T>,
1827 viennacl::op_sub>(proxy, vec);
1828 }
1829
1835 template<typename T, typename LHS, typename RHS, typename OP>
1836 vector_expression< const vector_base<T>,
1837 const vector_expression<LHS, RHS, OP>,
1838 viennacl::op_sub>
1839 operator - (vector_base<T> const & vec,
1840 vector_expression<LHS, RHS, OP> const & proxy)
1841 {
1842 assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1843 return vector_expression< const vector_base<T>,
1844 const vector_expression<LHS, RHS, OP>,
1845 viennacl::op_sub>(vec, proxy);
1846 }
1847
1850 template<typename T>
1851 vector_expression< const vector_base<T>, const vector_base<T>, op_sub>
1852 operator - (const vector_base<T> & v1, const vector_base<T> & v2)
1853 {
1854 return vector_expression< const vector_base<T>, const vector_base<T>, op_sub>(v1, v2);
1855 }
1856
1857
1858 //
1859 // operator *
1860 //
1861
1862
1868 template<typename S1, typename T>
1869 typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
1870 vector_expression< const vector_base<T>, const S1, op_mult> >::type
1871 operator * (S1 const & value, vector_base<T> const & vec)
1872 {
1873 return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
1874 }
1875
1881 template<typename T>
1882 vector_expression< const vector_base<T>, const T, op_mult>
1883 operator * (char value, vector_base<T> const & vec)
1884 {
1885 return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1886 }
1887
1893 template<typename T>
1894 vector_expression< const vector_base<T>, const T, op_mult>
1895 operator * (short value, vector_base<T> const & vec)
1896 {
1897 return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1898 }
1899
1905 template<typename T>
1906 vector_expression< const vector_base<T>, const T, op_mult>
1907 operator * (int value, vector_base<T> const & vec)
1908 {
1909 return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1910 }
1911
1917 template<typename T>
1918 vector_expression< const vector_base<T>, const T, op_mult>
1919 operator * (long value, vector_base<T> const & vec)
1920 {
1921 return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1922 }
1923
1929 template<typename T>
1930 vector_expression< const vector_base<T>, const T, op_mult>
1931 operator * (float value, vector_base<T> const & vec)
1932 {
1933 return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1934 }
1935
1941 template<typename T>
1942 vector_expression< const vector_base<T>, const T, op_mult>
1943 operator * (double value, vector_base<T> const & vec)
1944 {
1945 return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1946 }
1947
1948
1949
1955 template<typename LHS, typename RHS, typename OP, typename T>
1956 vector_expression< const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult>
1957 operator * (scalar_expression<LHS, RHS, OP> const & expr, vector_base<T> const & vec)
1958 {
1959 return vector_expression< const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult>(vec, expr);
1960 }
1961
1964 template<typename T, typename S1>
1965 typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
1966 vector_expression< const vector_base<T>, const S1, op_mult> >::type
1967 operator * (vector_base<T> const & vec, S1 const & value)
1968 {
1969 return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
1970 }
1971
1972 template<typename T>
1973 vector_expression< const vector_base<T>, const T, op_mult>
1974 operator * (vector_base<T> const & vec, T const & value)
1975 {
1976 return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1977 }
1978
1984 template<typename LHS, typename RHS, typename OP, typename S1>
1985 typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
1986 viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult> >::type
1987 operator * (vector_expression< LHS, RHS, OP> const & proxy,
1988 S1 const & val)
1989 {
1990 return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult>(proxy, val);
1991 }
1992
1998 template<typename S1, typename LHS, typename RHS, typename OP>
1999 typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
2000 viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult> >::type
2001 operator * (S1 const & val,
2002 vector_expression<LHS, RHS, OP> const & proxy)
2003 {
2004 return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult>(proxy, val);
2005 }
2006
2007 //
2008 // operator /
2009 //
2010
2016 template<typename S1, typename LHS, typename RHS, typename OP>
2017 typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
2018 viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_div> >::type
2019 operator / (vector_expression< LHS, RHS, OP> const & proxy,
2020 S1 const & val)
2021 {
2022 return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_div>(proxy, val);
2023 }
2024
2025
2028 template<typename T, typename S1>
2029 typename viennacl::enable_if< viennacl::is_any_scalar<S1>::value,
2030 vector_expression< const vector_base<T>, const S1, op_div> >::type
2031 operator / (vector_base<T> const & v1, S1 const & s1)
2032 {
2033 return vector_expression<const vector_base<T>, const S1, op_div>(v1, s1);
2034 }
2035
2036
2037
2038 //
2039 // Specify available operations:
2040 //
2041
2044 namespace linalg
2045 {
2046 namespace detail
2047 {
2048 // x = y
2049 template<typename T>
2050 struct op_executor<vector_base<T>, op_assign, vector_base<T> >
2051 {
2052 static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2053 {
2054 viennacl::linalg::av(lhs, rhs, T(1), 1, false, false);
2055 }
2056 };
2057
2058 // x = inner_prod(z, {y0, y1, ...})
2059 template<typename T>
2060 struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> >
2061 {
2062 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> const & rhs)
2063 {
2064 viennacl::linalg::inner_prod_impl(rhs.lhs(), rhs.rhs(), lhs);
2065 }
2066 };
2067
2068 // x += y
2069 template<typename T>
2070 struct op_executor<vector_base<T>, op_inplace_add, vector_base<T> >
2071 {
2072 static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2073 {
2074 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, false);
2075 }
2076 };
2077
2078 // x -= y
2079 template<typename T>
2080 struct op_executor<vector_base<T>, op_inplace_sub, vector_base<T> >
2081 {
2082 static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2083 {
2084 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, true);
2085 }
2086 };
2087
2089
2090
2091 // x = alpha * y
2092 template<typename T, typename ScalarType>
2093 struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2094 {
2095 // generic case: ScalarType is a scalar expression
2096 template<typename LHS, typename RHS, typename OP>
2097 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2098 {
2099 T alpha = proxy.rhs();
2100 viennacl::linalg::av(lhs, proxy.lhs(), alpha, 1, false, false);
2101 }
2102
2103 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2104 {
2105 viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
2106 }
2107
2108 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2109 {
2110 viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
2111 }
2112 };
2113
2114 // x += alpha * y
2115 template<typename T, typename ScalarType>
2116 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2117 {
2118 // generic case: ScalarType is a scalar expression
2119 template<typename LHS, typename RHS, typename OP>
2120 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2121 {
2122 T alpha = proxy.rhs();
2123 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, false);
2124 }
2125
2126 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2127 {
2128 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
2129 }
2130
2131 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2132 {
2133 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
2134 }
2135 };
2136
2137 // x -= alpha * y
2138 template<typename T, typename ScalarType>
2139 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2140 {
2141 // generic case: ScalarType is a scalar expression
2142 template<typename LHS, typename RHS, typename OP>
2143 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2144 {
2145 T alpha = proxy.rhs();
2146 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, true);
2147 }
2148
2149 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2150 {
2151 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
2152 }
2153
2154 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2155 {
2156 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
2157 }
2158 };
2159
2160
2162
2163 // x = alpha * vec_expr
2164 template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2165 struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2166 {
2167 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2168 {
2169 vector<T> temp(proxy.lhs());
2170 lhs = temp * proxy.rhs();
2171 }
2172 };
2173
2174 // x += alpha * vec_expr
2175 template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2176 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2177 {
2178 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2179 {
2180 vector<T> temp(proxy.lhs());
2181 lhs += temp * proxy.rhs();
2182 }
2183 };
2184
2185 // x -= alpha * vec_expr
2186 template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2187 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2188 {
2189 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2190 {
2191 vector<T> temp(proxy.lhs());
2192 lhs -= temp * proxy.rhs();
2193 }
2194 };
2195
2196
2198
2199 // x = y / alpha
2200 template<typename T, typename ScalarType>
2201 struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2202 {
2203 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2204 {
2205 viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, true, false);
2206 }
2207 };
2208
2209 // x += y / alpha
2210 template<typename T, typename ScalarType>
2211 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2212 {
2213 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2214 {
2215 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, false);
2216 }
2217 };
2218
2219 // x -= y / alpha
2220 template<typename T, typename ScalarType>
2221 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2222 {
2223 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2224 {
2225 viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, true);
2226 }
2227 };
2228
2229
2231
2232 // x = vec_expr / alpha
2233 template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2234 struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2235 {
2236 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2237 {
2238 vector<T> temp(proxy.lhs());
2239 lhs = temp / proxy.rhs();
2240 }
2241 };
2242
2243 // x += vec_expr / alpha
2244 template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2245 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2246 {
2247 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2248 {
2249 vector<T> temp(proxy.lhs());
2250 lhs += temp / proxy.rhs();
2251 }
2252 };
2253
2254 // x -= vec_expr / alpha
2255 template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2256 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2257 {
2258 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2259 {
2260 vector<T> temp(proxy.lhs());
2261 lhs -= temp / proxy.rhs();
2262 }
2263 };
2264
2265
2266
2267 // generic x = vec_expr1 + vec_expr2:
2268 template<typename T, typename LHS, typename RHS>
2269 struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_add> >
2270 {
2271 // generic x = vec_expr1 + vec_expr2:
2272 template<typename LHS1, typename RHS1>
2273 static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2274 {
2275 bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2276 bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2277
2278 if (op_aliasing_lhs || op_aliasing_rhs)
2279 {
2280 vector_base<T> temp(proxy.lhs());
2281 op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2282 lhs = temp;
2283 }
2284 else
2285 {
2286 op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
2287 op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2288 }
2289 }
2290
2291 // x = y + z
2292 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2293 {
2294 viennacl::linalg::avbv(lhs,
2295 proxy.lhs(), T(1), 1, false, false,
2296 proxy.rhs(), T(1), 1, false, false);
2297 }
2298
2299 // x = alpha * y + z
2300 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2301 const vector_base<T>,
2302 op_add> const & proxy)
2303 {
2304 viennacl::linalg::avbv(lhs,
2305 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2306 proxy.rhs(), T(1), 1, false, false);
2307 }
2308
2309 // x = y / alpha + z
2310 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2311 const vector_base<T>,
2312 op_add> const & proxy)
2313 {
2314 viennacl::linalg::avbv(lhs,
2315 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2316 proxy.rhs(), T(1), 1, false, false);
2317 }
2318
2319 // x = y + beta * z
2320 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2321 const vector_expression<const vector_base<T>, const T, op_mult>,
2322 op_add> const & proxy)
2323 {
2324 viennacl::linalg::avbv(lhs,
2325 proxy.lhs(), T(1), 1, false, false,
2326 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2327 }
2328
2329 // x = y + z / beta
2330 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2331 const vector_expression<const vector_base<T>, const T, op_div>,
2332 op_add> const & proxy)
2333 {
2334 viennacl::linalg::avbv(lhs,
2335 proxy.lhs(), T(1), 1, false, false,
2336 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2337 }
2338
2339 // x = alpha * y + beta * z
2340 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2341 const vector_expression<const vector_base<T>, const T, op_mult>,
2342 op_add> const & proxy)
2343 {
2344 viennacl::linalg::avbv(lhs,
2345 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2346 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2347 }
2348
2349 // x = alpha * y + z / beta
2350 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2351 const vector_expression<const vector_base<T>, const T, op_div>,
2352 op_add> const & proxy)
2353 {
2354 viennacl::linalg::avbv(lhs,
2355 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2356 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2357 }
2358
2359 // x = y / alpha + beta * z
2360 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2361 const vector_expression<const vector_base<T>, const T, op_mult>,
2362 op_add> const & proxy)
2363 {
2364 viennacl::linalg::avbv(lhs,
2365 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2366 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2367 }
2368
2369 // x = y / alpha + z / beta
2370 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2371 const vector_expression<const vector_base<T>, const T, op_div>,
2372 op_add> const & proxy)
2373 {
2374 viennacl::linalg::avbv(lhs,
2375 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2376 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2377 }
2378 };
2379
2380
2381 // generic x += vec_expr1 + vec_expr2:
2382 template<typename T, typename LHS, typename RHS>
2383 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_add> >
2384 {
2385 // generic x += vec_expr1 + vec_expr2:
2386 template<typename LHS1, typename RHS1>
2387 static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2388 {
2389 bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2390 bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2391
2392 if (op_aliasing_lhs || op_aliasing_rhs)
2393 {
2394 vector_base<T> temp(proxy.lhs());
2395 op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2396 lhs += temp;
2397 }
2398 else
2399 {
2400 op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
2401 op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2402 }
2403 }
2404
2405 // x += y + z
2406 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2407 {
2408 viennacl::linalg::avbv_v(lhs,
2409 proxy.lhs(), T(1), 1, false, false,
2410 proxy.rhs(), T(1), 1, false, false);
2411 }
2412
2413 // x += alpha * y + z
2414 template<typename ScalarType>
2415 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2416 const vector_base<T>,
2417 op_add> const & proxy)
2418 {
2419 viennacl::linalg::avbv_v(lhs,
2420 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2421 proxy.rhs(), T(1), 1, false, false);
2422 }
2423
2424 // x += y / alpha + z
2425 template<typename ScalarType>
2426 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2427 const vector_base<T>,
2428 op_add> const & proxy)
2429 {
2430 viennacl::linalg::avbv_v(lhs,
2431 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2432 proxy.rhs(), T(1), 1, false, false);
2433 }
2434
2435 // x += y + beta * z
2436 template<typename ScalarType>
2437 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2438 const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2439 op_add> const & proxy)
2440 {
2441 viennacl::linalg::avbv_v(lhs,
2442 proxy.lhs(), T(1), 1, false, false,
2443 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2444 }
2445
2446 // x += y + z / beta
2447 template<typename ScalarType>
2448 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2449 const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2450 op_add> const & proxy)
2451 {
2452 viennacl::linalg::avbv_v(lhs,
2453 proxy.lhs(), T(1), 1, false, false,
2454 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2455 }
2456
2457 // x += alpha * y + beta * z
2458 template<typename ScalarType1, typename ScalarType2>
2459 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2460 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2461 op_add> const & proxy)
2462 {
2463 viennacl::linalg::avbv_v(lhs,
2464 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2465 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2466 }
2467
2468 // x += alpha * y + z / beta
2469 template<typename ScalarType1, typename ScalarType2>
2470 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2471 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2472 op_add> const & proxy)
2473 {
2474 viennacl::linalg::avbv_v(lhs,
2475 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2476 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2477 }
2478
2479 // x += y / alpha + beta * z
2480 template<typename ScalarType1, typename ScalarType2>
2481 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2482 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2483 op_add> const & proxy)
2484 {
2485 viennacl::linalg::avbv_v(lhs,
2486 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2487 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2488 }
2489
2490 // x += y / alpha + z / beta
2491 template<typename ScalarType1, typename ScalarType2>
2492 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2493 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2494 op_add> const & proxy)
2495 {
2496 viennacl::linalg::avbv_v(lhs,
2497 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2498 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2499 }
2500 };
2501
2502
2503
2504 // generic x -= vec_expr1 + vec_expr2:
2505 template<typename T, typename LHS, typename RHS>
2506 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_add> >
2507 {
2508 // generic x -= vec_expr1 + vec_expr2:
2509 template<typename LHS1, typename RHS1>
2510 static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2511 {
2512 bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2513 bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2514
2515 if (op_aliasing_lhs || op_aliasing_rhs)
2516 {
2517 vector_base<T> temp(proxy.lhs());
2518 op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2519 lhs -= temp;
2520 }
2521 else
2522 {
2523 op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
2524 op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2525 }
2526 }
2527
2528 // x -= y + z
2529 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2530 {
2531 viennacl::linalg::avbv_v(lhs,
2532 proxy.lhs(), T(1), 1, false, true,
2533 proxy.rhs(), T(1), 1, false, true);
2534 }
2535
2536 // x -= alpha * y + z
2537 template<typename ScalarType>
2538 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2539 const vector_base<T>,
2540 op_add> const & proxy)
2541 {
2542 viennacl::linalg::avbv_v(lhs,
2543 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2544 proxy.rhs(), T(1), 1, false, true);
2545 }
2546
2547 // x -= y / alpha + z
2548 template<typename ScalarType>
2549 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2550 const vector_base<T>,
2551 op_add> const & proxy)
2552 {
2553 viennacl::linalg::avbv_v(lhs,
2554 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2555 proxy.rhs(), T(1), 1, false, true);
2556 }
2557
2558 // x -= y + beta * z
2559 template<typename ScalarType>
2560 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2561 const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2562 op_add> const & proxy)
2563 {
2564 viennacl::linalg::avbv_v(lhs,
2565 proxy.lhs(), T(1), 1, false, true,
2566 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2567 }
2568
2569 // x -= y + z / beta
2570 template<typename ScalarType>
2571 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2572 const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2573 op_add> const & proxy)
2574 {
2575 viennacl::linalg::avbv_v(lhs,
2576 proxy.lhs(), T(1), 1, false, true,
2577 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2578 }
2579
2580 // x -= alpha * y + beta * z
2581 template<typename ScalarType1, typename ScalarType2>
2582 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2583 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2584 op_add> const & proxy)
2585 {
2586 viennacl::linalg::avbv_v(lhs,
2587 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2588 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2589 }
2590
2591 // x -= alpha * y + z / beta
2592 template<typename ScalarType1, typename ScalarType2>
2593 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2594 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2595 op_add> const & proxy)
2596 {
2597 viennacl::linalg::avbv_v(lhs,
2598 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2599 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2600 }
2601
2602 // x -= y / alpha + beta * z
2603 template<typename ScalarType1, typename ScalarType2>
2604 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2605 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2606 op_add> const & proxy)
2607 {
2608 viennacl::linalg::avbv_v(lhs,
2609 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2610 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2611 }
2612
2613 // x -= y / alpha + z / beta
2614 template<typename ScalarType1, typename ScalarType2>
2615 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2616 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2617 op_add> const & proxy)
2618 {
2619 viennacl::linalg::avbv_v(lhs,
2620 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2621 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2622 }
2623 };
2624
2625
2626
2628
2629
2630
2631 // generic x = vec_expr1 - vec_expr2:
2632 template<typename T, typename LHS, typename RHS>
2633 struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_sub> >
2634 {
2635 // generic x = vec_expr1 - vec_expr2:
2636 template<typename LHS1, typename RHS1>
2637 static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2638 {
2639 bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2640 bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2641
2642 if (op_aliasing_lhs || op_aliasing_rhs)
2643 {
2644 vector_base<T> temp(proxy.lhs());
2645 op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2646 lhs = temp;
2647 }
2648 else
2649 {
2650 op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
2651 op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2652 }
2653 }
2654
2655 // x = y - z
2656 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2657 {
2658 viennacl::linalg::avbv(lhs,
2659 proxy.lhs(), T(1), 1, false, false,
2660 proxy.rhs(), T(1), 1, false, true);
2661 }
2662
2663 // x = alpha * y - z
2664 template<typename ScalarType>
2665 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2666 const vector_base<T>,
2667 op_sub> const & proxy)
2668 {
2669 viennacl::linalg::avbv(lhs,
2670 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2671 proxy.rhs(), T(1), 1, false, true);
2672 }
2673
2674 // x = y / alpha - z
2675 template<typename ScalarType>
2676 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2677 const vector_base<T>,
2678 op_sub> const & proxy)
2679 {
2680 viennacl::linalg::avbv(lhs,
2681 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2682 proxy.rhs(), T(1), 1, false, true);
2683 }
2684
2685 // x = y - beta * z
2686 template<typename ScalarType>
2687 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2688 const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2689 op_sub> const & proxy)
2690 {
2691 viennacl::linalg::avbv(lhs,
2692 proxy.lhs(), T(1), 1, false, false,
2693 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2694 }
2695
2696 // x = y - z / beta
2697 template<typename ScalarType>
2698 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2699 const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2700 op_sub> const & proxy)
2701 {
2702 viennacl::linalg::avbv(lhs,
2703 proxy.lhs(), T(1), 1, false, false,
2704 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2705 }
2706
2707 // x = alpha * y - beta * z
2708 template<typename ScalarType1, typename ScalarType2>
2709 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2710 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2711 op_sub> const & proxy)
2712 {
2713 viennacl::linalg::avbv(lhs,
2714 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2715 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2716 }
2717
2718 // x = alpha * y - z / beta
2719 template<typename ScalarType1, typename ScalarType2>
2720 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2721 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2722 op_sub> const & proxy)
2723 {
2724 viennacl::linalg::avbv(lhs,
2725 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2726 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2727 }
2728
2729 // x = y / alpha - beta * z
2730 template<typename ScalarType1, typename ScalarType2>
2731 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2732 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2733 op_sub> const & proxy)
2734 {
2735 viennacl::linalg::avbv(lhs,
2736 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2737 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2738 }
2739
2740 // x = y / alpha - z / beta
2741 template<typename ScalarType1, typename ScalarType2>
2742 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2743 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2744 op_sub> const & proxy)
2745 {
2746 viennacl::linalg::avbv(lhs,
2747 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2748 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2749 }
2750 };
2751
2752
2753 // generic x += vec_expr1 - vec_expr2:
2754 template<typename T, typename LHS, typename RHS>
2755 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_sub> >
2756 {
2757 // generic x += vec_expr1 - vec_expr2:
2758 template<typename LHS1, typename RHS1>
2759 static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2760 {
2761 bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2762 bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2763
2764 if (op_aliasing_lhs || op_aliasing_rhs)
2765 {
2766 vector_base<T> temp(proxy.lhs());
2767 op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2768 lhs += temp;
2769 }
2770 else
2771 {
2772 op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
2773 op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2774 }
2775 }
2776
2777 // x += y - z
2778 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2779 {
2780 viennacl::linalg::avbv_v(lhs,
2781 proxy.lhs(), T(1), 1, false, false,
2782 proxy.rhs(), T(1), 1, false, true);
2783 }
2784
2785 // x += alpha * y - z
2786 template<typename ScalarType>
2787 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2788 const vector_base<T>,
2789 op_sub> const & proxy)
2790 {
2791 viennacl::linalg::avbv_v(lhs,
2792 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2793 proxy.rhs(), T(1), 1, false, true);
2794 }
2795
2796 // x += y / alpha - z
2797 template<typename ScalarType>
2798 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2799 const vector_base<T>,
2800 op_sub> const & proxy)
2801 {
2802 viennacl::linalg::avbv_v(lhs,
2803 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2804 proxy.rhs(), T(1), 1, false, true);
2805 }
2806
2807 // x += y - beta * z
2808 template<typename ScalarType>
2809 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2810 const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2811 op_sub> const & proxy)
2812 {
2813 viennacl::linalg::avbv_v(lhs,
2814 proxy.lhs(), T(1), 1, false, false,
2815 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2816 }
2817
2818 // x += y - z / beta
2819 template<typename ScalarType>
2820 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2821 const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2822 op_sub> const & proxy)
2823 {
2824 viennacl::linalg::avbv_v(lhs,
2825 proxy.lhs(), T(1), 1, false, false,
2826 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2827 }
2828
2829 // x += alpha * y - beta * z
2830 template<typename ScalarType1, typename ScalarType2>
2831 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2832 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2833 op_sub> const & proxy)
2834 {
2835 viennacl::linalg::avbv_v(lhs,
2836 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2837 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2838 }
2839
2840 // x += alpha * y - z / beta
2841 template<typename ScalarType1, typename ScalarType2>
2842 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2843 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2844 op_sub> const & proxy)
2845 {
2846 viennacl::linalg::avbv_v(lhs,
2847 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2848 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2849 }
2850
2851 // x += y / alpha - beta * z
2852 template<typename ScalarType1, typename ScalarType2>
2853 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2854 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2855 op_sub> const & proxy)
2856 {
2857 viennacl::linalg::avbv_v(lhs,
2858 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2859 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2860 }
2861
2862 // x += y / alpha - z / beta
2863 template<typename ScalarType1, typename ScalarType2>
2864 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2865 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2866 op_sub> const & proxy)
2867 {
2868 viennacl::linalg::avbv_v(lhs,
2869 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2870 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2871 }
2872 };
2873
2874
2875
2876 // generic x -= vec_expr1 - vec_expr2:
2877 template<typename T, typename LHS, typename RHS>
2878 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_sub> >
2879 {
2880 // generic x -= vec_expr1 - vec_expr2:
2881 template<typename LHS1, typename RHS1>
2882 static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2883 {
2884 bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2885 bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2886
2887 if (op_aliasing_lhs || op_aliasing_rhs)
2888 {
2889 vector_base<T> temp(proxy.lhs());
2890 op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2891 lhs -= temp;
2892 }
2893 else
2894 {
2895 op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
2896 op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2897 }
2898 }
2899
2900 // x -= y - z
2901 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2902 {
2903 viennacl::linalg::avbv_v(lhs,
2904 proxy.lhs(), T(1), 1, false, true,
2905 proxy.rhs(), T(1), 1, false, false);
2906 }
2907
2908 // x -= alpha * y - z
2909 template<typename ScalarType>
2910 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2911 const vector_base<T>,
2912 op_sub> const & proxy)
2913 {
2914 viennacl::linalg::avbv_v(lhs,
2915 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2916 proxy.rhs(), T(1), 1, false, false);
2917 }
2918
2919 // x -= y / alpha - z
2920 template<typename ScalarType>
2921 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2922 const vector_base<T>,
2923 op_sub> const & proxy)
2924 {
2925 viennacl::linalg::avbv_v(lhs,
2926 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2927 proxy.rhs(), T(1), 1, false, false);
2928 }
2929
2930 // x -= y - beta * z
2931 template<typename ScalarType>
2932 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2933 const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2934 op_sub> const & proxy)
2935 {
2936 viennacl::linalg::avbv_v(lhs,
2937 proxy.lhs(), T(1), 1, false, true,
2938 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2939 }
2940
2941 // x -= y - z / beta
2942 template<typename ScalarType>
2943 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2944 const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2945 op_sub> const & proxy)
2946 {
2947 viennacl::linalg::avbv_v(lhs,
2948 proxy.lhs(), T(1), 1, false, true,
2949 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2950 }
2951
2952 // x -= alpha * y - beta * z
2953 template<typename ScalarType1, typename ScalarType2>
2954 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2955 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2956 op_sub> const & proxy)
2957 {
2958 viennacl::linalg::avbv_v(lhs,
2959 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2960 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2961 }
2962
2963 // x -= alpha * y - z / beta
2964 template<typename ScalarType1, typename ScalarType2>
2965 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2966 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2967 op_sub> const & proxy)
2968 {
2969 viennacl::linalg::avbv_v(lhs,
2970 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2971 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2972 }
2973
2974 // x -= y / alpha - beta * z
2975 template<typename ScalarType1, typename ScalarType2>
2976 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2977 const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2978 op_sub> const & proxy)
2979 {
2980 viennacl::linalg::avbv_v(lhs,
2981 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2982 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2983 }
2984
2985 // x -= y / alpha - z / beta
2986 template<typename ScalarType1, typename ScalarType2>
2987 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2988 const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2989 op_sub> const & proxy)
2990 {
2991 viennacl::linalg::avbv_v(lhs,
2992 proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2993 proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2994 }
2995 };
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3015
3016 // generic x = vec_expr1 .* vec_expr2:
3017 template<typename T, typename LHS, typename RHS, typename OP>
3018 struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3019 {
3020 // x = y .* z or x = y ./ z
3021 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3022 {
3023 viennacl::linalg::element_op(lhs, proxy);
3024 }
3025
3026 // x = y .* vec_expr or x = y ./ vec_expr
3027 template<typename LHS2, typename RHS2, typename OP2>
3028 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_expression<const LHS2, const RHS2, OP2>, op_element_binary<OP> > const & proxy)
3029 {
3030 vector<T> temp(proxy.rhs());
3031 viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3032 }
3033
3034 // x = vec_expr .* z or x = vec_expr ./ z
3035 template<typename LHS1, typename RHS1, typename OP1>
3036 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3037 {
3038 vector<T> temp(proxy.lhs());
3039 viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3040 }
3041
3042 // x = vec_expr .* vec_expr or z = vec_expr .* vec_expr
3043 template<typename LHS1, typename RHS1, typename OP1,
3044 typename LHS2, typename RHS2, typename OP2>
3045 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3046 const vector_expression<const LHS2, const RHS2, OP2>,
3047 op_element_binary<OP> > const & proxy)
3048 {
3049 vector<T> temp1(proxy.lhs());
3050 vector<T> temp2(proxy.rhs());
3051 viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3052 }
3053 };
3054
3055 // generic x += vec_expr1 .* vec_expr2:
3056 template<typename T, typename LHS, typename RHS, typename OP>
3057 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3058 {
3059 // x += y .* z or x += y ./ z
3060 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3061 {
3062 viennacl::vector<T> temp(proxy);
3063 lhs += temp;
3064 }
3065
3066 // x += y .* vec_expr or x += y ./ vec_expr
3067 template<typename LHS2, typename RHS2, typename OP2>
3068 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_expression<const LHS2, const RHS2, OP2>, op_element_binary<OP> > const & proxy)
3069 {
3070 vector<T> temp(proxy.rhs());
3071 vector<T> temp2(temp.size());
3072 viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3073 lhs += temp2;
3074 }
3075
3076 // x += vec_expr .* z or x += vec_expr ./ z
3077 template<typename LHS1, typename RHS1, typename OP1>
3078 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3079 {
3080 vector<T> temp(proxy.lhs());
3081 vector<T> temp2(temp.size());
3082 viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3083 lhs += temp2;
3084 }
3085
3086 // x += vec_expr .* vec_expr or x += vec_expr ./ vec_expr
3087 template<typename LHS1, typename RHS1, typename OP1,
3088 typename LHS2, typename RHS2, typename OP2>
3089 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3090 const vector_expression<const LHS2, const RHS2, OP2>,
3091 op_element_binary<OP> > const & proxy)
3092 {
3093 vector<T> temp1(proxy.lhs());
3094 vector<T> temp2(proxy.rhs());
3095 vector<T> temp3(temp1.size());
3096 viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3097 lhs += temp3;
3098 }
3099 };
3100
3101 // generic x -= vec_expr1 .* vec_expr2:
3102 template<typename T, typename LHS, typename RHS, typename OP>
3103 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3104 {
3105
3106 // x -= y .* z or x -= y ./ z
3107 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3108 {
3109 viennacl::vector<T> temp(proxy);
3110 lhs -= temp;
3111 }
3112
3113 // x -= y .* vec_expr or x -= y ./ vec_expr
3114 template<typename LHS2, typename RHS2, typename OP2>
3115 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_expression<const LHS2, const RHS2, OP2>, op_element_binary<OP> > const & proxy)
3116 {
3117 vector<T> temp(proxy.rhs());
3118 vector<T> temp2(temp.size());
3119 viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3120 lhs -= temp2;
3121 }
3122
3123 // x -= vec_expr .* z or x -= vec_expr ./ z
3124 template<typename LHS1, typename RHS1, typename OP1>
3125 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3126 {
3127 vector<T> temp(proxy.lhs());
3128 vector<T> temp2(temp.size());
3129 viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3130 lhs -= temp2;
3131 }
3132
3133 // x -= vec_expr .* vec_expr or x -= vec_expr ./ vec_expr
3134 template<typename LHS1, typename RHS1, typename OP1,
3135 typename LHS2, typename RHS2, typename OP2>
3136 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3137 const vector_expression<const LHS2, const RHS2, OP2>,
3138 op_element_binary<OP> > const & proxy)
3139 {
3140 vector<T> temp1(proxy.lhs());
3141 vector<T> temp2(proxy.rhs());
3142 vector<T> temp3(temp1.size());
3143 viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3144 lhs -= temp3;
3145 }
3146 };
3147
3149
3150 template<typename T, typename LHS, typename RHS, typename OP>
3151 struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3152 {
3153 // x = OP(y)
3154 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3155 {
3156 viennacl::linalg::element_op(lhs, proxy);
3157 }
3158
3159 // x = OP(vec_expr)
3160 template<typename LHS2, typename RHS2, typename OP2>
3161 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3162 const vector_expression<const LHS2, const RHS2, OP2>,
3163 op_element_unary<OP> > const & proxy)
3164 {
3165 vector<T> temp(proxy.rhs());
3166 viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp));
3167 }
3168 };
3169
3170 template<typename T, typename LHS, typename RHS, typename OP>
3171 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3172 {
3173 // x += OP(y)
3174 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3175 {
3176 vector<T> temp(proxy);
3177 lhs += temp;
3178 }
3179
3180 // x += OP(vec_expr)
3181 template<typename LHS2, typename RHS2, typename OP2>
3182 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3183 const vector_expression<const LHS2, const RHS2, OP2>,
3184 op_element_unary<OP> > const & proxy)
3185 {
3186 vector<T> temp(proxy.rhs());
3187 viennacl::linalg::element_op(temp, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp)); // inplace operation is safe here
3188 lhs += temp;
3189 }
3190 };
3191
3192 template<typename T, typename LHS, typename RHS, typename OP>
3193 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3194 {
3195 // x -= OP(y)
3196 static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3197 {
3198 vector<T> temp(proxy);
3199 lhs -= temp;
3200 }
3201
3202 // x -= OP(vec_expr)
3203 template<typename LHS2, typename RHS2, typename OP2>
3204 static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3205 const vector_expression<const LHS2, const RHS2, OP2>,
3206 op_element_unary<OP> > const & proxy)
3207 {
3208 vector<T> temp(proxy.rhs());
3209 viennacl::linalg::element_op(temp, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp)); // inplace operation is safe here
3210 lhs -= temp;
3211 }
3212 };
3213
3214
3215
3217
3218 template<typename T, typename UserMatrixT>
3219 struct op_executor<vector_base<T>, op_assign, vector_expression<const UserMatrixT, const vector_base<T>, op_prod> >
3220 {
3221 static void apply(vector_base<T> & lhs, vector_expression<const UserMatrixT, const vector_base<T>, op_prod> const & rhs)
3222 {
3223 rhs.lhs().apply(rhs.rhs(), lhs);
3224 }
3225 };
3226
3227
3228 } // namespace detail
3229 } // namespace linalg
3230
3233 } // namespace viennacl
3234
3235 #endif
viennacl::vector_base< NumericT >::difference_type
DistanceT difference_type
Definition: vector_def.hpp:113
viennacl::enable_if
Simple enable-if variant that uses the SFINAE pattern.
Definition: enable_if.hpp:30
viennacl::op_mult
A tag class representing multiplication by a scalar.
Definition: forwards.h:92
viennacl::vector_tuple::const_size
vcl_size_t const_size() const
Definition: vector.hpp:1143
viennacl::const_vector_iterator< NumericT, AlignmentV >
viennacl::cuda_not_available_exception
Definition: forwards.h:585
viennacl::backend::memory_write
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
viennacl::const_vector_iterator::handle
handle_type const & handle() const
Definition: vector.hpp:174
viennacl::vector_base::vector_base
vector_base()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:251
viennacl::scalar
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
Definition: forwards.h:227
viennacl::vector_base::operator*
vector_expression< const self_type, const NumericT, op_mult > operator*(char value) const
Scales the vector by a char (8-bit integer) 'alpha' and returns an expression template.
Definition: vector.hpp:742
viennacl::vector::vector
vector(scalar_vector< NumericT > const &v)
Creates the vector from the supplied scalar vector.
Definition: vector.hpp:1023
viennacl::vector_tuple::at
VectorType & at(vcl_size_t i) const
Definition: vector.hpp:1145
viennacl::const_vector_iterator::index_
size_type index_
Definition: vector.hpp:179
viennacl::linalg::detail::op_executor
Worker class for decomposing expression templates.
Definition: op_executor.hpp:80
viennacl::const_entry_proxy
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: forwards.h:236
viennacl::vector::size_type
base_type::size_type size_type
Definition: vector.hpp:956
viennacl::fast_swap
vector< NumericT, AlignmentV > & fast_swap(vector< NumericT, AlignmentV > &v1, vector< NumericT, AlignmentV > &v2)
Swaps the content of two vectors by swapping OpenCL handles only, NO data is copied.
Definition: vector.hpp:1659
op_executor.hpp
Defines the worker class for decomposing an expression tree into small chunks, which can be processed...
vector_operations.hpp
Implementations of vector operations.
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2, VectorType const &v3)
Definition: vector.hpp:1108
viennacl::const_vector_iterator::const_vector_iterator
const_vector_iterator(vector_base< NumericT > const &vec, size_type index, size_type start=0, size_type stride=1)
Constructor.
Definition: vector.hpp:125
viennacl::is_flip_sign_scalar
Helper struct for checking whether a type represents a sign flip on a viennacl::scalar<> ...
Definition: forwards.h:462
viennacl::implicit_vector_base::index
vcl_size_t index() const
Definition: vector_def.hpp:49
viennacl::vector_base::switch_memory_context
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:899
tools.hpp
Various little tools used here and there in ViennaCL.
viennacl::vector_base::operator[]
entry_proxy< NumericT > operator[](size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:571
viennacl::traits::size1
vcl_size_t size1(MatrixType const &mat)
Generic routine for obtaining the number of rows of a matrix (ViennaCL, uBLAS, etc.)
Definition: size.hpp:163
viennacl::const_vector_iterator::operator-
difference_type operator-(self_type const &other) const
Definition: vector.hpp:161
viennacl::tools::shared_ptr::inc
void inc()
Definition: shared_ptr.hpp:154
viennacl::vector_base::swap
self_type & swap(self_type &other)
Swaps the entries of the two vectors.
Definition: vector.hpp:867
viennacl::ocl::context
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:55
viennacl::op_sub
A tag class representing subtraction.
Definition: forwards.h:90
entry_proxy.hpp
A proxy class for entries in a vector.
viennacl::linalg::avbv_v
void avbv_v(vector_base< T > &vec1, vector_base< T > const &vec2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, vector_base< T > const &vec3, ScalarType2 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: vector_operations.hpp:144
viennacl::OPENCL_MEMORY
Definition: forwards.h:349
viennacl::const_vector_iterator::operator==
bool operator==(self_type const &other) const
Definition: vector.hpp:151
viennacl::matrix_base< NumericT >
viennacl::vector::vector
vector(vector_expression< const LHS, const RHS, OP > const &proxy)
Definition: vector.hpp:994
viennacl::matrix_expression
Expression template class for representing a tree of expressions which ultimately result in a matrix...
Definition: forwards.h:341
viennacl::vector::operator=
self_type & operator=(T const &other)
Definition: vector.hpp:1031
viennacl::vector_base::pad
void pad()
Pads vectors with alignment > 1 with trailing zeros if the internal size is larger than the visible s...
Definition: vector.hpp:889
viennacl::const_vector_iterator::elements_
handle_type const & elements_
The index of the entry the iterator is currently pointing to.
Definition: vector.hpp:178
viennacl::traits::stride
result_of::size_type< viennacl::vector_base< T > >::type stride(viennacl::vector_base< T > const &s)
Definition: stride.hpp:45
viennacl::traits::clear
void clear(VectorType &vec)
Generic routine for setting all entries of a vector to zero. This is the version for non-ViennaCL obj...
Definition: clear.hpp:43
viennacl::vector_tuple::vector_tuple
vector_tuple(std::vector< VectorType const * > const &vecs)
Definition: vector.hpp:1127
forwards.h
This file provides the forward declarations for the main types used within ViennaCL.
viennacl::zero_vector
Definition: vector_def.hpp:93
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2)
Definition: vector.hpp:1099
viennacl::op_div
A tag class representing division.
Definition: forwards.h:98
viennacl::backend::memory_read
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
viennacl::vector_base::operator/
vector_expression< const self_type, const NumericT, op_div > operator/(char value) const
Scales the vector by a char (8-bit integer) 'alpha' and returns an expression template.
Definition: vector.hpp:786
viennacl::operator/=
viennacl::enable_if< viennacl::is_scalar< S1 >::value, matrix_base< NumericT > & >::type operator/=(matrix_base< NumericT > &m1, S1 const &gpu_val)
Scales a matrix by a GPU scalar value.
Definition: matrix.hpp:1674
viennacl::operator*
viennacl::enable_if< viennacl::is_any_scalar< S1 >::value, matrix_expression< const matrix_base< NumericT >, const S1, op_mult >>::type operator*(S1 const &value, matrix_base< NumericT > const &m1)
Operator overload for the expression alpha * m1, where alpha is a host scalar (float or double) and m...
Definition: matrix.hpp:1374
s1
viennacl::scalar< float > s1
Definition: global_variables.cpp:57
viennacl::traits::internal_size
vcl_size_t internal_size(vector_base< NumericT > const &vec)
Helper routine for obtaining the buffer length of a ViennaCL vector.
Definition: size.hpp:375
viennacl::vector_base::operator-=
self_type & operator-=(const self_type &vec)
Definition: vector.hpp:616
viennacl::vector::vector
vector(const self_type &v)
Definition: vector.hpp:1002
viennacl::scalar_expression
A proxy for scalar expressions (e.g. from inner vector products)
Definition: forwards.h:230
viennacl::vector_expression::lhs
lhs_reference_type lhs() const
Get left hand side operand.
Definition: vector.hpp:74
viennacl::vector_expression
An expression template class that represents a binary operation that yields a vector.
Definition: forwards.h:239
viennacl::linalg::element_op
void element_op(matrix_base< T > &A, matrix_expression< const matrix_base< T >, const matrix_base< T >, OP > const &proxy)
Implementation of the element-wise operation A = B .* C and A = B ./ C for matrices (using MATLAB syn...
Definition: matrix_operations.hpp:702
viennacl::const_vector_iterator::operator*
value_type operator*(void) const
Dereferences the iterator and returns the value of the element. For convenience only, performance is poor due to OpenCL overhead!
Definition: vector.hpp:142
viennacl::linalg::detail::op_aliasing
bool op_aliasing(vector_base< NumericT > const &, B const &)
Definition: op_executor.hpp:36
viennacl::const_vector_iterator::value_type
scalar< NumericT > value_type
Definition: vector.hpp:112
viennacl::vector_base::resize
void resize(size_type new_size, bool preserve=true)
Resizes the allocated memory for the vector. Pads the memory to be a multiple of 'AlignmentV'.
Definition: vector.hpp:909
viennacl::vector_base::operator+=
self_type & operator+=(const self_type &vec)
Definition: vector.hpp:604
viennacl::operator-
viennacl::vector< NumericT > operator-(const vector_base< NumericT > &v1, const vector_expression< const matrix_base< NumericT >, const vector_base< NumericT >, op_prod > &proxy)
Implementation of the operation 'result = v1 - A * v2', where A is a matrix.
Definition: matrix_operations.hpp:1200
viennacl::swap
void swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
Definition: vector.hpp:1648
context.hpp
Implementation of a OpenCL-like context, which serves as a unification of {OpenMP, CUDA, OpenCL} at the user API.
viennacl::vector::vector
vector(const base_type &v)
Definition: vector.hpp:996
viennacl::vector::vector
vector(unit_vector< NumericT > const &v)
Creates the vector from the supplied unit vector.
Definition: vector.hpp:1009
viennacl::vector_expression::vector_expression
vector_expression(LHS &l, RHS &r)
Definition: vector.hpp:70
NumericT
float NumericT
Definition: bisect.cpp:40
viennacl::vector_base::operator-
vector_expression< const self_type, const NumericT, op_mult > operator-() const
Sign flip for the vector. Emulated to be equivalent to -1.0 * vector.
Definition: vector.hpp:830
viennacl::vector_base::operator()
entry_proxy< NumericT > operator()(size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:562
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType const &v0, VectorType const &v1)
Definition: vector.hpp:1080
viennacl::context
Represents a generic 'context' similar to an OpenCL context, but is backend-agnostic and thus also su...
Definition: context.hpp:39
viennacl::const_vector_iterator::handle_type
viennacl::backend::mem_handle handle_type
Definition: vector.hpp:115
viennacl::implicit_vector_base::context
viennacl::context context() const
Definition: vector_def.hpp:46
viennacl::const_vector_iterator::operator++
self_type operator++(void)
Definition: vector.hpp:148
viennacl::vector::vector
vector(NumericT *ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start=0, size_type stride=1)
Definition: vector.hpp:971
v1
viennacl::vector< float > v1
Definition: global_variables.cpp:60
viennacl::const_vector_iterator::difference_type
vcl_ptrdiff_t difference_type
Definition: vector.hpp:114
viennacl::vector_iterator::operator+
self_type operator+(difference_type diff) const
Definition: vector.hpp:236
viennacl::operator*=
viennacl::enable_if< viennacl::is_scalar< S1 >::value, matrix_base< NumericT > & >::type operator*=(matrix_base< NumericT > &m1, S1 const &gpu_val)
Scales a matrix by a GPU scalar value.
Definition: matrix.hpp:1522
viennacl::const_vector_iterator::operator!=
bool operator!=(self_type const &other) const
Definition: vector.hpp:152
viennacl::traits::size
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:239
viennacl::const_vector_iterator::offset
size_type offset() const
Offset of the current element index with respect to the beginning of the buffer.
Definition: vector.hpp:170
viennacl::linalg::inner_prod_impl
void inner_prod_impl(vector_base< T > const &vec1, vector_base< T > const &vec2, scalar< T > &result)
Computes the inner product of two vectors - dispatcher interface.
Definition: vector_operations.hpp:387
viennacl::vector_iterator::vector_iterator
vector_iterator(handle_type const &elements, size_type index, size_type start=0, size_type stride=1)
Definition: vector.hpp:214
viennacl::linalg::convert
void convert(matrix_base< DestNumericT > &dest, matrix_base< SrcNumericT > const &src)
Definition: matrix_operations.hpp:54
viennacl::CUDA_MEMORY
Definition: forwards.h:350
viennacl::vector_base::begin
iterator begin()
Returns an iterator pointing to the beginning of the vector (STL like)
Definition: vector.hpp:841
viennacl::vector_iterator::handle
handle_type & handle()
Definition: vector.hpp:238
viennacl::vector::difference_type
base_type::difference_type difference_type
Definition: vector.hpp:957
viennacl::vector_tuple
Tuple class holding pointers to multiple vectors. Mainly used as a temporary object returned from vie...
Definition: forwards.h:269
viennacl::implicit_vector_base::size
vcl_size_t size() const
Definition: vector_def.hpp:47
viennacl::vector_iterator
A STL-type iterator for vector elements. Elements can be accessed and manipulated. VERY SLOW!!
Definition: forwards.h:242
viennacl::traits::start
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:44
viennacl::linalg::host_based::detail::flip_sign
NumericT flip_sign(NumericT val)
Definition: vector_operations.hpp:57
viennacl::linalg::vector_swap
void vector_swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
Definition: vector_operations.hpp:218
viennacl::vector_expression::rhs
rhs_reference_type rhs() const
Get right hand side operand.
Definition: vector.hpp:77
viennacl::op_add
A tag class representing addition.
Definition: forwards.h:88
viennacl::vector::resize
void resize(size_type new_size, bool preserve=true)
Resizes the allocated memory for the vector. Pads the memory to be a multiple of 'AlignmentV'.
Definition: vector.hpp:1046
viennacl::vector::resize
void resize(size_type new_size, viennacl::context ctx, bool preserve=true)
Definition: vector.hpp:1051
viennacl::vector_base< NumericT >
viennacl::vector_base::cpu_value_type
NumericT cpu_value_type
Definition: vector_def.hpp:110
viennacl::operator/
viennacl::enable_if< viennacl::is_any_scalar< S1 >::value, matrix_expression< const matrix_expression< const LHS, const RHS, OP >, const S1, op_div > >::type operator/(matrix_expression< const LHS, const RHS, OP > const &proxy, S1 const &val)
Operator overload for the division of a matrix expression by a scalar from the right, e.g. (beta * m1) / alpha. Here, beta * m1 is wrapped into a matrix_expression and then divided by alpha.
Definition: matrix.hpp:1603
viennacl::vector_base::operator=
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
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
viennacl::tie
vector_tuple< ScalarT > tie(vector_base< ScalarT > const &v0, vector_base< ScalarT > const &v1)
Definition: vector.hpp:1155
viennacl::vector< NumericT >
viennacl::traits::active_handle_id
viennacl::memory_types active_handle_id(T const &obj)
Returns an ID for the currently active memory domain of an object.
Definition: handle.hpp:218
viennacl::result_of::cpu_value_type::type
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Definition: result_of.hpp:271
viennacl::linalg::avbv
void avbv(vector_base< T > &vec1, vector_base< T > const &vec2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, vector_base< T > const &vec3, ScalarType2 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: vector_operations.hpp:107
viennacl::vector_iterator::vector_iterator
vector_iterator(vector_base< NumericT > &vec, size_type index, size_type start=0, size_type stride=1)
Constructor.
Definition: vector.hpp:224
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2)
Definition: vector.hpp:1093
viennacl::vector_expression::alignment
Definition: vector.hpp:64
viennacl::vector_tuple::size
vcl_size_t size() const
Definition: vector.hpp:1142
viennacl::vector::fast_swap
self_type & fast_swap(self_type &other)
Swaps the handles of two vectors by swapping the OpenCL handles only, no data copy.
Definition: vector.hpp:1058
viennacl::MAIN_MEMORY
Definition: forwards.h:348
viennacl::vector_iterator::operator-
difference_type operator-(self_type const &other) const
Definition: vector.hpp:235
viennacl::const_vector_iterator::stride_
size_type stride_
Definition: vector.hpp:181
viennacl::operator+
viennacl::vector< NumericT > operator+(const vector_base< NumericT > &v1, const vector_expression< const matrix_base< NumericT >, const vector_base< NumericT >, op_prod > &proxy)
Implementation of the operation 'result = v1 + A * v2', where A is a matrix.
Definition: matrix_operations.hpp:1182
viennacl::backend::mem_handle::switch_active_handle_id
void switch_active_handle_id(memory_types new_id)
Switches the currently active handle. If no support for that backend is provided, an exception is thr...
Definition: mem_handle.hpp:121
viennacl::backend::memory_copy
void memory_copy(mem_handle const &src_buffer, mem_handle &dst_buffer, vcl_size_t src_offset, vcl_size_t dst_offset, vcl_size_t bytes_to_copy)
Copies 'bytes_to_copy' bytes from address 'src_buffer + src_offset' to memory starting at address 'ds...
Definition: memory.hpp:140
viennacl::op_prod
A tag class representing matrix-vector products and element-wise multiplications. ...
Definition: forwards.h:94
viennacl::vector_base::clear
void clear()
Resets all entries to zero. Does not change the size of the vector.
Definition: vector.hpp:875
viennacl::traits::context
viennacl::context context(T const &t)
Returns an ID for the currently active memory domain of an object.
Definition: context.hpp:40
viennacl::vector_base::operator/=
self_type & operator/=(char val)
Scales a vector (or proxy) by a char (8-bit integer)
Definition: vector.hpp:685
viennacl::unit_vector
Represents a vector consisting of 1 at a given index and zeros otherwise.
Definition: vector_def.hpp:76
viennacl::vector_iterator::operator*
entry_proxy< NumericT > operator*(void)
Definition: vector.hpp:230
viennacl::vector::vector
vector(size_type vec_size, viennacl::context ctx)
Definition: vector.hpp:969
viennacl::tools::align_to_multiple
INT_TYPE align_to_multiple(INT_TYPE to_reach, INT_TYPE base)
Rounds an integer to the next multiple of another integer.
Definition: tools.hpp:133
v2
viennacl::vector< int > v2
Definition: global_variables.cpp:61
viennacl::vector_expression::size
size_type size() const
Returns the size of the result vector.
Definition: vector.hpp:80
viennacl::scalar_vector
Represents a vector consisting of scalars 's' only, i.e. v[i] = s for all i. To be used as an initial...
Definition: vector_def.hpp:87
viennacl::copy
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) ...
Definition: circulant_matrix.hpp:150
viennacl::const_vector_iterator::operator+
self_type operator+(difference_type diff) const
Definition: vector.hpp:166
viennacl::vector_base::size
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector_def.hpp:118
viennacl::linalg::av
void av(vector_base< T > &vec1, vector_base< T > const &vec2, ScalarType1 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
Definition: vector_operations.hpp:78
ScalarType
float ScalarType
Definition: fft_1d.cpp:42
viennacl::tools::shared_ptr::reset
void reset()
Definition: shared_ptr.hpp:123
viennacl::copy
void copy(vector< NumericT, AlignmentV_SRC > const &gpu_src_vec, vector< NumericT, AlignmentV_DEST > &gpu_dest_vec)
Transfer from a ViennaCL vector to another ViennaCL vector. Convenience wrapper for viennacl::linalg:...
Definition: vector.hpp:1600
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType &v0, VectorType &v1)
Definition: vector.hpp:1085
viennacl::backend::mem_handle
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
Definition: mem_handle.hpp:89
viennacl::vector_tuple::const_at
VectorType const & const_at(vcl_size_t i) const
Definition: vector.hpp:1146
viennacl::op_trans
A tag class representing transposed matrices.
Definition: forwards.h:220
viennacl::vector_iterator::handle
handle_type const & handle() const
Definition: vector.hpp:239
viennacl::vector::vector
vector(size_type vec_size)
An explicit constructor for the vector, allocating the given amount of memory (plus a padding specifi...
Definition: vector.hpp:967
viennacl::vector_iterator::size_type
base_type::size_type size_type
Definition: vector.hpp:211
viennacl::backend::mem_handle::raw_size
vcl_size_t raw_size() const
Returns the number of bytes of the currently active buffer.
Definition: mem_handle.hpp:230
viennacl::const_vector_iterator::start_
size_type start_
Definition: vector.hpp:180
viennacl::backend::memory_create
void memory_create(mem_handle &handle, vcl_size_t size_in_bytes, viennacl::context const &ctx, const void *host_ptr=NULL)
Creates an array of the specified size. If the second argument is provided, the buffer is initialized...
Definition: memory.hpp:87
viennacl::linalg::vector_assign
void vector_assign(vector_base< T > &vec1, const T &alpha, bool up_to_internal_size=false)
Assign a constant value to a vector (-range/-slice)
Definition: vector_operations.hpp:187
vector_def.hpp
Forward declarations of the implicit_vector_base, vector_base class.
viennacl::vector_expression::size_type
vcl_size_t size_type
Extracts the vector type from the two operands.
Definition: vector.hpp:68
handle.hpp
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
viennacl::linalg::prod_impl
void prod_impl(const matrix_base< NumericT > &mat, const vector_base< NumericT > &vec, vector_base< NumericT > &result)
Carries out matrix-vector multiplication.
Definition: matrix_operations.hpp:438
viennacl::vector_base::internal_size
size_type internal_size() const
Returns the internal length of the vector, which is given by size() plus the extra memory due to padd...
Definition: vector_def.hpp:120
viennacl::traits::handle
viennacl::backend::mem_handle & handle(T &obj)
Returns the generic memory handle of an object. Non-const version.
Definition: handle.hpp:41
viennacl::vector_base::end
iterator end()
Returns an iterator pointing to the end of the vector (STL like)
Definition: vector.hpp:848
viennacl::memory_types
memory_types
Definition: forwards.h:345
viennacl::entry_proxy
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: forwards.h:233
viennacl::const_vector_iterator::size_type
vcl_size_t size_type
Definition: vector.hpp:113
diff
ScalarType diff(ScalarType &s1, viennacl::scalar< ScalarType > &s2)
Definition: blas3_solve.cpp:50
viennacl::vector::vector
vector()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:961
viennacl::async_copy
void async_copy(const const_vector_iterator< NumericT, AlignmentV > &gpu_begin, const const_vector_iterator< NumericT, AlignmentV > &gpu_end, CPU_ITERATOR cpu_begin)
Asynchronous version of fast_copy(), copying data from device to host. The host iterator cpu_begin ne...
Definition: vector.hpp:1284
scalar.hpp
Implementation of the ViennaCL scalar class.
result_of.hpp
A collection of compile time type deductions.
viennacl::const_vector_iterator::operator++
self_type operator++(int)
Definition: vector.hpp:149
op_assign
Definition: self_assign.cpp:132
viennacl::vector_base::operator*=
self_type & operator*=(char val)
Scales a vector (or proxy) by a char (8-bit integer)
Definition: vector.hpp:629
viennacl::vector_iterator::difference_type
base_type::difference_type difference_type
Definition: vector.hpp:212
viennacl::vector_base::handle
const handle_type & handle() const
Returns the memory handle.
Definition: vector_def.hpp:128
viennacl::vector::vector
vector(zero_vector< NumericT > const &v)
Creates the vector from the supplied zero vector.
Definition: vector.hpp:1016
viennacl::vector_tuple::vector_tuple
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2, VectorType &v3)
Definition: vector.hpp:1115
memory.hpp
Main interface routines for memory management.
viennacl::vector_base::fast_swap
self_type & fast_swap(self_type &other)
Swaps the handles of two vectors by swapping the OpenCL handles only, no data copy.
Definition: vector.hpp:881
viennacl::backend::mem_handle::ram_handle
ram_handle_type & ram_handle()
Returns the handle to a buffer in CPU RAM. NULL is returned if no such buffer has been allocated...
Definition: mem_handle.hpp:99
viennacl::vector_tuple::vector_tuple
vector_tuple(std::vector< VectorType * > const &vecs)
Definition: vector.hpp:1133
viennacl::const_vector_iterator::stride
size_type stride() const
Index increment in the underlying buffer when incrementing the iterator to the next element...
Definition: vector.hpp:173
viennacl::vector_iterator::handle_type
base_type::handle_type handle_type
Definition: vector.hpp:210
viennacl::const_vector_iterator::const_vector_iterator
const_vector_iterator(handle_type const &elements, size_type index, size_type start=0, size_type stride=1)
Constructor for vector-like treatment of arbitrary buffers.
Definition: vector.hpp:136
viennacl::vcl_ptrdiff_t
std::ptrdiff_t vcl_ptrdiff_t
Definition: forwards.h:76
viennacl::vector_base::size_type
SizeT size_type
Definition: vector_def.hpp:112
viennacl::vector::switch_memory_context
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:1064
viennacl::backend::mem_handle::get_active_handle_id
memory_types get_active_handle_id() const
Returns an ID for the currently active memory buffer. Other memory buffers might contain old or no da...
Definition: mem_handle.hpp:118
viennacl::fast_copy
void fast_copy(const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_begin, const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_end, CPU_ITERATOR cpu_begin)