Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_Vector.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 2.0
6 // Copyright (2014) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
44 #ifndef KOKKOS_VECTOR_HPP
45 #define KOKKOS_VECTOR_HPP
46 
47 #include <Kokkos_Core_fwd.hpp>
48 #include <Kokkos_DualView.hpp>
49 
50 /* Drop in replacement for std::vector based on Kokkos::DualView
51  * Most functions only work on the host (it will not compile if called from device kernel)
52  *
53  */
54  namespace Kokkos {
55 
56 template< class Scalar, class Arg1Type = void>
57 class vector : public DualView<Scalar*,LayoutLeft,Arg1Type> {
58 
59 public:
60  typedef Scalar value_type;
61  typedef Scalar* pointer;
62  typedef const Scalar* const_pointer;
63  typedef Scalar& reference;
64  typedef const Scalar& const_reference;
65  typedef Scalar* iterator;
66  typedef const Scalar* const_iterator;
67 
68 private:
69  size_t _size;
70  typedef size_t size_type;
71  float _extra_storage;
72  typedef DualView<Scalar*,LayoutLeft,Arg1Type> DV;
73 
74 
75 public:
76 #ifdef KOKKOS_ENABLE_CUDA_UVM
77  KOKKOS_INLINE_FUNCTION reference operator() (int i) const {return DV::h_view(i);};
78  KOKKOS_INLINE_FUNCTION reference operator[] (int i) const {return DV::h_view(i);};
79 #else
80  inline reference operator() (int i) const {return DV::h_view(i);};
81  inline reference operator[] (int i) const {return DV::h_view(i);};
82 #endif
83 
84  /* Member functions which behave like std::vector functions */
85 
86  vector():DV() {
87  _size = 0;
88  _extra_storage = 1.1;
89  }
90 
91 
92  vector(int n, Scalar val=Scalar()):DualView<Scalar*,LayoutLeft,Arg1Type>("Vector",size_t(n*(1.1))) {
93  _size = n;
94  _extra_storage = 1.1;
95  DV::modified_flags(0) = 1;
96 
97  assign(n,val);
98  }
99 
100 
101  void resize(size_t n) {
102  if(n>=span())
103  DV::resize(size_t (n*_extra_storage));
104  _size = n;
105  }
106 
107  void resize(size_t n, const Scalar& val) {
108  assign(n,val);
109  }
110 
111  void assign (size_t n, const Scalar& val) {
112 
113  /* Resize if necessary (behavour of std:vector) */
114 
115  if(n>span())
116  DV::resize(size_t (n*_extra_storage));
117  _size = n;
118 
119  /* Assign value either on host or on device */
120 
121  if( DV::template need_sync<typename DV::t_dev::device_type>() ) {
122  set_functor_host f(DV::h_view,val);
123  parallel_for(n,f);
124  DV::t_host::execution_space::fence();
125  DV::template modify<typename DV::t_host::device_type>();
126  } else {
127  set_functor f(DV::d_view,val);
128  parallel_for(n,f);
129  DV::t_dev::execution_space::fence();
130  DV::template modify<typename DV::t_dev::device_type>();
131  }
132  }
133 
134  void reserve(size_t n) {
135  DV::resize(size_t (n*_extra_storage));
136  }
137 
138  void push_back(Scalar val) {
139  DV::template sync<typename DV::t_host::device_type>();
140  DV::template modify<typename DV::t_host::device_type>();
141  if(_size == span()) {
142  size_t new_size = _size*_extra_storage;
143  if(new_size == _size) new_size++;
144  DV::resize(new_size);
145  }
146 
147  DV::h_view(_size) = val;
148  _size++;
149 
150  }
151 
152  void pop_back() {
153  _size--;
154  }
155 
156  void clear() {
157  _size = 0;
158  }
159 
160  size_type size() const {return _size;}
161  size_type max_size() const {return 2000000000;}
162 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
163  size_type capacity() const {return DV::capacity();}
164 #endif
165  size_type span() const {return DV::span();}
166  bool empty() const {return _size==0;}
167 
168  iterator begin() const {return &DV::h_view(0);}
169 
170  iterator end() const {return &DV::h_view(_size);}
171 
172  reference front() {return DV::h_view(0);}
173 
174  reference back() {return DV::h_view(_size - 1);}
175 
176  const_reference front() const {return DV::h_view(0);}
177 
178  const_reference back() const {return DV::h_view(_size - 1);}
179 
180  /* std::algorithms wich work originally with iterators, here they are implemented as member functions */
181 
182  size_t
183  lower_bound (const size_t& start,
184  const size_t& theEnd,
185  const Scalar& comp_val) const
186  {
187  int lower = start; // FIXME (mfh 24 Apr 2014) narrowing conversion
188  int upper = _size > theEnd? theEnd : _size-1; // FIXME (mfh 24 Apr 2014) narrowing conversion
189  if (upper <= lower) {
190  return theEnd;
191  }
192 
193  Scalar lower_val = DV::h_view(lower);
194  Scalar upper_val = DV::h_view(upper);
195  size_t idx = (upper+lower)/2;
196  Scalar val = DV::h_view(idx);
197  if(val>upper_val) return upper;
198  if(val<lower_val) return start;
199 
200  while(upper>lower) {
201  if(comp_val>val) {
202  lower = ++idx;
203  } else {
204  upper = idx;
205  }
206  idx = (upper+lower)/2;
207  val = DV::h_view(idx);
208  }
209  return idx;
210  }
211 
212  bool is_sorted() {
213  for(int i=0;i<_size-1;i++) {
214  if(DV::h_view(i)>DV::h_view(i+1)) return false;
215  }
216  return true;
217  }
218 
219  iterator find(Scalar val) const {
220  if(_size == 0) return end();
221 
222  int upper,lower,current;
223  current = _size/2;
224  upper = _size-1;
225  lower = 0;
226 
227  if((val<DV::h_view(0)) || (val>DV::h_view(_size-1)) ) return end();
228 
229  while(upper>lower)
230  {
231  if(val>DV::h_view(current)) lower = current+1;
232  else upper = current;
233  current = (upper+lower)/2;
234  }
235 
236  if(val==DV::h_view(current)) return &DV::h_view(current);
237  else return end();
238  }
239 
240  /* Additional functions for data management */
241 
242  void device_to_host(){
243  deep_copy(DV::h_view,DV::d_view);
244  }
245  void host_to_device() const {
246  deep_copy(DV::d_view,DV::h_view);
247  }
248 
249  void on_host() {
250  DV::template modify<typename DV::t_host::device_type>();
251  }
252  void on_device() {
253  DV::template modify<typename DV::t_dev::device_type>();
254  }
255 
256  void set_overallocation(float extra) {
257  _extra_storage = 1.0 + extra;
258  }
259 
260 
261 public:
262  struct set_functor {
263  typedef typename DV::t_dev::execution_space execution_space;
264  typename DV::t_dev _data;
265  Scalar _val;
266 
267  set_functor(typename DV::t_dev data, Scalar val) :
268  _data(data),_val(val) {}
269 
270  KOKKOS_INLINE_FUNCTION
271  void operator() (const int &i) const {
272  _data(i) = _val;
273  }
274  };
275 
276  struct set_functor_host {
277  typedef typename DV::t_host::execution_space execution_space;
278  typename DV::t_host _data;
279  Scalar _val;
280 
281  set_functor_host(typename DV::t_host data, Scalar val) :
282  _data(data),_val(val) {}
283 
284  KOKKOS_INLINE_FUNCTION
285  void operator() (const int &i) const {
286  _data(i) = _val;
287  }
288  };
289 
290 };
291 
292 
293 }
294 #endif
295 
Declaration and definition of Kokkos::DualView.
void parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename Impl::enable_if< Kokkos::Impl::is_execution_policy< ExecPolicy >::value >::type *=0)
Execute functor in parallel according to the execution policy.
std::enable_if< std::is_same< typename Kokkos::View< T, P...>::array_layout, Kokkos::LayoutLeft >::value||std::is_same< typename Kokkos::View< T, P...>::array_layout, Kokkos::LayoutRight >::value >::type resize(Kokkos::View< T, P...> &v, const size_t n0=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n1=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n2=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n3=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n4=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n5=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n6=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n7=KOKKOS_IMPL_CTOR_DEFAULT_ARG)
Resize a view with copying old data to new data at the corresponding indices.
void deep_copy(const View< DT, DP...> &dst, typename ViewTraits< DT, DP...>::const_value_type &value, typename std::enable_if< std::is_same< typename ViewTraits< DT, DP...>::specialize, void >::value >::type *=0)
Deep copy a value from Host memory into a view.
void resize(DynRankView< T, P...> &v, const size_t n0=KOKKOS_INVALID_INDEX, const size_t n1=KOKKOS_INVALID_INDEX, const size_t n2=KOKKOS_INVALID_INDEX, const size_t n3=KOKKOS_INVALID_INDEX, const size_t n4=KOKKOS_INVALID_INDEX, const size_t n5=KOKKOS_INVALID_INDEX, const size_t n6=KOKKOS_INVALID_INDEX, const size_t n7=KOKKOS_INVALID_INDEX)
Resize a view with copying old data to new data at the corresponding indices.