Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_DynamicStorage.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Stokhos Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Eric T. Phipps (etphipp@sandia.gov).
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef STOKHOS_DYNAMIC_STORAGE_HPP
43 #define STOKHOS_DYNAMIC_STORAGE_HPP
44 
46 
47 #include "Kokkos_Macros.hpp"
48 
49 #include "Sacado_Traits.hpp"
50 #include "Stokhos_KokkosTraits.hpp"
51 #include <sstream>
52 
53 namespace Stokhos {
54 
55  template <typename ordinal_t, typename value_t, typename device_t>
57  public:
58 
59  static const bool is_static = false;
60  static const int static_size = 0;
61  static const bool supports_reset = false;
62 
63  typedef ordinal_t ordinal_type;
64  typedef value_t value_type;
66  typedef typename device_t::memory_space memory_space;
68  typedef volatile value_type& volatile_reference;
69  typedef const value_type& const_reference;
70  typedef const volatile value_type& const_volatile_reference;
71  typedef value_type* pointer;
72  typedef volatile value_type* volatile_pointer;
73  typedef const value_type* const_pointer;
74  typedef const volatile value_type* const_volatile_pointer;
76 
78  template <typename ord_t, typename val_t = value_t , typename dev_t = device_t >
79  struct apply {
81  };
82 
83  template <int N>
84  struct apply_N {
86  };
87 
89  KOKKOS_INLINE_FUNCTION
91  const value_type& x = value_type(0.0)) :
92  sz_(sz), is_view_(false) {
93  if (sz_ == 0) {
94  sz_ = 1;
95  coeff_0_ = x;
96  coeff_ = &coeff_0_;
97  is_constant_ = true;
98  }
99  else if (sz_ == 1) {
100  coeff_0_ = x;
101  coeff_ = &coeff_0_;
102  is_constant_ = true;
103  }
104  else {
106  is_constant_ = false;
107  }
108  }
109 
111  KOKKOS_INLINE_FUNCTION
112  DynamicStorage(const ordinal_type& sz, const value_type* x) :
113  sz_(sz), is_view_(false) {
114  if (sz_ == 0) {
115  sz_ = 1;
116  coeff_0_ = 0.0;
117  coeff_ = &coeff_0_;
118  is_constant_ = true;
119  }
120  else if (sz_ == 1) {
121  coeff_0_ = *x;
122  coeff_ = &coeff_0_;
123  is_constant_ = true;
124  }
125  else {
127  is_constant_ = false;
128  }
129  }
130 
132  // This might be problematic if sz == 1 and owned == true
133  KOKKOS_INLINE_FUNCTION
134  DynamicStorage(const ordinal_type& sz, pointer v, bool owned) :
135  coeff_(v), sz_(sz), is_view_(!owned), is_constant_(false) {}
136 
138  KOKKOS_INLINE_FUNCTION
140  sz_(s.sz_), is_view_(false) {
141  if (sz_ > 1) {
143  is_constant_ = false;
144  }
145  else {
146  coeff_0_ = s.coeff_[0];
147  coeff_ = &coeff_0_;
148  is_constant_ = true;
149  }
150  }
151 
153  KOKKOS_INLINE_FUNCTION
154  DynamicStorage(const volatile DynamicStorage& s) :
155  sz_(s.sz_), is_view_(false) {
156  if (sz_ > 1) {
158  is_constant_ = false;
159  }
160  else {
161  coeff_0_ = s.coeff_[0];
162  coeff_ = &coeff_0_;
163  is_constant_ = true;
164  }
165  }
166 
168  KOKKOS_INLINE_FUNCTION
171  }
172 
174  // To do: add error check if is_view_ == true && s.sz_ > sz_
175  KOKKOS_INLINE_FUNCTION
177  if (&s != this) {
178  // Only reallocate if we own the array and the sizes
179  // differ
180  if (!is_view_ && s.sz_ != sz_) {
181  if (!is_constant_)
183  if (s.sz_ > 1) {
185  is_constant_ = false;
186  }
187  else {
188  coeff_0_ = s.coeff_[0];
189  coeff_ = &coeff_0_;
190  is_constant_ = true;
191  }
192  sz_ = s.sz_;
193  }
194  else {
195  // This should work if is_view_ or s.sz_ == sz_, regardless
196  // of whether s.sz_ or sz_ is 1
197  ds::copy(s.coeff_, coeff_, s.sz_);
198  }
199  }
200  return *this;
201  }
202 
204  // To do: add error check if is_view_ == true && s.sz_ > sz_
205  KOKKOS_INLINE_FUNCTION
207  if (&s != this) {
208  // Only reallocate if we own the array and the sizes
209  // differ
210  if (!is_view_ && s.sz_ != sz_) {
211  if (!is_constant_)
213  if (s.sz_ > 1) {
215  is_constant_ = false;
216  }
217  else {
218  coeff_0_ = s.coeff_[0];
219  coeff_ = &coeff_0_;
220  is_constant_ = true;
221  }
222  sz_ = s.sz_;
223  }
224  else {
225  // This should work if is_view_ or s.sz_ == sz_, regardless
226  // of whether s.sz_ or sz_ is 1
227  ds::copy(s.coeff_, coeff_, s.sz_);
228  }
229  }
230  return *this;
231  }
232 
234  // To do: add error check if is_view_ == true && s.sz_ > sz_
235  KOKKOS_INLINE_FUNCTION
236  /*volatile*/ DynamicStorage& operator=(const DynamicStorage& s) volatile {
237  if (&s != this) {
238  // Only reallocate if we own the array and the sizes
239  // differ
240  if (!is_view_ && s.sz_ != sz_) {
241  if (!is_constant_)
243  if (s.sz_ > 1) {
245  is_constant_ = false;
246  }
247  else {
248  coeff_0_ = s.coeff_[0];
249  coeff_ = const_cast<value_type*>(&coeff_0_);
250  is_constant_ = true;
251  }
252  sz_ = s.sz_;
253  }
254  else {
255  // This should work if is_view_ or s.sz_ == sz_, regardless
256  // of whether s.sz_ or sz_ is 1
257  ds::copy(s.coeff_, coeff_, s.sz_);
258  }
259  }
260  return const_cast<DynamicStorage&>(*this);
261  }
262 
264  // To do: add error check if is_view_ == true && s.sz_ > sz_
265  KOKKOS_INLINE_FUNCTION
266  /*volatile*/ DynamicStorage&
267  operator=(const volatile DynamicStorage& s) volatile {
268  if (&s != this) {
269  // Only reallocate if we own the array and the sizes
270  // differ
271  if (!is_view_ && s.sz_ != sz_) {
272  if (!is_constant_)
274  if (s.sz_ > 1) {
276  is_constant_ = false;
277  }
278  else {
279  coeff_0_ = s.coeff_[0];
280  coeff_ = &coeff_0_;
281  is_constant_ = true;
282  }
283  sz_ = s.sz_;
284  }
285  else {
286  // This should work if is_view_ or s.sz_ == sz_, regardless
287  // of whether s.sz_ or sz_ is 1
288  ds::copy(s.coeff_, coeff_, s.sz_);
289  }
290  }
291  return const_cast<DynamicStorage&>(*this);
292  }
293 
295  KOKKOS_INLINE_FUNCTION
297  ds::fill(coeff_, sz_, v);
298  }
299 
301  KOKKOS_INLINE_FUNCTION
302  void init(const_reference v) volatile {
303  ds::fill(coeff_, sz_, v);
304  }
305 
307  KOKKOS_INLINE_FUNCTION
308  void init(const_pointer v, const ordinal_type& sz = 0) {
309  if (sz == 0)
310  ds::copy(v, coeff_, sz_);
311  else
312  ds::copy(v, coeff_, sz);
313  }
314 
316  KOKKOS_INLINE_FUNCTION
317  void init(const_pointer v, const ordinal_type& sz = 0) volatile {
318  if (sz == 0)
319  ds::copy(v, coeff_, sz_);
320  else
321  ds::copy(v, coeff_, sz);
322  }
323 
325  KOKKOS_INLINE_FUNCTION
326  void load(pointer v) {
327  ds::copy(v, coeff_, sz_);
328  }
329 
331  KOKKOS_INLINE_FUNCTION
332  void load(pointer v) volatile {
333  ds::copy(v, coeff_, sz_);
334  }
335 
337  KOKKOS_INLINE_FUNCTION
338  void resize(const ordinal_type& sz) {
339  if (!is_view_ && sz != sz_) {
340  if (sz > 1) {
341  value_type *coeff_new = ds::get_and_fill(sz);
342  if (sz > sz_)
343  ds::copy(coeff_, coeff_new, sz_);
344  else
345  ds::copy(coeff_, coeff_new, sz);
346  if (!is_view_ && !is_constant_)
348  coeff_ = coeff_new;
349  is_constant_ = false;
350  }
351  else {
352  coeff_0_ = coeff_[0];
353  if (!is_constant_)
355  coeff_ = &coeff_0_;
356  is_constant_ = true;
357  }
358  sz_ = sz;
359  }
360  }
361 
363  KOKKOS_INLINE_FUNCTION
364  void resize(const ordinal_type& sz) volatile {
365  if (!is_view_ && sz != sz_) {
366  if (sz > 1) {
367  value_type *coeff_new = ds::get_and_fill(sz);
368  if (sz > sz_)
369  ds::copy(coeff_, coeff_new, sz_);
370  else
371  ds::copy(coeff_, coeff_new, sz);
372  if (!is_view_ && !is_constant_)
374  coeff_ = coeff_new;
375  is_constant_ = false;
376  }
377  else {
378  coeff_0_ = coeff_[0];
379  if (!is_constant_)
381  coeff_ = const_cast<value_type*>(&coeff_0_);
382  is_constant_ = true;
383  }
384  sz_ = sz;
385  }
386  }
387 
389  KOKKOS_INLINE_FUNCTION
390  void shallowReset(pointer v, const ordinal_type& sz,
391  const ordinal_type& stride, bool owned) {
392  if (!is_view_ && !is_constant_)
394  coeff_ = v;
395  sz_ = sz;
396  is_view_ = !owned;
397  }
398 
400  KOKKOS_INLINE_FUNCTION
401  void shallowReset(pointer v, const ordinal_type& sz,
402  const ordinal_type& stride, bool owned) volatile {
403  if (!is_view_ && !is_constant_)
405  coeff_ = v;
406  sz_ = sz;
407  is_view_ = !owned;
408  }
409 
411  KOKKOS_INLINE_FUNCTION
412  ordinal_type size() const { return sz_; }
413 
415  KOKKOS_INLINE_FUNCTION
416  ordinal_type size() const volatile { return sz_; }
417 
419  KOKKOS_INLINE_FUNCTION
420  bool is_view() const { return is_view_; }
421 
423  KOKKOS_INLINE_FUNCTION
424  bool is_view() const volatile { return is_view_; }
425 
427  KOKKOS_INLINE_FUNCTION
429  return coeff_[i];
430  }
431 
433  KOKKOS_INLINE_FUNCTION
435  return coeff_[i];
436  }
437 
439  KOKKOS_INLINE_FUNCTION
440  reference operator[] (const ordinal_type& i) { return coeff_[i]; }
441 
443  KOKKOS_INLINE_FUNCTION
445  return coeff_[i]; }
446 
447  template <int i>
448  KOKKOS_INLINE_FUNCTION
449  reference getCoeff() { return coeff_[i]; }
450 
451  template <int i>
452  KOKKOS_INLINE_FUNCTION
453  volatile_reference getCoeff() volatile { return coeff_[i]; }
454 
455  template <int i>
456  KOKKOS_INLINE_FUNCTION
457  const_volatile_reference getCoeff() const volatile { return coeff_[i]; }
458 
459  template <int i>
460  KOKKOS_INLINE_FUNCTION
461  const_reference getCoeff() const { return coeff_[i]; }
462 
464  KOKKOS_INLINE_FUNCTION
465  const_volatile_pointer coeff() const volatile { return coeff_; }
466 
468  KOKKOS_INLINE_FUNCTION
469  const_pointer coeff() const { return coeff_; }
470 
472  KOKKOS_INLINE_FUNCTION
473  volatile_pointer coeff() volatile { return coeff_; }
474 
476  KOKKOS_INLINE_FUNCTION
477  pointer coeff() { return coeff_; }
478 
479  private:
480 
483 
485 
487 
490 
492  bool is_view_;
493 
496 
497  };
498 
499 }
500 
501 namespace Sacado {
502  template <typename ordinal_t, typename value_t, typename device_t>
503  struct StringName< Stokhos::DynamicStorage<ordinal_t,
504  value_t,
505  device_t> > {
506  static std::string eval() {
507  std::stringstream ss;
508  ss << "Stokhos::DynamicStorage<"
509  << StringName<ordinal_t>::eval() << ","
510  << StringName<value_t>::eval() << ","
511  << StringName<device_t>::eval() << ">";
512  return ss.str();
513  }
514  };
515 }
516 
517 #endif // STOKHOS_DYNAMIC_STORAGE_HPP
pointer coeff_
Coefficient values.
KOKKOS_INLINE_FUNCTION DynamicStorage & operator=(const volatile DynamicStorage &s) volatile
Assignment operator.
KOKKOS_INLINE_FUNCTION void init(const_pointer v, const ordinal_type &sz=0) volatile
Initialize values to an array of values.
Stokhos::DynArrayTraits< value_type, execution_space > ds
KOKKOS_INLINE_FUNCTION const_volatile_pointer coeff() const volatile
Get coefficients.
KOKKOS_INLINE_FUNCTION void init(const_reference v)
Initialize values to a constant value.
KOKKOS_INLINE_FUNCTION DynamicStorage(const ordinal_type &sz=1, const value_type &x=value_type(0.0))
Constructor.
KOKKOS_INLINE_FUNCTION volatile_pointer coeff() volatile
Get coefficients.
KOKKOS_INLINE_FUNCTION const_volatile_reference getCoeff() const volatile
Kokkos::DefaultExecutionSpace execution_space
KOKKOS_INLINE_FUNCTION ~DynamicStorage()
Destructor.
device_t::memory_space memory_space
DynamicStorage< ord_t, val_t, dev_t > type
const volatile value_type & const_volatile_reference
KOKKOS_INLINE_FUNCTION DynamicStorage & operator=(const DynamicStorage &s)
Assignment operator.
KOKKOS_INLINE_FUNCTION const_pointer coeff() const
Get coefficients.
Turn DynamicStorage into a meta-function class usable with mpl::apply.
KOKKOS_INLINE_FUNCTION void shallowReset(pointer v, const ordinal_type &sz, const ordinal_type &stride, bool owned) volatile
Reset storage to given array, size, and stride.
KOKKOS_INLINE_FUNCTION DynamicStorage(const ordinal_type &sz, const value_type *x)
Constructor from array.
KOKKOS_INLINE_FUNCTION void resize(const ordinal_type &sz) volatile
Resize to new size (values are preserved)
KOKKOS_INLINE_FUNCTION const_reference operator[](const ordinal_type &i) const
Coefficient access (avoid if possible)
KOKKOS_INLINE_FUNCTION void init(const_reference v) volatile
Initialize values to a constant value.
static KOKKOS_INLINE_FUNCTION void fill(T *dest, std::size_t sz, const T &v)
Fill array dest of length sz with value v.
KOKKOS_INLINE_FUNCTION DynamicStorage(const volatile DynamicStorage &s)
Constructor.
static KOKKOS_INLINE_FUNCTION T * get_and_fill(std::size_t sz, const T &x=T(0.0))
Get memory for new array of length sz and fill with zeros.
device_t::execution_space execution_space
KOKKOS_INLINE_FUNCTION void resize(const ordinal_type &sz)
Resize to new size (values are preserved)
KOKKOS_INLINE_FUNCTION void load(pointer v) volatile
Load values to an array of values.
volatile value_type * volatile_pointer
KOKKOS_INLINE_FUNCTION const_reference getCoeff() const
KOKKOS_INLINE_FUNCTION volatile_reference getCoeff() volatile
ordinal_type sz_
Size of array used.
KOKKOS_INLINE_FUNCTION bool is_view() const
Return whether storage is a view.
KOKKOS_INLINE_FUNCTION pointer coeff()
Get coefficients.
volatile value_type & volatile_reference
KOKKOS_INLINE_FUNCTION bool is_view() const volatile
Return whether storage is a view.
KOKKOS_INLINE_FUNCTION ordinal_type size() const volatile
Return size.
KOKKOS_INLINE_FUNCTION void load(pointer v)
Load values to an array of values.
KOKKOS_INLINE_FUNCTION void shallowReset(pointer v, const ordinal_type &sz, const ordinal_type &stride, bool owned)
Reset storage to given array, size, and stride.
static KOKKOS_INLINE_FUNCTION void copy(const volatile T *src, volatile T *dest, std::size_t sz)
Copy array from src to dest of length sz.
Dynamic array allocation class that is specialized for scalar i.e., fundamental or built-in types (fl...
const value_type & const_reference
KOKKOS_INLINE_FUNCTION ordinal_type size() const
Return size.
bool is_view_
Do we own the array.
KOKKOS_INLINE_FUNCTION DynamicStorage & operator=(const DynamicStorage &s) volatile
Assignment operator.
KOKKOS_INLINE_FUNCTION DynamicStorage(const DynamicStorage &s)
Constructor.
KOKKOS_INLINE_FUNCTION reference getCoeff()
const volatile value_type * const_volatile_pointer
KOKKOS_INLINE_FUNCTION DynamicStorage(const ordinal_type &sz, pointer v, bool owned)
Constructor for creating a view.
DynamicStorage< ordinal_type, value_type, device_t > type
KOKKOS_INLINE_FUNCTION DynamicStorage & operator=(const volatile DynamicStorage &s)
Assignment operator.
bool is_constant_
Is the coefficient array length-1.
value_type coeff_0_
Coefficient value when sz_ == 1 (i.e., a constant)
KOKKOS_INLINE_FUNCTION void init(const_pointer v, const ordinal_type &sz=0)
Initialize values to an array of values.
static KOKKOS_INLINE_FUNCTION void destroy_and_release(T *m, std::size_t sz)
Destroy array elements and release memory.