|
Kokkos Core Kernels Package
Version of the Day
|
00001 /* 00002 //@HEADER 00003 // ************************************************************************ 00004 // 00005 // Kokkos 00006 // Manycore Performance-Portable Multidimensional Arrays 00007 // 00008 // Copyright (2012) Sandia Corporation 00009 // 00010 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00011 // the U.S. Government retains certain rights in this software. 00012 // 00013 // Redistribution and use in source and binary forms, with or without 00014 // modification, are permitted provided that the following conditions are 00015 // met: 00016 // 00017 // 1. Redistributions of source code must retain the above copyright 00018 // notice, this list of conditions and the following disclaimer. 00019 // 00020 // 2. Redistributions in binary form must reproduce the above copyright 00021 // notice, this list of conditions and the following disclaimer in the 00022 // documentation and/or other materials provided with the distribution. 00023 // 00024 // 3. Neither the name of the Corporation nor the names of the 00025 // contributors may be used to endorse or promote products derived from 00026 // this software without specific prior written permission. 00027 // 00028 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00029 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00030 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00031 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00032 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00033 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00034 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00035 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00036 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00037 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00038 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00039 // 00040 // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) 00041 // 00042 // ************************************************************************ 00043 //@HEADER 00044 */ 00045 00046 #ifndef KOKKOS_VECTOR_HPP 00047 #define KOKKOS_VECTOR_HPP 00048 00049 #include <Kokkos_Core_fwd.hpp> 00050 #include <Kokkos_DualView.hpp> 00051 00052 /* Drop in replacement for std::vector based on Kokkos::DualView 00053 * Most functions only work on the host (it will not compile if called from device kernel) 00054 * 00055 */ 00056 namespace Kokkos { 00057 00058 template <typename Scalar, class Device = Kokkos::DefaultExecutionSpace > 00059 class vector : public DualView<Scalar*,LayoutLeft,Device> { 00060 public: 00061 typedef Device device_type; 00062 typedef Scalar value_type; 00063 typedef Scalar* pointer; 00064 typedef const Scalar* const_pointer; 00065 typedef Scalar* reference; 00066 typedef const Scalar* const_reference; 00067 typedef Scalar* iterator; 00068 typedef const Scalar* const_iterator; 00069 00070 private: 00071 size_t _size; 00072 typedef size_t size_type; 00073 float _extra_storage; 00074 typedef DualView<Scalar*,LayoutLeft,Device> DV; 00075 00076 00077 public: 00078 inline Scalar& operator() (int i) const {return DV::h_view(i);}; 00079 inline Scalar& operator[] (int i) const {return DV::h_view(i);}; 00080 00081 00082 /* Member functions which behave like std::vector functions */ 00083 00084 vector():DV() { 00085 _size = 0; 00086 _extra_storage = 1.1; 00087 DV::modified_host = 1; 00088 }; 00089 00090 00091 vector(int n, Scalar val=Scalar()):DualView<Scalar*,LayoutLeft,Device>("Vector",size_t(n*(1.1))) { 00092 _size = n; 00093 _extra_storage = 1.1; 00094 DV::modified_host = 1; 00095 00096 assign(n,val); 00097 } 00098 00099 00100 void resize(size_t n) { 00101 if(n>=capacity()) 00102 DV::resize(size_t (n*_extra_storage)); 00103 _size = n; 00104 } 00105 00106 void resize(size_t n, const Scalar& val) { 00107 assign(n,val); 00108 } 00109 00110 void assign (size_t n, const Scalar& val) { 00111 00112 /* Resize if necessary (behavour of std:vector) */ 00113 00114 if(n>capacity()) 00115 DV::resize(size_t (n*_extra_storage)); 00116 _size = n; 00117 00118 /* Assign value either on host or on device */ 00119 00120 if( DV::modified_host >= DV::modified_device ) { 00121 set_functor_host f(DV::h_view,val); 00122 parallel_for(n,f); 00123 DV::t_host::device_type::fence(); 00124 DV::modified_host++; 00125 } else { 00126 set_functor f(DV::d_view,val); 00127 parallel_for(n,f); 00128 DV::t_dev::device_type::fence(); 00129 DV::modified_device++; 00130 } 00131 } 00132 00133 void reserve(size_t n) { 00134 DV::resize(size_t (n*_extra_storage)); 00135 } 00136 00137 void push_back(Scalar val) { 00138 DV::modified_host++; 00139 if(_size == capacity()) { 00140 size_t new_size = _size*_extra_storage; 00141 if(new_size == _size) new_size++; 00142 DV::resize(new_size); 00143 } 00144 00145 DV::h_view(_size) = val; 00146 _size++; 00147 00148 }; 00149 00150 void pop_back() { 00151 _size--; 00152 }; 00153 00154 void clear() { 00155 _size = 0; 00156 } 00157 00158 size_type size() const {return _size;}; 00159 size_type max_size() const {return 2000000000;} 00160 size_type capacity() const {return DV::capacity();}; 00161 bool empty() const {return _size==0;}; 00162 00163 iterator begin() const {return &DV::h_view(0);}; 00164 00165 iterator end() const {return &DV::h_view(_size);}; 00166 00167 00168 /* std::algorithms wich work originally with iterators, here they are implemented as member functions */ 00169 00170 size_t 00171 lower_bound (const size_t& start, 00172 const size_t& theEnd, 00173 const Scalar& comp_val) const 00174 { 00175 int lower = start; // FIXME (mfh 24 Apr 2014) narrowing conversion 00176 int upper = _size > theEnd? theEnd : _size-1; // FIXME (mfh 24 Apr 2014) narrowing conversion 00177 if (upper <= lower) { 00178 return theEnd; 00179 } 00180 00181 Scalar lower_val = DV::h_view(lower); 00182 Scalar upper_val = DV::h_view(upper); 00183 size_t idx = (upper+lower)/2; 00184 Scalar val = DV::h_view(idx); 00185 if(val>upper_val) return upper; 00186 if(val<lower_val) return start; 00187 00188 while(upper>lower) { 00189 if(comp_val>val) { 00190 lower = ++idx; 00191 } else { 00192 upper = idx; 00193 } 00194 idx = (upper+lower)/2; 00195 val = DV::h_view(idx); 00196 } 00197 return idx; 00198 } 00199 00200 bool is_sorted() { 00201 for(int i=0;i<_size-1;i++) { 00202 if(DV::h_view(i)>DV::h_view(i+1)) return false; 00203 } 00204 return true; 00205 } 00206 00207 iterator find(Scalar val) const { 00208 if(_size == 0) return end(); 00209 00210 int upper,lower,current; 00211 current = _size/2; 00212 upper = _size-1; 00213 lower = 0; 00214 00215 if((val<DV::h_view(0)) || (val>DV::h_view(_size-1)) ) return end(); 00216 00217 while(upper>lower) 00218 { 00219 if(val>DV::h_view(current)) lower = current+1; 00220 else upper = current; 00221 current = (upper+lower)/2; 00222 } 00223 00224 if(val==DV::h_view(current)) return &DV::h_view(current); 00225 else return end(); 00226 } 00227 00228 /* Additional functions for data management */ 00229 00230 void device_to_host(){ 00231 deep_copy(DV::h_view,DV::d_view); 00232 } 00233 void host_to_device() const { 00234 deep_copy(DV::d_view,DV::h_view); 00235 } 00236 00237 void on_host() { 00238 DV::modified_host = DV::modified_device + 1; 00239 } 00240 void on_device() { 00241 DV::modified_device = DV::modified_host + 1; 00242 } 00243 00244 void set_overallocation(float extra) { 00245 _extra_storage = 1.0 + extra; 00246 } 00247 00248 00249 public: 00250 struct set_functor { 00251 typedef typename DV::t_dev::device_type device_type; 00252 typename DV::t_dev _data; 00253 Scalar _val; 00254 00255 set_functor(typename DV::t_dev data, Scalar val) : 00256 _data(data),_val(val) {} 00257 00258 KOKKOS_INLINE_FUNCTION 00259 void operator() (const int &i) const { 00260 _data(i) = _val; 00261 } 00262 }; 00263 00264 struct set_functor_host { 00265 typedef typename DV::t_host::device_type device_type; 00266 typename DV::t_host _data; 00267 Scalar _val; 00268 00269 set_functor_host(typename DV::t_host data, Scalar val) : 00270 _data(data),_val(val) {} 00271 00272 KOKKOS_INLINE_FUNCTION 00273 void operator() (const int &i) const { 00274 _data(i) = _val; 00275 } 00276 }; 00277 00278 }; 00279 00280 00281 } 00282 #endif
1.7.6.1