• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/data/development/ViennaCL/dev/viennacl/vector.hpp

Go to the documentation of this file.
00001 #ifndef VIENNACL_VECTOR_HPP_
00002 #define VIENNACL_VECTOR_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2011, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                   ViennaCL - The Vienna Computing Library
00011                             -----------------
00012 
00013    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00014                
00015    (A list of authors and contributors can be found in the PDF manual)
00016 
00017    License:         MIT (X11), see file LICENSE in the base directory
00018 ============================================================================= */
00019 
00026 #include "viennacl/forwards.h"
00027 #include "viennacl/ocl/backend.hpp"
00028 #include "viennacl/scalar.hpp"
00029 #include "viennacl/tools/tools.hpp"
00030 #include "viennacl/tools/entry_proxy.hpp"
00031 #include "viennacl/linalg/vector_operations.hpp"
00032 
00033 namespace viennacl
00034 {
00035     
00048     template <typename LHS, typename RHS, typename OP>
00049     class vector_expression
00050     {
00051       public:
00054         typedef typename viennacl::tools::VECTOR_EXTRACTOR<LHS, RHS>::ResultType    VectorType;
00055       
00056         vector_expression(LHS & lhs, RHS & rhs) : _lhs(lhs), _rhs(rhs) {}
00057         
00060         LHS & lhs() const { return _lhs; }
00063         RHS & rhs() const { return _rhs; }
00064         
00066         std::size_t size() const { return viennacl::tools::VECTOR_SIZE_DEDUCER<LHS, RHS, OP>::size(_lhs, _rhs); }
00067         
00068       private:
00070         LHS & _lhs;
00072         RHS & _rhs;
00073     };
00074     
00093     template<class SCALARTYPE, unsigned int ALIGNMENT>
00094     class const_vector_iterator
00095     {
00096         typedef const_vector_iterator<SCALARTYPE, ALIGNMENT>    self_type;
00097       public:
00098         typedef scalar<SCALARTYPE>            value_type;
00099         typedef long                          difference_type;
00100         
00101         const_vector_iterator() {};
00106         const_vector_iterator(vector<SCALARTYPE, ALIGNMENT> const & vec,      cl_uint index)  : elements_(vec.handle()), index_(index) {};
00107         const_vector_iterator(viennacl::ocl::handle<cl_mem> const & elements, cl_uint index)  : elements_(elements), index_(index) {};
00108 
00109         
00110         value_type operator*(void) const 
00111         { 
00112            value_type result;
00113            result = entry_proxy<SCALARTYPE>(index_, elements_);
00114            return result;
00115         }
00116         self_type operator++(void) { ++index_; return *this; }
00117         self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
00118         
00119         bool operator==(self_type const & other) const { return index_ == other.index_; }
00120         bool operator!=(self_type const & other) const { return index_ != other.index_; }
00121         
00122 //        self_type & operator=(self_type const & other)
00123 //        {
00124 //           _index = other._index;
00125 //           elements_ = other._elements;
00126 //           return *this;
00127 //        }   
00128 
00129         difference_type operator-(self_type const & other) const { difference_type result = index_; return result - other.index_; }
00130         self_type operator+(difference_type diff) const { return self_type(elements_, index_ + diff); }
00131         
00132         std::size_t index() const { return index_; }
00133         viennacl::ocl::handle<cl_mem> const & handle() const { return elements_; }
00134 
00135       protected:
00137         viennacl::ocl::handle<cl_mem> elements_;
00138         std::size_t index_;
00139     };
00140     
00141 
00161     template<class SCALARTYPE, unsigned int ALIGNMENT>
00162     class vector_iterator : public const_vector_iterator<SCALARTYPE, ALIGNMENT>
00163     {
00164         typedef const_vector_iterator<SCALARTYPE, ALIGNMENT>  base_type;
00165         typedef vector_iterator<SCALARTYPE, ALIGNMENT>        self_type;
00166       public:
00167         vector_iterator() : base_type(){};
00168         vector_iterator(viennacl::ocl::handle<cl_mem> const & elements, std::size_t index)  : base_type(elements, index) {};
00173         vector_iterator(vector<SCALARTYPE, ALIGNMENT> & vec, cl_uint index) : base_type(vec, index) {};
00174         vector_iterator(base_type const & b) : base_type(b) {};
00175 
00176         typename base_type::value_type operator*(void)  
00177         { 
00178            typename base_type::value_type result;
00179            result = entry_proxy<SCALARTYPE>(base_type::index_, base_type::elements_); 
00180            return result;
00181         }
00182         
00183         viennacl::ocl::handle<cl_mem> handle() { return base_type::elements_; }
00184         
00185         operator base_type() const
00186         {
00187           return base_type(base_type::elements_, base_type::index_);
00188         }
00189     };
00190 
00191     // forward definition in VCLForwards.h!
00200     template<class SCALARTYPE, unsigned int ALIGNMENT>
00201     class vector
00202     {
00203       
00204     public:
00205       typedef scalar<typename viennacl::tools::CHECK_SCALAR_TEMPLATE_ARGUMENT<SCALARTYPE>::ResultType>   value_type;
00206       typedef vcl_size_t                                        size_type;
00207       typedef vcl_ptrdiff_t                                     difference_type;
00208       typedef const_vector_iterator<SCALARTYPE, ALIGNMENT>      const_iterator;
00209       typedef vector_iterator<SCALARTYPE, ALIGNMENT>            iterator;
00210       
00211       static const int alignment = ALIGNMENT;
00212 
00215       vector() : size_(0) { viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::init();  }
00216 
00221       explicit vector(size_type vec_size) : size_(vec_size)
00222       {
00223         viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::init(); 
00224         
00225         if (size_ > 0)
00226           elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*internal_size());
00227         
00228         //force entries above size_ to zero:
00229         if (size_ < internal_size())
00230         {
00231           std::vector<SCALARTYPE> temp(internal_size() - size_);
00232           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);
00233           //assert(err == CL_SUCCESS);
00234           VIENNACL_ERR_CHECK(err);
00235         }
00236       }
00237 
00246       explicit vector(cl_mem existing_mem, size_type vec_size) : size_(vec_size),  elements_(existing_mem)
00247       {
00248         elements_.inc();  //prevents that the user-provided memory is deleted once the vector object is destroyed.
00249       }
00250       
00251       template <typename LHS, typename RHS, typename OP>
00252       vector(vector_expression<LHS, RHS, OP> const & other) : size_(other.size())
00253       {
00254         elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*other.size());
00255         *this = other;
00256       }
00257       
00262       vector(const vector<SCALARTYPE, ALIGNMENT> & vec) :
00263         size_(vec.size())
00264       {
00265         viennacl::linalg::kernels::vector<SCALARTYPE, 1>::init(); 
00266         
00267         if (size() != 0)
00268         {
00269           elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*internal_size());
00270           cl_int err;
00271           err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), vec.handle(), elements_, 0, 0, sizeof(SCALARTYPE)*internal_size(), 0, NULL, NULL);
00272           //assert(err == CL_SUCCESS);
00273           VIENNACL_ERR_CHECK(err);
00274         }
00275       }
00276 
00279       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector<SCALARTYPE, ALIGNMENT> & vec)
00280       {
00281         resize(vec.size());
00282         if (size() != 0)
00283         {
00284           cl_int err;
00285           err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), vec.handle(), elements_, 0, 0, sizeof(SCALARTYPE)*internal_size(), 0, NULL, NULL);
00286           VIENNACL_ERR_CHECK(err);
00287         }
00288         return *this;
00289       }
00290 
00291 
00296       template <typename VectorType>   //use template to cover const/non-const of VectorType:
00297       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00298                                                                            const scalar<SCALARTYPE>,
00299                                                                            op_prod> & proxy)
00300       {
00301         resize(proxy.lhs().size());
00302         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00303         viennacl::linalg::mult(proxy.lhs(), proxy.rhs(), *this);
00304         return *this;
00305       }
00306 
00311       template <typename VectorType>   //use template to cover const/non-const of VectorType:
00312       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00313                                                                            const SCALARTYPE,
00314                                                                            op_prod> & proxy)
00315       {
00316         resize(proxy.lhs().size());
00317         viennacl::linalg::mult(proxy.lhs(), proxy.rhs(), *this);
00318         return *this;
00319       }
00320 
00325       template <typename VectorType>   //use template to cover const/non-const of VectorType:
00326       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00327                                                                            const scalar<SCALARTYPE>,
00328                                                                            op_div> & proxy)
00329       {
00330         resize(proxy.lhs().size());
00331         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00332         viennacl::linalg::divide(proxy.lhs(), proxy.rhs(), *this);
00333         return *this;
00334       }
00335 
00340       template <typename VectorType>   //use template to cover const/non-const of VectorType:
00341       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00342                                                                            const SCALARTYPE,
00343                                                                            op_div> & proxy)
00344       {
00345         resize(proxy.lhs().size());
00346         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00347         viennacl::linalg::mult(proxy.lhs(), static_cast<SCALARTYPE>(1.0) / proxy.rhs(), *this);
00348         return *this;
00349       }
00350 
00351       //v1 = v2 + v3; 
00356       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00357                                                                            vector<SCALARTYPE, ALIGNMENT>,
00358                                                                            op_add> & proxy)
00359       {
00360         resize(proxy.lhs().size());
00361         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00362         viennacl::linalg::add(proxy.lhs(), proxy.rhs(), *this);
00363         return *this;
00364       }
00365       
00366       //v1 = v2 - v3; 
00371       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00372                                                                            vector<SCALARTYPE, ALIGNMENT>,
00373                                                                            op_sub> & proxy)
00374       {
00375         resize(proxy.lhs().size());
00376         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00377         viennacl::linalg::sub(proxy.lhs(), proxy.rhs(), *this);
00378         return *this;
00379       }
00380       
00382 
00383       //Note: The following operator overloads are defined in matrix_operations.hpp, compressed_matrix_operations.hpp and coordinate_matrix_operations.hpp
00384       //This is certainly not the nicest approach and will most likely by changed in the future, but it works :-)
00385       
00386       //matrix<>
00391       template <typename F, unsigned int MAT_ALIGNMENT>
00392       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00393                                                 const vector<SCALARTYPE, ALIGNMENT>,
00394                                                 op_prod> & proxy);
00395 
00400       template <typename F, unsigned int MAT_ALIGNMENT>
00401       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00402                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00403                                                                           op_prod> & proxy);
00404                                                 
00409       template <typename F, unsigned int MAT_ALIGNMENT>
00410       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00411                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00412                                                                           op_prod> & proxy);
00413 
00418       template <typename F, unsigned int MAT_ALIGNMENT>
00419       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00420                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00421                                                                        op_prod> & proxy);
00422 
00427       template <typename F, unsigned int MAT_ALIGNMENT>
00428       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00429                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00430                                                                        op_prod> & proxy);
00431 
00432       //transposed_matrix_proxy:
00437       template <typename F, unsigned int MAT_ALIGNMENT>
00438       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00439                                                                                                   const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00440                                                                                                   op_trans >,
00441                                                                          const vector<SCALARTYPE, ALIGNMENT>,
00442                                                                          op_prod> & proxy);
00443 
00448       template <typename F, unsigned int MAT_ALIGNMENT>
00449       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00450                                                                                                    const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00451                                                                                                    op_trans >,
00452                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00453                                                                           op_prod> & proxy);
00454                                                 
00459       template <typename F, unsigned int MAT_ALIGNMENT>
00460       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00461                                                                                                    const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00462                                                                                                    op_trans >,
00463                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00464                                                                           op_prod> & proxy);
00465 
00470       template <typename F, unsigned int MAT_ALIGNMENT>
00471       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00472                                                                                                 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00473                                                                                                 op_trans >,
00474                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00475                                                                        op_prod> & proxy);
00476 
00481       template <typename F, unsigned int MAT_ALIGNMENT>
00482       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00483                                                                                                 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00484                                                                                                 op_trans >,
00485                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00486                                                                        op_prod> & proxy);
00487                                                                        
00488                                                                        
00489       //                                                                 
00491       //
00496       template <unsigned int MAT_ALIGNMENT>
00497       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00498                                                 const vector<SCALARTYPE, ALIGNMENT>,
00499                                                 op_prod> & proxy);
00500 
00505       template <unsigned int MAT_ALIGNMENT>
00506       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00507                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00508                                                                           op_prod> & proxy);
00509                                                 
00514       template <unsigned int MAT_ALIGNMENT>
00515       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00516                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00517                                                                           op_prod> & proxy);
00518 
00523       template <unsigned int MAT_ALIGNMENT>
00524       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00525                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00526                                                                        op_prod> & proxy);
00527 
00532       template <unsigned int MAT_ALIGNMENT>
00533       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00534                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00535                                                                        op_prod> & proxy);
00536 
00537       //
00538       // coordinate_matrix<>
00539       //
00544       template <unsigned int MAT_ALIGNMENT>
00545       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00546                                                 const vector<SCALARTYPE, ALIGNMENT>,
00547                                                 op_prod> & proxy);
00548 
00553       template <unsigned int MAT_ALIGNMENT>
00554       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00555                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00556                                                                           op_prod> & proxy);
00557                                                 
00562       template <unsigned int MAT_ALIGNMENT>
00563       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00564                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00565                                                                           op_prod> & proxy);
00566 
00571       template <unsigned int MAT_ALIGNMENT>
00572       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00573                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00574                                                                        op_prod> & proxy);
00575 
00580       template <unsigned int MAT_ALIGNMENT>
00581       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00582                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00583                                                                        op_prod> & proxy);
00584 
00585       //
00586       // circulant_matrix<>
00587       //
00592       template <unsigned int MAT_ALIGNMENT>
00593       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00594                                                 const vector<SCALARTYPE, ALIGNMENT>,
00595                                                 op_prod> & proxy);
00596 
00601       template <unsigned int MAT_ALIGNMENT>
00602       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00603                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00604                                                                           op_prod> & proxy);
00605                                                 
00610       template <unsigned int MAT_ALIGNMENT>
00611       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00612                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00613                                                                           op_prod> & proxy);
00614 
00619       template <unsigned int MAT_ALIGNMENT>
00620       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00621                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00622                                                                        op_prod> & proxy);
00623 
00628       template <unsigned int MAT_ALIGNMENT>
00629       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const circulant_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00630                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00631                                                                        op_prod> & proxy);
00632 
00633 
00634       //
00635       // hankel_matrix<>
00636       //
00641       template <unsigned int MAT_ALIGNMENT>
00642       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const hankel_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00643                                                 const vector<SCALARTYPE, ALIGNMENT>,
00644                                                 op_prod> & proxy);
00645 
00650       template <unsigned int MAT_ALIGNMENT>
00651       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const hankel_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00652                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00653                                                                           op_prod> & proxy);
00654                                                 
00659       template <unsigned int MAT_ALIGNMENT>
00660       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const hankel_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00661                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00662                                                                           op_prod> & proxy);
00663 
00668       template <unsigned int MAT_ALIGNMENT>
00669       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const hankel_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00670                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00671                                                                        op_prod> & proxy);
00672 
00677       template <unsigned int MAT_ALIGNMENT>
00678       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const hankel_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00679                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00680                                                                        op_prod> & proxy);
00681 
00682       //
00683       // toeplitz_matrix<>
00684       //
00689       template <unsigned int MAT_ALIGNMENT>
00690       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const toeplitz_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00691                                                 const vector<SCALARTYPE, ALIGNMENT>,
00692                                                 op_prod> & proxy);
00693 
00698       template <unsigned int MAT_ALIGNMENT>
00699       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const toeplitz_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00700                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00701                                                                           op_prod> & proxy);
00702                                                 
00707       template <unsigned int MAT_ALIGNMENT>
00708       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const toeplitz_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00709                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00710                                                                           op_prod> & proxy);
00711 
00716       template <unsigned int MAT_ALIGNMENT>
00717       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const toeplitz_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00718                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00719                                                                        op_prod> & proxy);
00720 
00725       template <unsigned int MAT_ALIGNMENT>
00726       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const toeplitz_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00727                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00728                                                                        op_prod> & proxy);
00729 
00730       
00731       //
00732       // vandermonde_matrix<>
00733       //
00738       template <unsigned int MAT_ALIGNMENT>
00739       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const vandermonde_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00740                                                 const vector<SCALARTYPE, ALIGNMENT>,
00741                                                 op_prod> & proxy);
00742 
00747       template <unsigned int MAT_ALIGNMENT>
00748       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const vandermonde_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00749                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00750                                                                           op_prod> & proxy);
00751                                                 
00756       template <unsigned int MAT_ALIGNMENT>
00757       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const vandermonde_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00758                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00759                                                                           op_prod> & proxy);
00760 
00765       template <unsigned int MAT_ALIGNMENT>
00766       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const vandermonde_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00767                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00768                                                                        op_prod> & proxy);
00769 
00774       template <unsigned int MAT_ALIGNMENT>
00775       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const vandermonde_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00776                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00777                                                                        op_prod> & proxy);
00778 
00779       
00780       
00782 
00783       //enlarge or reduce allocated memory and set unused memory to zero
00789       void resize(size_type new_size, bool preserve = true)
00790       {
00791         assert(new_size > 0);
00792         
00793         if (new_size != size_)
00794         {
00795           std::size_t new_internal_size = viennacl::tools::roundUpToNextMultiple<std::size_t>(new_size, ALIGNMENT);
00796         
00797           std::vector<SCALARTYPE> temp(size_);
00798           if (preserve && size_ > 0)
00799             fast_copy(*this, temp);
00800           temp.resize(new_size);  //drop all entries above new_size
00801           temp.resize(new_internal_size); //enlarge to fit new internal size
00802           
00803           if (new_internal_size != internal_size())
00804           {
00805             elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*new_internal_size);
00806           }
00807           
00808           fast_copy(temp, *this);
00809           size_ = new_size;
00810         }
00811         
00812       }
00813       
00814 
00815       //read-write access to an element of the vector
00818       entry_proxy<SCALARTYPE> operator()(size_type index)
00819       {
00820         return entry_proxy<SCALARTYPE>(index, elements_);
00821       }
00822 
00825       entry_proxy<SCALARTYPE> operator[](size_type index)
00826       {
00827         return entry_proxy<SCALARTYPE>(index, elements_);
00828       }
00829 
00830 
00833       scalar<SCALARTYPE> operator()(size_type index) const
00834       {
00835         scalar<SCALARTYPE> tmp;
00836         cl_int err;
00837         err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), elements_, tmp.handle(), sizeof(SCALARTYPE)*index, 0, sizeof(SCALARTYPE), 0, NULL, NULL);
00838         //assert(err == CL_SUCCESS);
00839         VIENNACL_ERR_CHECK(err);
00840         return tmp;
00841       }
00842       
00845       scalar<SCALARTYPE> operator[](size_type index) const
00846       {
00847         return operator()(index);
00848       }
00849       
00852       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector<SCALARTYPE, ALIGNMENT> & vec)
00853       {
00854         viennacl::linalg::inplace_add(*this, vec);
00855         return *this;
00856       }
00857 
00860       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00861                                                                            const scalar<SCALARTYPE>,
00862                                                                            op_prod> & proxy)
00863       {
00864         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs());
00865         return *this;
00866       }
00867 
00870       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00871                                                                            const scalar<SCALARTYPE>,
00872                                                                            op_prod> & proxy)
00873       {
00874         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs());
00875         return *this;
00876       }
00877 
00880       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00881                                                                            const SCALARTYPE,
00882                                                                            op_prod> & proxy)
00883       {
00884         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs());
00885         return *this;
00886       }
00887 
00890       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00891                                                                            const SCALARTYPE,
00892                                                                            op_prod> & proxy)
00893       {
00894         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs());
00895         return *this;
00896       }
00897 
00900       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00901                                                                            const scalar<SCALARTYPE>,
00902                                                                            op_div> & proxy)
00903       {
00904         viennacl::linalg::inplace_div_add(*this, proxy.lhs(), proxy.rhs());
00905         return *this;
00906       }
00907 
00908 
00909 
00912       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector<SCALARTYPE, ALIGNMENT> & vec)
00913       {
00914         viennacl::linalg::inplace_sub(*this, vec);
00915         return *this;
00916       }
00917 
00920       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00921                                                                            const scalar<SCALARTYPE>,
00922                                                                            op_prod> & proxy)
00923       {
00924         viennacl::linalg::inplace_mul_sub(*this, proxy.lhs(), proxy.rhs());
00925         return *this;
00926       }
00927 
00930       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00931                                                                            const scalar<SCALARTYPE>,
00932                                                                            op_prod> & proxy)
00933       {
00934         viennacl::linalg::inplace_mul_sub(*this, proxy.lhs(), proxy.rhs());
00935         return *this;
00936       }
00937 
00940       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00941                                                                             const SCALARTYPE,
00942                                                                             op_prod> & proxy)
00943       {
00944         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), -proxy.rhs());
00945         return *this;
00946       }
00947 
00950       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00951                                                                             const SCALARTYPE,
00952                                                                             op_prod> & proxy)
00953       {
00954         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), -proxy.rhs());
00955         return *this;
00956       }
00957       
00960       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00961                                                                             const scalar<SCALARTYPE>,
00962                                                                             op_div> & proxy)
00963       {
00964         viennacl::linalg::inplace_div_sub(*this, proxy.lhs(), proxy.rhs());
00965         return *this;
00966       }
00967       
00968       
00969       
00970 
00973       vector<SCALARTYPE, ALIGNMENT> & operator *= (SCALARTYPE val)
00974       {
00975         viennacl::linalg::inplace_mult(*this, val);
00976         return *this;
00977       }
00978 
00981       vector<SCALARTYPE, ALIGNMENT> & operator *= (scalar<SCALARTYPE> const & gpu_val)
00982       {
00983         viennacl::linalg::inplace_mult(*this, gpu_val);
00984         return *this;
00985       }
00986 
00989       vector<SCALARTYPE, ALIGNMENT> & operator /= (SCALARTYPE val)
00990       {
00991         viennacl::linalg::inplace_mult(*this, static_cast<SCALARTYPE>(1) / val);
00992         return *this;
00993       }
00994       
00997       vector<SCALARTYPE, ALIGNMENT> & operator /= (scalar<SCALARTYPE> const & gpu_val)
00998       {
00999         viennacl::linalg::inplace_divide(*this, gpu_val);
01000         return *this;
01001       }
01002       
01003       
01004       
01005       // free addition
01006       
01009       vector<SCALARTYPE, ALIGNMENT> operator + (const vector<SCALARTYPE, ALIGNMENT> & vec) const
01010       {
01011         vector<SCALARTYPE, ALIGNMENT> result(internal_size());
01012         viennacl::linalg::add(*this, vec, result);
01013         return result;
01014       }
01015       
01018       vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
01019                                                                          const scalar<SCALARTYPE>,
01020                                                                            op_prod> & proxy) const
01021       {
01022         vector<SCALARTYPE, ALIGNMENT> result(size_);
01023         viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result);
01024         return result;
01025       }
01026 
01029       vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
01030                                                                          const scalar<SCALARTYPE>,
01031                                                                            op_prod> & proxy) const
01032       {
01033         vector<SCALARTYPE, ALIGNMENT> result(size_);
01034         viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result);
01035         return result;
01036       }
01037 
01040       vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
01041                                                                          const SCALARTYPE,
01042                                                                          op_prod> & proxy) const
01043       {
01044         vector<SCALARTYPE, ALIGNMENT> result(size_);
01045         viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result);
01046         return result;
01047       }
01048 
01051       vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
01052                                                                          const SCALARTYPE,
01053                                                                          op_prod> & proxy) const
01054       {
01055         vector<SCALARTYPE, ALIGNMENT> result(size_);
01056         viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result);
01057         return result;
01058       }
01059 
01060 
01061       //free subtraction:
01064       vector<SCALARTYPE, ALIGNMENT> operator - (const vector<SCALARTYPE, ALIGNMENT> & vec) const
01065       {
01066         vector<SCALARTYPE, ALIGNMENT> result(size_);
01067         viennacl::linalg::sub(*this, vec, result);
01068         return result;
01069       }
01070 
01073       vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
01074                                                                          const scalar<SCALARTYPE>,
01075                                                                            op_prod> & proxy) const
01076       {
01077         vector<SCALARTYPE, ALIGNMENT> result(size_);
01078         result = *this;
01079         viennacl::linalg::inplace_mul_sub(result, proxy.lhs(), proxy.rhs());
01080         return result;
01081       }
01082 
01085       vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
01086                                                                          const scalar<SCALARTYPE>,
01087                                                                            op_prod> & proxy) const
01088       {
01089         vector<SCALARTYPE, ALIGNMENT> result(size_);
01090         result = *this;
01091         viennacl::linalg::inplace_mul_sub(result, proxy.lhs(), proxy.rhs());
01092         return result;
01093       }
01094 
01097       vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
01098                                                                          const SCALARTYPE,
01099                                                                          op_prod> & proxy) const
01100       {
01101         vector<SCALARTYPE, ALIGNMENT> result(size_);
01102         result = *this;
01103         viennacl::linalg::inplace_mul_add(result, proxy.lhs(), -proxy.rhs());
01104         return result;
01105       }
01106 
01109       vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
01110                                                                          const SCALARTYPE,
01111                                                                          op_prod> & proxy) const
01112       {
01113         vector<SCALARTYPE, ALIGNMENT> result(size_);
01114         result = *this;
01115         viennacl::linalg::inplace_mul_add(result, proxy.lhs(), -proxy.rhs());
01116         return result;
01117       }
01118 
01119       
01120       //free multiplication
01123       vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_prod> 
01124       operator * (SCALARTYPE value) const
01125       {
01126         return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_prod>(*this, value);
01127       }
01128 
01131       vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_prod> 
01132       operator * (scalar<SCALARTYPE> const & value) const
01133       {
01134         return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_prod>(*this, value);
01135       }
01136 
01137       //free division
01140       vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_div> 
01141       operator / (SCALARTYPE value) const
01142       {
01143         return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_div>(*this, value);
01144       }
01145 
01148       vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_div> 
01149       operator / (scalar<SCALARTYPE> const & value) const
01150       {
01151         return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_div>(*this, value);
01152       }
01153       
01154       
01156 
01157       iterator begin()
01158       {
01159         return iterator(*this, 0);
01160       }
01161 
01163       iterator end()
01164       {
01165         return iterator(*this, size());
01166       }
01167 
01169       const_iterator begin() const
01170       {
01171         return const_iterator(*this, 0);
01172       }
01173 
01175       const_iterator end() const
01176       {
01177         return const_iterator(*this, size());
01178       }
01179 
01182       vector<SCALARTYPE, ALIGNMENT> & swap(vector<SCALARTYPE, ALIGNMENT> & other)
01183       {
01184         swap(*this, other);
01185         return *this;
01186       };
01187       
01190       vector<SCALARTYPE, ALIGNMENT> & fast_swap(vector<SCALARTYPE, ALIGNMENT> & other) 
01191       { 
01192         assert(this->size_ == other.size_); 
01193         this->elements_.swap(other.elements_); 
01194         return *this; 
01195       };       
01196       
01199       size_type size() const { return size_; }
01200       
01203       size_type max_size() const
01204       {
01205         return (128*1024*1024) / sizeof(SCALARTYPE);  //128 MB is maximum size of memory chunks in OpenCL!
01206       }
01209       size_type internal_size() const { return viennacl::tools::roundUpToNextMultiple<size_type>(size_, ALIGNMENT); }
01210       
01212       bool empty() { return size_ == 0; }
01213       
01215       const viennacl::ocl::handle<cl_mem> & handle() const { return elements_; }
01216 
01219       void clear()
01220       {
01221         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::program_name(), "clear");
01222         
01223         viennacl::ocl::enqueue(k(elements_,
01224                                  cl_uint(0),
01225                                  cl_uint(internal_size()))
01226                               );
01227       }
01228       //void swap(vector & other){}
01229       
01230 
01231       //TODO: Think about implementing the following public member functions
01232       //void insert_element(unsigned int i, SCALARTYPE val){}
01233       //void erase_element(unsigned int i){}
01234       
01235     private:
01236       cl_uint size_;
01237       viennacl::ocl::handle<cl_mem> elements_;
01238     }; //vector
01239     
01240 
01241     //
01243     //
01244     
01251     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01252     void copy(const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin,
01253               const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end,
01254               CPU_ITERATOR cpu_begin )
01255     {
01256       assert(gpu_end - gpu_begin >= 0);
01257       if (gpu_end - gpu_begin != 0)
01258       {
01259         std::vector<SCALARTYPE> temp_buffer(gpu_end - gpu_begin);
01260         cl_int err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(),
01261                                          gpu_begin.handle(), CL_TRUE, 0, 
01262                                          sizeof(SCALARTYPE)*(gpu_end - gpu_begin),
01263                                          &(temp_buffer[0]), 0, NULL, NULL);
01264         VIENNACL_ERR_CHECK(err);
01265         viennacl::ocl::get_queue().finish();
01266         
01267         //now copy entries to cpu_vec:
01268         std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_begin);
01269       }
01270     }
01271 
01278     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01279     void copy(const vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin,
01280               const vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end,
01281               CPU_ITERATOR cpu_begin )
01282 
01283     {
01284       copy(const_vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_begin),
01285            const_vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_end),
01286            cpu_begin);
01287     }
01288     
01294     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR>
01295     void copy(vector<SCALARTYPE, ALIGNMENT> const & gpu_vec,
01296               CPUVECTOR & cpu_vec )
01297     {
01298       viennacl::copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
01299     }
01300 
01301     //from gpu to cpu. Type assumption: cpu_vec lies in a linear memory chunk
01313     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01314     void fast_copy(const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin,
01315                    const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end,
01316                    CPU_ITERATOR cpu_begin )
01317     {
01318       if (gpu_begin != gpu_end)
01319       {
01320         cl_int err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(),
01321                                          gpu_begin.handle(), CL_TRUE, 0,
01322                                          sizeof(SCALARTYPE)*(gpu_end - gpu_begin),
01323                                          &(*cpu_begin), 0, NULL, NULL);
01324         VIENNACL_ERR_CHECK(err);
01325         viennacl::ocl::get_queue().finish();
01326       }
01327     }
01328 
01334     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR>
01335     void fast_copy(vector<SCALARTYPE, ALIGNMENT> const & gpu_vec,
01336                    CPUVECTOR & cpu_vec )
01337     {
01338       viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
01339     }
01340 
01341 
01342 
01343     #ifdef VIENNACL_HAVE_EIGEN
01344     template <unsigned int ALIGNMENT>
01345     void copy(vector<float, ALIGNMENT> const & gpu_vec,
01346               Eigen::VectorXf & eigen_vec)
01347     {
01348       viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
01349     }
01350     
01351     template <unsigned int ALIGNMENT>
01352     void copy(vector<double, ALIGNMENT> & gpu_vec,
01353               Eigen::VectorXd & eigen_vec)
01354     {
01355       viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
01356     }
01357     #endif
01358 
01359 
01360     //
01362     //
01363 
01364     //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
01371     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01372     void copy(CPU_ITERATOR const & cpu_begin,
01373               CPU_ITERATOR const & cpu_end,
01374               vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin)
01375     {
01376       assert(cpu_end - cpu_begin > 0);
01377       if (cpu_begin != cpu_end)
01378       {
01379         //we require that the size of the gpu_vector is larger or equal to the cpu-size
01380         std::vector<SCALARTYPE> temp_buffer(cpu_end - cpu_begin);
01381         std::copy(cpu_begin, cpu_end, temp_buffer.begin());
01382         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(),
01383                                           gpu_begin.handle(), CL_TRUE, sizeof(SCALARTYPE)*gpu_begin.index(),
01384                                           sizeof(SCALARTYPE)*(cpu_end - cpu_begin),
01385                                           &(temp_buffer[0]), 0, NULL, NULL);
01386         VIENNACL_ERR_CHECK(err);
01387       }
01388     }
01389 
01390     // for things like copy(std_vec.begin(), std_vec.end(), vcl_vec.begin() + 1);
01391     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01392     void copy(CPU_ITERATOR const & cpu_begin,
01393               CPU_ITERATOR const & cpu_end,
01394               const_vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin)
01395     {
01396       copy(cpu_begin, cpu_end, vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_begin));
01397     }
01398 
01404     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR>
01405     void copy(const CPUVECTOR & cpu_vec, vector<SCALARTYPE, ALIGNMENT> & gpu_vec)
01406     {
01407       viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
01408     }
01409 
01421     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01422     void fast_copy(CPU_ITERATOR const & cpu_begin,
01423                    CPU_ITERATOR const & cpu_end,
01424                    vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin)
01425     {
01426       if (cpu_begin != cpu_end)
01427       {
01428         //we require that the size of the gpu_vector is larger or equal to the cpu-size
01429         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), 
01430                                           gpu_begin.handle(), CL_TRUE, 0, 
01431                                           sizeof(SCALARTYPE)*(cpu_end - cpu_begin), &(*cpu_begin), 0, NULL, NULL);
01432         VIENNACL_ERR_CHECK(err);
01433       }
01434     }
01435 
01436 
01442     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR>
01443     void fast_copy(const CPUVECTOR & cpu_vec, vector<SCALARTYPE, ALIGNMENT> & gpu_vec)
01444     {
01445       viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
01446     }
01447 
01448     #ifdef VIENNACL_HAVE_EIGEN
01449     template <unsigned int ALIGNMENT>
01450     void copy(Eigen::VectorXf const & eigen_vec,
01451               vector<float, ALIGNMENT> & gpu_vec)
01452     {
01453       std::vector<float> entries(eigen_vec.size());
01454       for (size_t i = 0; i<entries.size(); ++i)
01455         entries[i] = eigen_vec(i);
01456       viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
01457     }
01458     
01459     template <unsigned int ALIGNMENT>
01460     void copy(Eigen::VectorXd const & eigen_vec,
01461               vector<double, ALIGNMENT> & gpu_vec)
01462     {
01463       std::vector<double> entries(eigen_vec.size());
01464       for (size_t i = 0; i<entries.size(); ++i)
01465         entries[i] = eigen_vec(i);
01466       viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
01467     }
01468     #endif
01469     
01470 
01471 
01472     //
01474     //
01481     template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
01482     void copy(const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_begin,
01483               const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end,
01484               vector_iterator<SCALARTYPE, ALIGNMENT_DEST> gpu_dest_begin)
01485     {
01486       assert(gpu_src_end - gpu_src_begin >= 0);
01487       if (gpu_src_begin != gpu_src_end)
01488       {
01489         cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(),
01490                                           gpu_src_begin.handle(),  //src handle
01491                                           gpu_dest_begin.handle(), //dest handle
01492                                           sizeof(SCALARTYPE) * gpu_src_begin.index(), //src offset
01493                                           sizeof(SCALARTYPE) * gpu_dest_begin.index(), //dest offset
01494                                           sizeof(SCALARTYPE) * (gpu_src_end.index() - gpu_src_begin.index()), //data length
01495                                           0, //don't know -> check!! (something related to increment?)
01496                                           NULL, NULL);
01497         VIENNACL_ERR_CHECK(err);
01498       }
01499     }
01500 
01507     template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
01508     void copy(const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_begin,
01509               const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end,
01510               const_vector_iterator<SCALARTYPE, ALIGNMENT_DEST> gpu_dest_begin)
01511     {
01512       copy(gpu_src_begin, gpu_src_end, vector_iterator<SCALARTYPE, ALIGNMENT_DEST>(gpu_dest_begin));
01513     }
01514 
01520     template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
01521     void copy(vector<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_vec,
01522               vector<SCALARTYPE, ALIGNMENT_DEST> & gpu_dest_vec )
01523     {
01524       viennacl::copy(gpu_src_vec.begin(), gpu_src_vec.end(), gpu_dest_vec.begin());
01525     } 
01526 
01527 
01528     
01529     
01530     
01531 
01532     //global functions for handling vectors:
01537     template<class SCALARTYPE, unsigned int ALIGNMENT>
01538     std::ostream & operator<<(std::ostream & s, vector<SCALARTYPE,ALIGNMENT> const & val)
01539     {
01540       viennacl::ocl::get_queue().finish();
01541       std::vector<SCALARTYPE> tmp(val.size());
01542       copy(val.begin(), val.end(), tmp.begin());
01543       std::cout << "[" << val.size() << "](";
01544       for (typename std::vector<SCALARTYPE>::size_type i=0; i<val.size(); ++i)
01545       {
01546         if (i > 0)
01547           s << ",";
01548         s << tmp[i];
01549       }
01550       std::cout << ")";
01551       return s;
01552     }
01553 
01559     template<class SCALARTYPE, unsigned int ALIGNMENT>
01560     void swap(viennacl::vector<SCALARTYPE, ALIGNMENT> & vec1,
01561               viennacl::vector<SCALARTYPE, ALIGNMENT> & vec2)
01562     {
01563       assert(viennacl::traits::size(vec1) == viennacl::traits::size(vec2)
01564              && "Incompatible vector sizes in swap()");
01565 
01566       viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::program_name(), "swap");
01567 
01568       viennacl::ocl::enqueue(k(viennacl::traits::handle(vec1), cl_uint(viennacl::traits::start(vec1)), cl_uint(viennacl::traits::size(vec1)),
01569                                viennacl::traits::handle(vec2), cl_uint(viennacl::traits::start(vec2)), cl_uint(viennacl::traits::size(vec2)))
01570                             );
01571     }
01572     
01578     template <typename SCALARTYPE, unsigned int ALIGNMENT>
01579     vector<SCALARTYPE, ALIGNMENT> & fast_swap(vector<SCALARTYPE, ALIGNMENT> & v1,
01580                                               vector<SCALARTYPE, ALIGNMENT> & v2) 
01581     { 
01582       return v1.fast_swap(v2);
01583     }       
01584     
01585     
01586     
01588 
01593     template <typename SCALARTYPE, unsigned int A>
01594     vector_expression< const vector<SCALARTYPE, A>, const SCALARTYPE, op_prod> operator * (SCALARTYPE const & value, vector<SCALARTYPE, A> const & vec)
01595     {
01596       return vector_expression< const vector<SCALARTYPE, A>, const SCALARTYPE, op_prod>(vec, value);
01597     }
01598 
01604     template <typename SCALARTYPE, unsigned int A>
01605     vector_expression< const vector<SCALARTYPE, A>, const scalar<SCALARTYPE>, op_prod> operator * (scalar<SCALARTYPE> const & value, vector<SCALARTYPE, A> const & vec)
01606     {
01607         return vector_expression< const vector<SCALARTYPE, A>, const scalar<SCALARTYPE>, op_prod>(vec, value);
01608     }
01609 
01610 
01611     //addition and subtraction of two vector_expressions:
01617     template <typename LHS1, typename RHS1, typename OP1,
01618               typename LHS2, typename RHS2, typename OP2>
01619     typename vector_expression< LHS1, RHS1, OP1>::VectorType
01620     operator + (vector_expression< LHS1, RHS1, OP1> const & proxy1,
01621                 vector_expression< LHS2, RHS2, OP2> const & proxy2)
01622     {
01623       assert(proxy1.size() == proxy2.size());
01624       typename vector_expression< LHS1, RHS1, OP1>::VectorType result(proxy1.size());
01625       result = proxy1;
01626       result += proxy2;
01627       return result;
01628     }
01629 
01635     template <typename LHS1, typename RHS1, typename OP1,
01636               typename LHS2, typename RHS2, typename OP2>
01637     typename vector_expression< LHS1, RHS1, OP1>::VectorType
01638     operator - (vector_expression< LHS1, RHS1, OP1> const & proxy1,
01639                 vector_expression< LHS2, RHS2, OP2> const & proxy2)
01640     {
01641       assert(proxy1.size() == proxy2.size());
01642       typename vector_expression< LHS1, RHS1, OP1>::VectorType result(proxy1.size());
01643       result = proxy1;
01644       result -= proxy2;
01645       return result;
01646     }
01647     
01649     
01655     template <typename SCALARTYPE, unsigned int A, typename LHS, typename RHS, typename OP>
01656     vector<SCALARTYPE, A> operator + (vector_expression< LHS, RHS, OP> const & proxy,
01657                                       vector<SCALARTYPE, A> const & vec)
01658     {
01659       assert(proxy.size() == vec.size());
01660       vector<SCALARTYPE, A> result(vec.size());
01661       result = proxy;
01662       result += vec;
01663       return result;
01664     }
01665 
01671     template <typename SCALARTYPE, unsigned int A, typename LHS, typename RHS, typename OP>
01672     vector<SCALARTYPE, A> operator - (vector_expression< LHS, RHS, OP> const & proxy,
01673                                       vector<SCALARTYPE, A> const & vec)
01674     {
01675       assert(proxy.size() == vec.size());
01676       vector<SCALARTYPE, A> result(vec.size());
01677       result = proxy;
01678       result -= vec;
01679       return result;
01680     }
01681 
01682 
01688     template <typename SCALARTYPE, typename LHS, typename RHS, typename OP>
01689     vector<SCALARTYPE> operator * (vector_expression< LHS, RHS, OP> const & proxy,
01690                                    scalar<SCALARTYPE> const & val)
01691     {
01692       vector<SCALARTYPE> result(proxy.size());
01693       result = proxy;
01694       result *= val;
01695       return result;
01696     }
01697 
01703     template <typename SCALARTYPE, typename LHS, typename RHS, typename OP>
01704     vector<SCALARTYPE> operator / (vector_expression< LHS, RHS, OP> const & proxy,
01705                                       scalar<SCALARTYPE> const & val)
01706     {
01707       vector<SCALARTYPE> result(proxy.size());
01708       result = proxy;
01709       result /= val;
01710       return result;
01711     }
01712 
01713 
01715     
01721     template <typename SCALARTYPE, typename LHS, typename RHS, typename OP>
01722     vector<SCALARTYPE> operator * (scalar<SCALARTYPE> const & val,
01723                                    vector_expression< LHS, RHS, OP> const & proxy)
01724     {
01725       vector<SCALARTYPE> result(proxy.size());
01726       result = proxy;
01727       result *= val;
01728       return result;
01729     }
01730     
01736     template <typename SCALARTYPE, typename LHS, typename RHS, typename OP>
01737     viennacl::vector<SCALARTYPE> operator * (SCALARTYPE val,
01738                                    viennacl::vector_expression< LHS, RHS, OP> const & proxy)
01739     {
01740       viennacl::vector<SCALARTYPE> result(proxy.size());
01741       result = proxy;
01742       result *= val;
01743       return result;
01744     }
01745 
01746 }
01747 
01748 #endif

Generated on Fri Dec 30 2011 23:20:44 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1