ViennaCL - The Vienna Computing Library  1.6.0
Free open-source GPU-accelerated linear algebra and solver library.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
26 #include "viennacl/forwards.h"
29 #include "viennacl/scalar.hpp"
30 #include "viennacl/tools/tools.hpp"
35 #include "viennacl/context.hpp"
37 
38 namespace viennacl
39 {
40 
41 //
42 // Vector expression
43 //
44 
57 template<typename LHS, typename RHS, typename OP>
58 class vector_expression
59 {
60  typedef typename viennacl::result_of::reference_if_nonscalar<LHS>::type lhs_reference_type;
61  typedef typename viennacl::result_of::reference_if_nonscalar<RHS>::type rhs_reference_type;
62 
63 public:
64  enum { alignment = 1 };
65 
69 
70  vector_expression(LHS & l, RHS & r) : lhs_(l), rhs_(r) {}
71 
74  lhs_reference_type lhs() const { return lhs_; }
77  rhs_reference_type rhs() const { return rhs_; }
78 
80  size_type size() const { return viennacl::traits::size(*this); }
81 
82 private:
84  lhs_reference_type lhs_;
86  rhs_reference_type rhs_;
87 };
88 
107 template<class NumericT, unsigned int AlignmentV>
108 class const_vector_iterator
109 {
110  typedef const_vector_iterator<NumericT, AlignmentV> self_type;
111 public:
116 
117  //const_vector_iterator() {}
118 
126  size_type index,
127  size_type start = 0,
128  size_type stride = 1) : elements_(vec.handle()), index_(index), start_(start), stride_(stride) {}
129 
137  size_type index,
138  size_type start = 0,
139  size_type stride = 1) : elements_(elements), index_(index), start_(start), stride_(stride) {}
140 
142  value_type operator*(void) const
143  {
144  value_type result;
146  return result;
147  }
148  self_type operator++(void) { ++index_; return *this; }
149  self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
150 
151  bool operator==(self_type const & other) const { return index_ == other.index_; }
152  bool operator!=(self_type const & other) const { return index_ != other.index_; }
153 
154  // self_type & operator=(self_type const & other)
155  // {
156  // index_ = other._index;
157  // elements_ = other._elements;
158  // return *this;
159  // }
160 
161  difference_type operator-(self_type const & other) const
162  {
163  assert( (other.start_ == start_) && (other.stride_ == stride_) && bool("Iterators are not from the same vector (proxy)!"));
164  return static_cast<difference_type>(index_) - static_cast<difference_type>(other.index_);
165  }
167 
168  //vcl_size_t index() const { return index_; }
170  size_type offset() const { return start_ + index_ * stride(); }
171 
173  size_type stride() const { return stride_; }
174  handle_type const & handle() const { return elements_; }
175 
176 protected:
179  size_type index_; //offset from the beginning of elements_
182 };
183 
184 
204 template<class NumericT, unsigned int AlignmentV>
205 class vector_iterator : public const_vector_iterator<NumericT, AlignmentV>
206 {
208  typedef vector_iterator<NumericT, AlignmentV> self_type;
209 public:
211  typedef typename base_type::size_type size_type;
213 
214  vector_iterator() : base_type(), elements_(NULL) {}
216  size_type index,
217  size_type start = 0,
218  size_type stride = 1) : base_type(elements, index, start, stride), elements_(elements) {}
226  size_type index,
227  size_type start = 0,
228  size_type stride = 1) : base_type(vec, index, start, stride), elements_(vec.handle()) {}
229  //vector_iterator(base_type const & b) : base_type(b) {}
230 
232  {
234  }
235 
236  difference_type operator-(self_type const & other) const { difference_type result = base_type::index_; return (result - static_cast<difference_type>(other.index_)); }
237  self_type operator+(difference_type diff) const { return self_type(elements_, static_cast<vcl_size_t>(static_cast<difference_type>(base_type::index_) + diff), base_type::start_, base_type::stride_); }
238 
239  handle_type & handle() { return elements_; }
240  handle_type const & handle() const { return base_type::elements_; }
241 
242  //operator base_type() const
243  //{
244  // return base_type(base_type::elements_, base_type::index_, base_type::start_, base_type::stride_);
245  //}
246 private:
247  handle_type & elements_;
248 };
249 
250 
251 template<class NumericT, typename SizeT, typename DistanceT>
252 vector_base<NumericT, SizeT, DistanceT>::vector_base() : size_(0), start_(0), stride_(1), internal_size_(0) { /* Note: One must not call ::init() here because a vector might have been created globally before the backend has become available */ }
253 
254 template<class NumericT, typename SizeT, typename DistanceT>
256  size_type vec_size, size_type vec_start, size_type vec_stride)
257  : size_(vec_size), start_(vec_start), stride_(vec_stride), internal_size_(vec_size), elements_(h) {}
258 
259 template<class NumericT, typename SizeT, typename DistanceT>
261  : size_(vec_size), start_(0), stride_(1), internal_size_(viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size))
262 {
263  if (size_ > 0)
264  {
265  viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), ctx);
266  clear();
267  }
268 }
269 
270 // CUDA or host memory:
271 template<class NumericT, typename SizeT, typename DistanceT>
273  : size_(vec_size), start_(start), stride_(stride), internal_size_(vec_size)
274 {
275  if (mem_type == viennacl::CUDA_MEMORY)
276  {
277 #ifdef VIENNACL_WITH_CUDA
279  elements_.cuda_handle().reset(reinterpret_cast<char*>(ptr_to_mem));
280  elements_.cuda_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
281 #else
283 #endif
284  }
285  else if (mem_type == viennacl::MAIN_MEMORY)
286  {
288  elements_.ram_handle().reset(reinterpret_cast<char*>(ptr_to_mem));
289  elements_.ram_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
290  }
291 
292  elements_.raw_size(sizeof(NumericT) * vec_size);
293 
294 }
295 
296 #ifdef VIENNACL_WITH_OPENCL
297 template<class NumericT, typename SizeT, typename DistanceT>
298 vector_base<NumericT, SizeT, DistanceT>::vector_base(cl_mem existing_mem, size_type vec_size, size_type start, size_type stride, viennacl::context ctx)
299  : size_(vec_size), start_(start), stride_(stride), internal_size_(vec_size)
300 {
302  elements_.opencl_handle() = existing_mem;
303  elements_.opencl_handle().inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed.
304  elements_.opencl_handle().context(ctx.opencl_context());
305  elements_.raw_size(sizeof(NumericT) * vec_size);
306 }
307 #endif
308 
309 
310 template<class NumericT, typename SizeT, typename DistanceT>
311 template<typename LHS, typename RHS, typename OP>
313  : size_(viennacl::traits::size(proxy)), start_(0), stride_(1), internal_size_(viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size))
314 {
315  if (size_ > 0)
316  {
317  viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(proxy));
318  clear();
319  }
320  self_type::operator=(proxy);
321 }
322 
323 // Copy CTOR:
324 template<class NumericT, typename SizeT, typename DistanceT>
326  size_(other.size_), start_(0), stride_(1),
327  internal_size_(viennacl::tools::align_to_multiple<size_type>(other.size_, dense_padding_size))
328 {
330  if (internal_size() > 0)
331  {
332  viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(other));
333  clear();
334  self_type::operator=(other);
335  }
336 }
337 
338 
339 
340 template<class NumericT, typename SizeT, typename DistanceT>
342 {
343  assert( ( (vec.size() == size()) || (size() == 0) )
344  && bool("Incompatible vector sizes!"));
345 
346  if (&vec==this)
347  return *this;
348 
349  if (vec.size() > 0)
350  {
351  if (size_ == 0)
352  {
353  size_ = vec.size();
354  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
355  elements_.switch_active_handle_id(vec.handle().get_active_handle_id());
356  viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(vec));
357  pad();
358  }
359 
360  viennacl::linalg::av(*this,
361  vec, cpu_value_type(1.0), 1, false, false);
362  }
363 
364  return *this;
365 }
366 
367 
372 template<class NumericT, typename SizeT, typename DistanceT>
373 template<typename LHS, typename RHS, typename OP>
375 {
376  assert( ( (viennacl::traits::size(proxy) == size()) || (size() == 0) )
377  && bool("Incompatible vector sizes!"));
378 
379  // initialize the necessary buffer
380  if (size() == 0)
381  {
382  size_ = viennacl::traits::size(proxy);
383  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
384  viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), viennacl::traits::context(proxy));
385  pad();
386  }
387 
389 
390  return *this;
391 }
392 
393 // assign vector range or vector slice
394 template<class NumericT, typename SizeT, typename DistanceT>
395 template<typename T>
397 {
398  assert( ( (v1.size() == size()) || (size() == 0) )
399  && bool("Incompatible vector sizes!"));
400 
401  if (size() == 0)
402  {
403  size_ = v1.size();
404  if (size_ > 0)
405  {
406  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
408  pad();
409  }
410  }
411 
412  viennacl::linalg::av(*this,
413  v1, NumericT(1.0), 1, false, false);
414 
415  return *this;
416 }
417 
419 template<class NumericT, typename SizeT, typename DistanceT>
421 {
422  assert( ( (v.size() == size()) || (size() == 0) )
423  && bool("Incompatible vector sizes!"));
424 
425  if (size() == 0)
426  {
427  size_ = v.size();
428  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
429  if (size_ > 0)
430  {
431  viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
432  clear();
433  }
434  }
435  else
436  viennacl::linalg::vector_assign(*this, NumericT(0));
437 
438  if (size_ > 0)
439  this->operator()(v.index()) = NumericT(1);
440 
441  return *this;
442 }
443 
445 template<class NumericT, typename SizeT, typename DistanceT>
447 {
448  assert( ( (v.size() == size()) || (size() == 0) )
449  && bool("Incompatible vector sizes!"));
450 
451  if (size() == 0)
452  {
453  size_ = v.size();
454  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
455  if (size_ > 0)
456  {
457  viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
458  clear();
459  }
460  }
461  else
462  viennacl::linalg::vector_assign(*this, NumericT(0));
463 
464  return *this;
465 }
466 
468 template<class NumericT, typename SizeT, typename DistanceT>
470 {
471  assert( ( (v.size() == size()) || (size() == 0) )
472  && bool("Incompatible vector sizes!"));
473 
474  if (size() == 0)
475  {
476  size_ = v.size();
477  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
478  if (size_ > 0)
479  {
480  viennacl::backend::memory_create(elements_, sizeof(NumericT)*internal_size(), v.context());
481  pad();
482  }
483  }
484 
485  if (size_ > 0)
486  viennacl::linalg::vector_assign(*this, v[0]);
487 
488  return *this;
489 }
490 
491 
492 
494 
495 //Note: The following operator overloads are defined in matrix_operations.hpp, compressed_matrix_operations.hpp and coordinate_matrix_operations.hpp
496 //This is certainly not the nicest approach and will most likely by changed in the future, but it works :-)
497 
498 //matrix<>
499 template<class NumericT, typename SizeT, typename DistanceT>
501 {
502  assert(viennacl::traits::size1(proxy.lhs()) == size() && bool("Size check failed for v1 = A * v2: size1(A) != size(v1)"));
503 
504  // check for the special case x = A * x
505  if (viennacl::traits::handle(proxy.rhs()) == viennacl::traits::handle(*this))
506  {
508  viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
509  *this = result;
510  }
511  else
512  {
513  viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
514  }
515  return *this;
516 }
517 
518 
519 //transposed_matrix_proxy:
520 template<class NumericT, typename SizeT, typename DistanceT>
522  const vector_base<NumericT>,
523  op_prod> & proxy)
524 {
525  assert(viennacl::traits::size1(proxy.lhs()) == size() && bool("Size check failed in v1 = trans(A) * v2: size2(A) != size(v1)"));
526 
527  // check for the special case x = trans(A) * x
528  if (viennacl::traits::handle(proxy.rhs()) == viennacl::traits::handle(*this))
529  {
531  viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
532  *this = result;
533  }
534  else
535  {
536  viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
537  }
538  return *this;
539 }
540 
542 
543 
545 //read-write access to an element of the vector
546 
547 template<class NumericT, typename SizeT, typename DistanceT>
549 {
550  assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
551  assert( index < size() && bool("Index out of bounds!") );
552 
553  return entry_proxy<NumericT>(start_ + stride_ * index, elements_);
554 }
555 
556 template<class NumericT, typename SizeT, typename DistanceT>
558 {
559  assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
560  assert( index < size() && bool("Index out of bounds!") );
561 
562  return entry_proxy<NumericT>(start_ + stride_ * index, elements_);
563 }
564 
565 template<class NumericT, typename SizeT, typename DistanceT>
567 {
568  assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
569  assert( index < size() && bool("Index out of bounds!") );
570 
571  return const_entry_proxy<NumericT>(start_ + stride_ * index, elements_);
572 }
573 
574 template<class NumericT, typename SizeT, typename DistanceT>
576 {
577  assert( (size() > 0) && bool("Cannot apply operator() to vector of size zero!"));
578  assert( index < size() && bool("Index out of bounds!") );
579 
580  return const_entry_proxy<NumericT>(start_ + stride_ * index, elements_);
581 }
582 
584 
585 
586 //
587 // Operator overloads with implicit conversion (thus cannot be made global without introducing additional headache)
588 //
589 template<class NumericT, typename SizeT, typename DistanceT>
591 {
592  assert(vec.size() == size() && bool("Incompatible vector sizes!"));
593 
594  if (size() > 0)
596  *this, NumericT(1.0), 1, false, false,
597  vec, NumericT(1.0), 1, false, false);
598  return *this;
599 }
600 
601 template<class NumericT, typename SizeT, typename DistanceT>
603 {
604  assert(vec.size() == size() && bool("Incompatible vector sizes!"));
605 
606  if (size() > 0)
608  *this, NumericT(1.0), 1, false, false,
609  vec, NumericT(-1.0), 1, false, false);
610  return *this;
611 }
612 
614 template<class NumericT, typename SizeT, typename DistanceT>
616 {
617  if (size() > 0)
618  viennacl::linalg::av(*this,
619  *this, NumericT(val), 1, false, false);
620  return *this;
621 }
623 template<class NumericT, typename SizeT, typename DistanceT>
625 {
626  if (size() > 0)
627  viennacl::linalg::av(*this,
628  *this, NumericT(val), 1, false, false);
629  return *this;
630 }
632 template<class NumericT, typename SizeT, typename DistanceT>
634 {
635  if (size() > 0)
636  viennacl::linalg::av(*this,
637  *this, NumericT(val), 1, false, false);
638  return *this;
639 }
641 template<class NumericT, typename SizeT, typename DistanceT>
643 {
644  if (size() > 0)
645  viennacl::linalg::av(*this,
646  *this, NumericT(val), 1, false, false);
647  return *this;
648 }
650 template<class NumericT, typename SizeT, typename DistanceT>
652 {
653  if (size() > 0)
654  viennacl::linalg::av(*this,
655  *this, NumericT(val), 1, false, false);
656  return *this;
657 }
659 template<class NumericT, typename SizeT, typename DistanceT>
661 {
662  if (size() > 0)
663  viennacl::linalg::av(*this,
664  *this, NumericT(val), 1, false, false);
665  return *this;
666 }
667 
668 
670 template<class NumericT, typename SizeT, typename DistanceT>
672 {
673  if (size() > 0)
674  viennacl::linalg::av(*this,
675  *this, NumericT(val), 1, true, false);
676  return *this;
677 }
679 template<class NumericT, typename SizeT, typename DistanceT>
681 {
682  if (size() > 0)
683  viennacl::linalg::av(*this,
684  *this, NumericT(val), 1, true, false);
685  return *this;
686 }
688 template<class NumericT, typename SizeT, typename DistanceT>
690 {
691  if (size() > 0)
692  viennacl::linalg::av(*this,
693  *this, NumericT(val), 1, true, false);
694  return *this;
695 }
697 template<class NumericT, typename SizeT, typename DistanceT>
699 {
700  if (size() > 0)
701  viennacl::linalg::av(*this,
702  *this, NumericT(val), 1, true, false);
703  return *this;
704 }
706 template<class NumericT, typename SizeT, typename DistanceT>
708 {
709  if (size() > 0)
710  viennacl::linalg::av(*this,
711  *this, NumericT(val), 1, true, false);
712  return *this;
713 }
715 template<class NumericT, typename SizeT, typename DistanceT>
717 {
718  if (size() > 0)
719  viennacl::linalg::av(*this,
720  *this, NumericT(val), 1, true, false);
721  return *this;
722 }
723 
724 
726 template<class NumericT, typename SizeT, typename DistanceT>
729 {
731 }
733 template<class NumericT, typename SizeT, typename DistanceT>
736 {
738 }
740 template<class NumericT, typename SizeT, typename DistanceT>
743 {
745 }
747 template<class NumericT, typename SizeT, typename DistanceT>
750 {
752 }
754 template<class NumericT, typename SizeT, typename DistanceT>
757 {
759 }
761 template<class NumericT, typename SizeT, typename DistanceT>
764 {
766 }
767 
768 
770 template<class NumericT, typename SizeT, typename DistanceT>
773 {
775 }
777 template<class NumericT, typename SizeT, typename DistanceT>
780 {
782 }
784 template<class NumericT, typename SizeT, typename DistanceT>
787 {
789 }
791 template<class NumericT, typename SizeT, typename DistanceT>
794 {
796 }
798 template<class NumericT, typename SizeT, typename DistanceT>
801 {
803 }
805 template<class NumericT, typename SizeT, typename DistanceT>
808 {
810 }
811 
812 
814 template<class NumericT, typename SizeT, typename DistanceT>
817 {
819 }
820 
821 //
823 //
824 
826 template<class NumericT, typename SizeT, typename DistanceT>
828 {
829  return iterator(*this, 0, start_, stride_);
830 }
831 
833 template<class NumericT, typename SizeT, typename DistanceT>
835 {
836  return iterator(*this, size(), start_, stride_);
837 }
838 
840 template<class NumericT, typename SizeT, typename DistanceT>
842 {
843  return const_iterator(*this, 0, start_, stride_);
844 }
845 
846 template<class NumericT, typename SizeT, typename DistanceT>
848 {
849  return const_iterator(*this, size(), start_, stride_);
850 }
851 
852 template<class NumericT, typename SizeT, typename DistanceT>
854 {
855  viennacl::linalg::vector_swap(*this, other);
856  return *this;
857 }
858 
859 
860 template<class NumericT, typename SizeT, typename DistanceT>
862 {
864 }
865 
866 template<class NumericT, typename SizeT, typename DistanceT>
868 {
869  assert(this->size_ == other.size_ && bool("Vector size mismatch"));
870  this->elements_.swap(other.elements_);
871  return *this;
872 }
873 
874 template<class NumericT, typename SizeT, typename DistanceT>
876 {
877  if (internal_size() != size())
878  {
879  std::vector<NumericT> pad(internal_size() - size());
880  viennacl::backend::memory_write(elements_, sizeof(NumericT) * size(), sizeof(NumericT) * pad.size(), &(pad[0]));
881  }
882 }
883 
884 template<class NumericT, typename SizeT, typename DistanceT>
886 {
887  viennacl::backend::switch_memory_context<NumericT>(elements_, new_ctx);
888 }
889 
890 //TODO: Think about implementing the following public member functions
891 //void insert_element(unsigned int i, NumericT val){}
892 //void erase_element(unsigned int i){}
893 
894 template<class NumericT, typename SizeT, typename DistanceT>
896 {
897  resize_impl(new_size, viennacl::traits::context(*this), preserve);
898 }
899 
900 template<class NumericT, typename SizeT, typename DistanceT>
902 {
903  resize_impl(new_size, ctx, preserve);
904 }
905 
906 template<class NumericT, typename SizeT, typename DistanceT>
907 void vector_base<NumericT, SizeT, DistanceT>::resize_impl(size_type new_size, viennacl::context ctx, bool preserve)
908 {
909  assert(new_size > 0 && bool("Positive size required when resizing vector!"));
910 
911  if (new_size != size_)
912  {
913  vcl_size_t new_internal_size = viennacl::tools::align_to_multiple<vcl_size_t>(new_size, dense_padding_size);
914 
915  std::vector<NumericT> temp(size_);
916  if (preserve && size_ > 0)
917  fast_copy(*this, temp);
918  temp.resize(new_size); //drop all entries above new_size
919  temp.resize(new_internal_size); //enlarge to fit new internal size
920 
921  if (new_internal_size != internal_size())
922  {
923  viennacl::backend::memory_create(elements_, sizeof(NumericT)*new_internal_size, ctx, NULL);
924  }
925 
926  fast_copy(temp, *this);
927  size_ = new_size;
928  internal_size_ = viennacl::tools::align_to_multiple<size_type>(size_, dense_padding_size);
929  pad();
930  }
931 
932 }
933 
934 
935 template<class NumericT, unsigned int AlignmentV>
936 class vector : public vector_base<NumericT>
937 {
938  typedef vector<NumericT, AlignmentV> self_type;
939  typedef vector_base<NumericT> base_type;
940 
941 public:
942  typedef typename base_type::size_type size_type;
944 
947  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 */ }
948 
953  explicit vector(size_type vec_size) : base_type(vec_size) {}
954 
955  explicit vector(size_type vec_size, viennacl::context ctx) : base_type(vec_size, ctx) {}
956 
957  explicit vector(NumericT * ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start = 0, size_type stride = 1)
958  : base_type(ptr_to_mem, mem_type, vec_size, start, stride) {}
959 
960 #ifdef VIENNACL_WITH_OPENCL
961 
969  explicit vector(cl_mem existing_mem, size_type vec_size, size_type start = 0, size_type stride = 1) : base_type(existing_mem, vec_size, start, stride) {}
970 
976  explicit vector(size_type vec_size, viennacl::ocl::context const & ctx) : base_type(vec_size, ctx) {}
977 #endif
978 
979  template<typename LHS, typename RHS, typename OP>
981 
982  vector(const base_type & v) : base_type(v.size(), viennacl::traits::context(v))
983  {
984  if (v.size() > 0)
985  base_type::operator=(v);
986  }
987 
988  vector(const self_type & v) : base_type(v.size(), viennacl::traits::context(v))
989  {
990  if (v.size() > 0)
991  base_type::operator=(v);
992  }
993 
996  {
997  if (v.size() > 0)
998  this->operator()(v.index()) = NumericT(1);;
999  }
1000 
1003  {
1004  if (v.size() > 0)
1005  viennacl::linalg::vector_assign(*this, NumericT(0.0));
1006  }
1007 
1010  {
1011  if (v.size() > 0)
1012  viennacl::linalg::vector_assign(*this, v[0]);
1013  }
1014 
1015  // the following is used to circumvent an issue with Clang 3.0 when 'using base_type::operator=;' directly
1016  template<typename T>
1017  self_type & operator=(T const & other)
1018  {
1019  base_type::operator=(other);
1020  return *this;
1021  }
1022 
1023  using base_type::operator+=;
1024  using base_type::operator-=;
1025 
1026  //enlarge or reduce allocated memory and set unused memory to zero
1032  void resize(size_type new_size, bool preserve = true)
1033  {
1034  base_type::resize(new_size, preserve);
1035  }
1036 
1037  void resize(size_type new_size, viennacl::context ctx, bool preserve = true)
1038  {
1039  base_type::resize(new_size, ctx, preserve);
1040  }
1041 
1045  {
1046  base_type::fast_swap(other);
1047  return *this;
1048  }
1049 
1051  {
1053  }
1054 
1055 }; //vector
1056 
1058 template<typename ScalarT>
1059 class vector_tuple
1060 {
1061  typedef vector_base<ScalarT> VectorType;
1062 
1063 public:
1064  // 2 vectors
1065 
1066  vector_tuple(VectorType const & v0, VectorType const & v1) : const_vectors_(2), non_const_vectors_()
1067  {
1068  const_vectors_[0] = &v0;
1069  const_vectors_[1] = &v1;
1070  }
1071  vector_tuple(VectorType & v0, VectorType & v1) : const_vectors_(2), non_const_vectors_(2)
1072  {
1073  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1074  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1075  }
1076 
1077  // 3 vectors
1078 
1079  vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2) : const_vectors_(3), non_const_vectors_()
1080  {
1081  const_vectors_[0] = &v0;
1082  const_vectors_[1] = &v1;
1083  const_vectors_[2] = &v2;
1084  }
1085  vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2) : const_vectors_(3), non_const_vectors_(3)
1086  {
1087  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1088  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1089  const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
1090  }
1091 
1092  // 4 vectors
1093 
1094  vector_tuple(VectorType const & v0, VectorType const & v1, VectorType const & v2, VectorType const & v3) : const_vectors_(4), non_const_vectors_()
1095  {
1096  const_vectors_[0] = &v0;
1097  const_vectors_[1] = &v1;
1098  const_vectors_[2] = &v2;
1099  const_vectors_[3] = &v3;
1100  }
1101  vector_tuple(VectorType & v0, VectorType & v1, VectorType & v2, VectorType & v3) : const_vectors_(4), non_const_vectors_(4)
1102  {
1103  const_vectors_[0] = &v0; non_const_vectors_[0] = &v0;
1104  const_vectors_[1] = &v1; non_const_vectors_[1] = &v1;
1105  const_vectors_[2] = &v2; non_const_vectors_[2] = &v2;
1106  const_vectors_[3] = &v3; non_const_vectors_[3] = &v3;
1107  }
1108 
1109  // add more overloads here
1110 
1111  // generic interface:
1112 
1113  vector_tuple(std::vector<VectorType const *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_()
1114  {
1115  for (vcl_size_t i=0; i<vecs.size(); ++i)
1116  const_vectors_[i] = vecs[i];
1117  }
1118 
1119  vector_tuple(std::vector<VectorType *> const & vecs) : const_vectors_(vecs.size()), non_const_vectors_(vecs.size())
1120  {
1121  for (vcl_size_t i=0; i<vecs.size(); ++i)
1122  {
1123  const_vectors_[i] = vecs[i];
1124  non_const_vectors_[i] = vecs[i];
1125  }
1126  }
1127 
1128  vcl_size_t size() const { return non_const_vectors_.size(); }
1129  vcl_size_t const_size() const { return const_vectors_.size(); }
1130 
1131  VectorType & at(vcl_size_t i) const { return *(non_const_vectors_.at(i)); }
1132  VectorType const & const_at(vcl_size_t i) const { return *(const_vectors_.at(i)); }
1133 
1134 private:
1135  std::vector<VectorType const *> const_vectors_;
1136  std::vector<VectorType *> non_const_vectors_;
1137 };
1138 
1139 // 2 args
1140 template<typename ScalarT>
1142 
1143 template<typename ScalarT>
1145 
1146 // 3 args
1147 template<typename ScalarT>
1149 
1150 template<typename ScalarT>
1152 
1153 // 4 args
1154 template<typename ScalarT>
1156 {
1157  return vector_tuple<ScalarT>(v0, v1, v2, v3);
1158 }
1159 
1160 template<typename ScalarT>
1162 {
1163  return vector_tuple<ScalarT>(v0, v1, v2, v3);
1164 }
1165 
1166 // 5 args
1167 template<typename ScalarT>
1169  vector_base<ScalarT> const & v1,
1170  vector_base<ScalarT> const & v2,
1171  vector_base<ScalarT> const & v3,
1172  vector_base<ScalarT> const & v4)
1173 {
1174  typedef vector_base<ScalarT> const * VectorPointerType;
1175  std::vector<VectorPointerType> vec(5);
1176  vec[0] = &v0;
1177  vec[1] = &v1;
1178  vec[2] = &v2;
1179  vec[3] = &v3;
1180  vec[4] = &v4;
1181  return vector_tuple<ScalarT>(vec);
1182 }
1183 
1184 template<typename ScalarT>
1188  vector_base<ScalarT> & v3,
1189  vector_base<ScalarT> & v4)
1190 {
1191  typedef vector_base<ScalarT> * VectorPointerType;
1192  std::vector<VectorPointerType> vec(5);
1193  vec[0] = &v0;
1194  vec[1] = &v1;
1195  vec[2] = &v2;
1196  vec[3] = &v3;
1197  vec[4] = &v4;
1198  return vector_tuple<ScalarT>(vec);
1199 }
1200 
1201 // TODO: Add more arguments to tie() here. Maybe use some preprocessor magic to accomplish this.
1202 
1203 //
1205 //
1206 
1207 
1219 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1222  CPU_ITERATOR cpu_begin )
1223 {
1224  if (gpu_begin != gpu_end)
1225  {
1226  if (gpu_begin.stride() == 1)
1227  {
1229  sizeof(NumericT)*gpu_begin.offset(),
1230  sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(gpu_end - gpu_begin),
1231  &(*cpu_begin));
1232  }
1233  else
1234  {
1235  vcl_size_t gpu_size = static_cast<vcl_size_t>(gpu_end - gpu_begin);
1236  std::vector<NumericT> temp_buffer(gpu_begin.stride() * gpu_size);
1237  viennacl::backend::memory_read(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
1238 
1239  for (vcl_size_t i=0; i<gpu_size; ++i)
1240  {
1241  (&(*cpu_begin))[i] = temp_buffer[i * gpu_begin.stride()];
1242  }
1243  }
1244  }
1245 }
1246 
1252 template<typename NumericT, typename CPUVECTOR>
1253 void fast_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1254 {
1255  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1256 }
1257 
1258 
1269 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1272  CPU_ITERATOR cpu_begin )
1273 {
1274  if (gpu_begin != gpu_end)
1275  {
1276  if (gpu_begin.stride() == 1)
1277  {
1279  sizeof(NumericT)*gpu_begin.offset(),
1280  sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(gpu_end - gpu_begin),
1281  &(*cpu_begin),
1282  true);
1283  }
1284  else // no async copy possible, so fall-back to fast_copy
1285  fast_copy(gpu_begin, gpu_end, cpu_begin);
1286  }
1287 }
1288 
1294 template<typename NumericT, typename CPUVECTOR>
1295 void async_copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1296 {
1297  viennacl::async_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1298 }
1299 
1300 
1307 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1310  CPU_ITERATOR cpu_begin )
1311 {
1312  assert(gpu_end - gpu_begin >= 0 && bool("Iterators incompatible"));
1313  if (gpu_end - gpu_begin != 0)
1314  {
1315  std::vector<NumericT> temp_buffer(static_cast<vcl_size_t>(gpu_end - gpu_begin));
1316  fast_copy(gpu_begin, gpu_end, temp_buffer.begin());
1317 
1318  //now copy entries to cpu_vec:
1319  std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_begin);
1320  }
1321 }
1322 
1329 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1331  const vector_iterator<NumericT, AlignmentV> & gpu_end,
1332  CPU_ITERATOR cpu_begin )
1333 
1334 {
1337  cpu_begin);
1338 }
1339 
1345 template<typename NumericT, typename CPUVECTOR>
1346 void copy(vector_base<NumericT> const & gpu_vec, CPUVECTOR & cpu_vec )
1347 {
1348  viennacl::copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
1349 }
1350 
1351 
1352 
1353 #ifdef VIENNACL_WITH_EIGEN
1354 template<unsigned int AlignmentV>
1355 void copy(vector<float, AlignmentV> const & gpu_vec,
1356  Eigen::VectorXf & eigen_vec)
1357 {
1358  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
1359 }
1360 
1361 template<unsigned int AlignmentV>
1362 void copy(vector<double, AlignmentV> & gpu_vec,
1363  Eigen::VectorXd & eigen_vec)
1364 {
1365  viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
1366 }
1367 #endif
1368 
1369 
1370 //
1372 //
1373 
1385 template<typename CPU_ITERATOR, typename NumericT, unsigned int AlignmentV>
1386 void fast_copy(CPU_ITERATOR const & cpu_begin,
1387  CPU_ITERATOR const & cpu_end,
1389 {
1390  if (cpu_end - cpu_begin > 0)
1391  {
1392  if (gpu_begin.stride() == 1)
1393  {
1395  sizeof(NumericT)*gpu_begin.offset(),
1396  sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(cpu_end - cpu_begin), &(*cpu_begin));
1397  }
1398  else //writing to slice:
1399  {
1400  vcl_size_t cpu_size = static_cast<vcl_size_t>(cpu_end - cpu_begin);
1401  std::vector<NumericT> temp_buffer(gpu_begin.stride() * cpu_size);
1402 
1403  viennacl::backend::memory_read(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
1404 
1405  for (vcl_size_t i=0; i<cpu_size; ++i)
1406  temp_buffer[i * gpu_begin.stride()] = (&(*cpu_begin))[i];
1407 
1408  viennacl::backend::memory_write(gpu_begin.handle(), sizeof(NumericT)*gpu_begin.offset(), sizeof(NumericT)*temp_buffer.size(), &(temp_buffer[0]));
1409  }
1410  }
1411 }
1412 
1413 
1419 template<typename CPUVECTOR, typename NumericT>
1420 void fast_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
1421 {
1422  viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1423 }
1424 
1435 template<typename CPU_ITERATOR, typename NumericT, unsigned int AlignmentV>
1436 void async_copy(CPU_ITERATOR const & cpu_begin,
1437  CPU_ITERATOR const & cpu_end,
1439 {
1440  if (cpu_end - cpu_begin > 0)
1441  {
1442  if (gpu_begin.stride() == 1)
1443  {
1445  sizeof(NumericT)*gpu_begin.offset(),
1446  sizeof(NumericT)*gpu_begin.stride() * static_cast<vcl_size_t>(cpu_end - cpu_begin), &(*cpu_begin),
1447  true);
1448  }
1449  else // fallback to blocking copy. There's nothing we can do to prevent this
1450  fast_copy(cpu_begin, cpu_end, gpu_begin);
1451  }
1452 }
1453 
1454 
1460 template<typename CPUVECTOR, typename NumericT>
1461 void async_copy(const CPUVECTOR & cpu_vec, vector_base<NumericT> & gpu_vec)
1462 {
1463  viennacl::async_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1464 }
1465 
1466 //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
1473 template<typename NumericT, unsigned int AlignmentV, typename CPU_ITERATOR>
1474 void copy(CPU_ITERATOR const & cpu_begin,
1475  CPU_ITERATOR const & cpu_end,
1477 {
1478  assert(cpu_end - cpu_begin > 0 && bool("Iterators incompatible"));
1479  if (cpu_begin != cpu_end)
1480  {
1481  //we require that the size of the gpu_vector is larger or equal to the cpu-size
1482  std::vector<NumericT> temp_buffer(static_cast<vcl_size_t>(cpu_end - cpu_begin));
1483  std::copy(cpu_begin, cpu_end, temp_buffer.begin());
1484  viennacl::fast_copy(temp_buffer.begin(), temp_buffer.end(), gpu_begin);
1485  }
1486 }
1487 
1488 // for things like copy(std_vec.begin(), std_vec.end(), vcl_vec.begin() + 1);
1489 
1495 template<typename HostVectorT, typename T>
1496 void copy(HostVectorT const & cpu_vec, vector_base<T> & gpu_vec)
1497 {
1498  viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1499 }
1500 
1506 template<typename HostVectorT, typename T, unsigned int AlignmentV>
1507 void copy(HostVectorT const & cpu_vec, vector<T, AlignmentV> & gpu_vec)
1508 {
1509  if (gpu_vec.size() == 0)
1510  gpu_vec.resize(static_cast<vcl_size_t>(cpu_vec.end() - cpu_vec.begin()));
1511  viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
1512 }
1513 
1514 
1515 #ifdef VIENNACL_WITH_EIGEN
1516 template<unsigned int AlignmentV>
1517 void copy(Eigen::VectorXf const & eigen_vec,
1518  vector<float, AlignmentV> & gpu_vec)
1519 {
1520  std::vector<float> entries(eigen_vec.size());
1521  for (vcl_size_t i = 0; i<entries.size(); ++i)
1522  entries[i] = eigen_vec(i);
1523  viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
1524 }
1525 
1526 template<unsigned int AlignmentV>
1527 void copy(Eigen::VectorXd const & eigen_vec,
1528  vector<double, AlignmentV> & gpu_vec)
1529 {
1530  std::vector<double> entries(eigen_vec.size());
1531  for (vcl_size_t i = 0; i<entries.size(); ++i)
1532  entries[i] = eigen_vec(i);
1533  viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
1534 }
1535 #endif
1536 
1537 
1538 
1539 //
1541 //
1548 template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
1552 {
1553  assert(gpu_src_end - gpu_src_begin >= 0);
1554  assert(gpu_src_begin.stride() == 1 && bool("ViennaCL ERROR: copy() for GPU->GPU not implemented for slices! Use operator= instead for the moment."));
1555 
1556  if (gpu_src_begin.stride() == 1 && gpu_dest_begin.stride() == 1)
1557  {
1558  if (gpu_src_begin != gpu_src_end)
1559  viennacl::backend::memory_copy(gpu_src_begin.handle(), gpu_dest_begin.handle(),
1560  sizeof(NumericT) * gpu_src_begin.offset(),
1561  sizeof(NumericT) * gpu_dest_begin.offset(),
1562  sizeof(NumericT) * (gpu_src_end.offset() - gpu_src_begin.offset()));
1563  }
1564  else
1565  {
1566  assert( false && bool("not implemented yet"));
1567  }
1568 }
1569 
1576 template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
1578  vector_iterator<NumericT, AlignmentV_SRC> const & gpu_src_end,
1580 {
1582  static_cast<const_vector_iterator<NumericT, AlignmentV_SRC> >(gpu_src_end),
1583  gpu_dest_begin);
1584 }
1585 
1591 template<typename NumericT, unsigned int AlignmentV_SRC, unsigned int AlignmentV_DEST>
1592 void copy(vector<NumericT, AlignmentV_SRC> const & gpu_src_vec,
1593  vector<NumericT, AlignmentV_DEST> & gpu_dest_vec )
1594 {
1595  viennacl::copy(gpu_src_vec.begin(), gpu_src_vec.end(), gpu_dest_vec.begin());
1596 }
1597 
1598 
1599 
1600 
1601 
1602 
1603 //global functions for handling vectors:
1608 template<typename T>
1609 std::ostream & operator<<(std::ostream & os, vector_base<T> const & val)
1610 {
1611  std::vector<T> tmp(val.size());
1612  viennacl::copy(val.begin(), val.end(), tmp.begin());
1613  os << "[" << val.size() << "](";
1614  for (typename std::vector<T>::size_type i=0; i<val.size(); ++i)
1615  {
1616  if (i > 0)
1617  os << ",";
1618  os << tmp[i];
1619  }
1620  os << ")";
1621  return os;
1622 }
1623 
1624 template<typename LHS, typename RHS, typename OP>
1625 std::ostream & operator<<(std::ostream & os, vector_expression<LHS, RHS, OP> const & proxy)
1626 
1627 {
1629  viennacl::vector<ScalarType> result = proxy;
1630  os << result;
1631  return os;
1632 }
1633 
1639 template<typename T>
1640 void swap(vector_base<T> & vec1, vector_base<T> & vec2)
1641 {
1642  viennacl::linalg::vector_swap(vec1, vec2);
1643 }
1644 
1650 template<typename NumericT, unsigned int AlignmentV>
1653 {
1654  return v1.fast_swap(v2);
1655 }
1656 
1657 
1658 
1659 
1660 
1661 //
1662 //
1664 //
1665 //
1666 
1667 
1668 //
1669 // operator *=
1670 //
1671 
1674 template<typename T, typename S1>
1676 vector_base<T> &
1677 >::type
1678 operator *= (vector_base<T> & v1, S1 const & gpu_val)
1679 {
1681  if (v1.size() > 0)
1683  v1, gpu_val, 1, false, flip_sign);
1684  return v1;
1685 }
1686 
1687 
1688 //
1689 // operator /=
1690 //
1691 
1692 
1695 template<typename T, typename S1>
1697 vector_base<T> &
1698 >::type
1699 operator /= (vector_base<T> & v1, S1 const & gpu_val)
1700 {
1702  if (v1.size() > 0)
1704  v1, gpu_val, 1, true, flip_sign);
1705  return v1;
1706 }
1707 
1708 
1709 //
1710 // operator +
1711 //
1712 
1713 
1719 template<typename LHS1, typename RHS1, typename OP1,
1720  typename LHS2, typename RHS2, typename OP2>
1721 vector_expression< const vector_expression< LHS1, RHS1, OP1>,
1722 const vector_expression< LHS2, RHS2, OP2>,
1725  vector_expression<LHS2, RHS2, OP2> const & proxy2)
1726 {
1727  assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
1730  viennacl::op_add>(proxy1, proxy2);
1731 }
1732 
1738 template<typename LHS, typename RHS, typename OP, typename T>
1739 vector_expression< const vector_expression<LHS, RHS, OP>,
1740 const vector_base<T>,
1743  vector_base<T> const & vec)
1744 {
1745  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1747  const vector_base<T>,
1748  viennacl::op_add>(proxy, vec);
1749 }
1750 
1756 template<typename T, typename LHS, typename RHS, typename OP>
1757 vector_expression< const vector_base<T>,
1758 const vector_expression<LHS, RHS, OP>,
1761  vector_expression<LHS, RHS, OP> const & proxy)
1762 {
1763  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1766  viennacl::op_add>(vec, proxy);
1767 }
1768 
1771 template<typename T>
1772 vector_expression< const vector_base<T>, const vector_base<T>, op_add>
1774 {
1776 }
1777 
1778 
1779 
1780 //
1781 // operator -
1782 //
1783 
1789 template<typename LHS1, typename RHS1, typename OP1,
1790  typename LHS2, typename RHS2, typename OP2>
1791 vector_expression< const vector_expression< LHS1, RHS1, OP1>,
1792 const vector_expression< LHS2, RHS2, OP2>,
1795  vector_expression<LHS2, RHS2, OP2> const & proxy2)
1796 {
1797  assert(proxy1.size() == proxy2.size() && bool("Incompatible vector sizes!"));
1800  viennacl::op_sub>(proxy1, proxy2);
1801 }
1802 
1803 
1809 template<typename LHS, typename RHS, typename OP, typename T>
1810 vector_expression< const vector_expression<LHS, RHS, OP>,
1811 const vector_base<T>,
1814  vector_base<T> const & vec)
1815 {
1816  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1818  const vector_base<T>,
1819  viennacl::op_sub>(proxy, vec);
1820 }
1821 
1827 template<typename T, typename LHS, typename RHS, typename OP>
1828 vector_expression< const vector_base<T>,
1829 const vector_expression<LHS, RHS, OP>,
1832  vector_expression<LHS, RHS, OP> const & proxy)
1833 {
1834  assert(proxy.size() == vec.size() && bool("Incompatible vector sizes!"));
1837  viennacl::op_sub>(vec, proxy);
1838 }
1839 
1842 template<typename T>
1843 vector_expression< const vector_base<T>, const vector_base<T>, op_sub>
1845 {
1847 }
1848 
1849 
1850 //
1851 // operator *
1852 //
1853 
1854 
1860 template<typename S1, typename T>
1862 vector_expression< const vector_base<T>, const S1, op_mult> >::type
1863 operator * (S1 const & value, vector_base<T> const & vec)
1864 {
1865  return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
1866 }
1867 
1873 template<typename T>
1874 vector_expression< const vector_base<T>, const T, op_mult>
1875 operator * (char value, vector_base<T> const & vec)
1876 {
1877  return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1878 }
1879 
1885 template<typename T>
1886 vector_expression< const vector_base<T>, const T, op_mult>
1887 operator * (short value, vector_base<T> const & vec)
1888 {
1889  return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1890 }
1891 
1897 template<typename T>
1898 vector_expression< const vector_base<T>, const T, op_mult>
1899 operator * (int value, vector_base<T> const & vec)
1900 {
1901  return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1902 }
1903 
1909 template<typename T>
1910 vector_expression< const vector_base<T>, const T, op_mult>
1911 operator * (long value, vector_base<T> const & vec)
1912 {
1913  return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1914 }
1915 
1921 template<typename T>
1922 vector_expression< const vector_base<T>, const T, op_mult>
1923 operator * (float value, vector_base<T> const & vec)
1924 {
1925  return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1926 }
1927 
1933 template<typename T>
1934 vector_expression< const vector_base<T>, const T, op_mult>
1935 operator * (double value, vector_base<T> const & vec)
1936 {
1937  return vector_expression< const vector_base<T>, const T, op_mult>(vec, T(value));
1938 }
1939 
1940 
1941 
1947 template<typename LHS, typename RHS, typename OP, typename T>
1948 vector_expression< const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult>
1950 {
1952 }
1953 
1956 template<typename T, typename S1>
1958 vector_expression< const vector_base<T>, const S1, op_mult> >::type
1959 operator * (vector_base<T> const & vec, S1 const & value)
1960 {
1961  return vector_expression< const vector_base<T>, const S1, op_mult>(vec, value);
1962 }
1963 
1964 template<typename T>
1965 vector_expression< const vector_base<T>, const T, op_mult>
1966 operator * (vector_base<T> const & vec, T const & value)
1967 {
1968  return vector_expression< const vector_base<T>, const T, op_mult>(vec, value);
1969 }
1970 
1976 template<typename LHS, typename RHS, typename OP, typename S1>
1980  S1 const & val)
1981 {
1983 }
1984 
1990 template<typename S1, typename LHS, typename RHS, typename OP>
1993 operator * (S1 const & val,
1994  vector_expression<LHS, RHS, OP> const & proxy)
1995 {
1997 }
1998 
1999 //
2000 // operator /
2001 //
2002 
2008 template<typename S1, typename LHS, typename RHS, typename OP>
2012  S1 const & val)
2013 {
2015 }
2016 
2017 
2020 template<typename T, typename S1>
2022 vector_expression< const vector_base<T>, const S1, op_div> >::type
2023 operator / (vector_base<T> const & v1, S1 const & s1)
2024 {
2025  return vector_expression<const vector_base<T>, const S1, op_div>(v1, s1);
2026 }
2027 
2028 
2029 
2030 //
2031 // Specify available operations:
2032 //
2033 
2036 namespace linalg
2037 {
2038 namespace detail
2039 {
2040  // x = y
2041  template<typename T>
2042  struct op_executor<vector_base<T>, op_assign, vector_base<T> >
2043  {
2044  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2045  {
2046  viennacl::linalg::av(lhs, rhs, T(1), 1, false, false);
2047  }
2048  };
2049 
2050  // x = inner_prod(z, {y0, y1, ...})
2051  template<typename T>
2052  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> >
2053  {
2054  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_tuple<T>, op_inner_prod> const & rhs)
2055  {
2056  viennacl::linalg::inner_prod_impl(rhs.lhs(), rhs.rhs(), lhs);
2057  }
2058  };
2059 
2060  // x += y
2061  template<typename T>
2062  struct op_executor<vector_base<T>, op_inplace_add, vector_base<T> >
2063  {
2064  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2065  {
2066  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, false);
2067  }
2068  };
2069 
2070  // x -= y
2071  template<typename T>
2072  struct op_executor<vector_base<T>, op_inplace_sub, vector_base<T> >
2073  {
2074  static void apply(vector_base<T> & lhs, vector_base<T> const & rhs)
2075  {
2076  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, rhs, T(1), 1, false, true);
2077  }
2078  };
2079 
2081 
2082 
2083  // x = alpha * y
2084  template<typename T, typename ScalarType>
2085  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2086  {
2087  // generic case: ScalarType is a scalar expression
2088  template<typename LHS, typename RHS, typename OP>
2089  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2090  {
2091  T alpha = proxy.rhs();
2092  viennacl::linalg::av(lhs, proxy.lhs(), alpha, 1, false, false);
2093  }
2094 
2095  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2096  {
2097  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
2098  }
2099 
2100  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2101  {
2102  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, false, false);
2103  }
2104  };
2105 
2106  // x += alpha * y
2107  template<typename T, typename ScalarType>
2108  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2109  {
2110  // generic case: ScalarType is a scalar expression
2111  template<typename LHS, typename RHS, typename OP>
2112  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2113  {
2114  T alpha = proxy.rhs();
2115  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, false);
2116  }
2117 
2118  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2119  {
2120  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
2121  }
2122 
2123  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2124  {
2125  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, false);
2126  }
2127  };
2128 
2129  // x -= alpha * y
2130  template<typename T, typename ScalarType>
2131  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_mult> >
2132  {
2133  // generic case: ScalarType is a scalar expression
2134  template<typename LHS, typename RHS, typename OP>
2135  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar_expression<LHS, RHS, OP>, op_mult> const & proxy)
2136  {
2137  T alpha = proxy.rhs();
2138  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), alpha, 1, false, true);
2139  }
2140 
2141  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const scalar<T>, op_mult> const & proxy)
2142  {
2143  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
2144  }
2145 
2146  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const T, op_mult> const & proxy)
2147  {
2148  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, false, true);
2149  }
2150  };
2151 
2152 
2154 
2155  // x = alpha * vec_expr
2156  template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2157  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2158  {
2159  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2160  {
2161  vector<T> temp(proxy.lhs());
2162  lhs = temp * proxy.rhs();
2163  }
2164  };
2165 
2166  // x += alpha * vec_expr
2167  template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2168  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2169  {
2170  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2171  {
2172  vector<T> temp(proxy.lhs());
2173  lhs += temp * proxy.rhs();
2174  }
2175  };
2176 
2177  // x -= alpha * vec_expr
2178  template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2179  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> >
2180  {
2181  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_mult> const & proxy)
2182  {
2183  vector<T> temp(proxy.lhs());
2184  lhs -= temp * proxy.rhs();
2185  }
2186  };
2187 
2188 
2190 
2191  // x = y / alpha
2192  template<typename T, typename ScalarType>
2193  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2194  {
2195  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2196  {
2197  viennacl::linalg::av(lhs, proxy.lhs(), proxy.rhs(), 1, true, false);
2198  }
2199  };
2200 
2201  // x += y / alpha
2202  template<typename T, typename ScalarType>
2203  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2204  {
2205  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2206  {
2207  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, false);
2208  }
2209  };
2210 
2211  // x -= y / alpha
2212  template<typename T, typename ScalarType>
2213  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_base<T>, const ScalarType, op_div> >
2214  {
2215  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const ScalarType, op_div> const & proxy)
2216  {
2217  viennacl::linalg::avbv(lhs, lhs, T(1), 1, false, false, proxy.lhs(), proxy.rhs(), 1, true, true);
2218  }
2219  };
2220 
2221 
2223 
2224  // x = vec_expr / alpha
2225  template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2226  struct op_executor<vector_base<T>, op_assign, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2227  {
2228  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2229  {
2230  vector<T> temp(proxy.lhs());
2231  lhs = temp / proxy.rhs();
2232  }
2233  };
2234 
2235  // x += vec_expr / alpha
2236  template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2237  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2238  {
2239  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2240  {
2241  vector<T> temp(proxy.lhs());
2242  lhs += temp / proxy.rhs();
2243  }
2244  };
2245 
2246  // x -= vec_expr / alpha
2247  template<typename T, typename LHS, typename RHS, typename OP, typename ScalarType>
2248  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> >
2249  {
2250  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS, const RHS, OP>, const ScalarType, op_div> const & proxy)
2251  {
2252  vector<T> temp(proxy.lhs());
2253  lhs -= temp / proxy.rhs();
2254  }
2255  };
2256 
2257 
2258 
2259  // generic x = vec_expr1 + vec_expr2:
2260  template<typename T, typename LHS, typename RHS>
2261  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_add> >
2262  {
2263  // generic x = vec_expr1 + vec_expr2:
2264  template<typename LHS1, typename RHS1>
2265  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2266  {
2267  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2268  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2269 
2270  if (op_aliasing_lhs || op_aliasing_rhs)
2271  {
2272  vector_base<T> temp(proxy.lhs());
2273  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2274  lhs = temp;
2275  }
2276  else
2277  {
2278  op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
2279  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2280  }
2281  }
2282 
2283  // x = y + z
2284  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2285  {
2287  proxy.lhs(), T(1), 1, false, false,
2288  proxy.rhs(), T(1), 1, false, false);
2289  }
2290 
2291  // x = alpha * y + z
2292  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2293  const vector_base<T>,
2294  op_add> const & proxy)
2295  {
2297  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2298  proxy.rhs(), T(1), 1, false, false);
2299  }
2300 
2301  // x = y / alpha + z
2302  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2303  const vector_base<T>,
2304  op_add> const & proxy)
2305  {
2307  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2308  proxy.rhs(), T(1), 1, false, false);
2309  }
2310 
2311  // x = y + beta * z
2312  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2313  const vector_expression<const vector_base<T>, const T, op_mult>,
2314  op_add> const & proxy)
2315  {
2317  proxy.lhs(), T(1), 1, false, false,
2318  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2319  }
2320 
2321  // x = y + z / beta
2322  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2323  const vector_expression<const vector_base<T>, const T, op_div>,
2324  op_add> const & proxy)
2325  {
2327  proxy.lhs(), T(1), 1, false, false,
2328  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2329  }
2330 
2331  // x = alpha * y + beta * z
2332  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2333  const vector_expression<const vector_base<T>, const T, op_mult>,
2334  op_add> const & proxy)
2335  {
2337  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2338  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2339  }
2340 
2341  // x = alpha * y + z / beta
2342  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_mult>,
2343  const vector_expression<const vector_base<T>, const T, op_div>,
2344  op_add> const & proxy)
2345  {
2347  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2348  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2349  }
2350 
2351  // x = y / alpha + beta * z
2352  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2353  const vector_expression<const vector_base<T>, const T, op_mult>,
2354  op_add> const & proxy)
2355  {
2357  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2358  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2359  }
2360 
2361  // x = y / alpha + z / beta
2362  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const T, op_div>,
2363  const vector_expression<const vector_base<T>, const T, op_div>,
2364  op_add> const & proxy)
2365  {
2367  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2368  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2369  }
2370  };
2371 
2372 
2373  // generic x += vec_expr1 + vec_expr2:
2374  template<typename T, typename LHS, typename RHS>
2375  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_add> >
2376  {
2377  // generic x += vec_expr1 + vec_expr2:
2378  template<typename LHS1, typename RHS1>
2379  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2380  {
2381  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2382  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2383 
2384  if (op_aliasing_lhs || op_aliasing_rhs)
2385  {
2386  vector_base<T> temp(proxy.lhs());
2387  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2388  lhs += temp;
2389  }
2390  else
2391  {
2392  op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
2393  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2394  }
2395  }
2396 
2397  // x += y + z
2398  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2399  {
2401  proxy.lhs(), T(1), 1, false, false,
2402  proxy.rhs(), T(1), 1, false, false);
2403  }
2404 
2405  // x += alpha * y + z
2406  template<typename ScalarType>
2407  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2408  const vector_base<T>,
2409  op_add> const & proxy)
2410  {
2412  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2413  proxy.rhs(), T(1), 1, false, false);
2414  }
2415 
2416  // x += y / alpha + z
2417  template<typename ScalarType>
2418  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2419  const vector_base<T>,
2420  op_add> const & proxy)
2421  {
2423  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2424  proxy.rhs(), T(1), 1, false, false);
2425  }
2426 
2427  // x += y + beta * z
2428  template<typename ScalarType>
2429  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2430  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2431  op_add> const & proxy)
2432  {
2434  proxy.lhs(), T(1), 1, false, false,
2435  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2436  }
2437 
2438  // x += y + z / beta
2439  template<typename ScalarType>
2440  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2441  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2442  op_add> const & proxy)
2443  {
2445  proxy.lhs(), T(1), 1, false, false,
2446  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2447  }
2448 
2449  // x += alpha * y + beta * z
2450  template<typename ScalarType1, typename ScalarType2>
2451  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2452  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2453  op_add> const & proxy)
2454  {
2456  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2457  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2458  }
2459 
2460  // x += alpha * y + z / beta
2461  template<typename ScalarType1, typename ScalarType2>
2462  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2463  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2464  op_add> const & proxy)
2465  {
2467  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2468  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2469  }
2470 
2471  // x += y / alpha + beta * z
2472  template<typename ScalarType1, typename ScalarType2>
2473  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2474  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2475  op_add> const & proxy)
2476  {
2478  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2479  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2480  }
2481 
2482  // x += y / alpha + z / beta
2483  template<typename ScalarType1, typename ScalarType2>
2484  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2485  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2486  op_add> const & proxy)
2487  {
2489  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2490  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2491  }
2492  };
2493 
2494 
2495 
2496  // generic x -= vec_expr1 + vec_expr2:
2497  template<typename T, typename LHS, typename RHS>
2498  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_add> >
2499  {
2500  // generic x -= vec_expr1 + vec_expr2:
2501  template<typename LHS1, typename RHS1>
2502  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_add> const & proxy)
2503  {
2504  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2505  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2506 
2507  if (op_aliasing_lhs || op_aliasing_rhs)
2508  {
2509  vector_base<T> temp(proxy.lhs());
2510  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(temp, proxy.rhs());
2511  lhs -= temp;
2512  }
2513  else
2514  {
2515  op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
2516  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2517  }
2518  }
2519 
2520  // x -= y + z
2521  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_add> const & proxy)
2522  {
2524  proxy.lhs(), T(1), 1, false, true,
2525  proxy.rhs(), T(1), 1, false, true);
2526  }
2527 
2528  // x -= alpha * y + z
2529  template<typename ScalarType>
2530  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2531  const vector_base<T>,
2532  op_add> const & proxy)
2533  {
2535  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2536  proxy.rhs(), T(1), 1, false, true);
2537  }
2538 
2539  // x -= y / alpha + z
2540  template<typename ScalarType>
2541  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2542  const vector_base<T>,
2543  op_add> const & proxy)
2544  {
2546  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2547  proxy.rhs(), T(1), 1, false, true);
2548  }
2549 
2550  // x -= y + beta * z
2551  template<typename ScalarType>
2552  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2553  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2554  op_add> const & proxy)
2555  {
2557  proxy.lhs(), T(1), 1, false, true,
2558  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2559  }
2560 
2561  // x -= y + z / beta
2562  template<typename ScalarType>
2563  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2564  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2565  op_add> const & proxy)
2566  {
2568  proxy.lhs(), T(1), 1, false, true,
2569  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2570  }
2571 
2572  // x -= alpha * y + beta * z
2573  template<typename ScalarType1, typename ScalarType2>
2574  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2575  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2576  op_add> const & proxy)
2577  {
2579  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2580  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2581  }
2582 
2583  // x -= alpha * y + z / beta
2584  template<typename ScalarType1, typename ScalarType2>
2585  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2586  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2587  op_add> const & proxy)
2588  {
2590  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2591  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2592  }
2593 
2594  // x -= y / alpha + beta * z
2595  template<typename ScalarType1, typename ScalarType2>
2596  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2597  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2598  op_add> const & proxy)
2599  {
2601  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2602  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2603  }
2604 
2605  // x -= y / alpha + z / beta
2606  template<typename ScalarType1, typename ScalarType2>
2607  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2608  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2609  op_add> const & proxy)
2610  {
2612  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2613  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2614  }
2615  };
2616 
2617 
2618 
2620 
2621 
2622 
2623  // generic x = vec_expr1 - vec_expr2:
2624  template<typename T, typename LHS, typename RHS>
2625  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_sub> >
2626  {
2627  // generic x = vec_expr1 - vec_expr2:
2628  template<typename LHS1, typename RHS1>
2629  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2630  {
2631  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2632  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2633 
2634  if (op_aliasing_lhs || op_aliasing_rhs)
2635  {
2636  vector_base<T> temp(proxy.lhs());
2637  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2638  lhs = temp;
2639  }
2640  else
2641  {
2642  op_executor<vector_base<T>, op_assign, LHS>::apply(lhs, proxy.lhs());
2643  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2644  }
2645  }
2646 
2647  // x = y - z
2648  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2649  {
2651  proxy.lhs(), T(1), 1, false, false,
2652  proxy.rhs(), T(1), 1, false, true);
2653  }
2654 
2655  // x = alpha * y - z
2656  template<typename ScalarType>
2657  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2658  const vector_base<T>,
2659  op_sub> const & proxy)
2660  {
2662  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2663  proxy.rhs(), T(1), 1, false, true);
2664  }
2665 
2666  // x = y / alpha - z
2667  template<typename ScalarType>
2668  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2669  const vector_base<T>,
2670  op_sub> const & proxy)
2671  {
2673  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2674  proxy.rhs(), T(1), 1, false, true);
2675  }
2676 
2677  // x = y - beta * z
2678  template<typename ScalarType>
2679  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2680  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2681  op_sub> const & proxy)
2682  {
2684  proxy.lhs(), T(1), 1, false, false,
2685  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2686  }
2687 
2688  // x = y - z / beta
2689  template<typename ScalarType>
2690  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2691  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2692  op_sub> const & proxy)
2693  {
2695  proxy.lhs(), T(1), 1, false, false,
2696  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2697  }
2698 
2699  // x = alpha * y - beta * z
2700  template<typename ScalarType1, typename ScalarType2>
2701  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2702  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2703  op_sub> const & proxy)
2704  {
2706  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2707  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2708  }
2709 
2710  // x = alpha * y - z / beta
2711  template<typename ScalarType1, typename ScalarType2>
2712  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2713  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2714  op_sub> const & proxy)
2715  {
2717  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2718  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2719  }
2720 
2721  // x = y / alpha - beta * z
2722  template<typename ScalarType1, typename ScalarType2>
2723  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2724  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2725  op_sub> const & proxy)
2726  {
2728  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2729  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2730  }
2731 
2732  // x = y / alpha - z / beta
2733  template<typename ScalarType1, typename ScalarType2>
2734  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2735  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2736  op_sub> const & proxy)
2737  {
2739  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2740  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2741  }
2742  };
2743 
2744 
2745  // generic x += vec_expr1 - vec_expr2:
2746  template<typename T, typename LHS, typename RHS>
2747  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_sub> >
2748  {
2749  // generic x += vec_expr1 - vec_expr2:
2750  template<typename LHS1, typename RHS1>
2751  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2752  {
2753  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2754  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2755 
2756  if (op_aliasing_lhs || op_aliasing_rhs)
2757  {
2758  vector_base<T> temp(proxy.lhs());
2759  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2760  lhs += temp;
2761  }
2762  else
2763  {
2764  op_executor<vector_base<T>, op_inplace_add, LHS>::apply(lhs, proxy.lhs());
2765  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(lhs, proxy.rhs());
2766  }
2767  }
2768 
2769  // x += y - z
2770  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2771  {
2773  proxy.lhs(), T(1), 1, false, false,
2774  proxy.rhs(), T(1), 1, false, true);
2775  }
2776 
2777  // x += alpha * y - z
2778  template<typename ScalarType>
2779  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2780  const vector_base<T>,
2781  op_sub> const & proxy)
2782  {
2784  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2785  proxy.rhs(), T(1), 1, false, true);
2786  }
2787 
2788  // x += y / alpha - z
2789  template<typename ScalarType>
2790  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2791  const vector_base<T>,
2792  op_sub> const & proxy)
2793  {
2795  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2796  proxy.rhs(), T(1), 1, false, true);
2797  }
2798 
2799  // x += y - beta * z
2800  template<typename ScalarType>
2801  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2802  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2803  op_sub> const & proxy)
2804  {
2806  proxy.lhs(), T(1), 1, false, false,
2807  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2808  }
2809 
2810  // x += y - z / beta
2811  template<typename ScalarType>
2812  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2813  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2814  op_sub> const & proxy)
2815  {
2817  proxy.lhs(), T(1), 1, false, false,
2818  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2819  }
2820 
2821  // x += alpha * y - beta * z
2822  template<typename ScalarType1, typename ScalarType2>
2823  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2824  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2825  op_sub> const & proxy)
2826  {
2828  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2829  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2830  }
2831 
2832  // x += alpha * y - z / beta
2833  template<typename ScalarType1, typename ScalarType2>
2834  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2835  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2836  op_sub> const & proxy)
2837  {
2839  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, false,
2840  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2841  }
2842 
2843  // x += y / alpha - beta * z
2844  template<typename ScalarType1, typename ScalarType2>
2845  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2846  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2847  op_sub> const & proxy)
2848  {
2850  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2851  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, true);
2852  }
2853 
2854  // x += y / alpha - z / beta
2855  template<typename ScalarType1, typename ScalarType2>
2856  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2857  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2858  op_sub> const & proxy)
2859  {
2861  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, false,
2862  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, true);
2863  }
2864  };
2865 
2866 
2867 
2868  // generic x -= vec_expr1 - vec_expr2:
2869  template<typename T, typename LHS, typename RHS>
2870  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_sub> >
2871  {
2872  // generic x -= vec_expr1 - vec_expr2:
2873  template<typename LHS1, typename RHS1>
2874  static void apply(vector_base<T> & lhs, vector_expression<const LHS1, const RHS1, op_sub> const & proxy)
2875  {
2876  bool op_aliasing_lhs = op_aliasing(lhs, proxy.lhs());
2877  bool op_aliasing_rhs = op_aliasing(lhs, proxy.rhs());
2878 
2879  if (op_aliasing_lhs || op_aliasing_rhs)
2880  {
2881  vector_base<T> temp(proxy.lhs());
2882  op_executor<vector_base<T>, op_inplace_sub, RHS>::apply(temp, proxy.rhs());
2883  lhs -= temp;
2884  }
2885  else
2886  {
2887  op_executor<vector_base<T>, op_inplace_sub, LHS>::apply(lhs, proxy.lhs());
2888  op_executor<vector_base<T>, op_inplace_add, RHS>::apply(lhs, proxy.rhs());
2889  }
2890  }
2891 
2892  // x -= y - z
2893  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_sub> const & proxy)
2894  {
2896  proxy.lhs(), T(1), 1, false, true,
2897  proxy.rhs(), T(1), 1, false, false);
2898  }
2899 
2900  // x -= alpha * y - z
2901  template<typename ScalarType>
2902  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2903  const vector_base<T>,
2904  op_sub> const & proxy)
2905  {
2907  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2908  proxy.rhs(), T(1), 1, false, false);
2909  }
2910 
2911  // x -= y / alpha - z
2912  template<typename ScalarType>
2913  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2914  const vector_base<T>,
2915  op_sub> const & proxy)
2916  {
2918  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2919  proxy.rhs(), T(1), 1, false, false);
2920  }
2921 
2922  // x -= y - beta * z
2923  template<typename ScalarType>
2924  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2925  const vector_expression<const vector_base<T>, const ScalarType, op_mult>,
2926  op_sub> const & proxy)
2927  {
2929  proxy.lhs(), T(1), 1, false, true,
2930  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2931  }
2932 
2933  // x -= y - z / beta
2934  template<typename ScalarType>
2935  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>,
2936  const vector_expression<const vector_base<T>, const ScalarType, op_div>,
2937  op_sub> const & proxy)
2938  {
2940  proxy.lhs(), T(1), 1, false, true,
2941  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2942  }
2943 
2944  // x -= alpha * y - beta * z
2945  template<typename ScalarType1, typename ScalarType2>
2946  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2947  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2948  op_sub> const & proxy)
2949  {
2951  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2952  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2953  }
2954 
2955  // x -= alpha * y - z / beta
2956  template<typename ScalarType1, typename ScalarType2>
2957  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_mult>,
2958  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2959  op_sub> const & proxy)
2960  {
2962  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, false, true,
2963  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2964  }
2965 
2966  // x -= y / alpha - beta * z
2967  template<typename ScalarType1, typename ScalarType2>
2968  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2969  const vector_expression<const vector_base<T>, const ScalarType2, op_mult>,
2970  op_sub> const & proxy)
2971  {
2973  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2974  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, false, false);
2975  }
2976 
2977  // x -= y / alpha - z / beta
2978  template<typename ScalarType1, typename ScalarType2>
2979  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const vector_base<T>, const ScalarType1, op_div>,
2980  const vector_expression<const vector_base<T>, const ScalarType2, op_div>,
2981  op_sub> const & proxy)
2982  {
2984  proxy.lhs().lhs(), proxy.lhs().rhs(), 1, true, true,
2985  proxy.rhs().lhs(), proxy.rhs().rhs(), 1, true, false);
2986  }
2987  };
2988 
2989 
2990 
2991 
2992 
2993 
2994 
2995 
2996 
2997 
2998 
2999 
3000 
3001 
3002 
3003 
3004 
3005 
3007 
3008  // generic x = vec_expr1 .* vec_expr2:
3009  template<typename T, typename LHS, typename RHS, typename OP>
3010  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3011  {
3012  // x = y .* z or x = y ./ z
3013  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3014  {
3015  viennacl::linalg::element_op(lhs, proxy);
3016  }
3017 
3018  // x = y .* vec_expr or x = y ./ vec_expr
3019  template<typename LHS2, typename RHS2, typename OP2>
3020  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)
3021  {
3022  vector<T> temp(proxy.rhs());
3023  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3024  }
3025 
3026  // x = vec_expr .* z or x = vec_expr ./ z
3027  template<typename LHS1, typename RHS1, typename OP1>
3028  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)
3029  {
3030  vector<T> temp(proxy.lhs());
3031  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3032  }
3033 
3034  // x = vec_expr .* vec_expr or z = vec_expr .* vec_expr
3035  template<typename LHS1, typename RHS1, typename OP1,
3036  typename LHS2, typename RHS2, typename OP2>
3037  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3038  const vector_expression<const LHS2, const RHS2, OP2>,
3039  op_element_binary<OP> > const & proxy)
3040  {
3041  vector<T> temp1(proxy.lhs());
3042  vector<T> temp2(proxy.rhs());
3043  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3044  }
3045  };
3046 
3047  // generic x += vec_expr1 .* vec_expr2:
3048  template<typename T, typename LHS, typename RHS, typename OP>
3049  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3050  {
3051  // x += y .* z or x += y ./ z
3052  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3053  {
3054  viennacl::vector<T> temp(proxy);
3055  lhs += temp;
3056  }
3057 
3058  // x += y .* vec_expr or x += y ./ vec_expr
3059  template<typename LHS2, typename RHS2, typename OP2>
3060  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)
3061  {
3062  vector<T> temp(proxy.rhs());
3063  vector<T> temp2(temp.size());
3064  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3065  lhs += temp2;
3066  }
3067 
3068  // x += vec_expr .* z or x += vec_expr ./ z
3069  template<typename LHS1, typename RHS1, typename OP1>
3070  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)
3071  {
3072  vector<T> temp(proxy.lhs());
3073  vector<T> temp2(temp.size());
3074  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3075  lhs += temp2;
3076  }
3077 
3078  // x += vec_expr .* vec_expr or x += vec_expr ./ vec_expr
3079  template<typename LHS1, typename RHS1, typename OP1,
3080  typename LHS2, typename RHS2, typename OP2>
3081  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3082  const vector_expression<const LHS2, const RHS2, OP2>,
3083  op_element_binary<OP> > const & proxy)
3084  {
3085  vector<T> temp1(proxy.lhs());
3086  vector<T> temp2(proxy.rhs());
3087  vector<T> temp3(temp1.size());
3088  viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3089  lhs += temp3;
3090  }
3091  };
3092 
3093  // generic x -= vec_expr1 .* vec_expr2:
3094  template<typename T, typename LHS, typename RHS, typename OP>
3095  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_binary<OP> > >
3096  {
3097 
3098  // x -= y .* z or x -= y ./ z
3099  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> > const & proxy)
3100  {
3101  viennacl::vector<T> temp(proxy);
3102  lhs -= temp;
3103  }
3104 
3105  // x -= y .* vec_expr or x -= y ./ vec_expr
3106  template<typename LHS2, typename RHS2, typename OP2>
3107  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)
3108  {
3109  vector<T> temp(proxy.rhs());
3110  vector<T> temp2(temp.size());
3111  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(proxy.lhs(), temp));
3112  lhs -= temp2;
3113  }
3114 
3115  // x -= vec_expr .* z or x -= vec_expr ./ z
3116  template<typename LHS1, typename RHS1, typename OP1>
3117  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)
3118  {
3119  vector<T> temp(proxy.lhs());
3120  vector<T> temp2(temp.size());
3121  viennacl::linalg::element_op(temp2, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp, proxy.rhs()));
3122  lhs -= temp2;
3123  }
3124 
3125  // x -= vec_expr .* vec_expr or x -= vec_expr ./ vec_expr
3126  template<typename LHS1, typename RHS1, typename OP1,
3127  typename LHS2, typename RHS2, typename OP2>
3128  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS1, const RHS1, OP1>,
3129  const vector_expression<const LHS2, const RHS2, OP2>,
3130  op_element_binary<OP> > const & proxy)
3131  {
3132  vector<T> temp1(proxy.lhs());
3133  vector<T> temp2(proxy.rhs());
3134  vector<T> temp3(temp1.size());
3135  viennacl::linalg::element_op(temp3, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<OP> >(temp1, temp2));
3136  lhs -= temp3;
3137  }
3138  };
3139 
3141 
3142  template<typename T, typename LHS, typename RHS, typename OP>
3143  struct op_executor<vector_base<T>, op_assign, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3144  {
3145  // x = OP(y)
3146  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3147  {
3148  viennacl::linalg::element_op(lhs, proxy);
3149  }
3150 
3151  // x = OP(vec_expr)
3152  template<typename LHS2, typename RHS2, typename OP2>
3153  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3154  const vector_expression<const LHS2, const RHS2, OP2>,
3155  op_element_unary<OP> > const & proxy)
3156  {
3157  vector<T> temp(proxy.rhs());
3158  viennacl::linalg::element_op(lhs, viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> >(temp, temp));
3159  }
3160  };
3161 
3162  template<typename T, typename LHS, typename RHS, typename OP>
3163  struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3164  {
3165  // x += OP(y)
3166  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3167  {
3168  vector<T> temp(proxy);
3169  lhs += temp;
3170  }
3171 
3172  // x += OP(vec_expr)
3173  template<typename LHS2, typename RHS2, typename OP2>
3174  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3175  const vector_expression<const LHS2, const RHS2, OP2>,
3176  op_element_unary<OP> > const & proxy)
3177  {
3178  vector<T> temp(proxy.rhs());
3179  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
3180  lhs += temp;
3181  }
3182  };
3183 
3184  template<typename T, typename LHS, typename RHS, typename OP>
3185  struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, op_element_unary<OP> > >
3186  {
3187  // x -= OP(y)
3188  static void apply(vector_base<T> & lhs, vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<OP> > const & proxy)
3189  {
3190  vector<T> temp(proxy);
3191  lhs -= temp;
3192  }
3193 
3194  // x -= OP(vec_expr)
3195  template<typename LHS2, typename RHS2, typename OP2>
3196  static void apply(vector_base<T> & lhs, vector_expression<const vector_expression<const LHS2, const RHS2, OP2>,
3197  const vector_expression<const LHS2, const RHS2, OP2>,
3198  op_element_unary<OP> > const & proxy)
3199  {
3200  vector<T> temp(proxy.rhs());
3201  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
3202  lhs -= temp;
3203  }
3204  };
3205 
3206 } // namespace detail
3207 } // namespace linalg
3208 
3211 } // namespace viennacl
3212 
3213 #endif
Simple enable-if variant that uses the SFINAE pattern.
Definition: enable_if.hpp:30
A tag class representing multiplication by a scalar.
Definition: forwards.h:91
vcl_size_t const_size() const
Definition: vector.hpp:1129
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
handle_type const & handle() const
Definition: vector.hpp:174
vector_base()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:252
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
Definition: forwards.h:226
vector_expression< const self_type, const NumericT, op_mult > operator*(char value) const
Scales the vector by a char (8-bit integer) 'alpha' and returns an expression template.
Definition: vector.hpp:728
vector(scalar_vector< NumericT > const &v)
Creates the vector from the supplied scalar vector.
Definition: vector.hpp:1009
VectorType & at(vcl_size_t i) const
Definition: vector.hpp:1131
Worker class for decomposing expression templates.
Definition: op_executor.hpp:80
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: forwards.h:235
vector_iterator(handle_type &elements, size_type index, size_type start=0, size_type stride=1)
Definition: vector.hpp:215
base_type::size_type size_type
Definition: vector.hpp:942
vector< NumericT, AlignmentV > & fast_swap(vector< NumericT, AlignmentV > &v1, vector< NumericT, AlignmentV > &v2)
Swaps the content of two vectors by swapping OpenCL handles only, NO data is copied.
Definition: vector.hpp:1651
Defines the worker class for decomposing an expression tree into small chunks, which can be processed...
Implementations of vector operations.
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2, VectorType const &v3)
Definition: vector.hpp:1094
const_vector_iterator(vector_base< NumericT > const &vec, size_type index, size_type start=0, size_type stride=1)
Constructor.
Definition: vector.hpp:125
Helper struct for checking whether a type represents a sign flip on a viennacl::scalar<> ...
Definition: forwards.h:461
vcl_size_t index() const
Definition: vector_def.hpp:49
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:885
Various little tools used here and there in ViennaCL.
entry_proxy< NumericT > operator[](size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:557
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
difference_type operator-(self_type const &other) const
Definition: vector.hpp:161
self_type & swap(self_type &other)
Swaps the entries of the two vectors.
Definition: vector.hpp:853
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:54
A tag class representing subtraction.
Definition: forwards.h:89
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)
bool operator==(self_type const &other) const
Definition: vector.hpp:151
vector(vector_expression< const LHS, const RHS, OP > const &proxy)
Definition: vector.hpp:980
Expression template class for representing a tree of expressions which ultimately result in a matrix...
Definition: forwards.h:340
self_type & operator=(T const &other)
Definition: vector.hpp:1017
void pad()
Pads vectors with alignment > 1 with trailing zeros if the internal size is larger than the visible s...
Definition: vector.hpp:875
handle_type const & elements_
The index of the entry the iterator is currently pointing to.
Definition: vector.hpp:178
result_of::size_type< viennacl::vector_base< T > >::type stride(viennacl::vector_base< T > const &s)
Definition: stride.hpp:45
void clear(VectorType &vec)
Generic routine for setting all entries of a vector to zero. This is the version for non-ViennaCL obj...
Definition: clear.hpp:57
vector_tuple(std::vector< VectorType const * > const &vecs)
Definition: vector.hpp:1113
This file provides the forward declarations for the main types used within ViennaCL.
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2)
Definition: vector.hpp:1085
A tag class representing division.
Definition: forwards.h:97
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
vector_expression< const self_type, const NumericT, op_div > operator/(char value) const
Scales the vector by a char (8-bit integer) 'alpha' and returns an expression template.
Definition: vector.hpp:772
viennacl::enable_if< viennacl::is_scalar< S1 >::value, matrix_base< NumericT > & >::type operator/=(matrix_base< NumericT > &m1, S1 const &gpu_val)
Scales a matrix by a GPU scalar value.
Definition: matrix.hpp:1595
viennacl::enable_if< viennacl::is_any_scalar< S1 >::value, matrix_expression< const matrix_base< NumericT >, const S1, op_mult >>::type operator*(S1 const &value, matrix_base< NumericT > const &m1)
Operator overload for the expression alpha * m1, where alpha is a host scalar (float or double) and m...
Definition: matrix.hpp:1295
viennacl::scalar< float > s1
vcl_size_t internal_size(vector_base< NumericT > const &vec)
Helper routine for obtaining the buffer length of a ViennaCL vector.
Definition: size.hpp:268
self_type & operator-=(const self_type &vec)
Definition: vector.hpp:602
vector(const self_type &v)
Definition: vector.hpp:988
A proxy for scalar expressions (e.g. from inner vector products)
Definition: forwards.h:229
lhs_reference_type lhs() const
Get left hand side operand.
Definition: vector.hpp:74
An expression template class that represents a binary operation that yields a vector.
Definition: forwards.h:238
void element_op(matrix_base< T > &A, matrix_expression< const matrix_base< T >, const matrix_base< T >, OP > const &proxy)
Implementation of the element-wise operation A = B .* C and A = B ./ C for matrices (using MATLAB syn...
value_type operator*(void) const
Dereferences the iterator and returns the value of the element. For convenience only, performance is poor due to OpenCL overhead!
Definition: vector.hpp:142
bool op_aliasing(vector_base< NumericT > const &, B const &)
Definition: op_executor.hpp:36
scalar< NumericT > value_type
Definition: vector.hpp:112
void resize(size_type new_size, bool preserve=true)
Resizes the allocated memory for the vector. Pads the memory to be a multiple of 'AlignmentV'.
Definition: vector.hpp:895
self_type & operator+=(const self_type &vec)
Definition: vector.hpp:590
viennacl::vector< NumericT > operator-(const vector_base< NumericT > &v1, const vector_expression< const matrix_base< NumericT >, const vector_base< NumericT >, op_prod > &proxy)
Implementation of the operation 'result = v1 - A * v2', where A is a matrix.
void swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
Definition: vector.hpp:1640
Implementation of a OpenCL-like context, which serves as a unification of {OpenMP, CUDA, OpenCL} at the user API.
vector(const base_type &v)
Definition: vector.hpp:982
vector(unit_vector< NumericT > const &v)
Creates the vector from the supplied unit vector.
Definition: vector.hpp:995
vector_expression(LHS &l, RHS &r)
Definition: vector.hpp:70
vector_expression< const self_type, const NumericT, op_mult > operator-() const
Sign flip for the vector. Emulated to be equivalent to -1.0 * vector.
Definition: vector.hpp:816
entry_proxy< NumericT > operator()(size_type index)
Read-write access to a single element of the vector.
Definition: vector.hpp:548
vector_tuple(VectorType const &v0, VectorType const &v1)
Definition: vector.hpp:1066
Represents a generic 'context' similar to an OpenCL context, but is backend-agnostic and thus also su...
Definition: context.hpp:39
viennacl::backend::mem_handle handle_type
Definition: vector.hpp:115
viennacl::context context() const
Definition: vector_def.hpp:46
self_type operator++(void)
Definition: vector.hpp:148
vector(NumericT *ptr_to_mem, viennacl::memory_types mem_type, size_type vec_size, size_type start=0, size_type stride=1)
Definition: vector.hpp:957
viennacl::vector< float > v1
self_type operator+(difference_type diff) const
Definition: vector.hpp:237
viennacl::enable_if< viennacl::is_scalar< S1 >::value, matrix_base< NumericT > & >::type operator*=(matrix_base< NumericT > &m1, S1 const &gpu_val)
Scales a matrix by a GPU scalar value.
Definition: matrix.hpp:1443
bool operator!=(self_type const &other) const
Definition: vector.hpp:152
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:144
size_type offset() const
Offset of the current element index with respect to the beginning of the buffer.
Definition: vector.hpp:170
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.
iterator begin()
Returns an iterator pointing to the beginning of the vector (STL like)
Definition: vector.hpp:827
handle_type & handle()
Definition: vector.hpp:239
base_type::difference_type difference_type
Definition: vector.hpp:943
Tuple class holding pointers to multiple vectors. Mainly used as a temporary object returned from vie...
Definition: forwards.h:268
vcl_size_t size() const
Definition: vector_def.hpp:47
A STL-type iterator for vector elements. Elements can be accessed and manipulated. VERY SLOW!!
Definition: forwards.h:241
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:44
void vector_swap(vector_base< T > &vec1, vector_base< T > &vec2)
Swaps the contents of two vectors, data is copied.
rhs_reference_type rhs() const
Get right hand side operand.
Definition: vector.hpp:77
A tag class representing addition.
Definition: forwards.h:87
void resize(size_type new_size, bool preserve=true)
Resizes the allocated memory for the vector. Pads the memory to be a multiple of 'AlignmentV'.
Definition: vector.hpp:1032
void resize(size_type new_size, viennacl::context ctx, bool preserve=true)
Definition: vector.hpp:1037
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:1524
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:341
std::size_t vcl_size_t
Definition: forwards.h:74
vector_tuple< ScalarT > tie(vector_base< ScalarT > const &v0, vector_base< ScalarT > const &v1)
Definition: vector.hpp:1141
viennacl::memory_types active_handle_id(T const &obj)
Returns an ID for the currently active memory domain of an object.
Definition: handle.hpp:212
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Definition: result_of.hpp:238
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)
vector_iterator(vector_base< NumericT > &vec, size_type index, size_type start=0, size_type stride=1)
Constructor.
Definition: vector.hpp:225
vector_tuple(VectorType const &v0, VectorType const &v1, VectorType const &v2)
Definition: vector.hpp:1079
vcl_size_t size() const
Definition: vector.hpp:1128
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:1044
difference_type operator-(self_type const &other) const
Definition: vector.hpp:236
viennacl::vector< NumericT > operator+(const vector_base< NumericT > &v1, const vector_expression< const matrix_base< NumericT >, const vector_base< NumericT >, op_prod > &proxy)
Implementation of the operation 'result = v1 + A * v2', where A is a matrix.
void switch_active_handle_id(memory_types new_id)
Switches the currently active handle. If no support for that backend is provided, an exception is thr...
Definition: mem_handle.hpp:121
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:93
void clear()
Resets all entries to zero. Does not change the size of the vector.
Definition: vector.hpp:861
viennacl::context context(T const &t)
Returns an ID for the currently active memory domain of an object.
Definition: context.hpp:40
self_type & operator/=(char val)
Scales a vector (or proxy) by a char (8-bit integer)
Definition: vector.hpp:671
Represents a vector consisting of 1 at a given index and zeros otherwise.
Definition: vector_def.hpp:76
entry_proxy< NumericT > operator*(void)
Definition: vector.hpp:231
vector(size_type vec_size, viennacl::context ctx)
Definition: vector.hpp:955
INT_TYPE align_to_multiple(INT_TYPE to_reach, INT_TYPE base)
Rounds an integer to the next multiple of another integer.
Definition: tools.hpp:133
viennacl::vector< int > v2
size_type size() const
Returns the size of the result vector.
Definition: vector.hpp:80
Represents a vector consisting of scalars 's' only, i.e. v[i] = s for all i. To be used as an initial...
Definition: vector_def.hpp:87
void copy(std::vector< NumericT > &cpu_vec, circulant_matrix< NumericT, AlignmentV > &gpu_mat)
Copies a circulant matrix from the std::vector to the OpenCL device (either GPU or multi-core CPU) ...
self_type operator+(difference_type diff) const
Definition: vector.hpp:166
size_type size() const
Returns the length of the vector (cf. std::vector)
Definition: vector_def.hpp:118
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)
float ScalarType
Definition: fft_1d.cpp:42
void copy(vector< NumericT, AlignmentV_SRC > const &gpu_src_vec, vector< NumericT, AlignmentV_DEST > &gpu_dest_vec)
Transfer from a ViennaCL vector to another ViennaCL vector. Convenience wrapper for viennacl::linalg:...
Definition: vector.hpp:1592
vector_tuple(VectorType &v0, VectorType &v1)
Definition: vector.hpp:1071
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
Definition: mem_handle.hpp:89
VectorType const & const_at(vcl_size_t i) const
Definition: vector.hpp:1132
A tag class representing transposed matrices.
Definition: forwards.h:219
handle_type const & handle() const
Definition: vector.hpp:240
vector(size_type vec_size)
An explicit constructor for the vector, allocating the given amount of memory (plus a padding specifi...
Definition: vector.hpp:953
base_type::size_type size_type
Definition: vector.hpp:211
vcl_size_t raw_size() const
Returns the number of bytes of the currently active buffer.
Definition: mem_handle.hpp:230
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)
Forward declarations of the implicit_vector_base, vector_base class.
vcl_size_t size_type
Extracts the vector type from the two operands.
Definition: vector.hpp:68
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
void prod_impl(const matrix_base< NumericT > &mat, const vector_base< NumericT > &vec, vector_base< NumericT > &result)
Carries out matrix-vector multiplication.
size_type internal_size() const
Returns the internal length of the vector, which is given by size() plus the extra memory due to padd...
Definition: vector_def.hpp:120
viennacl::backend::mem_handle & handle(T &obj)
Returns the generic memory handle of an object. Non-const version.
Definition: handle.hpp:41
iterator end()
Returns an iterator pointing to the end of the vector (STL like)
Definition: vector.hpp:834
memory_types
Definition: forwards.h:344
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
Definition: forwards.h:232
ScalarType diff(ScalarType &s1, viennacl::scalar< ScalarType > &s2)
Definition: blas3_solve.cpp:69
vector()
Default constructor in order to be compatible with various containers.
Definition: vector.hpp:947
void async_copy(const const_vector_iterator< NumericT, AlignmentV > &gpu_begin, const const_vector_iterator< NumericT, AlignmentV > &gpu_end, CPU_ITERATOR cpu_begin)
Asynchronous version of fast_copy(), copying data from device to host. The host iterator cpu_begin ne...
Definition: vector.hpp:1270
Implementation of the ViennaCL scalar class.
A collection of compile time type deductions.
self_type & operator*=(char val)
Scales a vector (or proxy) by a char (8-bit integer)
Definition: vector.hpp:615
base_type::difference_type difference_type
Definition: vector.hpp:212
const handle_type & handle() const
Returns the memory handle.
Definition: vector_def.hpp:128
vector(zero_vector< NumericT > const &v)
Creates the vector from the supplied zero vector.
Definition: vector.hpp:1002
vector_tuple(VectorType &v0, VectorType &v1, VectorType &v2, VectorType &v3)
Definition: vector.hpp:1101
Main interface routines for memory management.
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:867
ram_handle_type & ram_handle()
Returns the handle to a buffer in CPU RAM. NULL is returned if no such buffer has been allocated...
Definition: mem_handle.hpp:99
vector_tuple(std::vector< VectorType * > const &vecs)
Definition: vector.hpp:1119
size_type stride() const
Index increment in the underlying buffer when incrementing the iterator to the next element...
Definition: vector.hpp:173
base_type::handle_type handle_type
Definition: vector.hpp:210
const_vector_iterator(handle_type const &elements, size_type index, size_type start=0, size_type stride=1)
Constructor for vector-like treatment of arbitrary buffers.
Definition: vector.hpp:136
std::ptrdiff_t vcl_ptrdiff_t
Definition: forwards.h:75
void switch_memory_context(viennacl::context new_ctx)
Definition: vector.hpp:1050
memory_types get_active_handle_id() const
Returns an ID for the currently active memory buffer. Other memory buffers might contain old or no da...
Definition: mem_handle.hpp:118
void fast_copy(const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_begin, const const_vector_iterator< SCALARTYPE, ALIGNMENT > &gpu_end, CPU_ITERATOR cpu_begin)