|
ViennaCL - The Vienna Computing Library
1.1.2
|
00001 /* ======================================================================= 00002 Copyright (c) 2010, Institute for Microelectronics, TU Vienna. 00003 http://www.iue.tuwien.ac.at 00004 ----------------- 00005 ViennaCL - The Vienna Computing Library 00006 ----------------- 00007 00008 authors: Karl Rupp rupp@iue.tuwien.ac.at 00009 Florian Rudolf flo.rudy+viennacl@gmail.com 00010 Josef Weinbub weinbub@iue.tuwien.ac.at 00011 00012 license: MIT (X11), see file LICENSE in the ViennaCL base directory 00013 ======================================================================= */ 00014 00020 #ifndef _VIENNACL_VECTOR_HPP_ 00021 #define _VIENNACL_VECTOR_HPP_ 00022 00023 #include "viennacl/forwards.h" 00024 #include "viennacl/ocl/backend.hpp" 00025 #include "viennacl/scalar.hpp" 00026 #include "viennacl/tools/tools.hpp" 00027 #include "viennacl/tools/entry_proxy.hpp" 00028 #include "viennacl/linalg/vector_operations.hpp" 00029 00030 namespace viennacl 00031 { 00032 00045 template <typename LHS, typename RHS, typename OP> 00046 class vector_expression 00047 { 00048 public: 00051 typedef typename viennacl::tools::VECTOR_EXTRACTOR<LHS, RHS>::ResultType VectorType; 00052 00053 vector_expression(LHS & lhs, RHS & rhs) : _lhs(lhs), _rhs(rhs) {} 00054 00057 LHS & lhs() const { return _lhs; } 00060 RHS & rhs() const { return _rhs; } 00061 00063 unsigned int size() const { return viennacl::tools::VECTOR_SIZE_DEDUCER<LHS, RHS, OP>::size(_lhs, _rhs); } 00064 00065 private: 00067 LHS & _lhs; 00069 RHS & _rhs; 00070 }; 00071 00090 template<class SCALARTYPE, unsigned int ALIGNMENT> 00091 class const_vector_iterator 00092 { 00093 typedef const_vector_iterator<SCALARTYPE, ALIGNMENT> self_type; 00094 public: 00095 typedef scalar<SCALARTYPE> value_type; 00096 typedef long difference_type; 00097 00098 const_vector_iterator() {}; 00103 const_vector_iterator(vector<SCALARTYPE, ALIGNMENT> const & vec, cl_uint index) : elements_(vec.handle()), index_(index) {}; 00104 const_vector_iterator(viennacl::ocl::handle<cl_mem> const & elements, cl_uint index) : elements_(elements), index_(index) {}; 00105 00106 00107 value_type operator*(void) const 00108 { 00109 value_type result; 00110 result = entry_proxy<SCALARTYPE>(index_, elements_); 00111 return result; 00112 } 00113 self_type operator++(void) { ++index_; return *this; } 00114 self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; } 00115 00116 bool operator==(self_type const & other) const { return index_ == other.index_; } 00117 bool operator!=(self_type const & other) const { return index_ != other.index_; } 00118 00119 // self_type & operator=(self_type const & other) 00120 // { 00121 // _index = other._index; 00122 // elements_ = other._elements; 00123 // return *this; 00124 // } 00125 00126 difference_type operator-(self_type const & other) const { difference_type result = index_; return result - other.index_; } 00127 self_type operator+(difference_type diff) const { return self_type(elements_, index_ + diff); } 00128 00129 unsigned int index() const { return index_; } 00130 viennacl::ocl::handle<cl_mem> const & handle() const { return elements_; } 00131 00132 protected: 00134 viennacl::ocl::handle<cl_mem> elements_; 00135 unsigned int index_; 00136 }; 00137 00138 00158 template<class SCALARTYPE, unsigned int ALIGNMENT> 00159 class vector_iterator : public const_vector_iterator<SCALARTYPE, ALIGNMENT> 00160 { 00161 typedef const_vector_iterator<SCALARTYPE, ALIGNMENT> base_type; 00162 typedef vector_iterator<SCALARTYPE, ALIGNMENT> self_type; 00163 public: 00164 vector_iterator() : base_type(){}; 00165 vector_iterator(viennacl::ocl::handle<cl_mem> const & elements, unsigned int index) : base_type(elements, index) {}; 00170 vector_iterator(vector<SCALARTYPE, ALIGNMENT> & vec, cl_uint index) : base_type(vec, index) {}; 00171 vector_iterator(base_type const & b) : base_type(b) {}; 00172 00173 typename base_type::value_type operator*(void) 00174 { 00175 typename base_type::value_type result; 00176 result = entry_proxy<SCALARTYPE>(base_type::index_, base_type::elements_); 00177 return result; 00178 } 00179 00180 viennacl::ocl::handle<cl_mem> handle() { return base_type::elements_; } 00181 00182 operator base_type() const 00183 { 00184 return base_type(base_type::elements_, base_type::index_); 00185 } 00186 }; 00187 00188 // forward definition in VCLForwards.h! 00197 template<class SCALARTYPE, unsigned int ALIGNMENT> 00198 class vector 00199 { 00200 00201 public: 00202 typedef scalar<typename viennacl::tools::CHECK_SCALAR_TEMPLATE_ARGUMENT<SCALARTYPE>::ResultType> value_type; 00203 typedef vcl_size_t size_type; 00204 typedef vcl_ptrdiff_t difference_type; 00205 typedef const_vector_iterator<SCALARTYPE, ALIGNMENT> const_iterator; 00206 typedef vector_iterator<SCALARTYPE, ALIGNMENT> iterator; 00207 00210 vector() : size_(0) { viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::init(); } 00211 00216 explicit vector(size_type vec_size) : size_(vec_size) 00217 { 00218 viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::init(); 00219 00220 if (size_ > 0) 00221 elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*internal_size()); 00222 00223 //force entries above size_ to zero: 00224 if (size_ < internal_size()) 00225 { 00226 std::vector<SCALARTYPE> temp(internal_size() - size_); 00227 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), elements_, CL_TRUE, sizeof(SCALARTYPE)*size_, sizeof(SCALARTYPE)*(internal_size() - size_), &(temp[0]), 0, NULL, NULL); 00228 //assert(err == CL_SUCCESS); 00229 VIENNACL_ERR_CHECK(err); 00230 } 00231 } 00232 00241 explicit vector(cl_mem existing_mem, size_type vec_size) : size_(vec_size), elements_(existing_mem) 00242 { 00243 elements_.inc(); //prevents that the user-provided memory is deleted once the vector object is destroyed. 00244 } 00245 00246 template <typename LHS, typename RHS, typename OP> 00247 vector(vector_expression<LHS, RHS, OP> const & other) : size_(other.size()) 00248 { 00249 elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*other.size()); 00250 *this = other; 00251 } 00252 00257 vector(const vector<SCALARTYPE, ALIGNMENT> & vec) : 00258 size_(vec.size()) 00259 { 00260 viennacl::linalg::kernels::vector<SCALARTYPE, 1>::init(); 00261 00262 if (size() != 0) 00263 { 00264 elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*internal_size()); 00265 cl_int err; 00266 err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), vec.handle(), elements_, 0, 0, sizeof(SCALARTYPE)*internal_size(), 0, NULL, NULL); 00267 //assert(err == CL_SUCCESS); 00268 VIENNACL_ERR_CHECK(err); 00269 } 00270 } 00271 00274 vector<SCALARTYPE, ALIGNMENT> & operator=(const vector<SCALARTYPE, ALIGNMENT> & vec) 00275 { 00276 resize(vec.size()); 00277 if (size() != 0) 00278 { 00279 cl_int err; 00280 err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), vec.handle(), elements_, 0, 0, sizeof(SCALARTYPE)*internal_size(), 0, NULL, NULL); 00281 VIENNACL_ERR_CHECK(err); 00282 } 00283 return *this; 00284 } 00285 00286 00291 template <typename VectorType> //use template to cover const/non-const of VectorType: 00292 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType, 00293 const scalar<SCALARTYPE>, 00294 op_prod> & proxy) 00295 { 00296 resize(proxy.lhs().size()); 00297 //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 00298 viennacl::linalg::mult(proxy.lhs(), proxy.rhs(), *this); 00299 return *this; 00300 } 00301 00306 template <typename VectorType> //use template to cover const/non-const of VectorType: 00307 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType, 00308 const SCALARTYPE, 00309 op_prod> & proxy) 00310 { 00311 resize(proxy.lhs().size()); 00312 viennacl::linalg::mult(proxy.lhs(), proxy.rhs(), *this); 00313 return *this; 00314 } 00315 00320 template <typename VectorType> //use template to cover const/non-const of VectorType: 00321 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType, 00322 const scalar<SCALARTYPE>, 00323 op_div> & proxy) 00324 { 00325 resize(proxy.lhs().size()); 00326 //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 00327 viennacl::linalg::divide(proxy.lhs(), proxy.rhs(), *this); 00328 return *this; 00329 } 00330 00335 template <typename VectorType> //use template to cover const/non-const of VectorType: 00336 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType, 00337 const SCALARTYPE, 00338 op_div> & proxy) 00339 { 00340 resize(proxy.lhs().size()); 00341 //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 00342 viennacl::linalg::mult(proxy.lhs(), static_cast<SCALARTYPE>(1.0) / proxy.rhs(), *this); 00343 return *this; 00344 } 00345 00346 //v1 = v2 + v3; 00351 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00352 vector<SCALARTYPE, ALIGNMENT>, 00353 op_add> & proxy) 00354 { 00355 resize(proxy.lhs().size()); 00356 //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 00357 viennacl::linalg::add(proxy.lhs(), proxy.rhs(), *this); 00358 return *this; 00359 } 00360 00361 //v1 = v2 - v3; 00366 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00367 vector<SCALARTYPE, ALIGNMENT>, 00368 op_sub> & proxy) 00369 { 00370 resize(proxy.lhs().size()); 00371 //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 00372 viennacl::linalg::sub(proxy.lhs(), proxy.rhs(), *this); 00373 return *this; 00374 } 00375 00377 00378 //Note: The following operator overloads are defined in matrix_operations.hpp, compressed_matrix_operations.hpp and coordinate_matrix_operations.hpp 00379 //This is certainly not the nicest approach and will most likely by changed in the future, but it works :-) 00380 00381 //matrix<> 00386 template <typename F, unsigned int MAT_ALIGNMENT> 00387 vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00388 const vector<SCALARTYPE, ALIGNMENT>, 00389 op_prod> & proxy); 00390 00395 template <typename F, unsigned int MAT_ALIGNMENT> 00396 vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00397 const vector<SCALARTYPE, ALIGNMENT>, 00398 op_prod> & proxy); 00399 00404 template <typename F, unsigned int MAT_ALIGNMENT> 00405 vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00406 const vector<SCALARTYPE, ALIGNMENT>, 00407 op_prod> & proxy); 00408 00413 template <typename F, unsigned int MAT_ALIGNMENT> 00414 vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00415 const vector<SCALARTYPE, ALIGNMENT>, 00416 op_prod> & proxy); 00417 00422 template <typename F, unsigned int MAT_ALIGNMENT> 00423 vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00424 const vector<SCALARTYPE, ALIGNMENT>, 00425 op_prod> & proxy); 00426 00427 //transposed_matrix_proxy: 00432 template <typename F, unsigned int MAT_ALIGNMENT> 00433 vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00434 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00435 op_trans >, 00436 const vector<SCALARTYPE, ALIGNMENT>, 00437 op_prod> & proxy); 00438 00443 template <typename F, unsigned int MAT_ALIGNMENT> 00444 vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00445 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00446 op_trans >, 00447 const vector<SCALARTYPE, ALIGNMENT>, 00448 op_prod> & proxy); 00449 00454 template <typename F, unsigned int MAT_ALIGNMENT> 00455 vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00456 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00457 op_trans >, 00458 const vector<SCALARTYPE, ALIGNMENT>, 00459 op_prod> & proxy); 00460 00465 template <typename F, unsigned int MAT_ALIGNMENT> 00466 vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00467 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00468 op_trans >, 00469 const vector<SCALARTYPE, ALIGNMENT>, 00470 op_prod> & proxy); 00471 00476 template <typename F, unsigned int MAT_ALIGNMENT> 00477 vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00478 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>, 00479 op_trans >, 00480 const vector<SCALARTYPE, ALIGNMENT>, 00481 op_prod> & proxy); 00482 00483 00484 00486 00490 template <unsigned int MAT_ALIGNMENT> 00491 vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00492 const vector<SCALARTYPE, ALIGNMENT>, 00493 op_prod> & proxy); 00494 00499 template <unsigned int MAT_ALIGNMENT> 00500 vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00501 const vector<SCALARTYPE, ALIGNMENT>, 00502 op_prod> & proxy); 00503 00508 template <unsigned int MAT_ALIGNMENT> 00509 vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00510 const vector<SCALARTYPE, ALIGNMENT>, 00511 op_prod> & proxy); 00512 00517 template <unsigned int MAT_ALIGNMENT> 00518 vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00519 const vector<SCALARTYPE, ALIGNMENT>, 00520 op_prod> & proxy); 00521 00526 template <unsigned int MAT_ALIGNMENT> 00527 vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00528 const vector<SCALARTYPE, ALIGNMENT>, 00529 op_prod> & proxy); 00530 00531 00532 //coordinate_matrix<> 00537 template <unsigned int MAT_ALIGNMENT> 00538 vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00539 const vector<SCALARTYPE, ALIGNMENT>, 00540 op_prod> & proxy); 00541 00546 template <unsigned int MAT_ALIGNMENT> 00547 vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00548 const vector<SCALARTYPE, ALIGNMENT>, 00549 op_prod> & proxy); 00550 00555 template <unsigned int MAT_ALIGNMENT> 00556 vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00557 const vector<SCALARTYPE, ALIGNMENT>, 00558 op_prod> & proxy); 00559 00564 template <unsigned int MAT_ALIGNMENT> 00565 vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00566 const vector<SCALARTYPE, ALIGNMENT>, 00567 op_prod> & proxy); 00568 00573 template <unsigned int MAT_ALIGNMENT> 00574 vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>, 00575 const vector<SCALARTYPE, ALIGNMENT>, 00576 op_prod> & proxy); 00577 00579 00580 //enlarge or reduce allocated memory and set unused memory to zero 00586 void resize(size_type new_size, bool preserve = true) 00587 { 00588 assert(new_size > 0); 00589 00590 if (new_size != size_) 00591 { 00592 unsigned int new_internal_size = viennacl::tools::roundUpToNextMultiple<unsigned int>(new_size, ALIGNMENT); 00593 00594 std::vector<SCALARTYPE> temp(size_); 00595 if (preserve && size_ > 0) 00596 fast_copy(*this, temp); 00597 temp.resize(new_size); //drop all entries above new_size 00598 temp.resize(new_internal_size); //enlarge to fit new internal size 00599 00600 if (new_internal_size != internal_size()) 00601 { 00602 elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*new_internal_size); 00603 } 00604 00605 fast_copy(temp, *this); 00606 size_ = new_size; 00607 } 00608 00609 } 00610 00611 00612 //read-write access to an element of the vector 00615 entry_proxy<SCALARTYPE> operator()(size_type index) 00616 { 00617 return entry_proxy<SCALARTYPE>(index, elements_); 00618 } 00619 00622 entry_proxy<SCALARTYPE> operator[](size_type index) 00623 { 00624 return entry_proxy<SCALARTYPE>(index, elements_); 00625 } 00626 00627 00630 scalar<SCALARTYPE> operator()(size_type index) const 00631 { 00632 scalar<SCALARTYPE> tmp; 00633 cl_int err; 00634 err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), elements_, tmp.handle(), sizeof(SCALARTYPE)*index, 0, sizeof(SCALARTYPE), 0, NULL, NULL); 00635 //assert(err == CL_SUCCESS); 00636 VIENNACL_ERR_CHECK(err); 00637 return tmp; 00638 } 00639 00642 scalar<SCALARTYPE> operator[](size_type index) const 00643 { 00644 return operator()(index); 00645 } 00646 00649 vector<SCALARTYPE, ALIGNMENT> & operator += (const vector<SCALARTYPE, ALIGNMENT> & vec) 00650 { 00651 viennacl::linalg::inplace_add(*this, vec); 00652 return *this; 00653 } 00654 00657 vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00658 const scalar<SCALARTYPE>, 00659 op_prod> & proxy) 00660 { 00661 viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs()); 00662 return *this; 00663 } 00664 00667 vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00668 const scalar<SCALARTYPE>, 00669 op_prod> & proxy) 00670 { 00671 viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs()); 00672 return *this; 00673 } 00674 00677 vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00678 const SCALARTYPE, 00679 op_prod> & proxy) 00680 { 00681 viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs()); 00682 return *this; 00683 } 00684 00687 vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00688 const SCALARTYPE, 00689 op_prod> & proxy) 00690 { 00691 viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs()); 00692 return *this; 00693 } 00694 00697 vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00698 const scalar<SCALARTYPE>, 00699 op_div> & proxy) 00700 { 00701 viennacl::linalg::inplace_div_add(*this, proxy.lhs(), proxy.rhs()); 00702 return *this; 00703 } 00704 00705 00706 00709 vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector<SCALARTYPE, ALIGNMENT> & vec) 00710 { 00711 viennacl::linalg::inplace_sub(*this, vec); 00712 return *this; 00713 } 00714 00717 vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00718 const scalar<SCALARTYPE>, 00719 op_prod> & proxy) 00720 { 00721 viennacl::linalg::inplace_mul_sub(*this, proxy.lhs(), proxy.rhs()); 00722 return *this; 00723 } 00724 00727 vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00728 const scalar<SCALARTYPE>, 00729 op_prod> & proxy) 00730 { 00731 viennacl::linalg::inplace_mul_sub(*this, proxy.lhs(), proxy.rhs()); 00732 return *this; 00733 } 00734 00737 vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00738 const SCALARTYPE, 00739 op_prod> & proxy) 00740 { 00741 viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), -proxy.rhs()); 00742 return *this; 00743 } 00744 00747 vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00748 const SCALARTYPE, 00749 op_prod> & proxy) 00750 { 00751 viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), -proxy.rhs()); 00752 return *this; 00753 } 00754 00757 vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00758 const scalar<SCALARTYPE>, 00759 op_div> & proxy) 00760 { 00761 viennacl::linalg::inplace_div_sub(*this, proxy.lhs(), proxy.rhs()); 00762 return *this; 00763 } 00764 00765 00766 00767 00770 vector<SCALARTYPE, ALIGNMENT> & operator *= (SCALARTYPE val) 00771 { 00772 viennacl::linalg::inplace_mult(*this, val); 00773 return *this; 00774 } 00775 00778 vector<SCALARTYPE, ALIGNMENT> & operator *= (scalar<SCALARTYPE> const & gpu_val) 00779 { 00780 viennacl::linalg::inplace_mult(*this, gpu_val); 00781 return *this; 00782 } 00783 00786 vector<SCALARTYPE, ALIGNMENT> & operator /= (SCALARTYPE val) 00787 { 00788 viennacl::linalg::inplace_mult(*this, static_cast<SCALARTYPE>(1) / val); 00789 return *this; 00790 } 00791 00794 vector<SCALARTYPE, ALIGNMENT> & operator /= (scalar<SCALARTYPE> const & gpu_val) 00795 { 00796 viennacl::linalg::inplace_divide(*this, gpu_val); 00797 return *this; 00798 } 00799 00800 00801 00802 // free addition 00803 00806 vector<SCALARTYPE, ALIGNMENT> operator + (const vector<SCALARTYPE, ALIGNMENT> & vec) const 00807 { 00808 vector<SCALARTYPE, ALIGNMENT> result(internal_size()); 00809 viennacl::linalg::add(*this, vec, result); 00810 return result; 00811 } 00812 00815 vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00816 const scalar<SCALARTYPE>, 00817 op_prod> & proxy) const 00818 { 00819 vector<SCALARTYPE, ALIGNMENT> result(size_); 00820 viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result); 00821 return result; 00822 } 00823 00826 vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00827 const scalar<SCALARTYPE>, 00828 op_prod> & proxy) const 00829 { 00830 vector<SCALARTYPE, ALIGNMENT> result(size_); 00831 viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result); 00832 return result; 00833 } 00834 00837 vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00838 const SCALARTYPE, 00839 op_prod> & proxy) const 00840 { 00841 vector<SCALARTYPE, ALIGNMENT> result(size_); 00842 viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result); 00843 return result; 00844 } 00845 00848 vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00849 const SCALARTYPE, 00850 op_prod> & proxy) const 00851 { 00852 vector<SCALARTYPE, ALIGNMENT> result(size_); 00853 viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result); 00854 return result; 00855 } 00856 00857 00858 //free subtraction: 00861 vector<SCALARTYPE, ALIGNMENT> operator - (const vector<SCALARTYPE, ALIGNMENT> & vec) const 00862 { 00863 vector<SCALARTYPE, ALIGNMENT> result(size_); 00864 viennacl::linalg::sub(*this, vec, result); 00865 return result; 00866 } 00867 00870 vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00871 const scalar<SCALARTYPE>, 00872 op_prod> & proxy) const 00873 { 00874 vector<SCALARTYPE, ALIGNMENT> result(size_); 00875 result = *this; 00876 viennacl::linalg::inplace_mul_sub(result, proxy.lhs(), proxy.rhs()); 00877 return result; 00878 } 00879 00882 vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00883 const scalar<SCALARTYPE>, 00884 op_prod> & proxy) const 00885 { 00886 vector<SCALARTYPE, ALIGNMENT> result(size_); 00887 result = *this; 00888 viennacl::linalg::inplace_mul_sub(result, proxy.lhs(), proxy.rhs()); 00889 return result; 00890 } 00891 00894 vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< vector<SCALARTYPE, ALIGNMENT>, 00895 const SCALARTYPE, 00896 op_prod> & proxy) const 00897 { 00898 vector<SCALARTYPE, ALIGNMENT> result(size_); 00899 result = *this; 00900 viennacl::linalg::inplace_mul_add(result, proxy.lhs(), -proxy.rhs()); 00901 return result; 00902 } 00903 00906 vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>, 00907 const SCALARTYPE, 00908 op_prod> & proxy) const 00909 { 00910 vector<SCALARTYPE, ALIGNMENT> result(size_); 00911 result = *this; 00912 viennacl::linalg::inplace_mul_add(result, proxy.lhs(), -proxy.rhs()); 00913 return result; 00914 } 00915 00916 00917 //free multiplication 00920 vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_prod> 00921 operator * (SCALARTYPE value) const 00922 { 00923 return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_prod>(*this, value); 00924 } 00925 00928 vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_prod> 00929 operator * (scalar<SCALARTYPE> const & value) const 00930 { 00931 return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_prod>(*this, value); 00932 } 00933 00934 //free division 00937 vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_div> 00938 operator / (SCALARTYPE value) const 00939 { 00940 return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_div>(*this, value); 00941 } 00942 00945 vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_div> 00946 operator / (scalar<SCALARTYPE> const & value) const 00947 { 00948 return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_div>(*this, value); 00949 } 00950 00951 00953 00954 iterator begin() 00955 { 00956 return iterator(*this, 0); 00957 } 00958 00960 iterator end() 00961 { 00962 return iterator(*this, size()); 00963 } 00964 00966 const_iterator begin() const 00967 { 00968 return const_iterator(*this, 0); 00969 } 00970 00972 const_iterator end() const 00973 { 00974 return const_iterator(*this, size()); 00975 } 00976 00979 vector<SCALARTYPE, ALIGNMENT> & swap(vector<SCALARTYPE, ALIGNMENT> & other) 00980 { 00981 swap(*this, other); 00982 return *this; 00983 }; 00984 00987 vector<SCALARTYPE, ALIGNMENT> & fast_swap(vector<SCALARTYPE, ALIGNMENT> & other) 00988 { 00989 assert(this->size_ == other.size_); 00990 this->elements_.swap(other.elements_); 00991 return *this; 00992 }; 00993 00996 size_type size() const { return size_; } 00997 01000 size_type max_size() const 01001 { 01002 return (128*1024*1024) / sizeof(SCALARTYPE); //128 MB is maximum size of memory chunks in OpenCL! 01003 } 01006 size_type internal_size() const { return viennacl::tools::roundUpToNextMultiple<size_type>(size_, ALIGNMENT); } 01007 01009 bool empty() { return size_ == 0; } 01010 01012 const viennacl::ocl::handle<cl_mem> & handle() const { return elements_; } 01013 01016 void clear() 01017 { 01018 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::program_name(), "clear"); 01019 01020 viennacl::ocl::enqueue(k(elements_, static_cast<cl_uint>(internal_size()))); 01021 } 01022 //void swap(vector & other){} 01023 01024 01025 //TODO: Think about implementing the following public member functions 01026 //void insert_element(unsigned int i, SCALARTYPE val){} 01027 //void erase_element(unsigned int i){} 01028 01029 private: 01030 cl_uint size_; 01031 viennacl::ocl::handle<cl_mem> elements_; 01032 }; //vector 01033 01034 01035 // 01037 // 01038 01045 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR> 01046 void copy(const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin, 01047 const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end, 01048 CPU_ITERATOR cpu_begin ) 01049 { 01050 assert(gpu_end - gpu_begin >= 0); 01051 if (gpu_end - gpu_begin != 0) 01052 { 01053 std::vector<SCALARTYPE> temp_buffer(gpu_end - gpu_begin); 01054 cl_int err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(), 01055 gpu_begin.handle(), CL_TRUE, 0, 01056 sizeof(SCALARTYPE)*(gpu_end - gpu_begin), 01057 &(temp_buffer[0]), 0, NULL, NULL); 01058 VIENNACL_ERR_CHECK(err); 01059 viennacl::ocl::get_queue().finish(); 01060 01061 //now copy entries to cpu_vec: 01062 std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_begin); 01063 } 01064 } 01065 01072 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR> 01073 void copy(const vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin, 01074 const vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end, 01075 CPU_ITERATOR cpu_begin ) 01076 01077 { 01078 copy(const_vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_begin), 01079 const_vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_end), 01080 cpu_begin); 01081 } 01082 01088 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR> 01089 void copy(vector<SCALARTYPE, ALIGNMENT> const & gpu_vec, 01090 CPUVECTOR & cpu_vec ) 01091 { 01092 viennacl::copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin()); 01093 } 01094 01095 //from gpu to cpu. Type assumption: cpu_vec lies in a linear memory chunk 01107 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR> 01108 void fast_copy(const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin, 01109 const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end, 01110 CPU_ITERATOR cpu_begin ) 01111 { 01112 if (gpu_begin != gpu_end) 01113 { 01114 cl_int err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(), 01115 gpu_begin.handle(), CL_TRUE, 0, 01116 sizeof(SCALARTYPE)*(gpu_end - gpu_begin), 01117 &(*cpu_begin), 0, NULL, NULL); 01118 VIENNACL_ERR_CHECK(err); 01119 viennacl::ocl::get_queue().finish(); 01120 } 01121 } 01122 01128 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR> 01129 void fast_copy(vector<SCALARTYPE, ALIGNMENT> const & gpu_vec, 01130 CPUVECTOR & cpu_vec ) 01131 { 01132 viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin()); 01133 } 01134 01135 01136 01137 #ifdef VIENNACL_HAVE_EIGEN 01138 template <unsigned int ALIGNMENT> 01139 void copy(vector<float, ALIGNMENT> const & gpu_vec, 01140 Eigen::VectorXf & eigen_vec) 01141 { 01142 viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0])); 01143 } 01144 01145 template <unsigned int ALIGNMENT> 01146 void copy(vector<double, ALIGNMENT> & gpu_vec, 01147 Eigen::VectorXd & eigen_vec) 01148 { 01149 viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0])); 01150 } 01151 #endif 01152 01153 01154 // 01156 // 01157 01158 //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 01165 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR> 01166 void copy(CPU_ITERATOR const & cpu_begin, 01167 CPU_ITERATOR const & cpu_end, 01168 vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin) 01169 { 01170 if (cpu_begin != cpu_end) 01171 { 01172 //we require that the size of the gpu_vector is larger or equal to the cpu-size 01173 std::vector<SCALARTYPE> temp_buffer(cpu_end - cpu_begin); 01174 std::copy(cpu_begin, cpu_end, temp_buffer.begin()); 01175 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), 01176 gpu_begin.handle(), CL_TRUE, sizeof(SCALARTYPE)*gpu_begin.index(), 01177 sizeof(SCALARTYPE)*(cpu_end - cpu_begin), 01178 &(temp_buffer[0]), 0, NULL, NULL); 01179 VIENNACL_ERR_CHECK(err); 01180 } 01181 } 01182 01183 // for things like copy(std_vec.begin(), std_vec.end(), vcl_vec.begin() + 1); 01184 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR> 01185 void copy(CPU_ITERATOR const & cpu_begin, 01186 CPU_ITERATOR const & cpu_end, 01187 const_vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin) 01188 { 01189 copy(cpu_begin, cpu_end, vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_begin)); 01190 } 01191 01197 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR> 01198 void copy(const CPUVECTOR & cpu_vec, vector<SCALARTYPE, ALIGNMENT> & gpu_vec) 01199 { 01200 viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin()); 01201 } 01202 01214 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR> 01215 void fast_copy(CPU_ITERATOR const & cpu_begin, 01216 CPU_ITERATOR const & cpu_end, 01217 vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin) 01218 { 01219 if (cpu_begin != cpu_end) 01220 { 01221 //we require that the size of the gpu_vector is larger or equal to the cpu-size 01222 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), 01223 gpu_begin.handle(), CL_TRUE, 0, 01224 sizeof(SCALARTYPE)*(cpu_end - cpu_begin), &(*cpu_begin), 0, NULL, NULL); 01225 VIENNACL_ERR_CHECK(err); 01226 } 01227 } 01228 01229 01235 template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR> 01236 void fast_copy(const CPUVECTOR & cpu_vec, vector<SCALARTYPE, ALIGNMENT> & gpu_vec) 01237 { 01238 viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin()); 01239 } 01240 01241 #ifdef VIENNACL_HAVE_EIGEN 01242 template <unsigned int ALIGNMENT> 01243 void copy(Eigen::VectorXf const & eigen_vec, 01244 vector<float, ALIGNMENT> & gpu_vec) 01245 { 01246 std::vector<float> entries(eigen_vec.size()); 01247 for (size_t i = 0; i<entries.size(); ++i) 01248 entries[i] = eigen_vec(i); 01249 viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin()); 01250 } 01251 01252 template <unsigned int ALIGNMENT> 01253 void copy(Eigen::VectorXd const & eigen_vec, 01254 vector<double, ALIGNMENT> & gpu_vec) 01255 { 01256 std::vector<double> entries(eigen_vec.size()); 01257 for (size_t i = 0; i<entries.size(); ++i) 01258 entries[i] = eigen_vec(i); 01259 viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin()); 01260 } 01261 #endif 01262 01263 01264 01265 // 01267 // 01274 template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST> 01275 void copy(const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_begin, 01276 const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end, 01277 vector_iterator<SCALARTYPE, ALIGNMENT_DEST> gpu_dest_begin) 01278 { 01279 assert(gpu_src_end - gpu_src_begin >= 0); 01280 if (gpu_src_begin != gpu_src_end) 01281 { 01282 cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), 01283 gpu_src_begin.handle(), //src handle 01284 gpu_dest_begin.handle(), //dest handle 01285 sizeof(SCALARTYPE) * gpu_src_begin.index(), //src offset 01286 sizeof(SCALARTYPE) * gpu_dest_begin.index(), //dest offset 01287 sizeof(SCALARTYPE) * (gpu_src_end.index() - gpu_src_begin.index()), //data length 01288 0, //don't know -> check!! (something related to increment?) 01289 NULL, NULL); 01290 VIENNACL_ERR_CHECK(err); 01291 } 01292 } 01293 01300 template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST> 01301 void copy(const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_begin, 01302 const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end, 01303 const_vector_iterator<SCALARTYPE, ALIGNMENT_DEST> gpu_dest_begin) 01304 { 01305 copy(gpu_src_begin, gpu_src_end, vector_iterator<SCALARTYPE, ALIGNMENT_DEST>(gpu_dest_begin)); 01306 } 01307 01313 template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST> 01314 void copy(vector<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_vec, 01315 vector<SCALARTYPE, ALIGNMENT_DEST> & gpu_dest_vec ) 01316 { 01317 viennacl::copy(gpu_src_vec.begin(), gpu_src_vec.end(), gpu_dest_vec.begin()); 01318 } 01319 01320 01321 01322 01323 01324 01325 //global functions for handling vectors: 01330 template<class SCALARTYPE, unsigned int ALIGNMENT> 01331 std::ostream & operator<<(std::ostream & s, vector<SCALARTYPE,ALIGNMENT> const & val) 01332 { 01333 viennacl::ocl::get_queue().finish(); 01334 std::vector<SCALARTYPE> tmp(val.size()); 01335 copy(val.begin(), val.end(), tmp.begin()); 01336 std::cout << "[" << val.size() << "]("; 01337 for (typename std::vector<SCALARTYPE>::size_type i=0; i<val.size(); ++i) 01338 { 01339 if (i > 0) 01340 s << ","; 01341 s << tmp[i]; 01342 } 01343 std::cout << ")"; 01344 return s; 01345 } 01346 01353 template<class SCALARTYPE, unsigned int ALIGNMENT> 01354 void swap(viennacl::vector<SCALARTYPE, ALIGNMENT> & vec1, 01355 viennacl::vector<SCALARTYPE, ALIGNMENT> & vec2) 01356 { 01357 assert(vec1.size() == vec2.size()); 01358 01359 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::program_name(), "swap"); 01360 01361 viennacl::ocl::enqueue(k(vec1, vec2, static_cast<cl_uint>(vec1.size()))); 01362 } 01363 01369 template <typename SCALARTYPE, unsigned int ALIGNMENT> 01370 vector<SCALARTYPE, ALIGNMENT> & fast_swap(vector<SCALARTYPE, ALIGNMENT> & v1, 01371 vector<SCALARTYPE, ALIGNMENT> & v2) 01372 { 01373 return v1.fast_swap(v2); 01374 } 01375 01376 01377 01379 01384 template <typename SCALARTYPE, unsigned int A> 01385 vector_expression< const vector<SCALARTYPE, A>, const SCALARTYPE, op_prod> operator * (SCALARTYPE const & value, vector<SCALARTYPE, A> const & vec) 01386 { 01387 return vector_expression< const vector<SCALARTYPE, A>, const SCALARTYPE, op_prod>(vec, value); 01388 } 01389 01395 template <typename SCALARTYPE, unsigned int A> 01396 vector_expression< const vector<SCALARTYPE, A>, const scalar<SCALARTYPE>, op_prod> operator * (scalar<SCALARTYPE> const & value, vector<SCALARTYPE, A> const & vec) 01397 { 01398 return vector_expression< const vector<SCALARTYPE, A>, const scalar<SCALARTYPE>, op_prod>(vec, value); 01399 } 01400 01401 01402 //addition and subtraction of two vector_expressions: 01408 template <typename LHS1, typename RHS1, typename OP1, 01409 typename LHS2, typename RHS2, typename OP2> 01410 typename vector_expression< LHS1, RHS1, OP1>::VectorType 01411 operator + (vector_expression< LHS1, RHS1, OP1> const & proxy1, 01412 vector_expression< LHS2, RHS2, OP2> const & proxy2) 01413 { 01414 assert(proxy1.size() == proxy2.size()); 01415 typename vector_expression< LHS1, RHS1, OP1>::VectorType result(proxy1.size()); 01416 result = proxy1; 01417 result += proxy2; 01418 return result; 01419 } 01420 01426 template <typename LHS1, typename RHS1, typename OP1, 01427 typename LHS2, typename RHS2, typename OP2> 01428 typename vector_expression< LHS1, RHS1, OP1>::VectorType 01429 operator - (vector_expression< LHS1, RHS1, OP1> const & proxy1, 01430 vector_expression< LHS2, RHS2, OP2> const & proxy2) 01431 { 01432 assert(proxy1.size() == proxy2.size()); 01433 typename vector_expression< LHS1, RHS1, OP1>::VectorType result(proxy1.size()); 01434 result = proxy1; 01435 result -= proxy2; 01436 return result; 01437 } 01438 01440 01446 template <typename SCALARTYPE, unsigned int A, typename LHS, typename RHS, typename OP> 01447 vector<SCALARTYPE, A> operator + (vector_expression< LHS, RHS, OP> const & proxy, 01448 vector<SCALARTYPE, A> const & vec) 01449 { 01450 assert(proxy.size() == vec.size()); 01451 vector<SCALARTYPE, A> result(vec.size()); 01452 result = proxy; 01453 result += vec; 01454 return result; 01455 } 01456 01462 template <typename SCALARTYPE, unsigned int A, typename LHS, typename RHS, typename OP> 01463 vector<SCALARTYPE, A> operator - (vector_expression< LHS, RHS, OP> const & proxy, 01464 vector<SCALARTYPE, A> const & vec) 01465 { 01466 assert(proxy.size() == vec.size()); 01467 vector<SCALARTYPE, A> result(vec.size()); 01468 result = proxy; 01469 result -= vec; 01470 return result; 01471 } 01472 01473 01479 template <typename SCALARTYPE, typename LHS, typename RHS, typename OP> 01480 vector<SCALARTYPE> operator * (vector_expression< LHS, RHS, OP> const & proxy, 01481 scalar<SCALARTYPE> const & val) 01482 { 01483 vector<SCALARTYPE> result(proxy.size()); 01484 result = proxy; 01485 result *= val; 01486 return result; 01487 } 01488 01494 template <typename SCALARTYPE, typename LHS, typename RHS, typename OP> 01495 vector<SCALARTYPE> operator / (vector_expression< LHS, RHS, OP> const & proxy, 01496 scalar<SCALARTYPE> const & val) 01497 { 01498 vector<SCALARTYPE> result(proxy.size()); 01499 result = proxy; 01500 result /= val; 01501 return result; 01502 } 01503 01504 01506 01512 template <typename SCALARTYPE, typename LHS, typename RHS, typename OP> 01513 vector<SCALARTYPE> operator * (scalar<SCALARTYPE> const & val, 01514 vector_expression< LHS, RHS, OP> const & proxy) 01515 { 01516 vector<SCALARTYPE> result(proxy.size()); 01517 result = proxy; 01518 result *= val; 01519 return result; 01520 } 01521 01527 template <typename SCALARTYPE, typename LHS, typename RHS, typename OP> 01528 viennacl::vector<SCALARTYPE> operator * (SCALARTYPE val, 01529 viennacl::vector_expression< LHS, RHS, OP> const & proxy) 01530 { 01531 viennacl::vector<SCALARTYPE> result(proxy.size()); 01532 result = proxy; 01533 result *= val; 01534 return result; 01535 } 01536 01537 } 01538 01539 #endif
1.7.6.1