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