ViennaCL - The Vienna Computing Library  1.5.2
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-2014, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8  Portions of this software are copyright by UChicago Argonne, LLC.
9 
10  -----------------
11  ViennaCL - The Vienna Computing Library
12  -----------------
13 
14  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15 
16  (A list of authors and contributors can be found in the PDF manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
27 #include "viennacl/forwards.h"
29 #include "viennacl/scalar.hpp"
30 #include "viennacl/tools/tools.hpp"
35 //#include "viennacl/rand/utils.hpp"
36 #include "viennacl/context.hpp"
38 
39 namespace viennacl
40 {
41 
46  template<typename SCALARTYPE>
47  class implicit_vector_base
48  {
49  protected:
51  implicit_vector_base(size_type s, vcl_size_t i, std::pair<SCALARTYPE, bool> v, viennacl::context ctx) : size_(s), index_(std::make_pair(true,i)), value_(v), ctx_(ctx){ }
52  implicit_vector_base(size_type s, std::pair<SCALARTYPE, bool> v, viennacl::context ctx) : size_(s), index_(std::make_pair(false,0)), value_(v), ctx_(ctx){ }
53 
54  public:
55  typedef SCALARTYPE const & const_reference;
56  typedef SCALARTYPE cpu_value_type;
57 
58  viennacl::context context() const { return ctx_; }
59 
60  size_type size() const { return size_; }
61 
62  cpu_value_type value() const { return value_.first; }
63 
64  bool is_value_static() const { return value_.second; }
65 
66  vcl_size_t index() const { return index_.second; }
67 
68  bool has_index() const { return index_.first; }
69 
70  cpu_value_type operator()(size_type i) const {
71  if(index_.first)
72  return (i==index_.second)?value_.first:0;
73  return value_.first;
74  }
75 
76  cpu_value_type operator[](size_type i) const {
77  if(index_.first)
78  return (i==index_.second)?value_.first:0;
79  return
80  value_.first;
81  }
82 
83  protected:
84  size_type size_;
85  std::pair<bool, vcl_size_t> index_;
86  std::pair<SCALARTYPE, bool> value_;
88  };
89 
91  template <typename SCALARTYPE>
92  class unit_vector : public implicit_vector_base<SCALARTYPE>
93  {
94  typedef implicit_vector_base<SCALARTYPE> base_type;
95  public:
96  typedef typename base_type::size_type size_type;
97  unit_vector(size_type s, size_type ind, viennacl::context ctx = viennacl::context()) : base_type(s, ind, std::make_pair(SCALARTYPE(1),true), ctx)
98  {
99  assert( (ind < s) && bool("Provided index out of range!") );
100  }
101  };
102 
103 
105  template <typename SCALARTYPE>
106  class zero_vector : public implicit_vector_base<SCALARTYPE>
107  {
108  typedef implicit_vector_base<SCALARTYPE> base_type;
109  public:
110  typedef typename base_type::size_type size_type;
111  typedef SCALARTYPE const_reference;
112  zero_vector(size_type s, viennacl::context ctx = viennacl::context()) : base_type(s, std::make_pair(SCALARTYPE(0),true), ctx) {}
113  };
114 
116  template <typename SCALARTYPE>
117  class one_vector : public implicit_vector_base<SCALARTYPE>
118  {
119  typedef implicit_vector_base<SCALARTYPE> base_type;
120  public:
121  typedef typename base_type::size_type size_type;
122  typedef SCALARTYPE const_reference;
123  one_vector(size_type s, viennacl::context ctx = viennacl::context()) : base_type(s, std::make_pair(SCALARTYPE(1),true), ctx) {}
124  };
125 
126 
128  template <typename SCALARTYPE>
129  class scalar_vector : public implicit_vector_base<SCALARTYPE>
130  {
131  typedef implicit_vector_base<SCALARTYPE> base_type;
132  public:
133  typedef typename base_type::size_type size_type;
134  typedef SCALARTYPE const & const_reference;
135 
136  scalar_vector(size_type s, SCALARTYPE val, viennacl::context ctx = viennacl::context()) : base_type(s, std::make_pair(val,false), ctx) {}
137  };
138 
139 
140 //#ifdef VIENNACL_WITH_OPENCL
141 // template<class SCALARTYPE, class DISTRIBUTION>
142 // rand::random_vector_t<SCALARTYPE, DISTRIBUTION> random_vector(unsigned int size, DISTRIBUTION const & distribution){
143 // return rand::random_vector_t<SCALARTYPE,DISTRIBUTION>(size,distribution);
144 // }
145 //#endif
146 
147 
148  //
149  // Vector expression
150  //
151 
164  template <typename LHS, typename RHS, typename OP>
165  class vector_expression
166  {
167  typedef typename viennacl::result_of::reference_if_nonscalar<LHS>::type lhs_reference_type;
168  typedef typename viennacl::result_of::reference_if_nonscalar<RHS>::type rhs_reference_type;
169 
170  public:
171  enum { alignment = 1 };
172 
176 
177  vector_expression(LHS & l, RHS & r) : lhs_(l), rhs_(r) {}
178 
181  lhs_reference_type lhs() const { return lhs_; }
184  rhs_reference_type rhs() const { return rhs_; }
185 
187  size_type size() const { return viennacl::traits::size(*this); }
188 
189  private:
191  lhs_reference_type lhs_;
193  rhs_reference_type rhs_;
194  };
195 
214  template<class SCALARTYPE, unsigned int ALIGNMENT>
215  class const_vector_iterator
216  {
217  typedef const_vector_iterator<SCALARTYPE, ALIGNMENT> self_type;
218  public:
222 
223  //const_vector_iterator() {}
224 
232  vcl_size_t index,
233  vcl_size_t start = 0,
234  vcl_ptrdiff_t stride = 1) : elements_(vec.handle()), index_(index), start_(start), stride_(stride) {}
235 
242  const_vector_iterator(handle_type const & elements,
243  vcl_size_t index,
244  vcl_size_t start = 0,
245  vcl_ptrdiff_t stride = 1) : elements_(elements), index_(index), start_(start), stride_(stride) {}
246 
248  value_type operator*(void) const
249  {
250  value_type result;
252  return result;
253  }
254  self_type operator++(void) { index_ += stride_; return *this; }
255  self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
256 
257  bool operator==(self_type const & other) const { return index_ == other.index_; }
258  bool operator!=(self_type const & other) const { return index_ != other.index_; }
259 
260 // self_type & operator=(self_type const & other)
261 // {
262 // index_ = other._index;
263 // elements_ = other._elements;
264 // return *this;
265 // }
266 
267  difference_type operator-(self_type const & other) const
268  {
269  assert( (other.start_ == start_) && (other.stride_ == stride_) && bool("Iterators are not from the same vector (proxy)!"));
270  return static_cast<difference_type>(index_) - static_cast<difference_type>(other.index_);
271  }
272  self_type operator+(difference_type diff) const { return self_type(elements_, index_ + diff * stride_, start_, stride_); }
273 
274  //vcl_size_t index() const { return index_; }
276  vcl_size_t offset() const { return start_ + index_ * stride_; }
277 
279  vcl_size_t stride() const { return stride_; }
280  handle_type const & handle() const { return elements_; }
281 
282  protected:
284  handle_type const & elements_;
285  vcl_size_t index_; //offset from the beginning of elements_
288  };
289 
290 
310  template<class SCALARTYPE, unsigned int ALIGNMENT>
311  class vector_iterator : public const_vector_iterator<SCALARTYPE, ALIGNMENT>
312  {
314  typedef vector_iterator<SCALARTYPE, ALIGNMENT> self_type;
315  public:
318 
319  vector_iterator() : base_type(), elements_(NULL) {}
320  vector_iterator(handle_type & elements,
321  vcl_size_t index,
322  vcl_size_t start = 0,
323  vcl_ptrdiff_t stride = 1) : base_type(elements, index, start, stride), elements_(elements) {}
331  vcl_size_t index,
332  vcl_size_t start = 0,
333  vcl_ptrdiff_t stride = 1) : base_type(vec, index, start, stride), elements_(vec.handle()) {}
334  //vector_iterator(base_type const & b) : base_type(b) {}
335 
337  {
338  typename base_type::value_type result;
340  return result;
341  }
342 
343  difference_type operator-(self_type const & other) const { difference_type result = base_type::index_; return (result - static_cast<difference_type>(other.index_)); }
344  self_type operator+(difference_type diff) const { return self_type(elements_, base_type::index_ + diff * base_type::stride_, base_type::start_, base_type::stride_); }
345 
346  handle_type & handle() { return elements_; }
347  handle_type const & handle() const { return base_type::elements_; }
348 
349  //operator base_type() const
350  //{
351  // return base_type(base_type::elements_, base_type::index_, base_type::start_, base_type::stride_);
352  //}
353  private:
354  handle_type & elements_;
355  };
356 
357 
362  template<class SCALARTYPE, typename SizeType /* see forwards.h for default type */, typename DistanceType /* see forwards.h for default type */>
363  class vector_base
364  {
365  typedef vector_base<SCALARTYPE> self_type;
366 
367  public:
369  typedef SCALARTYPE cpu_value_type;
371  typedef SizeType size_type;
372  typedef DistanceType difference_type;
375 
376  static const size_type alignment = 128;
377 
380  explicit 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 */ }
381 
392  size_type vec_size, size_type vec_start, difference_type vec_stride)
393  : size_(vec_size), start_(vec_start), stride_(vec_stride), internal_size_(vec_size), elements_(h) {}
394 
396  explicit vector_base(size_type vec_size, viennacl::context ctx = viennacl::context())
397  : size_(vec_size), start_(0), stride_(1), internal_size_(viennacl::tools::align_to_multiple<size_type>(size_, alignment))
398  {
399  if (size_ > 0)
400  {
401  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size(), ctx);
402  clear();
403  }
404  }
405 
406  // CUDA or host memory:
407  explicit vector_base(SCALARTYPE * ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, vcl_size_t start = 0, difference_type stride = 1)
408  : size_(vec_size), start_(start), stride_(stride), internal_size_(vec_size)
409  {
410  if (mem_type == viennacl::CUDA_MEMORY)
411  {
412 #ifdef VIENNACL_WITH_CUDA
414  elements_.cuda_handle().reset(reinterpret_cast<char*>(ptr_to_mem));
415  elements_.cuda_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
416 #else
418 #endif
419  }
420  else if (mem_type == viennacl::MAIN_MEMORY)
421  {
423  elements_.ram_handle().reset(reinterpret_cast<char*>(ptr_to_mem));
424  elements_.ram_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
425  }
426 
427  elements_.raw_size(sizeof(SCALARTYPE) * vec_size);
428 
429  }
430 
431 #ifdef VIENNACL_WITH_OPENCL
432 
440  explicit vector_base(cl_mem existing_mem, size_type vec_size, size_type start = 0, difference_type stride = 1, viennacl::context ctx = viennacl::context())
441  : size_(vec_size), start_(start), stride_(stride), internal_size_(vec_size)
442  {
444  elements_.opencl_handle() = existing_mem;
445  elements_.opencl_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
446  elements_.opencl_handle().context(ctx.opencl_context());
447  elements_.raw_size(sizeof(SCALARTYPE) * vec_size);
448  }
449 #endif
450 
452  /*template<class DISTRIBUTION>
453  vector(rand::random_vector_t<SCALARTYPE, DISTRIBUTION> v) : size_(v.size)
454  {
455  if(size_ > 0)
456  {
457  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size());
458  rand::buffer_dumper<SCALARTYPE, DISTRIBUTION>::dump(elements_,v.distribution,0,size_);
459  }
460  } */
461 
462  template <typename LHS, typename RHS, typename OP>
464  : size_(viennacl::traits::size(proxy)), start_(0), stride_(1), internal_size_(viennacl::tools::align_to_multiple<size_type>(size_, alignment))
465  {
466  if (size_ > 0)
467  {
468  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size(), viennacl::traits::context(proxy));
469  clear();
470  }
471  self_type::operator=(proxy);
472  }
473 
474 
475  //
476  // operator=
477  //
478 
479 
482  self_type & operator=(const self_type & vec)
483  {
484  assert( ( (vec.size() == size()) || (size() == 0) )
485  && bool("Incompatible vector sizes!"));
486 
487  if (vec.size() > 0)
488  {
489  if (size_ == 0)
490  {
491  size_ = vec.size();
492  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, alignment);
494  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size(), viennacl::traits::context(vec));
495  pad();
496  }
497 
498  viennacl::linalg::av(*this,
499  vec, cpu_value_type(1.0), 1, false, false);
500  }
501 
502  return *this;
503  }
504 
505 
510  template <typename LHS, typename RHS, typename OP>
512  {
513  assert( ( (viennacl::traits::size(proxy) == size()) || (size() == 0) )
514  && bool("Incompatible vector sizes!"));
515 
516  // initialize the necessary buffer
517  if (size() == 0)
518  {
519  size_ = viennacl::traits::size(proxy);
520  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, alignment);
521  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size(), viennacl::traits::context(proxy));
522  pad();
523  }
524 
526 
527  return *this;
528  }
529 
530  // assign vector range or vector slice
531  template <typename T>
532  self_type &
534  {
535  assert( ( (v1.size() == size()) || (size() == 0) )
536  && bool("Incompatible vector sizes!"));
537 
538  if (size() == 0)
539  {
540  size_ = v1.size();
541  if (size_ > 0)
542  {
543  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, alignment);
544  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size(), viennacl::traits::context(v1));
545  pad();
546  }
547  }
548 
549  viennacl::linalg::av(*this,
550  v1, SCALARTYPE(1.0), 1, false, false);
551 
552  return *this;
553  }
554 
556  self_type & operator = (unit_vector<SCALARTYPE> const & v)
557  {
558  assert( ( (v.size() == size()) || (size() == 0) )
559  && bool("Incompatible vector sizes!"));
560 
561  if (size() == 0)
562  {
563  size_ = v.size();
564  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, alignment);
565  if (size_ > 0)
566  {
567  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size(), v.context());
568  clear();
569  }
570  }
571  else
572  viennacl::linalg::vector_assign(*this, SCALARTYPE(0));
573 
574  if (size_ > 0)
575  this->operator()(v.index()) = SCALARTYPE(1);
576 
577  return *this;
578  }
579 
581  self_type & operator = (zero_vector<SCALARTYPE> const & v)
582  {
583  assert( ( (v.size() == size()) || (size() == 0) )
584  && bool("Incompatible vector sizes!"));
585 
586  if (size() == 0)
587  {
588  size_ = v.size();
589  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, alignment);
590  if (size_ > 0)
591  {
592  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size(), v.context());
593  clear();
594  }
595  }
596  else
597  viennacl::linalg::vector_assign(*this, SCALARTYPE(0));
598 
599  return *this;
600  }
601 
603  self_type & operator = (scalar_vector<SCALARTYPE> const & v)
604  {
605  assert( ( (v.size() == size()) || (size() == 0) )
606  && bool("Incompatible vector sizes!"));
607 
608  if (size() == 0)
609  {
610  size_ = v.size();
611  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, alignment);
612  if (size_ > 0)
613  {
614  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*internal_size(), v.context());
615  pad();
616  }
617  }
618 
619  if (size_ > 0)
620  viennacl::linalg::vector_assign(*this, v[0]);
621 
622  return *this;
623  }
624 
625 
626 
628 
629  //Note: The following operator overloads are defined in matrix_operations.hpp, compressed_matrix_operations.hpp and coordinate_matrix_operations.hpp
630  //This is certainly not the nicest approach and will most likely by changed in the future, but it works :-)
631 
632  //matrix<>
637  template <typename F>
639  {
640  assert(viennacl::traits::size1(proxy.lhs()) == size() && bool("Size check failed for v1 = A * v2: size1(A) != size(v1)"));
641 
642  // check for the special case x = A * x
643  if (viennacl::traits::handle(proxy.rhs()) == viennacl::traits::handle(*this))
644  {
646  viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
647  *this = result;
648  }
649  else
650  {
651  viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
652  }
653  return *this;
654  }
655 
656 
657  //transposed_matrix_proxy:
662  template <typename F>
665  op_prod> & proxy)
666  {
667  assert(viennacl::traits::size1(proxy.lhs()) == size() && bool("Size check failed in v1 = trans(A) * v2: size2(A) != size(v1)"));
668 
669  // check for the special case x = trans(A) * x
670  if (viennacl::traits::handle(proxy.rhs()) == viennacl::traits::handle(*this))
671  {
673  viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
674  *this = result;
675  }
676  else
677  {
678  viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
679  }
680  return *this;
681  }
682 
684 
685 
686  //read-write access to an element of the vector
690  {
691  assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
692  assert( index < size() && bool("Index out of bounds!") );
693 
694  return entry_proxy<SCALARTYPE>(start_ + stride_ * index, elements_);
695  }
696 
700  {
701  assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
702  assert( index < size() && bool("Index out of bounds!") );
703 
704  return entry_proxy<SCALARTYPE>(start_ + stride_ * index, elements_);
705  }
706 
707 
711  {
712  assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
713  assert( index < size() && bool("Index out of bounds!") );
714 
715  return const_entry_proxy<SCALARTYPE>(start_ + stride_ * index, elements_);
716  }
717 
721  {
722  assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
723  assert( index < size() && bool("Index out of bounds!") );
724 
725  return const_entry_proxy<SCALARTYPE>(start_ + stride_ * index, elements_);
726  }
727 
728  //
729  // Operator overloads with implicit conversion (thus cannot be made global without introducing additional headache)
730  //
731  self_type & operator += (const self_type & vec)
732  {
733  assert(vec.size() == size() && bool("Incompatible vector sizes!"));
734 
735  if (size() > 0)
737  *this, SCALARTYPE(1.0), 1, false, false,
738  vec, SCALARTYPE(1.0), 1, false, false);
739  return *this;
740  }
741 
742  self_type & operator -= (const self_type & vec)
743  {
744  assert(vec.size() == size() && bool("Incompatible vector sizes!"));
745 
746  if (size() > 0)
748  *this, SCALARTYPE(1.0), 1, false, false,
749  vec, SCALARTYPE(-1.0), 1, false, false);
750  return *this;
751  }
752 
755  self_type & operator *= (SCALARTYPE val)
756  {
757  if (size() > 0)
758  viennacl::linalg::av(*this,
759  *this, val, 1, false, false);
760  return *this;
761  }
762 
765  self_type & operator /= (SCALARTYPE val)
766  {
767  if (size() > 0)
768  viennacl::linalg::av(*this,
769  *this, val, 1, true, false);
770  return *this;
771  }
772 
773 
777  operator * (SCALARTYPE value) const
778  {
780  }
781 
782 
786  operator / (SCALARTYPE value) const
787  {
789  }
790 
791 
794  {
796  }
797 
798  //
800  //
801 
803  iterator begin()
804  {
805  return iterator(*this, 0, start_, stride_);
806  }
807 
809  iterator end()
810  {
811  return iterator(*this, size(), start_, stride_);
812  }
813 
815  const_iterator begin() const
816  {
817  return const_iterator(*this, 0, start_, stride_);
818  }
819 
821  const_iterator end() const
822  {
823  return const_iterator(*this, size(), start_, stride_);
824  }
825 
828  self_type & swap(self_type & other)
829  {
830  viennacl::linalg::vector_swap(*this, other);
831  return *this;
832  };
833 
834 
837  size_type size() const { return size_; }
838 
841  size_type internal_size() const { return internal_size_; }
842 
845  size_type start() const { return start_; }
846 
849  size_type stride() const { return stride_; }
850 
851 
853  bool empty() const { return size_ == 0; }
854 
856  const handle_type & handle() const { return elements_; }
857 
859  handle_type & handle() { return elements_; }
860 
863  void clear()
864  {
866  }
867 
869  {
870  return elements_.get_active_handle_id();
871  }
872 
873  protected:
874 
876  {
877  elements_ = h;
878  }
879 
882  self_type & fast_swap(self_type & other)
883  {
884  assert(this->size_ == other.size_ && bool("Vector size mismatch"));
885  this->elements_.swap(other.elements_);
886  return *this;
887  }
888 
890  void pad()
891  {
892  if (internal_size() != size())
893  {
894  std::vector<SCALARTYPE> pad(internal_size() - size());
895  viennacl::backend::memory_write(elements_, sizeof(SCALARTYPE) * size(), sizeof(SCALARTYPE) * pad.size(), &(pad[0]));
896  }
897  }
898 
900  {
901  viennacl::backend::switch_memory_context<SCALARTYPE>(elements_, new_ctx);
902  }
903 
904  //TODO: Think about implementing the following public member functions
905  //void insert_element(unsigned int i, SCALARTYPE val){}
906  //void erase_element(unsigned int i){}
907 
908  //enlarge or reduce allocated memory and set unused memory to zero
914  void resize(size_type new_size, bool preserve = true)
915  {
916  resize_impl(new_size, viennacl::traits::context(*this), preserve);
917  }
918 
925  void resize(size_type new_size, viennacl::context ctx, bool preserve = true)
926  {
927  resize_impl(new_size, ctx, preserve);
928  }
929 
930  private:
931 
932  void resize_impl(size_type new_size, viennacl::context ctx, bool preserve = true)
933  {
934  assert(new_size > 0 && bool("Positive size required when resizing vector!"));
935 
936  if (new_size != size_)
937  {
938  vcl_size_t new_internal_size = viennacl::tools::align_to_multiple<vcl_size_t>(new_size, alignment);
939 
940  std::vector<SCALARTYPE> temp(size_);
941  if (preserve && size_ > 0)
942  fast_copy(*this, temp);
943  temp.resize(new_size); //drop all entries above new_size
944  temp.resize(new_internal_size); //enlarge to fit new internal size
945 
946  if (new_internal_size != internal_size())
947  {
948  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*new_internal_size, ctx, NULL);
949  }
950 
951  fast_copy(temp, *this);
952  size_ = new_size;
953  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, alignment);
954  pad();
955  }
956 
957  }
958 
959  size_type size_;
960  size_type start_;
961  difference_type stride_;
962  size_type internal_size_;
963  handle_type elements_;
964  }; //vector_base
965 
966 
967 
968  // forward definition in forwards.h!
977  template<class SCALARTYPE, unsigned int ALIGNMENT>
978  class vector : public vector_base<SCALARTYPE>
979  {
980  typedef vector<SCALARTYPE, ALIGNMENT> self_type;
981  typedef vector_base<SCALARTYPE> base_type;
982 
983  public:
984  typedef typename base_type::size_type size_type;
986 
989  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 */ }
990 
995  explicit vector(size_type vec_size) : base_type(vec_size) {}
996 
997  explicit vector(size_type vec_size, viennacl::context ctx) : base_type(vec_size, ctx) {}
998 
999  explicit vector(SCALARTYPE * ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start = 0, difference_type stride = 1)
1000  : base_type(ptr_to_mem, mem_type, vec_size, start, stride) {}
1001 
1002 #ifdef VIENNACL_WITH_OPENCL
1003 
1011  explicit vector(cl_mem existing_mem, size_type vec_size, size_type start = 0, difference_type stride = 1) : base_type(existing_mem, vec_size, start, stride) {}
1012 
1018  explicit vector(size_type vec_size, viennacl::ocl::context const & ctx) : base_type(vec_size, ctx) {}
1019 #endif
1020 
1021  template <typename LHS, typename RHS, typename OP>
1022  vector(vector_expression<const LHS, const RHS, OP> const & proxy) : base_type(proxy) {}
1023 
1024  vector(const base_type & v) : base_type(v.size(), viennacl::traits::context(v))
1025  {
1026  if (v.size() > 0)
1027  base_type::operator=(v);
1028  }
1029 
1030  vector(const self_type & v) : base_type(v.size(), viennacl::traits::context(v))
1031  {
1032  if (v.size() > 0)
1033  base_type::operator=(v);
1034  }
1035 
1037  vector(unit_vector<SCALARTYPE> const & v) : base_type(v.size())
1038  {
1039  if (v.size() > 0)
1040  this->operator()(v.index()) = SCALARTYPE(1);;
1041  }
1042 
1044  vector(zero_vector<SCALARTYPE> const & v) : base_type(v.size(), v.context())
1045  {
1046  if (v.size() > 0)
1047  viennacl::linalg::vector_assign(*this, SCALARTYPE(0.0));
1048  }
1049 
1051  vector(scalar_vector<SCALARTYPE> const & v) : base_type(v.size(), v.context())
1052  {
1053  if (v.size() > 0)
1054  viennacl::linalg::vector_assign(*this, v[0]);
1055  }
1056 
1057  // the following is used to circumvent an issue with Clang 3.0 when 'using base_type::operator=;' directly
1058  template <typename T>
1059  self_type & operator=(T const & other)
1060  {
1061  base_type::operator=(other);
1062  return *this;
1063  }
1064 
1065  using base_type::operator+=;
1066  using base_type::operator-=;
1067 
1068  //enlarge or reduce allocated memory and set unused memory to zero
1074  void resize(size_type new_size, bool preserve = true)
1075  {
1076  base_type::resize(new_size, preserve);
1077  }
1078 
1079  void resize(size_type new_size, viennacl::context ctx, bool preserve = true)
1080  {
1081  base_type::resize(new_size, ctx, preserve);
1082  }
1083 
1086  self_type & fast_swap(self_type & other)
1087  {
1088  base_type::fast_swap(other);
1089  return *this;
1090  }
1091 
1093  {
1095  }
1096 
1097  }; //vector
1098 
1100  template <typename ScalarT>
1101  class vector_tuple
1102  {
1103  typedef vector_base<ScalarT> VectorType;
1104 
1105  public:
1106  // 2 vectors
1107 
1108  vector_tuple(VectorType const & v0, VectorType const & v1) : const_vectors_(2), non_const_vectors_()
1109  {
1110  const_vectors_[0] = &v0;
1111  const_vectors_[1] = &v1;
1112  }
1113  vector_tuple(VectorType & v0, VectorType & v1) : const_vectors_(2), non_const_vectors_(2)
1114  {
1115  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1116  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1117  }
1118 
1119  // 3 vectors
1120 
1121  vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2) : const_vectors_(3), non_const_vectors_()
1122  {
1123  const_vectors_[0] = &v0;
1124  const_vectors_[1] = &v1;
1125  const_vectors_[2] = &v2;
1126  }
1127  vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2) : const_vectors_(3), non_const_vectors_(3)
1128  {
1129  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1130  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1131  const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
1132  }
1133 
1134  // 4 vectors
1135 
1136  vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2, VectorType const & v3) : const_vectors_(4), non_const_vectors_()
1137  {
1138  const_vectors_[0] = &v0;
1139  const_vectors_[1] = &v1;
1140  const_vectors_[2] = &v2;
1141  const_vectors_[3] = &v3;
1142  }
1143  vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2, VectorType & v3) : const_vectors_(4), non_const_vectors_(4)
1144  {
1145  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1146  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1147  const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
1148  const_vectors_[3] = &v3; non_const_vectors_[3] = &v3;
1149  }
1150 
1151  // add more overloads here
1152 
1153  // generic interface:
1154 
1155  vector_tuple(std::vector<VectorType const *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_()
1156  {
1157  for (vcl_size_t i=0; i<vecs.size(); ++i)
1158  const_vectors_[i] = vecs[i];
1159  }
1160 
1161  vector_tuple(std::vector<VectorType *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_(vecs.size())
1162  {
1163  for (vcl_size_t i=0; i<vecs.size(); ++i)
1164  {
1165  const_vectors_[i] = vecs[i];
1166  non_const_vectors_[i] = vecs[i];
1167  }
1168  }
1169 
1170  vcl_size_t size() const { return non_const_vectors_.size(); }
1171  vcl_size_t const_size() const { return const_vectors_.size(); }
1172 
1173  VectorType & at(vcl_size_t i) const { return *(non_const_vectors_.at(i)); }
1174  VectorType const & const_at(vcl_size_t i) const { return *(const_vectors_.at(i)); }
1175 
1176  private:
1177  std::vector<VectorType const *> const_vectors_;
1178  std::vector<VectorType *> non_const_vectors_;
1179  };
1180 
1181  // 2 args
1182  template <typename ScalarT>
1184 
1185  template <typename ScalarT>
1187 
1188  // 3 args
1189  template <typename ScalarT>
1191 
1192  template <typename ScalarT>
1194 
1195  // 4 args
1196  template <typename ScalarT>
1198  {
1199  return vector_tuple<ScalarT>(v0, v1, v2, v3);
1200  }
1201 
1202  template <typename ScalarT>
1204  {
1205  return vector_tuple<ScalarT>(v0, v1, v2, v3);
1206  }
1207 
1208  // 5 args
1209  template <typename ScalarT>
1211  vector_base<ScalarT> const & v1,
1212  vector_base<ScalarT> const & v2,
1213  vector_base<ScalarT> const & v3,
1214  vector_base<ScalarT> const & v4)
1215  {
1216  typedef vector_base<ScalarT> const * VectorPointerType;
1217  std::vector<VectorPointerType> vec(5);
1218  vec[0] = &v0;
1219  vec[1] = &v1;
1220  vec[2] = &v2;
1221  vec[3] = &v3;
1222  vec[4] = &v4;
1223  return vector_tuple<ScalarT>(vec);
1224  }
1225 
1226  template <typename ScalarT>
1228  vector_base<ScalarT> & v1,
1229  vector_base<ScalarT> & v2,
1230  vector_base<ScalarT> & v3,
1231  vector_base<ScalarT> & v4)
1232  {
1233  typedef vector_base<ScalarT> * VectorPointerType;
1234  std::vector<VectorPointerType> vec(5);
1235  vec[0] = &v0;
1236  vec[1] = &v1;
1237  vec[2] = &v2;
1238  vec[3] = &v3;
1239  vec[4] = &v4;
1240  return vector_tuple<ScalarT>(vec);
1241  }
1242 
1243  // TODO: Add more arguments to tie() here. Maybe use some preprocessor magic to accomplish this.
1244 
1245  //
1247  //
1248 
1249 
1261  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1264  CPU_ITERATOR cpu_begin )
1265  {
1266  if (gpu_begin != gpu_end)
1267  {
1268  if (gpu_begin.stride() == 1)
1269  {
1270  viennacl::backend::memory_read(gpu_begin.handle(),
1271  sizeof(SCALARTYPE)*gpu_begin.offset(),
1272  sizeof(SCALARTYPE)*gpu_begin.stride() * (gpu_end - gpu_begin),
1273  &(*cpu_begin));
1274  }
1275  else
1276  {
1277  vcl_size_t gpu_size = (gpu_end - gpu_begin);
1278  std::vector<SCALARTYPE> temp_buffer(gpu_begin.stride() * gpu_size);
1279  viennacl::backend::memory_read(gpu_begin.handle(), sizeof(SCALARTYPE)*gpu_begin.offset(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
1280 
1281  for (vcl_size_t i=0; i<gpu_size; ++i)
1282  {
1283  (&(*cpu_begin))[i] = temp_buffer[i * gpu_begin.stride()];
1284  }
1285  }
1286  }
1287  }
1288 
1294  template <typename NumericT, typename CPUVECTOR>
1295  void fast_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1296  {
1297  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1298  }
1299 
1300 
1311  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1314  CPU_ITERATOR cpu_begin )
1315  {
1316  if (gpu_begin != gpu_end)
1317  {
1318  if (gpu_begin.stride() == 1)
1319  {
1320  viennacl::backend::memory_read(gpu_begin.handle(),
1321  sizeof(SCALARTYPE)*gpu_begin.offset(),
1322  sizeof(SCALARTYPE)*gpu_begin.stride() * (gpu_end - gpu_begin),
1323  &(*cpu_begin),
1324  true);
1325  }
1326  else // no async copy possible, so fall-back to fast_copy
1327  fast_copy(gpu_begin, gpu_end, cpu_begin);
1328  }
1329  }
1330 
1336  template <typename NumericT, typename CPUVECTOR>
1337  void async_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1338  {
1339  viennacl::async_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1340  }
1341 
1342 
1349  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1352  CPU_ITERATOR cpu_begin )
1353  {
1354  assert(gpu_end - gpu_begin >= 0 && bool("Iterators incompatible"));
1355  if (gpu_end - gpu_begin != 0)
1356  {
1357  std::vector<SCALARTYPE> temp_buffer(gpu_end - gpu_begin);
1358  fast_copy(gpu_begin, gpu_end, temp_buffer.begin());
1359 
1360  //now copy entries to cpu_vec:
1361  std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_begin);
1362  }
1363  }
1364 
1371  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1374  CPU_ITERATOR cpu_begin )
1375 
1376  {
1379  cpu_begin);
1380  }
1381 
1387  template <typename NumericT, typename CPUVECTOR>
1388  void copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1389  {
1390  viennacl::copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1391  }
1392 
1393 
1394 
1395  #ifdef VIENNACL_WITH_EIGEN
1396  template <unsigned int ALIGNMENT>
1397  void copy(vector<float, ALIGNMENT> const & gpu_vec,
1398  Eigen::VectorXf & eigen_vec)
1399  {
1400  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
1401  }
1402 
1403  template <unsigned int ALIGNMENT>
1404  void copy(vector<double, ALIGNMENT> & gpu_vec,
1405  Eigen::VectorXd & eigen_vec)
1406  {
1407  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
1408  }
1409  #endif
1410 
1411 
1412  //
1414  //
1415 
1427  template <typename CPU_ITERATOR, typename SCALARTYPE, unsigned int ALIGNMENT>
1428  void fast_copy(CPU_ITERATOR const & cpu_begin,
1429  CPU_ITERATOR const & cpu_end,
1431  {
1432  if (cpu_end - cpu_begin > 0)
1433  {
1434  if (gpu_begin.stride() == 1)
1435  {
1437  sizeof(SCALARTYPE)*gpu_begin.offset(),
1438  sizeof(SCALARTYPE)*gpu_begin.stride() * (cpu_end - cpu_begin), &(*cpu_begin));
1439  }
1440  else //writing to slice:
1441  {
1442  vcl_size_t cpu_size = (cpu_end - cpu_begin);
1443  std::vector<SCALARTYPE> temp_buffer(gpu_begin.stride() * cpu_size);
1444 
1445  viennacl::backend::memory_read(gpu_begin.handle(), sizeof(SCALARTYPE)*gpu_begin.offset(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
1446 
1447  for (vcl_size_t i=0; i<cpu_size; ++i)
1448  temp_buffer[i * gpu_begin.stride()] = (&(*cpu_begin))[i];
1449 
1450  viennacl::backend::memory_write(gpu_begin.handle(), sizeof(SCALARTYPE)*gpu_begin.offset(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
1451  }
1452  }
1453  }
1454 
1455 
1461  template <typename CPUVECTOR, typename NumericT>
1462  void fast_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
1463  {
1464  viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1465  }
1466 
1477  template <typename CPU_ITERATOR, typename SCALARTYPE, unsigned int ALIGNMENT>
1478  void async_copy(CPU_ITERATOR const & cpu_begin,
1479  CPU_ITERATOR const & cpu_end,
1481  {
1482  if (cpu_end - cpu_begin > 0)
1483  {
1484  if (gpu_begin.stride() == 1)
1485  {
1487  sizeof(SCALARTYPE)*gpu_begin.offset(),
1488  sizeof(SCALARTYPE)*gpu_begin.stride() * (cpu_end - cpu_begin), &(*cpu_begin),
1489  true);
1490  }
1491  else // fallback to blocking copy. There's nothing we can do to prevent this
1492  fast_copy(cpu_begin, cpu_end, gpu_begin);
1493  }
1494  }
1495 
1496 
1502  template <typename CPUVECTOR, typename NumericT>
1503  void async_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
1504  {
1505  viennacl::async_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1506  }
1507 
1508  //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
1515  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1516  void copy(CPU_ITERATOR const & cpu_begin,
1517  CPU_ITERATOR const & cpu_end,
1519  {
1520  assert(cpu_end - cpu_begin > 0 && bool("Iterators incompatible"));
1521  if (cpu_begin != cpu_end)
1522  {
1523  //we require that the size of the gpu_vector is larger or equal to the cpu-size
1524  std::vector<SCALARTYPE> temp_buffer(cpu_end - cpu_begin);
1525  std::copy(cpu_begin, cpu_end, temp_buffer.begin());
1526  viennacl::fast_copy(temp_buffer.begin(), temp_buffer.end(), gpu_begin);
1527  }
1528  }
1529 
1530  // for things like copy(std_vec.begin(), std_vec.end(), vcl_vec.begin() + 1);
1531 
1537  template <typename CPUVECTOR, typename T>
1538  void copy(const CPUVECTOR & cpu_vec, vector_base<T> & gpu_vec)
1539  {
1540  viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1541  }
1542 
1543 
1544  #ifdef VIENNACL_WITH_EIGEN
1545  template <unsigned int ALIGNMENT>
1546  void copy(Eigen::VectorXf const & eigen_vec,
1547  vector<float, ALIGNMENT> & gpu_vec)
1548  {
1549  std::vector<float> entries(eigen_vec.size());
1550  for (vcl_size_t i = 0; i<entries.size(); ++i)
1551  entries[i] = eigen_vec(i);
1552  viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
1553  }
1554 
1555  template <unsigned int ALIGNMENT>
1556  void copy(Eigen::VectorXd const & eigen_vec,
1557  vector<double, ALIGNMENT> & gpu_vec)
1558  {
1559  std::vector<double> entries(eigen_vec.size());
1560  for (vcl_size_t i = 0; i<entries.size(); ++i)
1561  entries[i] = eigen_vec(i);
1562  viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
1563  }
1564  #endif
1565 
1566 
1567 
1568  //
1570  //
1577  template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
1581  {
1582  assert(gpu_src_end - gpu_src_begin >= 0);
1583  assert(gpu_src_begin.stride() == 1 && bool("ViennaCL ERROR: copy() for GPU->GPU not implemented for slices! Use operator= instead for the moment."));
1584 
1585  if (gpu_src_begin.stride() == 1 && gpu_dest_begin.stride() == 1)
1586  {
1587  if (gpu_src_begin != gpu_src_end)
1588  viennacl::backend::memory_copy(gpu_src_begin.handle(), gpu_dest_begin.handle(),
1589  sizeof(SCALARTYPE) * gpu_src_begin.offset(),
1590  sizeof(SCALARTYPE) * gpu_dest_begin.offset(),
1591  sizeof(SCALARTYPE) * (gpu_src_end.offset() - gpu_src_begin.offset()));
1592  }
1593  else
1594  {
1595  assert( false && bool("not implemented yet"));
1596  }
1597  }
1598 
1605  template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
1607  vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end,
1609  {
1611  static_cast<const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> >(gpu_src_end),
1612  gpu_dest_begin);
1613  }
1614 
1620  template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
1621  void copy(vector<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_vec,
1622  vector<SCALARTYPE, ALIGNMENT_DEST> & gpu_dest_vec )
1623  {
1624  viennacl::copy(gpu_src_vec.begin(), gpu_src_vec.end(), gpu_dest_vec.begin());
1625  }
1626 
1627 
1628 
1629 
1630 
1631 
1632  //global functions for handling vectors:
1637  template <typename T>
1638  std::ostream & operator<<(std::ostream & os, vector_base<T> const & val)
1639  {
1640  std::vector<T> tmp(val.size());
1641  viennacl::copy(val.begin(), val.end(), tmp.begin());
1642  os << "[" << val.size() << "](";
1643  for (typename std::vector<T>::size_type i=0; i<val.size(); ++i)
1644  {
1645  if (i > 0)
1646  os << ",";
1647  os << tmp[i];
1648  }
1649  os << ")";
1650  return os;
1651  }
1652 
1653  template <typename LHS, typename RHS, typename OP>
1654  std::ostream & operator<<(std::ostream & os, vector_expression<LHS, RHS, OP> const & proxy)
1655 
1656  {
1658  viennacl::vector<ScalarType> result = proxy;
1659  os << result;
1660  return os;
1661  }
1662 
1668  template <typename T>
1669  void swap(vector_base<T> & vec1, vector_base<T> & vec2)
1670  {
1671  viennacl::linalg::vector_swap(vec1, vec2);
1672  }
1673 
1679  template <typename SCALARTYPE, unsigned int ALIGNMENT>
1682  {
1683  return v1.fast_swap(v2);
1684  }
1685 
1686 
1687 
1688 
1689 
1690  //
1691  //
1693  //
1694  //
1695 
1696 
1697  //
1698  // operator *=
1699  //
1700 
1703  template <typename T, typename S1>
1705  vector_base<T> &
1706  >::type
1707  operator *= (vector_base<T> & v1, S1 const & gpu_val)
1708  {
1709  if (v1.size() > 0)
1711  v1, gpu_val, 1, false, (viennacl::is_flip_sign_scalar<S1>::value ? true : false));
1712  return v1;
1713  }
1714 
1715 
1716  //
1717  // operator /=
1718  //
1719 
1720 
1723  template <typename T, typename S1>
1725  vector_base<T> &
1726  >::type
1727  operator /= (vector_base<T> & v1, S1 const & gpu_val)
1728  {
1729  if (v1.size() > 0)
1731  v1, gpu_val, 1, true, (viennacl::is_flip_sign_scalar<S1>::value ? true : false));
1732  return v1;
1733  }
1734 
1735 
1736  //
1737  // operator +
1738  //
1739 
1740 
1746  template <typename LHS1, typename RHS1, typename OP1,
1747  typename LHS2, typename RHS2, typename OP2>
1748  vector_expression< const vector_expression< LHS1, RHS1, OP1>,
1749  const vector_expression< LHS2, RHS2, OP2>,
1752  vector_expression<LHS2, RHS2, OP2> const & proxy2)
1753  {
1754  assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
1757  viennacl::op_add>(proxy1, proxy2);
1758  }
1759 
1765  template <typename LHS, typename RHS, typename OP, typename T>
1766  vector_expression< const vector_expression<LHS, RHS, OP>,
1767  const vector_base<T>,
1770  vector_base<T> const & vec)
1771  {
1772  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1774  const vector_base<T>,
1775  viennacl::op_add>(proxy, vec);
1776  }
1777 
1783  template <typename T, typename LHS, typename RHS, typename OP>
1784  vector_expression< const vector_base<T>,
1785  const vector_expression<LHS, RHS, OP>,
1787  operator + (vector_base<T> const & vec,
1788  vector_expression<LHS, RHS, OP> const & proxy)
1789  {
1790  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1792  const vector_expression<LHS, RHS, OP>,
1793  viennacl::op_add>(vec, proxy);
1794  }
1795 
1798  template <typename T>
1799  vector_expression< const vector_base<T>, const vector_base<T>, op_add>
1800  operator + (const vector_base<T> & v1, const vector_base<T> & v2)
1801  {
1802  return vector_expression< const vector_base<T>, const vector_base<T>, op_add>(v1, v2);
1803  }
1804 
1805 
1806 
1807  //
1808  // operator -
1809  //
1810 
1816  template <typename LHS1, typename RHS1, typename OP1,
1817  typename LHS2, typename RHS2, typename OP2>
1818  vector_expression< const vector_expression< LHS1, RHS1, OP1>,
1819  const vector_expression< LHS2, RHS2, OP2>,
1822  vector_expression<LHS2, RHS2, OP2> const & proxy2)
1823  {
1824  assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
1827  viennacl::op_sub>(proxy1, proxy2);
1828  }
1829 
1830 
1836  template <typename LHS, typename RHS, typename OP, typename T>
1837  vector_expression< const vector_expression<LHS, RHS, OP>,
1838  const vector_base<T>,
1840  operator - (vector_expression<LHS, RHS, OP> const & proxy,
1841  vector_base<T> const & vec)
1842  {
1843  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1845  const vector_base<T>,
1846  viennacl::op_sub>(proxy, vec);
1847  }
1848 
1854  template <typename T, typename LHS, typename RHS, typename OP>
1855  vector_expression< const vector_base<T>,
1856  const vector_expression<LHS, RHS, OP>,
1858  operator - (vector_base<T> const & vec,
1859  vector_expression<LHS, RHS, OP> const & proxy)
1860  {
1861  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1863  const vector_expression<LHS, RHS, OP>,
1864  viennacl::op_sub>(vec, proxy);
1865  }
1866 
1869  template <typename T>
1870  vector_expression< const vector_base<T>, const vector_base<T>, op_sub>
1871  operator - (const vector_base<T> & v1, const vector_base<T> & v2)
1872  {
1873  return vector_expression< const vector_base<T>, const vector_base<T>, op_sub>(v1, v2);
1874  }
1875 
1876 
1877  //
1878  // operator *
1879  //
1880 
1881 
1887  template <typename S1, typename T>
1889  vector_expression< const vector_base<T>, const S1, op_mult> >::type
1890  operator * (S1 const & value, vector_base<T> const & vec)
1891  {
1892  return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
1893  }
1894 
1900  template <typename T>
1901  vector_expression< const vector_base<T>, const T, op_mult>
1902  operator * (char value, vector_base<T> const & vec)
1903  {
1904  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1905  }
1906 
1912  template <typename T>
1913  vector_expression< const vector_base<T>, const T, op_mult>
1914  operator * (short value, vector_base<T> const & vec)
1915  {
1916  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1917  }
1918 
1924  template <typename T>
1925  vector_expression< const vector_base<T>, const T, op_mult>
1926  operator * (int value, vector_base<T> const & vec)
1927  {
1928  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1929  }
1930 
1936  template <typename T>
1937  vector_expression< const vector_base<T>, const T, op_mult>
1938  operator * (long value, vector_base<T> const & vec)
1939  {
1940  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1941  }
1942 
1943 
1944 
1945 
1951  template <typename LHS, typename RHS, typename OP, typename T>
1952  vector_expression< const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult>
1953  operator * (scalar_expression<LHS, RHS, OP> const & expr, vector_base<T> const & vec)
1954  {
1955  return vector_expression< const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult>(vec, expr);
1956  }
1957 
1960  template <typename T, typename S1>
1962  vector_expression< const vector_base<T>, const S1, op_mult> >::type
1963  operator * (vector_base<T> const & vec, S1 const & value)
1964  {
1965  return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
1966  }
1967 
1968  template <typename T>
1969  vector_expression< const vector_base<T>, const T, op_mult>
1970  operator * (vector_base<T> const & vec, T const & value)
1971  {
1972  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1973  }
1974 
1980  template <typename LHS, typename RHS, typename OP, typename S1>
1984  S1 const & val)
1985  {
1986  return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult>(proxy, val);
1987  }
1988 
1994  template <typename S1, typename LHS, typename RHS, typename OP>
1996  viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult> >::type
1997  operator * (S1 const & val,
1998  vector_expression<LHS, RHS, OP> const & proxy)
1999  {
2000  return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_mult>(proxy, val);
2001  }
2002 
2003  //
2004  // operator /
2005  //
2006 
2012  template <typename S1, typename LHS, typename RHS, typename OP>
2014  viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_div> >::type
2016  S1 const & val)
2017  {
2018  return viennacl::vector_expression<const vector_expression<LHS, RHS, OP>, const S1, op_div>(proxy, val);
2019  }
2020 
2021 
2024  template <typename T, typename S1>
2026  vector_expression< const vector_base<T>, const S1, op_div> >::type
2027  operator / (vector_base<T> const & v1, S1 const & s1)
2028  {
2029  return vector_expression<const vector_base<T>, const S1, op_div>(v1, s1);
2030  }
2031 
2032 
2033 
2034  //
2035  // Specify available operations:
2036  //
2037 
2040  namespace linalg
2041  {
2042  namespace detail
2043  {
2044  // x = y
2045  template <typename T>
2046  struct op_executor<vector_base<T>, op_assign, vector_base<T> >
2047  {
2048  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2049  {
2050  viennacl::linalg::av(lhs, rhs, T(1), 1, false, false);
2051  }
2052  };
2053 
2054  // x = inner_prod(z, {y0, y1, ...})
2055  template <typename T>
2056  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> >
2057  {
2058  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> const & rhs)
2059  {
2060  viennacl::linalg::inner_prod_impl(rhs.lhs(), rhs.rhs(), lhs);
2061  }
2062  };
2063 
2064  // x += y
2065  template <typename T>
2066  struct op_executor<vector_base<T>, op_inplace_add, vector_base<T> >
2067  {
2068  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2069  {
2070  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, false);
2071  }
2072  };
2073 
2074  // x -= y
2075  template <typename T>
2076  struct op_executor<vector_base<T>, op_inplace_sub, vector_base<T> >
2077  {
2078  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2079  {
2080  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, true);
2081  }
2082  };
2083 
2085 
2086 
2087  // x = alpha * y
2088  template <typename T, typename ScalarType>
2089  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2090  {
2091  // generic case: ScalarType is a scalar expression
2092  template <typename LHS, typename RHS, typename OP>
2093  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2094  {
2095  T alpha = proxy.rhs();
2096  viennacl::linalg::av(lhs, proxy.lhs(), alpha, 1, false, false);
2097  }
2098 
2099  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2100  {
2101  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
2102  }
2103 
2104  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2105  {
2106  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
2107  }
2108  };
2109 
2110  // x += alpha * y
2111  template <typename T, typename ScalarType>
2112  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2113  {
2114  // generic case: ScalarType is a scalar expression
2115  template <typename LHS, typename RHS, typename OP>
2116  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2117  {
2118  T alpha = proxy.rhs();
2119  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, false);
2120  }
2121 
2122  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2123  {
2124  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
2125  }
2126 
2127  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2128  {
2129  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
2130  }
2131  };
2132 
2133  // x -= alpha * y
2134  template <typename T, typename ScalarType>
2135  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2136  {
2137  // generic case: ScalarType is a scalar expression
2138  template <typename LHS, typename RHS, typename OP>
2139  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2140  {
2141  T alpha = proxy.rhs();
2142  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, true);
2143  }
2144 
2145  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2146  {
2147  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
2148  }
2149 
2150  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2151  {
2152  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
2153  }
2154  };
2155 
2156 
2158 
2159  // x = alpha * vec_expr
2160  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2161  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2162  {
2163  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2164  {
2165  vector<T> temp(proxy.lhs());
2166  lhs = temp * proxy.rhs();
2167  }
2168  };
2169 
2170  // x += alpha * vec_expr
2171  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2172  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2173  {
2174  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2175  {
2176  vector<T> temp(proxy.lhs());
2177  lhs += temp * proxy.rhs();
2178  }
2179  };
2180 
2181  // x -= alpha * vec_expr
2182  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2183  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2184  {
2185  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2186  {
2187  vector<T> temp(proxy.lhs());
2188  lhs -= temp * proxy.rhs();
2189  }
2190  };
2191 
2192 
2194 
2195  // x = y / alpha
2196  template <typename T, typename ScalarType>
2197  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2198  {
2199  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2200  {
2201  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, true, false);
2202  }
2203  };
2204 
2205  // x += y / alpha
2206  template <typename T, typename ScalarType>
2207  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2208  {
2209  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2210  {
2211  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, false);
2212  }
2213  };
2214 
2215  // x -= y / alpha
2216  template <typename T, typename ScalarType>
2217  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2218  {
2219  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2220  {
2221  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, true);
2222  }
2223  };
2224 
2225 
2227 
2228  // x = vec_expr / alpha
2229  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2230  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2231  {
2232  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2233  {
2234  vector<T> temp(proxy.lhs());
2235  lhs = temp / proxy.rhs();
2236  }
2237  };
2238 
2239  // x += vec_expr / alpha
2240  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2241  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2242  {
2243  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2244  {
2245  vector<T> temp(proxy.lhs());
2246  lhs += temp / proxy.rhs();
2247  }
2248  };
2249 
2250  // x -= vec_expr / alpha
2251  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2252  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2253  {
2254  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2255  {
2256  vector<T> temp(proxy.lhs());
2257  lhs -= temp / proxy.rhs();
2258  }
2259  };
2260 
2261 
2262 
2263  // generic x = vec_expr1 + vec_expr2:
2264  template <typename T, typename LHS, typename RHS>
2265  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_add> >
2266  {
2267  // generic x = vec_expr1 + vec_expr2:
2268  template <typename LHS1, typename RHS1>
2269  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2270  {
2271  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2272  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2273 
2274  if (op_aliasing_lhs || op_aliasing_rhs)
2275  {
2276  vector_base<T> temp(proxy.lhs());
2277  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2278  lhs = temp;
2279  }
2280  else
2281  {
2282  op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
2283  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2284  }
2285  }
2286 
2287  // x = y + z
2288  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2289  {
2291  proxy.lhs(), T(1), 1, false, false,
2292  proxy.rhs(), T(1), 1, false, false);
2293  }
2294 
2295  // x = alpha * y + z
2296  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2297  const vector_base<T>,
2298  op_add> const & proxy)
2299  {
2301  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2302  proxy.rhs(), T(1), 1, false, false);
2303  }
2304 
2305  // x = y / alpha + z
2306  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2307  const vector_base<T>,
2308  op_add> const & proxy)
2309  {
2311  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2312  proxy.rhs(), T(1), 1, false, false);
2313  }
2314 
2315  // x = y + beta * z
2316  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2317  const vector_expression<const vector_base<T>, const T, op_mult>,
2318  op_add> const & proxy)
2319  {
2321  proxy.lhs(), T(1), 1, false, false,
2322  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2323  }
2324 
2325  // x = y + z / beta
2326  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2327  const vector_expression<const vector_base<T>, const T, op_div>,
2328  op_add> const & proxy)
2329  {
2331  proxy.lhs(), T(1), 1, false, false,
2332  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2333  }
2334 
2335  // x = alpha * y + beta * z
2336  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2337  const vector_expression<const vector_base<T>, const T, op_mult>,
2338  op_add> const & proxy)
2339  {
2341  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2342  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2343  }
2344 
2345  // x = alpha * y + z / beta
2346  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2347  const vector_expression<const vector_base<T>, const T, op_div>,
2348  op_add> const & proxy)
2349  {
2351  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2352  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2353  }
2354 
2355  // x = y / alpha + beta * z
2356  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2357  const vector_expression<const vector_base<T>, const T, op_mult>,
2358  op_add> const & proxy)
2359  {
2361  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2362  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2363  }
2364 
2365  // x = y / alpha + z / beta
2366  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2367  const vector_expression<const vector_base<T>, const T, op_div>,
2368  op_add> const & proxy)
2369  {
2371  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2372  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2373  }
2374  };
2375 
2376 
2377  // generic x += vec_expr1 + vec_expr2:
2378  template <typename T, typename LHS, typename RHS>
2379  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_add> >
2380  {
2381  // generic x += vec_expr1 + vec_expr2:
2382  template <typename LHS1, typename RHS1>
2383  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2384  {
2385  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2386  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2387 
2388  if (op_aliasing_lhs || op_aliasing_rhs)
2389  {
2390  vector_base<T> temp(proxy.lhs());
2391  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2392  lhs += temp;
2393  }
2394  else
2395  {
2396  op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
2397  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2398  }
2399  }
2400 
2401  // x += y + z
2402  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2403  {
2405  proxy.lhs(), T(1), 1, false, false,
2406  proxy.rhs(), T(1), 1, false, false);
2407  }
2408 
2409  // x += alpha * y + z
2410  template <typename ScalarType>
2411  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2412  const vector_base<T>,
2413  op_add> const & proxy)
2414  {
2416  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2417  proxy.rhs(), T(1), 1, false, false);
2418  }
2419 
2420  // x += y / alpha + z
2421  template <typename ScalarType>
2422  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2423  const vector_base<T>,
2424  op_add> const & proxy)
2425  {
2427  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2428  proxy.rhs(), T(1), 1, false, false);
2429  }
2430 
2431  // x += y + beta * z
2432  template <typename ScalarType>
2433  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2434  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2435  op_add> const & proxy)
2436  {
2438  proxy.lhs(), T(1), 1, false, false,
2439  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2440  }
2441 
2442  // x += y + z / beta
2443  template <typename ScalarType>
2444  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2445  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2446  op_add> const & proxy)
2447  {
2449  proxy.lhs(), T(1), 1, false, false,
2450  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2451  }
2452 
2453  // x += alpha * y + beta * z
2454  template <typename ScalarType1, typename ScalarType2>
2455  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2456  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2457  op_add> const & proxy)
2458  {
2460  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2461  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2462  }
2463 
2464  // x += alpha * y + z / beta
2465  template <typename ScalarType1, typename ScalarType2>
2466  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2467  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2468  op_add> const & proxy)
2469  {
2471  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2472  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2473  }
2474 
2475  // x += y / alpha + beta * z
2476  template <typename ScalarType1, typename ScalarType2>
2477  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2478  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2479  op_add> const & proxy)
2480  {
2482  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2483  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2484  }
2485 
2486  // x += y / alpha + z / beta
2487  template <typename ScalarType1, typename ScalarType2>
2488  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2489  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2490  op_add> const & proxy)
2491  {
2493  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2494  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2495  }
2496  };
2497 
2498 
2499 
2500  // generic x -= vec_expr1 + vec_expr2:
2501  template <typename T, typename LHS, typename RHS>
2502  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_add> >
2503  {
2504  // generic x -= vec_expr1 + vec_expr2:
2505  template <typename LHS1, typename RHS1>
2506  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2507  {
2508  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2509  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2510 
2511  if (op_aliasing_lhs || op_aliasing_rhs)
2512  {
2513  vector_base<T> temp(proxy.lhs());
2514  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2515  lhs -= temp;
2516  }
2517  else
2518  {
2519  op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
2520  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2521  }
2522  }
2523 
2524  // x -= y + z
2525  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2526  {
2528  proxy.lhs(), T(1), 1, false, true,
2529  proxy.rhs(), T(1), 1, false, true);
2530  }
2531 
2532  // x -= alpha * y + z
2533  template <typename ScalarType>
2534  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2535  const vector_base<T>,
2536  op_add> const & proxy)
2537  {
2539  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2540  proxy.rhs(), T(1), 1, false, true);
2541  }
2542 
2543  // x -= y / alpha + z
2544  template <typename ScalarType>
2545  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2546  const vector_base<T>,
2547  op_add> const & proxy)
2548  {
2550  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2551  proxy.rhs(), T(1), 1, false, true);
2552  }
2553 
2554  // x -= y + beta * z
2555  template <typename ScalarType>
2556  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2557  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2558  op_add> const & proxy)
2559  {
2561  proxy.lhs(), T(1), 1, false, true,
2562  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2563  }
2564 
2565  // x -= y + z / beta
2566  template <typename ScalarType>
2567  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2568  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2569  op_add> const & proxy)
2570  {
2572  proxy.lhs(), T(1), 1, false, true,
2573  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2574  }
2575 
2576  // x -= alpha * y + beta * z
2577  template <typename ScalarType1, typename ScalarType2>
2578  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2579  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2580  op_add> const & proxy)
2581  {
2583  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2584  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2585  }
2586 
2587  // x -= alpha * y + z / beta
2588  template <typename ScalarType1, typename ScalarType2>
2589  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2590  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2591  op_add> const & proxy)
2592  {
2594  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2595  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2596  }
2597 
2598  // x -= y / alpha + beta * z
2599  template <typename ScalarType1, typename ScalarType2>
2600  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2601  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2602  op_add> const & proxy)
2603  {
2605  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2606  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2607  }
2608 
2609  // x -= y / alpha + z / beta
2610  template <typename ScalarType1, typename ScalarType2>
2611  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2612  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2613  op_add> const & proxy)
2614  {
2616  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2617  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2618  }
2619  };
2620 
2621 
2622 
2624 
2625 
2626 
2627  // generic x = vec_expr1 - vec_expr2:
2628  template <typename T, typename LHS, typename RHS>
2629  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_sub> >
2630  {
2631  // generic x = vec_expr1 - vec_expr2:
2632  template <typename LHS1, typename RHS1>
2633  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2634  {
2635  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2636  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2637 
2638  if (op_aliasing_lhs || op_aliasing_rhs)
2639  {
2640  vector_base<T> temp(proxy.lhs());
2641  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2642  lhs = temp;
2643  }
2644  else
2645  {
2646  op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
2647  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2648  }
2649  }
2650 
2651  // x = y - z
2652  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2653  {
2655  proxy.lhs(), T(1), 1, false, false,
2656  proxy.rhs(), T(1), 1, false, true);
2657  }
2658 
2659  // x = alpha * y - z
2660  template <typename ScalarType>
2661  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2662  const vector_base<T>,
2663  op_sub> const & proxy)
2664  {
2666  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2667  proxy.rhs(), T(1), 1, false, true);
2668  }
2669 
2670  // x = y / alpha - z
2671  template <typename ScalarType>
2672  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2673  const vector_base<T>,
2674  op_sub> const & proxy)
2675  {
2677  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2678  proxy.rhs(), T(1), 1, false, true);
2679  }
2680 
2681  // x = y - beta * z
2682  template <typename ScalarType>
2683  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2684  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2685  op_sub> const & proxy)
2686  {
2688  proxy.lhs(), T(1), 1, false, false,
2689  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2690  }
2691 
2692  // x = y - z / beta
2693  template <typename ScalarType>
2694  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2695  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2696  op_sub> const & proxy)
2697  {
2699  proxy.lhs(), T(1), 1, false, false,
2700  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2701  }
2702 
2703  // x = alpha * y - beta * z
2704  template <typename ScalarType1, typename ScalarType2>
2705  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2706  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2707  op_sub> const & proxy)
2708  {
2710  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2711  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2712  }
2713 
2714  // x = alpha * y - z / beta
2715  template <typename ScalarType1, typename ScalarType2>
2716  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2717  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2718  op_sub> const & proxy)
2719  {
2721  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2722  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2723  }
2724 
2725  // x = y / alpha - beta * z
2726  template <typename ScalarType1, typename ScalarType2>
2727  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2728  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2729  op_sub> const & proxy)
2730  {
2732  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2733  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2734  }
2735 
2736  // x = y / alpha - z / beta
2737  template <typename ScalarType1, typename ScalarType2>
2738  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2739  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2740  op_sub> const & proxy)
2741  {
2743  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2744  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2745  }
2746  };
2747 
2748 
2749  // generic x += vec_expr1 - vec_expr2:
2750  template <typename T, typename LHS, typename RHS>
2751  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_sub> >
2752  {
2753  // generic x += vec_expr1 - vec_expr2:
2754  template <typename LHS1, typename RHS1>
2755  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2756  {
2757  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2758  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2759 
2760  if (op_aliasing_lhs || op_aliasing_rhs)
2761  {
2762  vector_base<T> temp(proxy.lhs());
2763  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2764  lhs += temp;
2765  }
2766  else
2767  {
2768  op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
2769  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2770  }
2771  }
2772 
2773  // x += y - z
2774  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2775  {
2777  proxy.lhs(), T(1), 1, false, false,
2778  proxy.rhs(), T(1), 1, false, true);
2779  }
2780 
2781  // x += alpha * y - z
2782  template <typename ScalarType>
2783  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2784  const vector_base<T>,
2785  op_sub> const & proxy)
2786  {
2788  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2789  proxy.rhs(), T(1), 1, false, true);
2790  }
2791 
2792  // x += y / alpha - z
2793  template <typename ScalarType>
2794  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2795  const vector_base<T>,
2796  op_sub> const & proxy)
2797  {
2799  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2800  proxy.rhs(), T(1), 1, false, true);
2801  }
2802 
2803  // x += y - beta * z
2804  template <typename ScalarType>
2805  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2806  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2807  op_sub> const & proxy)
2808  {
2810  proxy.lhs(), T(1), 1, false, false,
2811  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2812  }
2813 
2814  // x += y - z / beta
2815  template <typename ScalarType>
2816  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2817  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2818  op_sub> const & proxy)
2819  {
2821  proxy.lhs(), T(1), 1, false, false,
2822  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2823  }
2824 
2825  // x += alpha * y - beta * z
2826  template <typename ScalarType1, typename ScalarType2>
2827  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2828  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2829  op_sub> const & proxy)
2830  {
2832  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2833  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2834  }
2835 
2836  // x += alpha * y - z / beta
2837  template <typename ScalarType1, typename ScalarType2>
2838  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2839  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2840  op_sub> const & proxy)
2841  {
2843  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2844  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2845  }
2846 
2847  // x += y / alpha - beta * z
2848  template <typename ScalarType1, typename ScalarType2>
2849  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2850  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2851  op_sub> const & proxy)
2852  {
2854  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2855  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2856  }
2857 
2858  // x += y / alpha - z / beta
2859  template <typename ScalarType1, typename ScalarType2>
2860  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2861  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2862  op_sub> const & proxy)
2863  {
2865  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2866  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2867  }
2868  };
2869 
2870 
2871 
2872  // generic x -= vec_expr1 - vec_expr2:
2873  template <typename T, typename LHS, typename RHS>
2874  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_sub> >
2875  {
2876  // generic x -= vec_expr1 - vec_expr2:
2877  template <typename LHS1, typename RHS1>
2878  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2879  {
2880  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2881  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2882 
2883  if (op_aliasing_lhs || op_aliasing_rhs)
2884  {
2885  vector_base<T> temp(proxy.lhs());
2886  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2887  lhs -= temp;
2888  }
2889  else
2890  {
2891  op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
2892  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2893  }
2894  }
2895 
2896  // x -= y - z
2897  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2898  {
2900  proxy.lhs(), T(1), 1, false, true,
2901  proxy.rhs(), T(1), 1, false, false);
2902  }
2903 
2904  // x -= alpha * y - z
2905  template <typename ScalarType>
2906  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2907  const vector_base<T>,
2908  op_sub> const & proxy)
2909  {
2911  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2912  proxy.rhs(), T(1), 1, false, false);
2913  }
2914 
2915  // x -= y / alpha - z
2916  template <typename ScalarType>
2917  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2918  const vector_base<T>,
2919  op_sub> const & proxy)
2920  {
2922  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2923  proxy.rhs(), T(1), 1, false, false);
2924  }
2925 
2926  // x -= y - beta * z
2927  template <typename ScalarType>
2928  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2929  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2930  op_sub> const & proxy)
2931  {
2933  proxy.lhs(), T(1), 1, false, true,
2934  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2935  }
2936 
2937  // x -= y - z / beta
2938  template <typename ScalarType>
2939  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2940  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2941  op_sub> const & proxy)
2942  {
2944  proxy.lhs(), T(1), 1, false, true,
2945  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2946  }
2947 
2948  // x -= alpha * y - beta * z
2949  template <typename ScalarType1, typename ScalarType2>
2950  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2951  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2952  op_sub> const & proxy)
2953  {
2955  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2956  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2957  }
2958 
2959  // x -= alpha * y - z / beta
2960  template <typename ScalarType1, typename ScalarType2>
2961  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2962  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2963  op_sub> const & proxy)
2964  {
2966  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2967  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2968  }
2969 
2970  // x -= y / alpha - beta * z
2971  template <typename ScalarType1, typename ScalarType2>
2972  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2973  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2974  op_sub> const & proxy)
2975  {
2977  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2978  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2979  }
2980 
2981  // x -= y / alpha - z / beta
2982  template <typename ScalarType1, typename ScalarType2>
2983  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2984  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2985  op_sub> const & proxy)
2986  {
2988  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2989  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2990  }
2991  };
2992 
2993 
2994 
2995 
2996 
2997 
2998 
2999 
3000 
3001 
3002 
3003 
3004 
3005 
3006 
3007 
3008 
3009 
3011 
3012  // generic x = vec_expr1 .* vec_expr2:
3013  template <typename T, typename LHS, typename RHS, typename OP>
3014  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3015  {
3016  // x = y .* z or x = y ./ z
3017  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3018  {
3019  viennacl::linalg::element_op(lhs, proxy);
3020  }
3021 
3022  // x = y .* vec_expr or x = y ./ vec_expr
3023  template <typename LHS2, typename RHS2, typename OP2>
3024  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)
3025  {
3026  vector<T> temp(proxy.rhs());
3027  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3028  }
3029 
3030  // x = vec_expr .* z or x = vec_expr ./ z
3031  template <typename LHS1, typename RHS1, typename OP1>
3032  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)
3033  {
3034  vector<T> temp(proxy.lhs());
3035  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3036  }
3037 
3038  // x = vec_expr .* vec_expr or z = vec_expr .* vec_expr
3039  template <typename LHS1, typename RHS1, typename OP1,
3040  typename LHS2, typename RHS2, typename OP2>
3041  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3042  const vector_expression<const LHS2, const RHS2, OP2>,
3043  op_element_binary<OP> > const & proxy)
3044  {
3045  vector<T> temp1(proxy.lhs());
3046  vector<T> temp2(proxy.rhs());
3047  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3048  }
3049  };
3050 
3051  // generic x += vec_expr1 .* vec_expr2:
3052  template <typename T, typename LHS, typename RHS, typename OP>
3053  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3054  {
3055  // x += y .* z or x += y ./ z
3056  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3057  {
3058  viennacl::vector<T> temp(proxy);
3059  lhs += temp;
3060  }
3061 
3062  // x += y .* vec_expr or x += y ./ vec_expr
3063  template <typename LHS2, typename RHS2, typename OP2>
3064  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)
3065  {
3066  vector<T> temp(proxy.rhs());
3067  vector<T> temp2(temp.size());
3068  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3069  lhs += temp2;
3070  }
3071 
3072  // x += vec_expr .* z or x += vec_expr ./ z
3073  template <typename LHS1, typename RHS1, typename OP1>
3074  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)
3075  {
3076  vector<T> temp(proxy.lhs());
3077  vector<T> temp2(temp.size());
3078  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3079  lhs += temp2;
3080  }
3081 
3082  // x += vec_expr .* vec_expr or x += vec_expr ./ vec_expr
3083  template <typename LHS1, typename RHS1, typename OP1,
3084  typename LHS2, typename RHS2, typename OP2>
3085  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3086  const vector_expression<const LHS2, const RHS2, OP2>,
3087  op_element_binary<OP> > const & proxy)
3088  {
3089  vector<T> temp1(proxy.lhs());
3090  vector<T> temp2(proxy.rhs());
3091  vector<T> temp3(temp1.size());
3092  viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3093  lhs += temp3;
3094  }
3095  };
3096 
3097  // generic x -= vec_expr1 .* vec_expr2:
3098  template <typename T, typename LHS, typename RHS, typename OP>
3099  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3100  {
3101 
3102  // x -= y .* z or x -= y ./ z
3103  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3104  {
3105  viennacl::vector<T> temp(proxy);
3106  lhs -= temp;
3107  }
3108 
3109  // x -= y .* vec_expr or x -= y ./ vec_expr
3110  template <typename LHS2, typename RHS2, typename OP2>
3111  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)
3112  {
3113  vector<T> temp(proxy.rhs());
3114  vector<T> temp2(temp.size());
3115  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3116  lhs -= temp2;
3117  }
3118 
3119  // x -= vec_expr .* z or x -= vec_expr ./ z
3120  template <typename LHS1, typename RHS1, typename OP1>
3121  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)
3122  {
3123  vector<T> temp(proxy.lhs());
3124  vector<T> temp2(temp.size());
3125  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3126  lhs -= temp2;
3127  }
3128 
3129  // x -= vec_expr .* vec_expr or x -= vec_expr ./ vec_expr
3130  template <typename LHS1, typename RHS1, typename OP1,
3131  typename LHS2, typename RHS2, typename OP2>
3132  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3133  const vector_expression<const LHS2, const RHS2, OP2>,
3134  op_element_binary<OP> > const & proxy)
3135  {
3136  vector<T> temp1(proxy.lhs());
3137  vector<T> temp2(proxy.rhs());
3138  vector<T> temp3(temp1.size());
3139  viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3140  lhs -= temp3;
3141  }
3142  };
3143 
3145 
3146  template <typename T, typename LHS, typename RHS, typename OP>
3147  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3148  {
3149  // x = OP(y)
3150  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3151  {
3152  viennacl::linalg::element_op(lhs, proxy);
3153  }
3154 
3155  // x = OP(vec_expr)
3156  template <typename LHS2, typename RHS2, typename OP2>
3157  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3158  const vector_expression<const LHS2, const RHS2, OP2>,
3159  op_element_unary<OP> > const & proxy)
3160  {
3161  vector<T> temp(proxy.rhs());
3162  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp));
3163  }
3164  };
3165 
3166  template <typename T, typename LHS, typename RHS, typename OP>
3167  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3168  {
3169  // x += OP(y)
3170  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3171  {
3172  vector<T> temp(proxy);
3173  lhs += temp;
3174  }
3175 
3176  // x += OP(vec_expr)
3177  template <typename LHS2, typename RHS2, typename OP2>
3178  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3179  const vector_expression<const LHS2, const RHS2, OP2>,
3180  op_element_unary<OP> > const & proxy)
3181  {
3182  vector<T> temp(proxy.rhs());
3183  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
3184  lhs += temp;
3185  }
3186  };
3187 
3188  template <typename T, typename LHS, typename RHS, typename OP>
3189  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3190  {
3191  // x -= OP(y)
3192  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3193  {
3194  vector<T> temp(proxy);
3195  lhs -= temp;
3196  }
3197 
3198  // x -= OP(vec_expr)
3199  template <typename LHS2, typename RHS2, typename OP2>
3200  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3201  const vector_expression<const LHS2, const RHS2, OP2>,
3202  op_element_unary<OP> > const & proxy)
3203  {
3204  vector<T> temp(proxy.rhs());
3205  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
3206  lhs -= temp;
3207  }
3208  };
3209 
3210  } // namespace detail
3211 
3212  } // namespace linalg
3213 
3216 } // namespace viennacl
3217 
3218 #endif
Simple enable-if variant that uses the SFINAE pattern.
Definition: enable_if.hpp:29
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:1419
base_type::value_type operator*(void)
Definition: vector.hpp:336
A tag class representing multiplication by a scalar.
Definition: forwards.h:74
base_type::difference_type difference_type
Definition: vector.hpp:985
vcl_size_t stride() const
Index increment in the underlying buffer when incrementing the iterator to the next element...
Definition: vector.hpp:279
VectorType & at(vcl_size_t i) const
Definition: vector.hpp:1173
void set_handle(viennacl::backend::mem_handle const &h)
Definition: vector.hpp:875
std::size_t vcl_size_t
Definition: forwards.h:58
Definition: forwards.h:498
vector_base(viennacl::backend::mem_handle &h, size_type vec_size, size_type vec_start, difference_type vec_stride)
An explicit constructor for wrapping an existing vector into a vector_range or vector_slice.
Definition: vector.hpp:391
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::context context() const
Definition: vector.hpp:58
size_type size() const
Returns the size of the result vector.
Definition: vector.hpp:187
vcl_size_t size() const
Definition: vector.hpp:1170
DistanceType difference_type
Definition: vector.hpp:372
size_type size() const
Definition: vector.hpp:60
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:72
base_type::size_type size_type
Definition: vector.hpp:984
Worker class for decomposing expression templates.
Definition: op_executor.hpp:79
vector(zero_vector< SCALARTYPE > const &v)
Creates the vector from the supplied zero vector.
Definition: vector.hpp:1044
entry_proxy< SCALARTYPE > operator[](size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:699
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: entry_proxy.hpp:178
self_type & operator=(const vector_expression< const matrix_expression< const matrix_base< SCALARTYPE, F >, const matrix_base< SCALARTYPE, F >, op_trans >, const vector_base< SCALARTYPE >, op_prod > &proxy)
Operator overload for v1 = trans(A) * v2, where v1, v2 are vectors and A is a dense matrix...
Definition: vector.hpp:663
scalar< SCALARTYPE > value_type
Definition: vector.hpp:368
self_type & operator=(const vector_expression< const LHS, const RHS, OP > &proxy)
Implementation of the operation v1 = v2 @ alpha, where @ denotes either multiplication or division...
Definition: vector.hpp:511
viennacl::backend::mem_handle handle_type
Definition: vector.hpp:370
viennacl::memory_types memory_domain() const
Definition: vector.hpp:868
bool is_value_static() const
Definition: vector.hpp:64
Defines the worker class for decomposing an expression tree into small chunks, which can be processed...
Implementations of vector operations.
Definition: vector.hpp:171
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:351
Helper struct for checking whether a type represents a sign flip on a viennacl::scalar<> ...
Definition: forwards.h:377
iterator end()
Returns an iterator pointing to the end of the vector (STL like)
Definition: vector.hpp:809
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
Definition: forwards.h:172
Various little tools used here and there in ViennaCL.
SCALARTYPE const & const_reference
Definition: vector.hpp:55
A STL-type const-iterator for vector elements. Elements can be accessed, but cannot be manipulated...
Definition: forwards.h:187
vcl_size_t size1(MatrixType const &mat)
Generic routine for obtaining the number of rows of a matrix (ViennaCL, uBLAS, etc.)
Definition: size.hpp:216
Common base class for representing vectors where the entries are not all stored explicitly.
Definition: forwards.h:190
lhs_reference_type lhs() const
Get left hand side operand.
Definition: vector.hpp:181
scalar_vector(size_type s, SCALARTYPE val, viennacl::context ctx=viennacl::context())
Definition: vector.hpp:136
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:51
A tag class representing subtraction.
Definition: forwards.h:72
self_type operator++(void)
Definition: vector.hpp:254
vector_base(size_type vec_size, viennacl::context ctx=viennacl::context())
Creates a vector and allocates the necessary memory.
Definition: vector.hpp:396
A proxy class for entries in a vector.
base_type::difference_type difference_type
Definition: vector.hpp:317
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:115
vector(size_type vec_size)
An explicit constructor for the vector, allocating the given amount of memory (plus a padding specifi...
Definition: vector.hpp:995
vector_base()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:380
self_type & operator=(T const &other)
Definition: vector.hpp:1059
vector_iterator(vector_base< SCALARTYPE > &vec, vcl_size_t index, vcl_size_t start=0, vcl_ptrdiff_t stride=1)
Constructor.
Definition: vector.hpp:330
vcl_size_t index_
Definition: vector.hpp:285
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:1086
This file provides the forward declarations for the main types used within ViennaCL.
std::pair< SCALARTYPE, bool > value_
Definition: vector.hpp:86
vector_iterator< SCALARTYPE, 1 > iterator
Definition: vector.hpp:374
handle_type const & elements_
The index of the entry the iterator is currently pointing to.
Definition: vector.hpp:284
SCALARTYPE const_reference
Definition: vector.hpp:111
A tag class representing division.
Definition: forwards.h:80
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
static const size_type alignment
Definition: vector.hpp:376
vcl_size_t size_type
Definition: vector.hpp:50
entry_proxy< SCALARTYPE > operator()(size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:689
vcl_ptrdiff_t stride_
Definition: vector.hpp:287
const_vector_iterator(vector_base< SCALARTYPE > const &vec, vcl_size_t index, vcl_size_t start=0, vcl_ptrdiff_t stride=1)
Constructor.
Definition: vector.hpp:231
bool operator==(self_type const &other) const
Definition: vector.hpp:257
Tuple class holding pointers to multiple vectors. Mainly used as a temporary object returned from vie...
Definition: forwards.h:211
vector_tuple(std::vector< VectorType * > const &vecs)
Definition: vector.hpp:1161
viennacl::enable_if< viennacl::is_scalar< S1 >::value, matrix_base< NumericT, F > & >::type operator/=(matrix_base< NumericT, F > &m1, S1 const &gpu_val)
Scales a matrix by a GPU scalar value.
Definition: matrix.hpp:1445
self_type operator+(difference_type diff) const
Definition: vector.hpp:344
Definition: forwards.h:481
vcl_size_t index() const
Definition: vector.hpp:66
memory_types
Definition: forwards.h:476
base_type::size_type size_type
Definition: vector.hpp:96
viennacl::backend::mem_handle handle_type
Definition: vector.hpp:221
viennacl::context ctx_
Definition: vector.hpp:87
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2)
Definition: vector.hpp:1127
void swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
Definition: vector.hpp:1669
Implementation of a OpenCL-like context, which serves as a unification of {OpenMP, CUDA, OpenCL} at the user API.
difference_type operator-(self_type const &other) const
Definition: vector.hpp:343
void resize(size_type new_size, bool preserve=true)
Resizes the allocated memory for the vector. Pads the memory to be a multiple of 'ALIGNMENT'.
Definition: vector.hpp:1074
self_type & operator*=(SCALARTYPE val)
Scales a vector (or proxy) by a CPU scalar value.
Definition: vector.hpp:755
Represents a generic 'context' similar to an OpenCL context, but is backend-agnostic and thus also su...
Definition: context.hpp:39
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:91
void copy(vector< SCALARTYPE, ALIGNMENT_SRC > const &gpu_src_vec, vector< SCALARTYPE, ALIGNMENT_DEST > &gpu_dest_vec)
Transfer from a ViennaCL vector to another ViennaCL vector. Convenience wrapper for viennacl::linalg:...
Definition: vector.hpp:1621
self_type operator+(difference_type diff) const
Definition: vector.hpp:272
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:29
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.hpp:841
vector(const self_type &v)
Definition: vector.hpp:1030
const_iterator end() const
Returns a const-iterator pointing to the end of the vector (STL like)
Definition: vector.hpp:821
SCALARTYPE const & const_reference
Definition: vector.hpp:134
SCALARTYPE const_reference
Definition: vector.hpp:122
viennacl::enable_if< viennacl::is_any_scalar< S1 >::value, matrix_expression< const matrix_base< NumericT, F >, const S1, op_mult > >::type operator*(S1 const &value, matrix_base< NumericT, F > const &m1)
Operator overload for the expression alpha * m1, where alpha is a host scalar (float or double) and m...
Definition: matrix.hpp:1345
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:1092
vector(scalar_vector< SCALARTYPE > const &v)
Creates the vector from the supplied scalar vector.
Definition: vector.hpp:1051
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:144
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: forwards.h:178
vector_expression< const self_type, const SCALARTYPE, op_mult > operator-() const
Sign flip for the vector. Emulated to be equivalent to -1.0 * vector.
Definition: vector.hpp:793
unit_vector(size_type s, size_type ind, viennacl::context ctx=viennacl::context())
Definition: vector.hpp:97
vector()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:989
vector(unit_vector< SCALARTYPE > const &v)
Creates the vector from the supplied unit vector.
Definition: vector.hpp:1037
self_type & operator=(const viennacl::vector_expression< const matrix_base< SCALARTYPE, F >, const vector_base< SCALARTYPE >, viennacl::op_prod > &proxy)
Operator overload for v1 = A * v2, where v1, v2 are vectors and A is a dense matrix.
Definition: vector.hpp:638
Definition: forwards.h:480
vector(SCALARTYPE *ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start=0, difference_type stride=1)
Definition: vector.hpp:999
const_vector_iterator(handle_type const &elements, vcl_size_t index, vcl_size_t start=0, vcl_ptrdiff_t stride=1)
Constructor for vector-like treatment of arbitrary buffers.
Definition: vector.hpp:242
const_entry_proxy< SCALARTYPE > operator[](size_type index) const
Read access to a single element of the vector.
Definition: vector.hpp:720
base_type::size_type size_type
Definition: vector.hpp:110
vector< SCALARTYPE, ALIGNMENT > & fast_swap(vector< SCALARTYPE, ALIGNMENT > &v1, vector< SCALARTYPE, ALIGNMENT > &v2)
Swaps the content of two vectors by swapping OpenCL handles only, NO data is copied.
Definition: vector.hpp:1680
void resize(size_type new_size, bool preserve=true)
Resizes the allocated memory for the vector. Pads the memory to be a multiple of 'ALIGNMENT'.
Definition: vector.hpp:914
std::pair< bool, vcl_size_t > index_
Definition: vector.hpp:85
size_type size_
Definition: vector.hpp:84
SizeType size_type
Definition: vector.hpp:371
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:43
bool empty() const
Returns true is the size is zero.
Definition: vector.hpp:853
base_type::handle_type handle_type
Definition: vector.hpp:316
void vector_swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
Definition: vector_operations.hpp:189
vector(const base_type &v)
Definition: vector.hpp:1024
handle_type & handle()
Returns the memory handle.
Definition: vector.hpp:859
A tag class representing addition.
Definition: forwards.h:70
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:882
base_type::size_type size_type
Definition: vector.hpp:133
An expression template class that represents a binary operation that yields a vector.
Definition: forwards.h:181
Represents a vector consisting of zeros only.
Definition: forwards.h:193
void copy(std::vector< SCALARTYPE > &cpu_vec, circulant_matrix< SCALARTYPE, ALIGNMENT > &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
iterator begin()
Returns an iterator pointing to the beginning of the vector (STL like)
Definition: vector.hpp:803
VectorType const & const_at(vcl_size_t i) const
Definition: vector.hpp:1174
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:899
A STL-type iterator for vector elements. Elements can be accessed and manipulated. VERY SLOW!!
Definition: forwards.h:184
Represents a vector consisting of scalars 's' only, i.e. v[i] = s for all i. To be used as an initial...
Definition: forwards.h:202
Represents a vector consisting of 1 at a given index and zeros otherwise.
Definition: forwards.h:196
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector.hpp:837
cpu_value_type value() const
Definition: vector.hpp:62
vcl_size_t size_type
Extracts the vector type from the two operands.
Definition: vector.hpp:175
vector_tuple(std::vector< VectorType const * > const &vecs)
Definition: vector.hpp:1155
void element_op(matrix_base< T, F > &A, matrix_expression< const matrix_base< T, F >, const matrix_base< T, F >, 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:598
SCALARTYPE cpu_value_type
Definition: vector.hpp:56
vector_tuple< ScalarT > tie(vector_base< ScalarT > const &v0, vector_base< ScalarT > const &v1)
Definition: vector.hpp:1183
Expression template class for representing a tree of expressions which ultimately result in a matrix...
Definition: forwards.h:283
implicit_vector_base(size_type s, std::pair< SCALARTYPE, bool > v, viennacl::context ctx)
Definition: vector.hpp:52
one_vector(size_type s, viennacl::context ctx=viennacl::context())
Definition: vector.hpp:123
base_type::size_type size_type
Definition: vector.hpp:121
void resize(size_type new_size, viennacl::context ctx, bool preserve=true)
Resizes the allocated memory for the vector. Convenience function for setting an OpenCL context in ca...
Definition: vector.hpp:925
viennacl::vector< NumericT > operator-(const vector_base< NumericT > &v1, const vector_expression< const matrix_base< NumericT, F >, const vector_base< NumericT >, op_prod > &proxy)
Implementation of the operation 'result = v1 - A * v2', where A is a matrix.
Definition: matrix_operations.hpp:858
vcl_size_t offset() const
Offset of the current element index with respect to the beginning of the buffer.
Definition: vector.hpp:276
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:78
size_type start() const
Returns the offset within the buffer.
Definition: vector.hpp:845
zero_vector(size_type s, viennacl::context ctx=viennacl::context())
Definition: vector.hpp:112
implicit_vector_base(size_type s, vcl_size_t i, std::pair< SCALARTYPE, bool > v, viennacl::context ctx)
Definition: vector.hpp:51
vector(vector_expression< const LHS, const RHS, OP > const &proxy)
Definition: vector.hpp:1022
A vector class representing a linear memory sequence on the GPU. Inspired by boost::numeric::ublas::v...
Definition: forwards.h:208
vector_base(vector_expression< const LHS, const RHS, OP > const &proxy)
Creates the vector from the supplied random vector.
Definition: vector.hpp:463
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
A tag class representing matrix-vector products and element-wise multiplications. ...
Definition: forwards.h:76
vcl_size_t raw_size() const
Returns the number of bytes of the currently active buffer.
Definition: mem_handle.hpp:203
viennacl::context context(T const &t)
Returns an ID for the currently active memory domain of an object.
Definition: context.hpp:41
SCALARTYPE cpu_value_type
Definition: vector.hpp:369
self_type & operator+=(const self_type &vec)
Definition: vector.hpp:731
vector_base(SCALARTYPE *ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, vcl_size_t start=0, difference_type stride=1)
Definition: vector.hpp:407
vector(size_type vec_size, viennacl::context ctx)
Definition: vector.hpp:997
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2, VectorType &v3)
Definition: vector.hpp:1143
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:127
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Definition: result_of.hpp:276
viennacl::enable_if< viennacl::is_scalar< S1 >::value, matrix_base< NumericT, F > & >::type operator*=(matrix_base< NumericT, F > &m1, S1 const &gpu_val)
Scales a matrix by a GPU scalar value.
Definition: matrix.hpp:1399
void inc()
Definition: shared_ptr.hpp:140
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2, VectorType const &v3)
Definition: vector.hpp:1136
handle_type const & handle() const
Definition: vector.hpp:280
Definition: forwards.h:479
void swap(mem_handle &other)
Implements a fast swapping method. No data is copied, only the handles are exchanged.
Definition: mem_handle.hpp:179
vcl_size_t start_
Definition: vector.hpp:286
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:49
const_iterator begin() const
Returns a const-iterator pointing to the beginning of the vector (STL like)
Definition: vector.hpp:815
const handle_type & handle() const
Returns the memory handle.
Definition: vector.hpp:856
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:248
std::ptrdiff_t vcl_ptrdiff_t
Definition: forwards.h:59
vector_iterator()
Definition: vector.hpp:319
vector_expression< const self_type, const SCALARTYPE, op_div > operator/(SCALARTYPE value) const
Scales the vector by a CPU scalar 'alpha' and returns an expression template.
Definition: vector.hpp:786
cpu_value_type operator()(size_type i) const
Definition: vector.hpp:70
rhs_reference_type rhs() const
Get right hand side operand.
Definition: vector.hpp:184
void pad()
Pads vectors with alignment > 1 with trailing zeros if the internal size is larger than the visible s...
Definition: vector.hpp:890
self_type operator++(int)
Definition: vector.hpp:255
const_vector_iterator< SCALARTYPE, 1 > const_iterator
Definition: vector.hpp:373
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2)
Definition: vector.hpp:1121
vcl_size_t const_size() const
Definition: vector.hpp:1171
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
Definition: mem_handle.hpp:62
A tag class representing transposed matrices.
Definition: forwards.h:165
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:482
void prod_impl(const matrix_base< NumericT, F > &mat, const vector_base< NumericT > &vec, vector_base< NumericT > &result)
Carries out matrix-vector multiplication.
Definition: matrix_operations.hpp:350
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
difference_type operator-(self_type const &other) const
Definition: vector.hpp:267
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:158
void reset()
Definition: shared_ptr.hpp:108
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:94
vector_expression< const self_type, const SCALARTYPE, op_mult > operator*(SCALARTYPE value) const
Scales the vector by a CPU scalar 'alpha' and returns an expression template.
Definition: vector.hpp:777
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
vector_tuple(VectorType &v0, VectorType &v1)
Definition: vector.hpp:1113
viennacl::backend::mem_handle & handle(T &obj)
Returns the generic memory handle of an object. Non-const version.
Definition: handle.hpp:41
vcl_ptrdiff_t difference_type
Definition: vector.hpp:220
handle_type & handle()
Definition: vector.hpp:346
bool operator!=(self_type const &other) const
Definition: vector.hpp:258
vector_expression(LHS &l, RHS &r)
Definition: vector.hpp:177
scalar< SCALARTYPE > value_type
Definition: vector.hpp:219
const_entry_proxy< SCALARTYPE > operator()(size_type index) const
Read access to a single element of the vector.
Definition: vector.hpp:710
bool op_aliasing(vector_base< T > const &, B const &)
Definition: op_executor.hpp:35
Implementation of the ViennaCL scalar class.
self_type & swap(self_type &other)
Swaps the entries of the two vectors.
Definition: vector.hpp:828
void fast_copy(const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_begin, const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_end, CPU_ITERATOR cpu_begin)
STL-like transfer of a GPU vector to the CPU. The cpu type is assumed to reside in a linear piece of ...
Definition: vector.hpp:1262
void async_copy(const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_begin, const const_vector_iterator< SCALARTYPE, ALIGNMENT > &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:1312
viennacl::vector< NumericT > operator+(const vector_base< NumericT > &v1, const vector_expression< const matrix_base< NumericT, F >, const vector_base< NumericT >, op_prod > &proxy)
Implementation of the operation 'result = v1 + A * v2', where A is a matrix.
Definition: matrix_operations.hpp:840
A collection of compile time type deductions.
void clear()
Resets all entries to zero. Does not change the size of the vector.
Definition: vector.hpp:863
self_type & operator-=(const self_type &vec)
Definition: vector.hpp:742
cpu_value_type operator[](size_type i) const
Definition: vector.hpp:76
vector_tuple(VectorType const &v0, VectorType const &v1)
Definition: vector.hpp:1108
vector_iterator(handle_type &elements, vcl_size_t index, vcl_size_t start=0, vcl_ptrdiff_t stride=1)
Definition: vector.hpp:320
Main interface routines for memory management.
size_type stride() const
Returns the stride within the buffer (in multiples of sizeof(SCALARTYPE))
Definition: vector.hpp:849
self_type & operator/=(SCALARTYPE val)
Scales this vector by a CPU scalar value.
Definition: vector.hpp:765
bool has_index() const
Definition: vector.hpp:68
handle_type const & handle() const
Definition: vector.hpp:347
void resize(size_type new_size, viennacl::context ctx, bool preserve=true)
Definition: vector.hpp:1079