Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Kokkos_Vector.hpp
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends