ViennaCL - The Vienna Computing Library  1.5.1
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 
71  if(index_.first)
72  return (i==index_.second)?value_.first:0;
73  return value_.first;
74  }
75 
77  if(index_.first)
78  return (i==index_.second)?value_.first:0;
79  return
80  value_.first;
81  }
82 
83  protected:
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 
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:
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) {}
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 
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 
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 
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 
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 
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  //
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 
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 
753  template <typename LHS, typename RHS, typename OP>
755  {
756  assert( (viennacl::traits::size(proxy) == size()) && bool("Incompatible vector sizes!"));
757  assert( (size() > 0) && bool("Vector not yet initialized!") );
758 
760 
761  return *this;
762  }
763 
764  template <typename LHS, typename RHS, typename OP>
766  {
767  assert( (viennacl::traits::size(proxy) == size()) && bool("Incompatible vector sizes!"));
768  assert( (size() > 0) && bool("Vector not yet initialized!") );
769 
771 
772  return *this;
773  }
774 
777  self_type & operator *= (SCALARTYPE val)
778  {
779  if (size() > 0)
780  viennacl::linalg::av(*this,
781  *this, val, 1, false, false);
782  return *this;
783  }
784 
787  self_type & operator /= (SCALARTYPE val)
788  {
789  if (size() > 0)
790  viennacl::linalg::av(*this,
791  *this, val, 1, true, false);
792  return *this;
793  }
794 
795 
799  operator * (SCALARTYPE value) const
800  {
802  }
803 
804 
808  operator / (SCALARTYPE value) const
809  {
811  }
812 
813 
816  {
818  }
819 
820  //
822  //
823 
826  {
827  return iterator(*this, 0, start_, stride_);
828  }
829 
832  {
833  return iterator(*this, size(), start_, stride_);
834  }
835 
838  {
839  return const_iterator(*this, 0, start_, stride_);
840  }
841 
844  {
845  return const_iterator(*this, size(), start_, stride_);
846  }
847 
851  {
852  viennacl::linalg::vector_swap(*this, other);
853  return *this;
854  };
855 
856 
859  size_type size() const { return size_; }
860 
863  size_type internal_size() const { return internal_size_; }
864 
867  size_type start() const { return start_; }
868 
871  size_type stride() const { return stride_; }
872 
873 
875  bool empty() const { return size_ == 0; }
876 
878  const handle_type & handle() const { return elements_; }
879 
881  handle_type & handle() { return elements_; }
882 
885  void clear()
886  {
888  }
889 
891  {
892  return elements_.get_active_handle_id();
893  }
894 
895  protected:
896 
898  {
899  elements_ = h;
900  }
901 
905  {
906  assert(this->size_ == other.size_ && bool("Vector size mismatch"));
907  this->elements_.swap(other.elements_);
908  return *this;
909  }
910 
912  void pad()
913  {
914  if (internal_size() != size())
915  {
916  std::vector<SCALARTYPE> pad(internal_size() - size());
917  viennacl::backend::memory_write(elements_, sizeof(SCALARTYPE) * size(), sizeof(SCALARTYPE) * pad.size(), &(pad[0]));
918  }
919  }
920 
922  {
923  viennacl::backend::switch_memory_context<SCALARTYPE>(elements_, new_ctx);
924  }
925 
926  //TODO: Think about implementing the following public member functions
927  //void insert_element(unsigned int i, SCALARTYPE val){}
928  //void erase_element(unsigned int i){}
929 
930  //enlarge or reduce allocated memory and set unused memory to zero
936  void resize(size_type new_size, bool preserve = true)
937  {
938  resize_impl(new_size, viennacl::traits::context(*this), preserve);
939  }
940 
947  void resize(size_type new_size, viennacl::context ctx, bool preserve = true)
948  {
949  resize_impl(new_size, ctx, preserve);
950  }
951 
952  private:
953 
954  void resize_impl(size_type new_size, viennacl::context ctx, bool preserve = true)
955  {
956  assert(new_size > 0 && bool("Positive size required when resizing vector!"));
957 
958  if (new_size != size_)
959  {
960  vcl_size_t new_internal_size = viennacl::tools::align_to_multiple<vcl_size_t>(new_size, alignment);
961 
962  std::vector<SCALARTYPE> temp(size_);
963  if (preserve && size_ > 0)
964  fast_copy(*this, temp);
965  temp.resize(new_size); //drop all entries above new_size
966  temp.resize(new_internal_size); //enlarge to fit new internal size
967 
968  if (new_internal_size != internal_size())
969  {
970  viennacl::backend::memory_create(elements_, sizeof(SCALARTYPE)*new_internal_size, ctx, NULL);
971  }
972 
973  fast_copy(temp, *this);
974  size_ = new_size;
975  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, alignment);
976  pad();
977  }
978 
979  }
980 
981  size_type size_;
982  size_type start_;
983  difference_type stride_;
984  size_type internal_size_;
985  handle_type elements_;
986  }; //vector_base
987 
988 
989 
990  // forward definition in forwards.h!
999  template<class SCALARTYPE, unsigned int ALIGNMENT>
1000  class vector : public vector_base<SCALARTYPE>
1001  {
1002  typedef vector<SCALARTYPE, ALIGNMENT> self_type;
1003  typedef vector_base<SCALARTYPE> base_type;
1004 
1005  public:
1008 
1011  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 */ }
1012 
1017  explicit vector(size_type vec_size) : base_type(vec_size) {}
1018 
1019  explicit vector(size_type vec_size, viennacl::context ctx) : base_type(vec_size, ctx) {}
1020 
1021  explicit vector(SCALARTYPE * ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start = 0, difference_type stride = 1)
1022  : base_type(ptr_to_mem, mem_type, vec_size, start, stride) {}
1023 
1024 #ifdef VIENNACL_WITH_OPENCL
1025 
1033  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) {}
1034 
1040  explicit vector(size_type vec_size, viennacl::ocl::context const & ctx) : base_type(vec_size, ctx) {}
1041 #endif
1042 
1043  template <typename LHS, typename RHS, typename OP>
1045 
1046  vector(const base_type & v) : base_type(v.size(), viennacl::traits::context(v))
1047  {
1048  if (v.size() > 0)
1049  base_type::operator=(v);
1050  }
1051 
1052  vector(const self_type & v) : base_type(v.size(), viennacl::traits::context(v))
1053  {
1054  if (v.size() > 0)
1055  base_type::operator=(v);
1056  }
1057 
1060  {
1061  if (v.size() > 0)
1062  this->operator()(v.index()) = SCALARTYPE(1);;
1063  }
1064 
1067  {
1068  if (v.size() > 0)
1069  viennacl::linalg::vector_assign(*this, SCALARTYPE(0.0));
1070  }
1071 
1074  {
1075  if (v.size() > 0)
1076  viennacl::linalg::vector_assign(*this, v[0]);
1077  }
1078 
1079  // the following is used to circumvent an issue with Clang 3.0 when 'using base_type::operator=;' directly
1080  template <typename T>
1081  self_type & operator=(T const & other)
1082  {
1083  base_type::operator=(other);
1084  return *this;
1085  }
1086 
1087  using base_type::operator+=;
1088  using base_type::operator-=;
1089 
1090  //enlarge or reduce allocated memory and set unused memory to zero
1096  void resize(size_type new_size, bool preserve = true)
1097  {
1098  base_type::resize(new_size, preserve);
1099  }
1100 
1101  void resize(size_type new_size, viennacl::context ctx, bool preserve = true)
1102  {
1103  base_type::resize(new_size, ctx, preserve);
1104  }
1105 
1109  {
1110  base_type::fast_swap(other);
1111  return *this;
1112  }
1113 
1115  {
1117  }
1118 
1119  }; //vector
1120 
1122  template <typename ScalarT>
1123  class vector_tuple
1124  {
1125  typedef vector_base<ScalarT> VectorType;
1126 
1127  public:
1128  // 2 vectors
1129 
1130  vector_tuple(VectorType const & v0, VectorType const & v1) : const_vectors_(2), non_const_vectors_()
1131  {
1132  const_vectors_[0] = &v0;
1133  const_vectors_[1] = &v1;
1134  }
1135  vector_tuple(VectorType & v0, VectorType & v1) : const_vectors_(2), non_const_vectors_(2)
1136  {
1137  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1138  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1139  }
1140 
1141  // 3 vectors
1142 
1143  vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2) : const_vectors_(3), non_const_vectors_()
1144  {
1145  const_vectors_[0] = &v0;
1146  const_vectors_[1] = &v1;
1147  const_vectors_[2] = &v2;
1148  }
1149  vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2) : const_vectors_(3), non_const_vectors_(3)
1150  {
1151  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1152  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1153  const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
1154  }
1155 
1156  // 4 vectors
1157 
1158  vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2, VectorType const & v3) : const_vectors_(4), non_const_vectors_()
1159  {
1160  const_vectors_[0] = &v0;
1161  const_vectors_[1] = &v1;
1162  const_vectors_[2] = &v2;
1163  const_vectors_[3] = &v3;
1164  }
1165  vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2, VectorType & v3) : const_vectors_(4), non_const_vectors_(4)
1166  {
1167  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1168  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1169  const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
1170  const_vectors_[3] = &v3; non_const_vectors_[3] = &v3;
1171  }
1172 
1173  // add more overloads here
1174 
1175  // generic interface:
1176 
1177  vector_tuple(std::vector<VectorType const *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_()
1178  {
1179  for (vcl_size_t i=0; i<vecs.size(); ++i)
1180  const_vectors_[i] = vecs[i];
1181  }
1182 
1183  vector_tuple(std::vector<VectorType *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_(vecs.size())
1184  {
1185  for (vcl_size_t i=0; i<vecs.size(); ++i)
1186  {
1187  const_vectors_[i] = vecs[i];
1188  non_const_vectors_[i] = vecs[i];
1189  }
1190  }
1191 
1192  vcl_size_t size() const { return non_const_vectors_.size(); }
1193  vcl_size_t const_size() const { return const_vectors_.size(); }
1194 
1195  VectorType & at(vcl_size_t i) const { return *(non_const_vectors_.at(i)); }
1196  VectorType const & const_at(vcl_size_t i) const { return *(const_vectors_.at(i)); }
1197 
1198  private:
1199  std::vector<VectorType const *> const_vectors_;
1200  std::vector<VectorType *> non_const_vectors_;
1201  };
1202 
1203  // 2 args
1204  template <typename ScalarT>
1206 
1207  template <typename ScalarT>
1209 
1210  // 3 args
1211  template <typename ScalarT>
1213 
1214  template <typename ScalarT>
1216 
1217  // 4 args
1218  template <typename ScalarT>
1220  {
1221  return vector_tuple<ScalarT>(v0, v1, v2, v3);
1222  }
1223 
1224  template <typename ScalarT>
1226  {
1227  return vector_tuple<ScalarT>(v0, v1, v2, v3);
1228  }
1229 
1230  // 5 args
1231  template <typename ScalarT>
1233  vector_base<ScalarT> const & v1,
1234  vector_base<ScalarT> const & v2,
1235  vector_base<ScalarT> const & v3,
1236  vector_base<ScalarT> const & v4)
1237  {
1238  typedef vector_base<ScalarT> const * VectorPointerType;
1239  std::vector<VectorPointerType> vec(5);
1240  vec[0] = &v0;
1241  vec[1] = &v1;
1242  vec[2] = &v2;
1243  vec[3] = &v3;
1244  vec[4] = &v4;
1245  return vector_tuple<ScalarT>(vec);
1246  }
1247 
1248  template <typename ScalarT>
1250  vector_base<ScalarT> & v1,
1251  vector_base<ScalarT> & v2,
1252  vector_base<ScalarT> & v3,
1253  vector_base<ScalarT> & v4)
1254  {
1255  typedef vector_base<ScalarT> * VectorPointerType;
1256  std::vector<VectorPointerType> vec(5);
1257  vec[0] = &v0;
1258  vec[1] = &v1;
1259  vec[2] = &v2;
1260  vec[3] = &v3;
1261  vec[4] = &v4;
1262  return vector_tuple<ScalarT>(vec);
1263  }
1264 
1265  // TODO: Add more arguments to tie() here. Maybe use some preprocessor magic to accomplish this.
1266 
1267  //
1269  //
1270 
1271 
1283  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1286  CPU_ITERATOR cpu_begin )
1287  {
1288  if (gpu_begin != gpu_end)
1289  {
1290  if (gpu_begin.stride() == 1)
1291  {
1292  viennacl::backend::memory_read(gpu_begin.handle(),
1293  sizeof(SCALARTYPE)*gpu_begin.offset(),
1294  sizeof(SCALARTYPE)*gpu_begin.stride() * (gpu_end - gpu_begin),
1295  &(*cpu_begin));
1296  }
1297  else
1298  {
1299  vcl_size_t gpu_size = (gpu_end - gpu_begin);
1300  std::vector<SCALARTYPE> temp_buffer(gpu_begin.stride() * gpu_size);
1301  viennacl::backend::memory_read(gpu_begin.handle(), sizeof(SCALARTYPE)*gpu_begin.offset(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
1302 
1303  for (vcl_size_t i=0; i<gpu_size; ++i)
1304  {
1305  (&(*cpu_begin))[i] = temp_buffer[i * gpu_begin.stride()];
1306  }
1307  }
1308  }
1309  }
1310 
1316  template <typename NumericT, typename CPUVECTOR>
1317  void fast_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1318  {
1319  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1320  }
1321 
1322 
1333  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1336  CPU_ITERATOR cpu_begin )
1337  {
1338  if (gpu_begin != gpu_end)
1339  {
1340  if (gpu_begin.stride() == 1)
1341  {
1342  viennacl::backend::memory_read(gpu_begin.handle(),
1343  sizeof(SCALARTYPE)*gpu_begin.offset(),
1344  sizeof(SCALARTYPE)*gpu_begin.stride() * (gpu_end - gpu_begin),
1345  &(*cpu_begin),
1346  true);
1347  }
1348  else // no async copy possible, so fall-back to fast_copy
1349  fast_copy(gpu_begin, gpu_end, cpu_begin);
1350  }
1351  }
1352 
1358  template <typename NumericT, typename CPUVECTOR>
1359  void async_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1360  {
1361  viennacl::async_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1362  }
1363 
1364 
1371  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1374  CPU_ITERATOR cpu_begin )
1375  {
1376  assert(gpu_end - gpu_begin >= 0 && bool("Iterators incompatible"));
1377  if (gpu_end - gpu_begin != 0)
1378  {
1379  std::vector<SCALARTYPE> temp_buffer(gpu_end - gpu_begin);
1380  fast_copy(gpu_begin, gpu_end, temp_buffer.begin());
1381 
1382  //now copy entries to cpu_vec:
1383  std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_begin);
1384  }
1385  }
1386 
1393  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1396  CPU_ITERATOR cpu_begin )
1397 
1398  {
1401  cpu_begin);
1402  }
1403 
1409  template <typename NumericT, typename CPUVECTOR>
1410  void copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1411  {
1412  viennacl::copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1413  }
1414 
1415 
1416 
1417  #ifdef VIENNACL_WITH_EIGEN
1418  template <unsigned int ALIGNMENT>
1419  void copy(vector<float, ALIGNMENT> const & gpu_vec,
1420  Eigen::VectorXf & eigen_vec)
1421  {
1422  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
1423  }
1424 
1425  template <unsigned int ALIGNMENT>
1426  void copy(vector<double, ALIGNMENT> & gpu_vec,
1427  Eigen::VectorXd & eigen_vec)
1428  {
1429  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
1430  }
1431  #endif
1432 
1433 
1434  //
1436  //
1437 
1449  template <typename CPU_ITERATOR, typename SCALARTYPE, unsigned int ALIGNMENT>
1450  void fast_copy(CPU_ITERATOR const & cpu_begin,
1451  CPU_ITERATOR const & cpu_end,
1453  {
1454  if (cpu_end - cpu_begin > 0)
1455  {
1456  if (gpu_begin.stride() == 1)
1457  {
1459  sizeof(SCALARTYPE)*gpu_begin.offset(),
1460  sizeof(SCALARTYPE)*gpu_begin.stride() * (cpu_end - cpu_begin), &(*cpu_begin));
1461  }
1462  else //writing to slice:
1463  {
1464  vcl_size_t cpu_size = (cpu_end - cpu_begin);
1465  std::vector<SCALARTYPE> temp_buffer(gpu_begin.stride() * cpu_size);
1466 
1467  viennacl::backend::memory_read(gpu_begin.handle(), sizeof(SCALARTYPE)*gpu_begin.offset(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
1468 
1469  for (vcl_size_t i=0; i<cpu_size; ++i)
1470  temp_buffer[i * gpu_begin.stride()] = (&(*cpu_begin))[i];
1471 
1472  viennacl::backend::memory_write(gpu_begin.handle(), sizeof(SCALARTYPE)*gpu_begin.offset(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
1473  }
1474  }
1475  }
1476 
1477 
1483  template <typename CPUVECTOR, typename NumericT>
1484  void fast_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
1485  {
1486  viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1487  }
1488 
1499  template <typename CPU_ITERATOR, typename SCALARTYPE, unsigned int ALIGNMENT>
1500  void async_copy(CPU_ITERATOR const & cpu_begin,
1501  CPU_ITERATOR const & cpu_end,
1503  {
1504  if (cpu_end - cpu_begin > 0)
1505  {
1506  if (gpu_begin.stride() == 1)
1507  {
1509  sizeof(SCALARTYPE)*gpu_begin.offset(),
1510  sizeof(SCALARTYPE)*gpu_begin.stride() * (cpu_end - cpu_begin), &(*cpu_begin),
1511  true);
1512  }
1513  else // fallback to blocking copy. There's nothing we can do to prevent this
1514  fast_copy(cpu_begin, cpu_end, gpu_begin);
1515  }
1516  }
1517 
1518 
1524  template <typename CPUVECTOR, typename NumericT>
1525  void async_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
1526  {
1527  viennacl::async_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1528  }
1529 
1530  //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
1537  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
1538  void copy(CPU_ITERATOR const & cpu_begin,
1539  CPU_ITERATOR const & cpu_end,
1541  {
1542  assert(cpu_end - cpu_begin > 0 && bool("Iterators incompatible"));
1543  if (cpu_begin != cpu_end)
1544  {
1545  //we require that the size of the gpu_vector is larger or equal to the cpu-size
1546  std::vector<SCALARTYPE> temp_buffer(cpu_end - cpu_begin);
1547  std::copy(cpu_begin, cpu_end, temp_buffer.begin());
1548  viennacl::fast_copy(temp_buffer.begin(), temp_buffer.end(), gpu_begin);
1549  }
1550  }
1551 
1552  // for things like copy(std_vec.begin(), std_vec.end(), vcl_vec.begin() + 1);
1553 
1559  template <typename CPUVECTOR, typename T>
1560  void copy(const CPUVECTOR & cpu_vec, vector_base<T> & gpu_vec)
1561  {
1562  viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1563  }
1564 
1565 
1566  #ifdef VIENNACL_WITH_EIGEN
1567  template <unsigned int ALIGNMENT>
1568  void copy(Eigen::VectorXf const & eigen_vec,
1569  vector<float, ALIGNMENT> & gpu_vec)
1570  {
1571  std::vector<float> entries(eigen_vec.size());
1572  for (vcl_size_t i = 0; i<entries.size(); ++i)
1573  entries[i] = eigen_vec(i);
1574  viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
1575  }
1576 
1577  template <unsigned int ALIGNMENT>
1578  void copy(Eigen::VectorXd const & eigen_vec,
1579  vector<double, ALIGNMENT> & gpu_vec)
1580  {
1581  std::vector<double> entries(eigen_vec.size());
1582  for (vcl_size_t i = 0; i<entries.size(); ++i)
1583  entries[i] = eigen_vec(i);
1584  viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
1585  }
1586  #endif
1587 
1588 
1589 
1590  //
1592  //
1599  template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
1603  {
1604  assert(gpu_src_end - gpu_src_begin >= 0);
1605  assert(gpu_src_begin.stride() == 1 && bool("ViennaCL ERROR: copy() for GPU->GPU not implemented for slices! Use operator= instead for the moment."));
1606 
1607  if (gpu_src_begin.stride() == 1 && gpu_dest_begin.stride() == 1)
1608  {
1609  if (gpu_src_begin != gpu_src_end)
1610  viennacl::backend::memory_copy(gpu_src_begin.handle(), gpu_dest_begin.handle(),
1611  sizeof(SCALARTYPE) * gpu_src_begin.offset(),
1612  sizeof(SCALARTYPE) * gpu_dest_begin.offset(),
1613  sizeof(SCALARTYPE) * (gpu_src_end.offset() - gpu_src_begin.offset()));
1614  }
1615  else
1616  {
1617  assert( false && bool("not implemented yet"));
1618  }
1619  }
1620 
1627  template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
1629  vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end,
1631  {
1633  static_cast<const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> >(gpu_src_end),
1634  gpu_dest_begin);
1635  }
1636 
1642  template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
1643  void copy(vector<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_vec,
1644  vector<SCALARTYPE, ALIGNMENT_DEST> & gpu_dest_vec )
1645  {
1646  viennacl::copy(gpu_src_vec.begin(), gpu_src_vec.end(), gpu_dest_vec.begin());
1647  }
1648 
1649 
1650 
1651 
1652 
1653 
1654  //global functions for handling vectors:
1659  template <typename T>
1660  std::ostream & operator<<(std::ostream & os, vector_base<T> const & val)
1661  {
1662  std::vector<T> tmp(val.size());
1663  viennacl::copy(val.begin(), val.end(), tmp.begin());
1664  os << "[" << val.size() << "](";
1665  for (typename std::vector<T>::size_type i=0; i<val.size(); ++i)
1666  {
1667  if (i > 0)
1668  os << ",";
1669  os << tmp[i];
1670  }
1671  os << ")";
1672  return os;
1673  }
1674 
1675  template <typename LHS, typename RHS, typename OP>
1676  std::ostream & operator<<(std::ostream & os, vector_expression<LHS, RHS, OP> const & proxy)
1677 
1678  {
1680  viennacl::vector<ScalarType> result = proxy;
1681  os << result;
1682  return os;
1683  }
1684 
1690  template <typename T>
1691  void swap(vector_base<T> & vec1, vector_base<T> & vec2)
1692  {
1693  viennacl::linalg::vector_swap(vec1, vec2);
1694  }
1695 
1701  template <typename SCALARTYPE, unsigned int ALIGNMENT>
1704  {
1705  return v1.fast_swap(v2);
1706  }
1707 
1708 
1709 
1710 
1711 
1712  //
1713  //
1715  //
1716  //
1717 
1718 
1719  //
1720  // operator *=
1721  //
1722 
1725  template <typename T, typename S1>
1727  vector_base<T> &
1728  >::type
1729  operator *= (vector_base<T> & v1, S1 const & gpu_val)
1730  {
1731  if (v1.size() > 0)
1733  v1, gpu_val, 1, false, (viennacl::is_flip_sign_scalar<S1>::value ? true : false));
1734  return v1;
1735  }
1736 
1737 
1738  //
1739  // operator /=
1740  //
1741 
1742 
1745  template <typename T, typename S1>
1747  vector_base<T> &
1748  >::type
1749  operator /= (vector_base<T> & v1, S1 const & gpu_val)
1750  {
1751  if (v1.size() > 0)
1753  v1, gpu_val, 1, true, (viennacl::is_flip_sign_scalar<S1>::value ? true : false));
1754  return v1;
1755  }
1756 
1757 
1758  //
1759  // operator +
1760  //
1761 
1762 
1768  template <typename LHS1, typename RHS1, typename OP1,
1769  typename LHS2, typename RHS2, typename OP2>
1770  vector_expression< const vector_expression< LHS1, RHS1, OP1>,
1771  const vector_expression< LHS2, RHS2, OP2>,
1774  vector_expression<LHS2, RHS2, OP2> const & proxy2)
1775  {
1776  assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
1779  viennacl::op_add>(proxy1, proxy2);
1780  }
1781 
1787  template <typename LHS, typename RHS, typename OP, typename T>
1788  vector_expression< const vector_expression<LHS, RHS, OP>,
1789  const vector_base<T>,
1792  vector_base<T> const & vec)
1793  {
1794  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1796  const vector_base<T>,
1797  viennacl::op_add>(proxy, vec);
1798  }
1799 
1805  template <typename T, typename LHS, typename RHS, typename OP>
1806  vector_expression< const vector_base<T>,
1807  const vector_expression<LHS, RHS, OP>,
1810  vector_expression<LHS, RHS, OP> const & proxy)
1811  {
1812  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1815  viennacl::op_add>(vec, proxy);
1816  }
1817 
1820  template <typename T>
1821  vector_expression< const vector_base<T>, const vector_base<T>, op_add>
1823  {
1825  }
1826 
1827 
1828 
1829  //
1830  // operator -
1831  //
1832 
1838  template <typename LHS1, typename RHS1, typename OP1,
1839  typename LHS2, typename RHS2, typename OP2>
1840  vector_expression< const vector_expression< LHS1, RHS1, OP1>,
1841  const vector_expression< LHS2, RHS2, OP2>,
1844  vector_expression<LHS2, RHS2, OP2> const & proxy2)
1845  {
1846  assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
1849  viennacl::op_sub>(proxy1, proxy2);
1850  }
1851 
1852 
1858  template <typename LHS, typename RHS, typename OP, typename T>
1859  vector_expression< const vector_expression<LHS, RHS, OP>,
1860  const vector_base<T>,
1863  vector_base<T> const & vec)
1864  {
1865  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1867  const vector_base<T>,
1868  viennacl::op_sub>(proxy, vec);
1869  }
1870 
1876  template <typename T, typename LHS, typename RHS, typename OP>
1877  vector_expression< const vector_base<T>,
1878  const vector_expression<LHS, RHS, OP>,
1881  vector_expression<LHS, RHS, OP> const & proxy)
1882  {
1883  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1886  viennacl::op_sub>(vec, proxy);
1887  }
1888 
1891  template <typename T>
1892  vector_expression< const vector_base<T>, const vector_base<T>, op_sub>
1894  {
1896  }
1897 
1898 
1899  //
1900  // operator *
1901  //
1902 
1903 
1909  template <typename S1, typename T>
1911  vector_expression< const vector_base<T>, const S1, op_mult> >::type
1912  operator * (S1 const & value, vector_base<T> const & vec)
1913  {
1914  return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
1915  }
1916 
1922  template <typename T>
1923  vector_expression< const vector_base<T>, const T, op_mult>
1924  operator * (char value, vector_base<T> const & vec)
1925  {
1926  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1927  }
1928 
1934  template <typename T>
1935  vector_expression< const vector_base<T>, const T, op_mult>
1936  operator * (short value, vector_base<T> const & vec)
1937  {
1938  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1939  }
1940 
1946  template <typename T>
1947  vector_expression< const vector_base<T>, const T, op_mult>
1948  operator * (int value, vector_base<T> const & vec)
1949  {
1950  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1951  }
1952 
1958  template <typename T>
1959  vector_expression< const vector_base<T>, const T, op_mult>
1960  operator * (long value, vector_base<T> const & vec)
1961  {
1962  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1963  }
1964 
1965 
1966 
1967 
1973  template <typename LHS, typename RHS, typename OP, typename T>
1974  vector_expression< const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult>
1976  {
1978  }
1979 
1982  template <typename T, typename S1>
1984  vector_expression< const vector_base<T>, const S1, op_mult> >::type
1985  operator * (vector_base<T> const & vec, S1 const & value)
1986  {
1987  return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
1988  }
1989 
1990  template <typename T>
1991  vector_expression< const vector_base<T>, const T, op_mult>
1992  operator * (vector_base<T> const & vec, T const & value)
1993  {
1994  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1995  }
1996 
2002  template <typename LHS, typename RHS, typename OP, typename S1>
2006  S1 const & val)
2007  {
2009  }
2010 
2016  template <typename S1, typename LHS, typename RHS, typename OP>
2019  operator * (S1 const & val,
2020  vector_expression<LHS, RHS, OP> const & proxy)
2021  {
2023  }
2024 
2025  //
2026  // operator /
2027  //
2028 
2034  template <typename S1, typename LHS, typename RHS, typename OP>
2038  S1 const & val)
2039  {
2041  }
2042 
2043 
2046  template <typename T, typename S1>
2048  vector_expression< const vector_base<T>, const S1, op_div> >::type
2049  operator / (vector_base<T> const & v1, S1 const & s1)
2050  {
2051  return vector_expression<const vector_base<T>, const S1, op_div>(v1, s1);
2052  }
2053 
2054 
2055 
2056  //
2057  // Specify available operations:
2058  //
2059 
2062  namespace linalg
2063  {
2064  namespace detail
2065  {
2066  // x = y
2067  template <typename T>
2068  struct op_executor<vector_base<T>, op_assign, vector_base<T> >
2069  {
2070  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2071  {
2072  viennacl::linalg::av(lhs, rhs, T(1), 1, false, false);
2073  }
2074  };
2075 
2076  // x = inner_prod(z, {y0, y1, ...})
2077  template <typename T>
2078  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> >
2079  {
2080  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> const & rhs)
2081  {
2082  viennacl::linalg::inner_prod_impl(rhs.lhs(), rhs.rhs(), lhs);
2083  }
2084  };
2085 
2086  // x += y
2087  template <typename T>
2088  struct op_executor<vector_base<T>, op_inplace_add, vector_base<T> >
2089  {
2090  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2091  {
2092  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, false);
2093  }
2094  };
2095 
2096  // x -= y
2097  template <typename T>
2098  struct op_executor<vector_base<T>, op_inplace_sub, vector_base<T> >
2099  {
2100  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2101  {
2102  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, true);
2103  }
2104  };
2105 
2107 
2108 
2109  // x = alpha * y
2110  template <typename T, typename ScalarType>
2111  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2112  {
2113  // generic case: ScalarType is a scalar expression
2114  template <typename LHS, typename RHS, typename OP>
2115  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2116  {
2117  T alpha = proxy.rhs();
2118  viennacl::linalg::av(lhs, proxy.lhs(), alpha, 1, false, false);
2119  }
2120 
2121  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2122  {
2123  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
2124  }
2125 
2126  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2127  {
2128  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
2129  }
2130  };
2131 
2132  // x += alpha * y
2133  template <typename T, typename ScalarType>
2134  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2135  {
2136  // generic case: ScalarType is a scalar expression
2137  template <typename LHS, typename RHS, typename OP>
2138  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2139  {
2140  T alpha = proxy.rhs();
2141  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, false);
2142  }
2143 
2144  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2145  {
2146  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
2147  }
2148 
2149  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2150  {
2151  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
2152  }
2153  };
2154 
2155  // x -= alpha * y
2156  template <typename T, typename ScalarType>
2157  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2158  {
2159  // generic case: ScalarType is a scalar expression
2160  template <typename LHS, typename RHS, typename OP>
2161  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2162  {
2163  T alpha = proxy.rhs();
2164  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, true);
2165  }
2166 
2167  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2168  {
2169  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
2170  }
2171 
2172  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2173  {
2174  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
2175  }
2176  };
2177 
2178 
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_assign, 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  // x += alpha * vec_expr
2193  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2194  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2195  {
2196  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2197  {
2198  vector<T> temp(proxy.lhs());
2199  lhs += temp * proxy.rhs();
2200  }
2201  };
2202 
2203  // x -= alpha * vec_expr
2204  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2205  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2206  {
2207  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2208  {
2209  vector<T> temp(proxy.lhs());
2210  lhs -= temp * proxy.rhs();
2211  }
2212  };
2213 
2214 
2216 
2217  // x = y / alpha
2218  template <typename T, typename ScalarType>
2219  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2220  {
2221  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2222  {
2223  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, true, false);
2224  }
2225  };
2226 
2227  // x += y / alpha
2228  template <typename T, typename ScalarType>
2229  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2230  {
2231  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2232  {
2233  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, false);
2234  }
2235  };
2236 
2237  // x -= y / alpha
2238  template <typename T, typename ScalarType>
2239  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2240  {
2241  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2242  {
2243  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, true);
2244  }
2245  };
2246 
2247 
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_assign, 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  // x += vec_expr / alpha
2262  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2263  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2264  {
2265  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2266  {
2267  vector<T> temp(proxy.lhs());
2268  lhs += temp / proxy.rhs();
2269  }
2270  };
2271 
2272  // x -= vec_expr / alpha
2273  template <typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2274  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2275  {
2276  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2277  {
2278  vector<T> temp(proxy.lhs());
2279  lhs -= temp / proxy.rhs();
2280  }
2281  };
2282 
2283 
2284 
2285  // generic x = vec_expr1 + vec_expr2:
2286  template <typename T, typename LHS, typename RHS>
2287  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_add> >
2288  {
2289  // generic x = vec_expr1 + vec_expr2:
2290  template <typename LHS1, typename RHS1>
2291  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2292  {
2293  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2294  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2295 
2296  if (op_aliasing_lhs || op_aliasing_rhs)
2297  {
2298  vector_base<T> temp(proxy.lhs());
2299  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2300  lhs = temp;
2301  }
2302  else
2303  {
2304  op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
2305  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2306  }
2307  }
2308 
2309  // x = y + z
2310  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2311  {
2313  proxy.lhs(), T(1), 1, false, false,
2314  proxy.rhs(), T(1), 1, false, false);
2315  }
2316 
2317  // x = alpha * y + z
2318  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2319  const vector_base<T>,
2320  op_add> const & proxy)
2321  {
2323  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2324  proxy.rhs(), T(1), 1, false, false);
2325  }
2326 
2327  // x = y / alpha + z
2328  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2329  const vector_base<T>,
2330  op_add> const & proxy)
2331  {
2333  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2334  proxy.rhs(), T(1), 1, false, false);
2335  }
2336 
2337  // x = y + beta * z
2338  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2339  const vector_expression<const vector_base<T>, const T, op_mult>,
2340  op_add> const & proxy)
2341  {
2343  proxy.lhs(), T(1), 1, false, false,
2344  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2345  }
2346 
2347  // x = y + z / beta
2348  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2349  const vector_expression<const vector_base<T>, const T, op_div>,
2350  op_add> const & proxy)
2351  {
2353  proxy.lhs(), T(1), 1, false, false,
2354  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2355  }
2356 
2357  // x = alpha * y + beta * z
2358  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2359  const vector_expression<const vector_base<T>, const T, op_mult>,
2360  op_add> const & proxy)
2361  {
2363  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2364  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2365  }
2366 
2367  // x = alpha * y + z / beta
2368  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2369  const vector_expression<const vector_base<T>, const T, op_div>,
2370  op_add> const & proxy)
2371  {
2373  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2374  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2375  }
2376 
2377  // x = y / alpha + beta * z
2378  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2379  const vector_expression<const vector_base<T>, const T, op_mult>,
2380  op_add> const & proxy)
2381  {
2383  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2384  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2385  }
2386 
2387  // x = y / alpha + z / beta
2388  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2389  const vector_expression<const vector_base<T>, const T, op_div>,
2390  op_add> const & proxy)
2391  {
2393  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2394  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2395  }
2396  };
2397 
2398 
2399  // generic x += vec_expr1 + vec_expr2:
2400  template <typename T, typename LHS, typename RHS>
2401  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_add> >
2402  {
2403  // generic x += vec_expr1 + vec_expr2:
2404  template <typename LHS1, typename RHS1>
2405  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2406  {
2407  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2408  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2409 
2410  if (op_aliasing_lhs || op_aliasing_rhs)
2411  {
2412  vector_base<T> temp(proxy.lhs());
2413  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2414  lhs += temp;
2415  }
2416  else
2417  {
2418  op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
2419  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2420  }
2421  }
2422 
2423  // x += y + z
2424  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2425  {
2427  proxy.lhs(), T(1), 1, false, false,
2428  proxy.rhs(), T(1), 1, false, false);
2429  }
2430 
2431  // x += alpha * y + z
2432  template <typename ScalarType>
2433  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2434  const vector_base<T>,
2435  op_add> const & proxy)
2436  {
2438  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2439  proxy.rhs(), T(1), 1, false, false);
2440  }
2441 
2442  // x += y / alpha + z
2443  template <typename ScalarType>
2444  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2445  const vector_base<T>,
2446  op_add> const & proxy)
2447  {
2449  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2450  proxy.rhs(), T(1), 1, false, false);
2451  }
2452 
2453  // x += y + beta * z
2454  template <typename ScalarType>
2455  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2456  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2457  op_add> const & proxy)
2458  {
2460  proxy.lhs(), T(1), 1, false, false,
2461  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2462  }
2463 
2464  // x += y + z / beta
2465  template <typename ScalarType>
2466  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2467  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2468  op_add> const & proxy)
2469  {
2471  proxy.lhs(), T(1), 1, false, false,
2472  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2473  }
2474 
2475  // x += alpha * y + 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_mult>,
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, false, false,
2483  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2484  }
2485 
2486  // x += alpha * y + 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_mult>,
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, false, false,
2494  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2495  }
2496 
2497  // x += y / alpha + beta * z
2498  template <typename ScalarType1, typename ScalarType2>
2499  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2500  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2501  op_add> const & proxy)
2502  {
2504  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2505  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2506  }
2507 
2508  // x += y / alpha + z / beta
2509  template <typename ScalarType1, typename ScalarType2>
2510  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2511  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2512  op_add> const & proxy)
2513  {
2515  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2516  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2517  }
2518  };
2519 
2520 
2521 
2522  // generic x -= vec_expr1 + vec_expr2:
2523  template <typename T, typename LHS, typename RHS>
2524  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_add> >
2525  {
2526  // generic x -= vec_expr1 + vec_expr2:
2527  template <typename LHS1, typename RHS1>
2528  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2529  {
2530  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2531  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2532 
2533  if (op_aliasing_lhs || op_aliasing_rhs)
2534  {
2535  vector_base<T> temp(proxy.lhs());
2536  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2537  lhs -= temp;
2538  }
2539  else
2540  {
2541  op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
2542  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2543  }
2544  }
2545 
2546  // x -= y + z
2547  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2548  {
2550  proxy.lhs(), T(1), 1, false, true,
2551  proxy.rhs(), T(1), 1, false, true);
2552  }
2553 
2554  // x -= alpha * y + z
2555  template <typename ScalarType>
2556  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2557  const vector_base<T>,
2558  op_add> const & proxy)
2559  {
2561  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2562  proxy.rhs(), T(1), 1, false, true);
2563  }
2564 
2565  // x -= y / alpha + z
2566  template <typename ScalarType>
2567  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2568  const vector_base<T>,
2569  op_add> const & proxy)
2570  {
2572  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2573  proxy.rhs(), T(1), 1, false, true);
2574  }
2575 
2576  // x -= y + beta * z
2577  template <typename ScalarType>
2578  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2579  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2580  op_add> const & proxy)
2581  {
2583  proxy.lhs(), T(1), 1, false, true,
2584  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2585  }
2586 
2587  // x -= y + z / beta
2588  template <typename ScalarType>
2589  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2590  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2591  op_add> const & proxy)
2592  {
2594  proxy.lhs(), T(1), 1, false, true,
2595  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2596  }
2597 
2598  // x -= alpha * y + 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_mult>,
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, false, true,
2606  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2607  }
2608 
2609  // x -= alpha * y + 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_mult>,
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, false, true,
2617  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2618  }
2619 
2620  // x -= y / alpha + beta * z
2621  template <typename ScalarType1, typename ScalarType2>
2622  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2623  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2624  op_add> const & proxy)
2625  {
2627  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2628  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2629  }
2630 
2631  // x -= y / alpha + z / beta
2632  template <typename ScalarType1, typename ScalarType2>
2633  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2634  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2635  op_add> const & proxy)
2636  {
2638  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2639  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2640  }
2641  };
2642 
2643 
2644 
2646 
2647 
2648 
2649  // generic x = vec_expr1 - vec_expr2:
2650  template <typename T, typename LHS, typename RHS>
2651  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_sub> >
2652  {
2653  // generic x = vec_expr1 - vec_expr2:
2654  template <typename LHS1, typename RHS1>
2655  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2656  {
2657  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2658  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2659 
2660  if (op_aliasing_lhs || op_aliasing_rhs)
2661  {
2662  vector_base<T> temp(proxy.lhs());
2663  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2664  lhs = temp;
2665  }
2666  else
2667  {
2668  op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
2669  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2670  }
2671  }
2672 
2673  // x = y - z
2674  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2675  {
2677  proxy.lhs(), T(1), 1, false, false,
2678  proxy.rhs(), T(1), 1, false, true);
2679  }
2680 
2681  // x = alpha * y - z
2682  template <typename ScalarType>
2683  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2684  const vector_base<T>,
2685  op_sub> const & proxy)
2686  {
2688  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2689  proxy.rhs(), T(1), 1, false, true);
2690  }
2691 
2692  // x = y / alpha - z
2693  template <typename ScalarType>
2694  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2695  const vector_base<T>,
2696  op_sub> const & proxy)
2697  {
2699  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2700  proxy.rhs(), T(1), 1, false, true);
2701  }
2702 
2703  // x = y - beta * z
2704  template <typename ScalarType>
2705  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2706  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2707  op_sub> const & proxy)
2708  {
2710  proxy.lhs(), T(1), 1, false, false,
2711  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2712  }
2713 
2714  // x = y - z / beta
2715  template <typename ScalarType>
2716  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2717  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2718  op_sub> const & proxy)
2719  {
2721  proxy.lhs(), T(1), 1, false, false,
2722  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2723  }
2724 
2725  // x = alpha * y - 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_mult>,
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, false, false,
2733  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2734  }
2735 
2736  // x = alpha * y - 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_mult>,
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, false, false,
2744  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2745  }
2746 
2747  // x = y / alpha - beta * z
2748  template <typename ScalarType1, typename ScalarType2>
2749  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2750  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2751  op_sub> const & proxy)
2752  {
2754  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2755  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2756  }
2757 
2758  // x = y / alpha - z / beta
2759  template <typename ScalarType1, typename ScalarType2>
2760  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2761  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2762  op_sub> const & proxy)
2763  {
2765  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2766  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2767  }
2768  };
2769 
2770 
2771  // generic x += vec_expr1 - vec_expr2:
2772  template <typename T, typename LHS, typename RHS>
2773  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_sub> >
2774  {
2775  // generic x += vec_expr1 - vec_expr2:
2776  template <typename LHS1, typename RHS1>
2777  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2778  {
2779  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2780  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2781 
2782  if (op_aliasing_lhs || op_aliasing_rhs)
2783  {
2784  vector_base<T> temp(proxy.lhs());
2785  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2786  lhs += temp;
2787  }
2788  else
2789  {
2790  op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
2791  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2792  }
2793  }
2794 
2795  // x += y - z
2796  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2797  {
2799  proxy.lhs(), T(1), 1, false, false,
2800  proxy.rhs(), T(1), 1, false, true);
2801  }
2802 
2803  // x += alpha * y - z
2804  template <typename ScalarType>
2805  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2806  const vector_base<T>,
2807  op_sub> const & proxy)
2808  {
2810  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2811  proxy.rhs(), T(1), 1, false, true);
2812  }
2813 
2814  // x += y / alpha - z
2815  template <typename ScalarType>
2816  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2817  const vector_base<T>,
2818  op_sub> const & proxy)
2819  {
2821  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2822  proxy.rhs(), T(1), 1, false, true);
2823  }
2824 
2825  // x += y - beta * z
2826  template <typename ScalarType>
2827  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2828  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2829  op_sub> const & proxy)
2830  {
2832  proxy.lhs(), T(1), 1, false, false,
2833  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2834  }
2835 
2836  // x += y - z / beta
2837  template <typename ScalarType>
2838  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2839  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2840  op_sub> const & proxy)
2841  {
2843  proxy.lhs(), T(1), 1, false, false,
2844  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2845  }
2846 
2847  // x += alpha * y - 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_mult>,
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, false, false,
2855  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2856  }
2857 
2858  // x += alpha * y - 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_mult>,
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, false, false,
2866  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2867  }
2868 
2869  // x += y / alpha - beta * z
2870  template <typename ScalarType1, typename ScalarType2>
2871  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2872  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2873  op_sub> const & proxy)
2874  {
2876  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2877  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2878  }
2879 
2880  // x += y / alpha - z / beta
2881  template <typename ScalarType1, typename ScalarType2>
2882  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2883  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2884  op_sub> const & proxy)
2885  {
2887  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2888  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2889  }
2890  };
2891 
2892 
2893 
2894  // generic x -= vec_expr1 - vec_expr2:
2895  template <typename T, typename LHS, typename RHS>
2896  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_sub> >
2897  {
2898  // generic x -= vec_expr1 - vec_expr2:
2899  template <typename LHS1, typename RHS1>
2900  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2901  {
2902  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2903  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2904 
2905  if (op_aliasing_lhs || op_aliasing_rhs)
2906  {
2907  vector_base<T> temp(proxy.lhs());
2908  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2909  lhs -= temp;
2910  }
2911  else
2912  {
2913  op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
2914  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2915  }
2916  }
2917 
2918  // x -= y - z
2919  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2920  {
2922  proxy.lhs(), T(1), 1, false, true,
2923  proxy.rhs(), T(1), 1, false, false);
2924  }
2925 
2926  // x -= alpha * y - z
2927  template <typename ScalarType>
2928  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2929  const vector_base<T>,
2930  op_sub> const & proxy)
2931  {
2933  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2934  proxy.rhs(), T(1), 1, false, false);
2935  }
2936 
2937  // x -= y / alpha - z
2938  template <typename ScalarType>
2939  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2940  const vector_base<T>,
2941  op_sub> const & proxy)
2942  {
2944  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2945  proxy.rhs(), T(1), 1, false, false);
2946  }
2947 
2948  // x -= y - beta * z
2949  template <typename ScalarType>
2950  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2951  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2952  op_sub> const & proxy)
2953  {
2955  proxy.lhs(), T(1), 1, false, true,
2956  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2957  }
2958 
2959  // x -= y - z / beta
2960  template <typename ScalarType>
2961  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2962  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2963  op_sub> const & proxy)
2964  {
2966  proxy.lhs(), T(1), 1, false, true,
2967  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2968  }
2969 
2970  // x -= alpha * y - 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_mult>,
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, false, true,
2978  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2979  }
2980 
2981  // x -= alpha * y - 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_mult>,
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, false, true,
2989  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2990  }
2991 
2992  // x -= y / alpha - beta * z
2993  template <typename ScalarType1, typename ScalarType2>
2994  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2995  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2996  op_sub> const & proxy)
2997  {
2999  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
3000  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
3001  }
3002 
3003  // x -= y / alpha - z / beta
3004  template <typename ScalarType1, typename ScalarType2>
3005  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
3006  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
3007  op_sub> const & proxy)
3008  {
3010  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
3011  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
3012  }
3013  };
3014 
3015 
3016 
3017 
3018 
3019 
3020 
3021 
3022 
3023 
3024 
3025 
3026 
3027 
3028 
3029 
3030 
3031 
3033 
3034  // generic x = vec_expr1 .* vec_expr2:
3035  template <typename T, typename LHS, typename RHS, typename OP>
3036  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3037  {
3038  // x = y .* z or x = y ./ z
3039  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3040  {
3041  viennacl::linalg::element_op(lhs, proxy);
3042  }
3043 
3044  // x = y .* vec_expr or x = y ./ vec_expr
3045  template <typename LHS2, typename RHS2, typename OP2>
3046  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)
3047  {
3048  vector<T> temp(proxy.rhs());
3049  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3050  }
3051 
3052  // x = vec_expr .* z or x = vec_expr ./ z
3053  template <typename LHS1, typename RHS1, typename OP1>
3054  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)
3055  {
3056  vector<T> temp(proxy.lhs());
3057  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3058  }
3059 
3060  // x = vec_expr .* vec_expr or z = vec_expr .* vec_expr
3061  template <typename LHS1, typename RHS1, typename OP1,
3062  typename LHS2, typename RHS2, typename OP2>
3063  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3064  const vector_expression<const LHS2, const RHS2, OP2>,
3065  op_element_binary<OP> > const & proxy)
3066  {
3067  vector<T> temp1(proxy.lhs());
3068  vector<T> temp2(proxy.rhs());
3069  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3070  }
3071  };
3072 
3073  // generic x += vec_expr1 .* vec_expr2:
3074  template <typename T, typename LHS, typename RHS, typename OP>
3075  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3076  {
3077  // x += y .* z or x += y ./ z
3078  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3079  {
3080  viennacl::vector<T> temp(proxy);
3081  lhs += temp;
3082  }
3083 
3084  // x += y .* vec_expr or x += y ./ vec_expr
3085  template <typename LHS2, typename RHS2, typename OP2>
3086  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)
3087  {
3088  vector<T> temp(proxy.rhs());
3089  vector<T> temp2(temp.size());
3090  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3091  lhs += temp2;
3092  }
3093 
3094  // x += vec_expr .* z or x += vec_expr ./ z
3095  template <typename LHS1, typename RHS1, typename OP1>
3096  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)
3097  {
3098  vector<T> temp(proxy.lhs());
3099  vector<T> temp2(temp.size());
3100  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3101  lhs += temp2;
3102  }
3103 
3104  // x += vec_expr .* vec_expr or x += vec_expr ./ vec_expr
3105  template <typename LHS1, typename RHS1, typename OP1,
3106  typename LHS2, typename RHS2, typename OP2>
3107  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3108  const vector_expression<const LHS2, const RHS2, OP2>,
3109  op_element_binary<OP> > const & proxy)
3110  {
3111  vector<T> temp1(proxy.lhs());
3112  vector<T> temp2(proxy.rhs());
3113  vector<T> temp3(temp1.size());
3114  viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3115  lhs += temp3;
3116  }
3117  };
3118 
3119  // generic x -= vec_expr1 .* vec_expr2:
3120  template <typename T, typename LHS, typename RHS, typename OP>
3121  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3122  {
3123 
3124  // x -= y .* z or x -= y ./ z
3125  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3126  {
3127  viennacl::vector<T> temp(proxy);
3128  lhs -= temp;
3129  }
3130 
3131  // x -= y .* vec_expr or x -= y ./ vec_expr
3132  template <typename LHS2, typename RHS2, typename OP2>
3133  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)
3134  {
3135  vector<T> temp(proxy.rhs());
3136  vector<T> temp2(temp.size());
3137  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3138  lhs -= temp2;
3139  }
3140 
3141  // x -= vec_expr .* z or x -= vec_expr ./ z
3142  template <typename LHS1, typename RHS1, typename OP1>
3143  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)
3144  {
3145  vector<T> temp(proxy.lhs());
3146  vector<T> temp2(temp.size());
3147  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3148  lhs -= temp2;
3149  }
3150 
3151  // x -= vec_expr .* vec_expr or x -= vec_expr ./ vec_expr
3152  template <typename LHS1, typename RHS1, typename OP1,
3153  typename LHS2, typename RHS2, typename OP2>
3154  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3155  const vector_expression<const LHS2, const RHS2, OP2>,
3156  op_element_binary<OP> > const & proxy)
3157  {
3158  vector<T> temp1(proxy.lhs());
3159  vector<T> temp2(proxy.rhs());
3160  vector<T> temp3(temp1.size());
3161  viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3162  lhs -= temp3;
3163  }
3164  };
3165 
3167 
3168  template <typename T, typename LHS, typename RHS, typename OP>
3169  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3170  {
3171  // x = OP(y)
3172  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3173  {
3174  viennacl::linalg::element_op(lhs, proxy);
3175  }
3176 
3177  // x = OP(vec_expr)
3178  template <typename LHS2, typename RHS2, typename OP2>
3179  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3180  const vector_expression<const LHS2, const RHS2, OP2>,
3181  op_element_unary<OP> > const & proxy)
3182  {
3183  vector<T> temp(proxy.rhs());
3184  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp));
3185  }
3186  };
3187 
3188  template <typename T, typename LHS, typename RHS, typename OP>
3189  struct op_executor<vector_base<T>, op_inplace_add, 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  template <typename T, typename LHS, typename RHS, typename OP>
3211  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3212  {
3213  // x -= OP(y)
3214  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3215  {
3216  vector<T> temp(proxy);
3217  lhs -= temp;
3218  }
3219 
3220  // x -= OP(vec_expr)
3221  template <typename LHS2, typename RHS2, typename OP2>
3222  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3223  const vector_expression<const LHS2, const RHS2, OP2>,
3224  op_element_unary<OP> > const & proxy)
3225  {
3226  vector<T> temp(proxy.rhs());
3227  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
3228  lhs -= temp;
3229  }
3230  };
3231 
3232  } // namespace detail
3233 
3234  } // namespace linalg
3235 
3238 } // namespace viennacl
3239 
3240 #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
vector_iterator()
Definition: vector.hpp:319
bool is_value_static() const
Definition: vector.hpp:64
handle_type const & handle() const
Definition: vector.hpp:347
Represents a vector consisting of zeros only.
Definition: forwards.h:193
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
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
A tag class representing multiplication by a scalar.
Definition: forwards.h:74
VectorType const & const_at(vcl_size_t i) const
Definition: vector.hpp:1196
self_type & swap(self_type &other)
Swaps the entries of the two vectors.
Definition: vector.hpp:850
A STL-type const-iterator for vector elements. Elements can be accessed, but cannot be manipulated...
Definition: forwards.h:187
SizeType size_type
Definition: vector.hpp:371
std::size_t vcl_size_t
Definition: forwards.h:58
void resize(size_type new_size, viennacl::context ctx, bool preserve=true)
Definition: vector.hpp:1101
Definition: forwards.h:498
scalar< SCALARTYPE > value_type
Definition: vector.hpp:219
SCALARTYPE const & const_reference
Definition: vector.hpp:134
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
self_type & operator+=(const self_type &vec)
Definition: vector.hpp:731
static const size_type alignment
Definition: vector.hpp:376
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
Definition: forwards.h:172
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector.hpp:859
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:121
viennacl::context ctx_
Definition: vector.hpp:87
Worker class for decomposing expression templates.
Definition: op_executor.hpp:79
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
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2)
Definition: vector.hpp:1143
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
vector(size_type vec_size)
An explicit constructor for the vector, allocating the given amount of memory (plus a padding specifi...
Definition: vector.hpp:1017
cpu_value_type operator()(size_type i) const
Definition: vector.hpp:70
Defines the worker class for decomposing an expression tree into small chunks, which can be processed...
bool operator!=(self_type const &other) const
Definition: vector.hpp:258
Implementations of vector operations.
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
viennacl::context context() const
Definition: vector.hpp:58
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
zero_vector(size_type s, viennacl::context ctx=viennacl::context())
Definition: vector.hpp:112
Helper struct for checking whether a type represents a sign flip on a viennacl::scalar<> ...
Definition: forwards.h:377
vcl_size_t start_
Definition: vector.hpp:286
Represents a vector consisting of 1 at a given index and zeros otherwise.
Definition: forwards.h:196
Various little tools used here and there in ViennaCL.
vcl_size_t index() const
Definition: vector.hpp:66
vector_tuple(std::vector< VectorType const * > const &vecs)
Definition: vector.hpp:1177
unit_vector(size_type s, size_type ind, viennacl::context ctx=viennacl::context())
Definition: vector.hpp:97
vector_iterator(handle_type &elements, vcl_size_t index, vcl_size_t start=0, vcl_ptrdiff_t stride=1)
Definition: vector.hpp:320
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
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
vector_base()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:380
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
A proxy class for entries in a vector.
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
vcl_size_t offset() const
Offset of the current element index with respect to the beginning of the buffer.
Definition: vector.hpp:276
implicit_vector_base(size_type s, std::pair< SCALARTYPE, bool > v, viennacl::context ctx)
Definition: vector.hpp:52
bool has_index() const
Definition: vector.hpp:68
const_vector_iterator< SCALARTYPE, 1 > const_iterator
Definition: vector.hpp:373
Expression template class for representing a tree of expressions which ultimately result in a matrix...
Definition: forwards.h:283
vector_base(size_type vec_size, viennacl::context ctx=viennacl::context())
Creates a vector and allocates the necessary memory.
Definition: vector.hpp:396
implicit_vector_base(size_type s, vcl_size_t i, std::pair< SCALARTYPE, bool > v, viennacl::context ctx)
Definition: vector.hpp:51
cpu_value_type operator[](size_type i) const
Definition: vector.hpp:76
vector_iterator< SCALARTYPE, 1 > iterator
Definition: vector.hpp:374
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
base_type::difference_type difference_type
Definition: vector.hpp:317
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2, VectorType const &v3)
Definition: vector.hpp:1158
const_iterator end() const
Returns a const-iterator pointing to the end of the vector (STL like)
Definition: vector.hpp:843
entry_proxy< SCALARTYPE > operator()(size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:689
vector(const base_type &v)
Definition: vector.hpp:1046
size_type size() const
Definition: vector.hpp:60
This file provides the forward declarations for the main types used within ViennaCL.
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
handle_type & handle()
Definition: vector.hpp:346
base_type::size_type size_type
Definition: vector.hpp:110
size_type start() const
Returns the offset within the buffer.
Definition: vector.hpp:867
base_type::handle_type handle_type
Definition: vector.hpp:316
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:815
VectorType & at(vcl_size_t i) const
Definition: vector.hpp:1195
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:1108
size_type size() const
Returns the size of the result vector.
Definition: vector.hpp:187
self_type & operator=(T const &other)
Definition: vector.hpp:1081
A proxy for scalar expressions (e.g. from inner vector products)
Definition: forwards.h:175
An expression template class that represents a binary operation that yields a vector.
Definition: forwards.h:181
SCALARTYPE cpu_value_type
Definition: vector.hpp:369
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
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
Definition: forwards.h:481
memory_types
Definition: forwards.h:476
viennacl::memory_types memory_domain() const
Definition: vector.hpp:890
self_type & operator/=(SCALARTYPE val)
Scales this vector by a CPU scalar value.
Definition: vector.hpp:787
void swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
Definition: vector.hpp:1691
Implementation of a OpenCL-like context, which serves as a unification of {OpenMP, CUDA, OpenCL} at the user API.
vector_expression(LHS &l, RHS &r)
Definition: vector.hpp:177
self_type operator+(difference_type diff) const
Definition: vector.hpp:344
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:1643
rhs_reference_type rhs() const
Get right hand side operand.
Definition: vector.hpp:184
SCALARTYPE const_reference
Definition: vector.hpp:122
vcl_ptrdiff_t difference_type
Definition: vector.hpp:220
base_type::size_type size_type
Definition: vector.hpp:133
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:1021
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
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:904
void clear()
Resets all entries to zero. Does not change the size of the vector.
Definition: vector.hpp:885
vector_tuple(std::vector< VectorType * > const &vecs)
Definition: vector.hpp:1183
vector(zero_vector< SCALARTYPE > const &v)
Creates the vector from the supplied zero vector.
Definition: vector.hpp:1066
self_type & operator-=(const self_type &vec)
Definition: vector.hpp:742
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:144
self_type & operator*=(SCALARTYPE val)
Scales a vector (or proxy) by a CPU scalar value.
Definition: vector.hpp:777
Definition: forwards.h:480
difference_type operator-(self_type const &other) const
Definition: vector.hpp:267
vector()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:1011
handle_type const & elements_
The index of the entry the iterator is currently pointing to.
Definition: vector.hpp:284
Tuple class holding pointers to multiple vectors. Mainly used as a temporary object returned from vie...
Definition: forwards.h:211
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:808
vcl_size_t size() const
Definition: vector.hpp:1192
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:1702
A STL-type iterator for vector elements. Elements can be accessed and manipulated. VERY SLOW!!
Definition: forwards.h:184
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:43
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:1114
base_type::size_type size_type
Definition: vector.hpp:1006
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
lhs_reference_type lhs() const
Get left hand side operand.
Definition: vector.hpp:181
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:1096
A tag class representing addition.
Definition: forwards.h:70
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
vector(unit_vector< SCALARTYPE > const &v)
Creates the vector from the supplied unit vector.
Definition: vector.hpp:1059
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:936
vector(size_type vec_size, viennacl::context ctx)
Definition: vector.hpp:1019
viennacl::backend::mem_handle handle_type
Definition: vector.hpp:221
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
vector_tuple< ScalarT > tie(vector_base< ScalarT > const &v0, vector_base< ScalarT > const &v1)
Definition: vector.hpp:1205
vcl_size_t stride() const
Index increment in the underlying buffer when incrementing the iterator to the next element...
Definition: vector.hpp:279
vector(scalar_vector< SCALARTYPE > const &v)
Creates the vector from the supplied scalar vector.
Definition: vector.hpp:1073
A vector class representing a linear memory sequence on the GPU. Inspired by boost::numeric::ublas::v...
Definition: forwards.h:208
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
self_type operator+(difference_type diff) const
Definition: vector.hpp:272
vector(vector_expression< const LHS, const RHS, OP > const &proxy)
Definition: vector.hpp:1044
SCALARTYPE const_reference
Definition: vector.hpp:111
handle_type & handle()
Returns the memory handle.
Definition: vector.hpp:881
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
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
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:947
SCALARTYPE const & const_reference
Definition: vector.hpp:55
Definition: vector.hpp:171
base_type::value_type operator*(void)
Definition: vector.hpp:336
entry_proxy< SCALARTYPE > operator[](size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:699
iterator begin()
Returns an iterator pointing to the beginning of the vector (STL like)
Definition: vector.hpp:825
void set_handle(viennacl::backend::mem_handle const &h)
Definition: vector.hpp:897
DistanceType difference_type
Definition: vector.hpp:372
vcl_ptrdiff_t stride_
Definition: vector.hpp:287
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
const_entry_proxy< SCALARTYPE > operator[](size_type index) const
Read access to a single element of the vector.
Definition: vector.hpp:720
vcl_size_t size_type
Definition: vector.hpp:50
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
const_iterator begin() const
Returns a const-iterator pointing to the beginning of the vector (STL like)
Definition: vector.hpp:837
std::pair< bool, vcl_size_t > index_
Definition: vector.hpp:85
difference_type operator-(self_type const &other) const
Definition: vector.hpp:343
base_type::size_type size_type
Definition: vector.hpp:96
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
const_entry_proxy< SCALARTYPE > operator()(size_type index) const
Read access to a single element of the vector.
Definition: vector.hpp:710
Definition: forwards.h:479
scalar_vector(size_type s, SCALARTYPE val, viennacl::context ctx=viennacl::context())
Definition: vector.hpp:136
void swap(mem_handle &other)
Implements a fast swapping method. No data is copied, only the handles are exchanged.
Definition: mem_handle.hpp:179
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
SCALARTYPE cpu_value_type
Definition: vector.hpp:56
iterator end()
Returns an iterator pointing to the end of the vector (STL like)
Definition: vector.hpp:831
base_type::difference_type difference_type
Definition: vector.hpp:1007
std::ptrdiff_t vcl_ptrdiff_t
Definition: forwards.h:59
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2)
Definition: vector.hpp:1149
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 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
size_type size_
Definition: vector.hpp:84
vcl_size_t index_
Definition: vector.hpp:285
self_type operator++(void)
Definition: vector.hpp:254
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
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
bool empty() const
Returns true is the size is zero.
Definition: vector.hpp:875
Common base class for representing vectors where the entries are not all stored explicitly.
Definition: forwards.h:190
handle_type const & handle() const
Definition: vector.hpp:280
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
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
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
viennacl::backend::mem_handle & handle(T &obj)
Returns the generic memory handle of an object. Non-const version.
Definition: handle.hpp:41
self_type operator++(int)
Definition: vector.hpp:255
const handle_type & handle() const
Returns the memory handle.
Definition: vector.hpp:878
one_vector(size_type s, viennacl::context ctx=viennacl::context())
Definition: vector.hpp:123
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
vcl_size_t size_type
Extracts the vector type from the two operands.
Definition: vector.hpp:175
bool op_aliasing(vector_base< T > const &, B const &)
Definition: op_executor.hpp:35
vector_tuple(VectorType const &v0, VectorType const &v1)
Definition: vector.hpp:1130
Implementation of the ViennaCL scalar class.
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:1284
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:1334
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.
bool operator==(self_type const &other) const
Definition: vector.hpp:257
vector_tuple(VectorType &v0, VectorType &v1)
Definition: vector.hpp:1135
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
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:863
cpu_value_type value() const
Definition: vector.hpp:62
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:799
Main interface routines for memory management.
size_type stride() const
Returns the stride within the buffer (in multiples of sizeof(SCALARTYPE))
Definition: vector.hpp:871
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2, VectorType &v3)
Definition: vector.hpp:1165
std::pair< SCALARTYPE, bool > value_
Definition: vector.hpp:86
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:921
scalar< SCALARTYPE > value_type
Definition: vector.hpp:368
void pad()
Pads vectors with alignment > 1 with trailing zeros if the internal size is larger than the visible s...
Definition: vector.hpp:912
vector(const self_type &v)
Definition: vector.hpp:1052
viennacl::backend::mem_handle handle_type
Definition: vector.hpp:370
vector_base(vector_expression< const LHS, const RHS, OP > const &proxy)
Creates the vector from the supplied random vector.
Definition: vector.hpp:463
vcl_size_t const_size() const
Definition: vector.hpp:1193