00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00120
00121
00122
00123
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
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
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
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();
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
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>
00292 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00293 const scalar<SCALARTYPE>,
00294 op_prod> & proxy)
00295 {
00296 resize(proxy.lhs().size());
00297
00298 viennacl::linalg::mult(proxy.lhs(), proxy.rhs(), *this);
00299 return *this;
00300 }
00301
00306 template <typename 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>
00321 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00322 const scalar<SCALARTYPE>,
00323 op_div> & proxy)
00324 {
00325 resize(proxy.lhs().size());
00326
00327 viennacl::linalg::divide(proxy.lhs(), proxy.rhs(), *this);
00328 return *this;
00329 }
00330
00335 template <typename VectorType>
00336 vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00337 const SCALARTYPE,
00338 op_div> & proxy)
00339 {
00340 resize(proxy.lhs().size());
00341
00342 viennacl::linalg::mult(proxy.lhs(), static_cast<SCALARTYPE>(1.0) / proxy.rhs(), *this);
00343 return *this;
00344 }
00345
00346
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
00357 viennacl::linalg::add(proxy.lhs(), proxy.rhs(), *this);
00358 return *this;
00359 }
00360
00361
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
00372 viennacl::linalg::sub(proxy.lhs(), proxy.rhs(), *this);
00373 return *this;
00374 }
00375
00377
00378
00379
00380
00381
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
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
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
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);
00598 temp.resize(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
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
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
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
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
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
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);
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
01023
01024
01025
01026
01027
01028
01029 private:
01030 cl_uint size_;
01031 viennacl::ocl::handle<cl_mem> elements_;
01032 };
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
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
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
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
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
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
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(),
01284 gpu_dest_begin.handle(),
01285 sizeof(SCALARTYPE) * gpu_src_begin.index(),
01286 sizeof(SCALARTYPE) * gpu_dest_begin.index(),
01287 sizeof(SCALARTYPE) * (gpu_src_end.index() - gpu_src_begin.index()),
01288 0,
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
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
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