ViennaCL - The Vienna Computing Library
1.5.2
|
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