ViennaCL - The Vienna Computing Library  1.5.1
viennacl/vector_proxy.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_VECTOR_PROXY_HPP_
00002 #define VIENNACL_VECTOR_PROXY_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2014, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008    Portions of this software are copyright by UChicago Argonne, LLC.
00009 
00010                             -----------------
00011                   ViennaCL - The Vienna Computing Library
00012                             -----------------
00013 
00014    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00015 
00016    (A list of authors and contributors can be found in the PDF manual)
00017 
00018    License:         MIT (X11), see file LICENSE in the base directory
00019 ============================================================================= */
00020 
00025 #include "viennacl/forwards.h"
00026 #include "viennacl/range.hpp"
00027 #include "viennacl/slice.hpp"
00028 #include "viennacl/vector.hpp"
00029 #include "viennacl/tools/entry_proxy.hpp"
00030 
00031 namespace viennacl
00032 {
00037   template <typename VectorType>
00038   class vector_range : public vector_base<typename VectorType::cpu_value_type>
00039   {
00040       typedef vector_range<VectorType>             self_type;
00041       typedef vector_base<typename VectorType::cpu_value_type> base_type;
00042 
00043     public:
00044       typedef typename VectorType::value_type      value_type;
00045       typedef range::size_type                     size_type;
00046       typedef range::difference_type               difference_type;
00047       typedef value_type                           reference;
00048       typedef const value_type &                   const_reference;
00049       typedef typename VectorType::const_iterator  const_iterator;
00050       typedef typename VectorType::iterator        iterator;
00051 
00052       typedef typename VectorType::cpu_value_type    cpu_value_type;
00053 
00054       static const int alignment = VectorType::alignment;
00055 
00056       vector_range(VectorType & v, range const & entry_range)
00057        : base_type(v.handle(), entry_range.size(), v.start() + v.stride() * entry_range.start(), v.stride()) {}
00058 
00059 
00060       using base_type::operator=;
00061 
00062   };
00063 
00064 
00065 
00069 
00070   template <typename VectorType, typename SCALARTYPE>
00071   void copy(const VectorType & cpu_vector,
00072             vector_range<vector<SCALARTYPE> > & gpu_vector_range )
00073   {
00074     assert(cpu_vector.end() - cpu_vector.begin() >= 0 && bool("Range must have nonnegative length!"));
00075 
00076     if (cpu_vector.end() - cpu_vector.begin() > 0)
00077     {
00078       //we require that the size of the gpu_vector is larger or equal to the cpu-size
00079       std::vector<SCALARTYPE> temp_buffer(cpu_vector.end() - cpu_vector.begin());
00080       std::copy(cpu_vector.begin(), cpu_vector.end(), temp_buffer.begin());
00081       viennacl::backend::memory_write(gpu_vector_range.handle(), sizeof(SCALARTYPE)*gpu_vector_range.start(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
00082     }
00083   }
00084 
00085 
00091   template <typename CPUVECTOR, typename VectorType>
00092   void fast_copy(const CPUVECTOR & cpu_vec, vector_range<VectorType> & gpu_vec)
00093   {
00094     viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
00095   }
00096 
00100 
00101 
00102   template <typename SCALARTYPE, typename VectorType>
00103   void copy(vector_range<vector<SCALARTYPE> > const & gpu_vector_range,
00104             VectorType & cpu_vector)
00105   {
00106     assert(cpu_vector.end() - cpu_vector.begin() >= 0 && bool("Range must have nonnegative length!"));
00107 
00108     if (cpu_vector.end() > cpu_vector.begin())
00109     {
00110       std::vector<SCALARTYPE> temp_buffer(cpu_vector.end() - cpu_vector.begin());
00111       viennacl::backend::memory_read(gpu_vector_range.handle(), sizeof(SCALARTYPE)*gpu_vector_range.start(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
00112 
00113       //now copy entries to cpu_vec:
00114       std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_vector.begin());
00115     }
00116   }
00117 
00118 
00124   template <typename VectorType, typename CPUVECTOR>
00125   void fast_copy(vector_range< VectorType > const & gpu_vec,
00126                  CPUVECTOR & cpu_vec )
00127   {
00128     viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
00129   }
00130 
00131 
00132 
00133   //
00134   // Convenience function
00135   //
00136   template <typename VectorType>
00137   vector_range<VectorType> project(VectorType & vec, viennacl::range const & r1)
00138   {
00139     return vector_range<VectorType>(vec, r1);
00140   }
00141 
00142   template <typename VectorType>
00143   vector_range<VectorType> project(viennacl::vector_range<VectorType> & vec, viennacl::range const & r1)
00144   {
00145     assert(r1.size() <= vec.size() && bool("Size of range invalid!"));
00146     return vector_range<VectorType>(vec, viennacl::range(vec.start() + r1.start(), vec.start() + r1.start() + r1.size()));
00147   }
00148 
00149 //
00150 //
00151 //
00153 //
00154 //
00155 //
00156 
00157 
00158 
00163   template <typename VectorType>
00164   class vector_slice : public vector_base<typename VectorType::cpu_value_type>
00165   {
00166       typedef vector_slice<VectorType>             self_type;
00167       typedef vector_base<typename VectorType::cpu_value_type> base_type;
00168 
00169     public:
00170       typedef typename VectorType::value_type      value_type;
00171       typedef slice::size_type                     size_type;
00172       typedef slice::difference_type               difference_type;
00173       typedef value_type                           reference;
00174       typedef const value_type &                   const_reference;
00175       typedef typename VectorType::const_iterator  const_iterator;
00176       typedef typename VectorType::iterator        iterator;
00177 
00178       typedef typename VectorType::cpu_value_type  cpu_value_type;
00179 
00180       static const int alignment = VectorType::alignment;
00181 
00182       vector_slice(VectorType & v, slice const & entry_slice)
00183           : base_type(v.handle(), entry_slice.size(), v.start() + v.stride() * entry_slice.start(), v.stride() * entry_slice.stride()) {}
00184 
00185 
00186       using base_type::operator=;
00187 
00188   };
00189 
00190 
00194 
00195   template <typename VectorType, typename SCALARTYPE>
00196   void copy(const VectorType & cpu_vector,
00197             vector_slice<vector<SCALARTYPE> > & gpu_vector_slice )
00198   {
00199     if (cpu_vector.size() > 0)
00200     {
00201       std::vector<SCALARTYPE> temp_buffer(gpu_vector_slice.stride() * gpu_vector_slice.size());
00202 
00203       viennacl::backend::memory_read(gpu_vector_slice.handle(), sizeof(SCALARTYPE)*gpu_vector_slice.start(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
00204 
00205       for (vcl_size_t i=0; i<cpu_vector.size(); ++i)
00206         temp_buffer[i * gpu_vector_slice.stride()] = cpu_vector[i];
00207 
00208       viennacl::backend::memory_write(gpu_vector_slice.handle(), sizeof(SCALARTYPE)*gpu_vector_slice.start(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
00209     }
00210   }
00211 
00212 
00213 
00217 
00218 
00219   template <typename VectorType, typename SCALARTYPE>
00220   void copy(vector_slice<vector<SCALARTYPE> > const & gpu_vector_slice,
00221             VectorType & cpu_vector)
00222   {
00223     assert(gpu_vector_slice.end() - gpu_vector_slice.begin() >= 0 && bool("Range must have nonnegative length!"));
00224 
00225     if (gpu_vector_slice.end() - gpu_vector_slice.begin() > 0)
00226     {
00227       std::vector<SCALARTYPE> temp_buffer(gpu_vector_slice.stride() * gpu_vector_slice.size());
00228       viennacl::backend::memory_read(gpu_vector_slice.handle(), sizeof(SCALARTYPE)*gpu_vector_slice.start(), sizeof(SCALARTYPE)*temp_buffer.size(), &(temp_buffer[0]));
00229 
00230       for (vcl_size_t i=0; i<cpu_vector.size(); ++i)
00231         cpu_vector[i] = temp_buffer[i * gpu_vector_slice.stride()];
00232     }
00233   }
00234 
00235 
00236 
00237 
00238 
00239   //
00240   // Convenience functions
00241   //
00242   template <typename VectorType>
00243   vector_slice<VectorType> project(VectorType & vec, viennacl::slice const & s1)
00244   {
00245     assert(s1.size() <= vec.size() && bool("Size of slice larger than vector size!"));
00246     return vector_slice<VectorType>(vec, s1);
00247   }
00248 
00249   template <typename VectorType>
00250   vector_slice<VectorType> project(viennacl::vector_slice<VectorType> & vec, viennacl::slice const & s1)
00251   {
00252     assert(s1.size() <= vec.size() && bool("Size of slice larger than vector proxy!"));
00253     return vector_slice<VectorType>(vec, viennacl::slice(vec.start() + s1.start(), vec.stride() * s1.stride(), s1.size()));
00254   }
00255 
00256   // interaction with range and vector_range:
00257 
00258   template <typename VectorType>
00259   vector_slice<VectorType> project(viennacl::vector_slice<VectorType> & vec, viennacl::range const & r1)
00260   {
00261     assert(r1.size() <= vec.size() && bool("Size of slice larger than vector proxy!"));
00262     return vector_slice<VectorType>(vec, viennacl::slice(vec.start() + r1.start(), vec.stride(), r1.size()));
00263   }
00264 
00265   template <typename VectorType>
00266   vector_slice<VectorType> project(viennacl::vector_range<VectorType> & vec, viennacl::slice const & s1)
00267   {
00268     assert(s1.size() <= vec.size() && bool("Size of slice larger than vector proxy!"));
00269     return vector_slice<VectorType>(vec, viennacl::range(vec.start() + s1.start(), s1.stride(), s1.size()));
00270   }
00271 
00272 
00273 }
00274 
00275 #endif