Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_Fad_SFad.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 //
8 // ***********************************************************************
9 //
10 // The forward-mode AD classes in Sacado are a derivative work of the
11 // expression template classes in the Fad package by Nicolas Di Cesare.
12 // The following banner is included in the original Fad source code:
13 //
14 // ************ DO NOT REMOVE THIS BANNER ****************
15 //
16 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
17 // http://www.ann.jussieu.fr/~dicesare
18 //
19 // CEMRACS 98 : C++ courses,
20 // templates : new C++ techniques
21 // for scientific computing
22 //
23 //********************************************************
24 //
25 // A short implementation ( not all operators and
26 // functions are overloaded ) of 1st order Automatic
27 // Differentiation in forward mode (FAD) using
28 // EXPRESSION TEMPLATES.
29 //
30 //********************************************************
31 // @HEADER
32 
33 #ifndef SACADO_FAD_SFAD_HPP
34 #define SACADO_FAD_SFAD_HPP
35 
36 #include "Sacado_ConfigDefs.h"
37 
38 #ifdef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
39 
40 #include "Sacado_Fad_Exp_SFad.hpp"
41 
42 namespace Sacado {
43  namespace Fad {
44  template <typename T, int Num>
45  using SFad = Exp::GeneralFad< Exp::StaticFixedStorage<T,Num> >;
46  }
47 }
48 
49 #else
50 
54 
55 namespace Sacado {
56 
58  namespace Fad {
59 
60 #ifndef SACADO_FAD_DERIV_LOOP
61 #if defined(SACADO_VIEW_CUDA_HIERARCHICAL_DFAD) && !defined(SACADO_DISABLE_CUDA_IN_KOKKOS) && defined(__CUDA_ARCH__)
62 #define SACADO_FAD_DERIV_LOOP(I,SZ) for (int I=threadIdx.x; I<SZ; I+=blockDim.x)
63 #else
64 #define SACADO_FAD_DERIV_LOOP(I,SZ) for (int I=0; I<SZ; ++I)
65 #endif
66 #endif
67 
68 #ifndef SACADO_FAD_THREAD_SINGLE
69 #if (defined(SACADO_VIEW_CUDA_HIERARCHICAL) || defined(SACADO_VIEW_CUDA_HIERARCHICAL_DFAD)) && !defined(SACADO_DISABLE_CUDA_IN_KOKKOS) && defined(__CUDA_ARCH__)
70 #define SACADO_FAD_THREAD_SINGLE if (threadIdx.x == 0)
71 #else
72 #define SACADO_FAD_THREAD_SINGLE /* */
73 #endif
74 #endif
75 
77  template <typename T, int Num>
78  struct SFadExprTag {};
79 
80  // Forward declaration
81  template <typename T, int Num> class SFad;
82 
90  template <typename T, int Num>
91  class Expr< SFadExprTag<T,Num>, ExprSpecDefault > {
92 
93  public:
94 
96  typedef typename RemoveConst<T>::type value_type;
97 
100 
103 
108 
111  Expr() : val_( T(0.)) {
112  ss_array<T>::zero(dx_, Num); }
113 
115 
118  template <typename S>
121  val_(x) {
122  ss_array<T>::zero(dx_, Num);
123  }
124 
126 
130  Expr(const int sz, const T & x, const DerivInit zero_out = InitDerivArray) : val_(x) {
131 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
132  if (sz != Num)
133  throw "SFad::SFad() Error: Supplied derivative dimension does not match compile time length.";
134 #endif
135  if (zero_out == InitDerivArray)
136  ss_array<T>::zero(dx_, Num);
137  }
138 
140 
146  Expr(const int sz, const int i, const T & x) :
147  val_(x) {
148 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
149  if (sz != Num)
150  throw "SFad::SFad() Error: Supplied derivative dimension does not match compile time length.";
151  if (i >= Num)
152  throw "SFad::SFad() Error: Invalid derivative index.";
153 #endif
154 
155  ss_array<T>::zero(dx_, Num);
156  dx_[i]=1.;
157  }
158 
161  Expr(const Expr& x) :
162  val_(x.val()) {
163  for (int i=0; i<Num; i++)
164  dx_[i] = x.dx_[i];
165  }
166 
168  template <typename S>
171 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
172  if (x.size() != Num)
173  throw "SFad::SFad() Error: Attempt to assign with incompatible sizes";
174 #endif
175 
176  for(int i=0; i<Num; ++i)
177  dx_[i] = x.fastAccessDx(i);
178 
179  this->val() = x.val();
180  }
181 
184  ~Expr() {}
185 
187 
194  void diff(const int ith, const int n) {
195 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
196  if (n != Num)
197  throw "SFad::diff() Error: Supplied derivative dimension does not match compile time length.";
198 #endif
199 
200  ss_array<T>::zero(dx_, Num);
201  dx_[ith] = T(1.);
202  }
203 
205 
210  void resize(int sz) {
211 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
212  if (sz != Num)
213  throw "SFad::resize() Error: Cannot resize fixed derivative array dimension";
214 #endif
215  }
216 
218 
223  void expand(int sz) { resize(sz); }
224 
227  void zero() { ss_array<T>::zero(dx_, Num); }
228 
231  void setUpdateValue(bool update_val) { }
232 
235  bool updateValue() const { return true; }
236 
239  void cache() const {}
240 
242  template <typename S>
244  SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr<S>& x) const {
245  typedef IsEqual<value_type> IE;
246  if (x.size() != this->size()) return false;
247  bool eq = IE::eval(x.val(), this->val());
248  for (int i=0; i<this->size(); i++)
249  eq = eq && IE::eval(x.dx(i), this->dx(i));
250  return eq;
251  }
252 
254 
259 
262  const T& val() const { return val_;}
263 
266  T& val() { return val_;}
267 
269 
274 
277  int size() const { return Num;}
278 
284  int availableSize() const { return Num; }
285 
288  bool hasFastAccess() const { return true; }
289 
292  bool isPassive() const { return false; }
293 
296  void setIsConstant(bool is_const) {}
297 
300  const T* dx() const { return &(dx_[0]);}
301 
304  const T& dx(int i) const { return dx_[i]; }
305 
308  T& fastAccessDx(int i) { return dx_[i];}
309 
312  const T& fastAccessDx(int i) const { return dx_[i];}
313 
315 
320 
322  template <typename S>
324  SACADO_ENABLE_VALUE_FUNC(Expr&) operator=(const S& v) {
325  val_ = v;
326  ss_array<T>::zero(dx_, Num);
327  return *this;
328  }
329 
332  Expr& operator=(const Expr& x) {
333  if (this != &x) {
334  // Copy value
335  val_ = x.val_;
336 
337  // Copy dx_
338  for (int i=0; i<Num; i++)
339  dx_[i] = x.dx_[i];
340  }
341  return *this;
342  }
343 
345  template <typename S>
347  SACADO_ENABLE_EXPR_FUNC(Expr&) operator=(const Expr<S>& x) {
348 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
349  if (x.size() != Num)
350  throw "SFad::operator=() Error: Attempt to assign with incompatible sizes";
351 #endif
352 
353  for(int i=0; i<Num; ++i)
354  dx_[i] = x.fastAccessDx(i);
355 
356  val_ = x.val();
357 
358  return *this;
359  }
360 
362 
367 
369  template <typename S>
371  SACADO_ENABLE_VALUE_FUNC(Expr&) operator += (const S& v) {
372  this->val() += v;
373  return *this;
374  }
375 
377  template <typename S>
379  SACADO_ENABLE_VALUE_FUNC(Expr&) operator -= (const S& v) {
380  this->val() -= v;
381  return *this;
382  }
383 
385  template <typename S>
387  SACADO_ENABLE_VALUE_FUNC(Expr&) operator *= (const S& v) {
388  this->val() *= v;
389  for (int i=0; i<Num; ++i)
390  dx_[i] *= v;
391  return *this;
392  }
393 
395  template <typename S>
397  SACADO_ENABLE_VALUE_FUNC(Expr&) operator /= (const S& v) {
398  this->val() /= v;
399  for (int i=0; i<Num; ++i)
400  dx_[i] /= v;
401  return *this;
402  }
403 
405  template <typename S>
407  SACADO_ENABLE_EXPR_FUNC(Expr&) operator += (const Expr<S>& x) {
408 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
409  if (x.size() != Num)
410  throw "SFad::operator+=() Error: Attempt to assign with incompatible sizes";
411 #endif
412 
413  for (int i=0; i<Num; ++i)
414  dx_[i] += x.fastAccessDx(i);
415 
416  val_ += x.val();
417 
418  return *this;
419  }
420 
422  template <typename S>
424  SACADO_ENABLE_EXPR_FUNC(Expr&) operator -= (const Expr<S>& x) {
425 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
426  if (x.size() != Num)
427  throw "SFad::operator-=() Error: Attempt to assign with incompatible sizes";
428 #endif
429 
430  for(int i=0; i<Num; ++i)
431  dx_[i] -= x.fastAccessDx(i);
432 
433  val_ -= x.val();
434 
435  return *this;
436  }
437 
439  template <typename S>
441  SACADO_ENABLE_EXPR_FUNC(Expr&) operator *= (const Expr<S>& x) {
442  T xval = x.val();
443 
444 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
445  if (x.size() != Num)
446  throw "SFad::operator*=() Error: Attempt to assign with incompatible sizes";
447 #endif
448 
449  for(int i=0; i<Num; ++i)
450  dx_[i] = val_ * x.fastAccessDx(i) + dx_[i] * xval;
451 
452  val_ *= xval;
453 
454  return *this;
455  }
456 
458  template <typename S>
460  SACADO_ENABLE_EXPR_FUNC(Expr&) operator /= (const Expr<S>& x) {
461  T xval = x.val();
462 
463 #if defined(SACADO_DEBUG) && !defined(__CUDA_ARCH__ )
464  if (x.size() != Num)
465  throw "SFad::operator/=() Error: Attempt to assign with incompatible sizes";
466 #endif
467 
468  for(int i=0; i<Num; ++i)
469  dx_[i] = ( dx_[i]*xval - val_*x.fastAccessDx(i) )/ (xval*xval);
470 
471  val_ /= xval;
472 
473  return *this;
474  }
475 
477 
478  protected:
479 
481  T dx_[Num];
482 
485 
486  }; // class Expr<SFadExprTag>
487 
488  } // namespace Fad
489 
490 } // namespace Sacado
491 
492 #define FAD_NS Fad
493 #include "Sacado_Fad_SFad_tmpl.hpp"
494 #undef FAD_NS
495 
496 #include "Sacado_Fad_Ops.hpp"
497 
498 #endif // SACADO_NEW_FAD_DESIGN_IS_DEFAULT
499 
500 #include "Sacado_Fad_ViewFad.hpp"
501 
502 #endif // SACADO_FAD_SFAD_HPP
SACADO_INLINE_FUNCTION Expr(const S &x, SACADO_ENABLE_VALUE_CTOR_DECL)
Constructor with supplied value x.
Wrapper for a generic expression template.
SACADO_INLINE_FUNCTION void setIsConstant(bool is_const)
Set whether variable is constant.
expr expr dx(i)
#define SACADO_ENABLE_VALUE_CTOR_DECL
SACADO_INLINE_FUNCTION bool isPassive() const
Returns true if derivative array is empty.
RemoveConst< T >::type value_type
Typename of values.
#define SACADO_ENABLE_EXPR_CTOR_DECL
SACADO_INLINE_FUNCTION void expand(int sz)
Expand derivative array to size sz.
SACADO_INLINE_FUNCTION void cache() const
Cache values.
SACADO_INLINE_FUNCTION const T & fastAccessDx(int i) const
Returns derivative component i without bounds checking.
expr val()
SACADO_INLINE_FUNCTION Expr()
Default constructor.
#define T
Definition: Sacado_rad.hpp:553
#define SACADO_ENABLE_VALUE_FUNC(RETURN_TYPE)
SACADO_INLINE_FUNCTION Expr(const Expr &x)
Copy constructor.
Base template specification for testing equivalence.
SACADO_INLINE_FUNCTION bool hasFastAccess() const
Returns true if derivative array is not empty.
SACADO_INLINE_FUNCTION void zero()
Zero out the derivative array.
SACADO_INLINE_FUNCTION const T & dx(int i) const
Returns derivative component i with bounds checking.
SACADO_INLINE_FUNCTION void diff(const int ith, const int n)
Set Fad object as the ith independent variable.
SACADO_INLINE_FUNCTION bool updateValue() const
Return whether this Fad object has an updated value.
SACADO_INLINE_FUNCTION int availableSize() const
Returns number of derivative components that can be stored without reallocation.
#define SACADO_ENABLE_EXPR_FUNC(RETURN_TYPE)
SACADO_INLINE_FUNCTION T & fastAccessDx(int i)
Returns derivative component i without bounds checking.
DerivInit
Enum use to signal whether the derivative array should be initialized in AD object constructors...
SACADO_INLINE_FUNCTION Expr(const int sz, const int i, const T &x)
Constructor with size sz, index i, and value x.
ScalarType< value_type >::type scalar_type
Typename of scalar&#39;s (which may be different from T)
SACADO_INLINE_FUNCTION const T & val() const
Returns value.
SACADO_INLINE_FUNCTION Expr(const int sz, const T &x, const DerivInit zero_out=InitDerivArray)
Constructor with size sz and value x.
static SACADO_INLINE_FUNCTION void zero(T *dest, int sz)
Zero out array dest of length sz.
Initialize the derivative array.
SACADO_INLINE_FUNCTION SACADO_ENABLE_EXPR_FUNC(bool) isEqualTo(const Expr< S > &x) const
Returns whether two Fad objects have the same values.
SACADO_INLINE_FUNCTION T & val()
Returns value.
SACADO_INLINE_FUNCTION void resize(int sz)
Resize derivative array to length sz.
#define SACADO_INLINE_FUNCTION
A tag for specializing Expr for SFad expressions.
SFad< value_type, Num > base_expr_type
Typename of base-expressions.
GeneralFad< StaticFixedStorage< T, Num > > SFad
SACADO_INLINE_FUNCTION int size() const
Returns number of derivative components.
SACADO_INLINE_FUNCTION const T * dx() const
Returns derivative array.
SACADO_INLINE_FUNCTION Expr(const Expr< S > &x, SACADO_ENABLE_EXPR_CTOR_DECL)
Copy constructor from any Expression object.
SACADO_INLINE_FUNCTION void setUpdateValue(bool update_val)
Set whether this Fad object should update values.