Reference documentation for deal.II version GIT 8ad845fa53 2023-12-10 20:50:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
ad_drivers.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2017 - 2023 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_differentiation_ad_ad_drivers_h
17 #define dealii_differentiation_ad_ad_drivers_h
18 
19 #include <deal.II/base/config.h>
20 
22 #include <deal.II/base/types.h>
23 
26 
28 #include <deal.II/lac/vector.h>
29 
30 #ifdef DEAL_II_WITH_ADOLC
31 
32 # include <adolc/internal/usrparms.h>
33 
34 #endif // DEAL_II_WITH_ADOLC
35 
36 #include <limits>
37 #include <vector>
38 
39 
41 
42 
43 namespace Differentiation
44 {
45  namespace AD
46  {
58  "This function is called in a class that is expected to be specialized "
59  "for auto-differentiable numbers.");
60 
66  "This function is only available if deal.II is compiled with ADOL-C.");
67 
78  std::size_t,
79  std::size_t,
80  << "The number of derivative levels that this auto-differentiable number type supports is "
81  << arg1
82  << ", but to perform the intended operation the number must support at least "
83  << arg2 << " levels.");
84 
92  template <typename ADNumberType, typename T = void>
93  struct Types
94  {
98  using tape_index = unsigned int;
99 
103  using tape_buffer_sizes = unsigned int;
104  }; // struct Types
105 
106 
111  template <typename ADNumberType, typename T = void>
112  struct Numbers
113  {
118  // Note: We stipulate in the documentation for the helper classes that the
119  // valid tape index range is (invalid_tape_index,max_tape_index).
121  0u;
122 
127  std::numeric_limits<typename Types<ADNumberType>::tape_index>::max();
128  }; // struct Numbers
129 
130 
146  template <typename ADNumberType, typename ScalarType, typename T = void>
148  {
149  // This dummy class definition safely supports compilation
150  // against tapeless numbers or taped number types that have
151  // not yet been implemented.
152 
162  bool
163  is_recording() const;
164 
170  active_tape_index() const;
171 
176  bool
178  const typename Types<ADNumberType>::tape_index tape_index) const;
179 
184  bool
185  keep_independent_values() const;
186 
212  void
214  const typename Types<ADNumberType>::tape_buffer_sizes obufsize = 64 *
215  1024 *
216  1024,
217  const typename Types<ADNumberType>::tape_buffer_sizes lbufsize = 64 *
218  1024 *
219  1024,
220  const typename Types<ADNumberType>::tape_buffer_sizes vbufsize = 64 *
221  1024 *
222  1024,
223  const typename Types<ADNumberType>::tape_buffer_sizes tbufsize = 64 *
224  1024 *
225  1024);
226 
235  void
236  start_taping(const typename Types<ADNumberType>::tape_index tape_index,
237  const bool keep_independent_values);
238 
247  void
248  stop_taping(
250  const bool write_tapes_to_file);
251 
255  std::vector<typename Types<ADNumberType>::tape_index>
257 
272  void
273  activate_tape(const typename Types<ADNumberType>::tape_index tape_index);
274 
312  bool
314  const typename Types<ADNumberType>::tape_index tape_index) const;
315 
349  bool
351 
355  void
356  remove_tape(const typename Types<ADNumberType>::tape_index tape_index);
357 
364  void
365  reset(const bool clear_registered_tapes);
366 
375  void
376  print(std::ostream &stream) const;
377 
385  void
387  const typename Types<ADNumberType>::tape_index tape_index,
388  std::ostream &stream) const;
389 
407  ScalarType
409  const std::vector<ScalarType> &independent_variables) const;
410 
424  void
426  const std::vector<ScalarType> &independent_variables,
428 
442  void
444  const std::vector<ScalarType> &independent_variables,
446 
466  void
468  const unsigned int n_dependent_variables,
469  const std::vector<ScalarType> &independent_variables,
470  Vector<ScalarType> &values) const;
471 
490  void
492  const unsigned int n_dependent_variables,
493  const std::vector<ScalarType> &independent_variables,
495 
497  };
498 
499 
500 
516  template <typename ADNumberType, typename ScalarType, typename T = void>
518  {
519  // This dummy class definition safely supports compilation
520  // against taped numbers or tapeless number types that have
521  // not yet been implemented.
522 
545  static void
546  initialize_global_environment(const unsigned int n_independent_variables);
547 
559  void
561 
566  void
568 
573  bool
575 
591  ScalarType
592  value(const std::vector<ADNumberType> &dependent_variables) const;
593 
607  void
608  gradient(const std::vector<ADNumberType> &independent_variables,
609  const std::vector<ADNumberType> &dependent_variables,
611 
625  void
626  hessian(const std::vector<ADNumberType> &independent_variables,
627  const std::vector<ADNumberType> &dependent_variables,
629 
646  void
647  values(const std::vector<ADNumberType> &dependent_variables,
648  Vector<ScalarType> &values) const;
649 
667  void
668  jacobian(const std::vector<ADNumberType> &independent_variables,
669  const std::vector<ADNumberType> &dependent_variables,
671 
673  };
674 
675  } // namespace AD
676 } // namespace Differentiation
677 
678 
679 
680 /* --------------------- inline and template functions --------------------- */
681 
682 
683 #ifndef DOXYGEN
684 
685 namespace Differentiation
686 {
687  namespace AD
688  {
689 # ifdef DEAL_II_WITH_ADOLC
690 
694  template <typename ADNumberType>
695  struct Types<ADNumberType,
696  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
697  NumberTypes::adolc_taped>>
698  {
703  using tape_index = unsigned short;
704 
708  using tape_buffer_sizes = unsigned int;
709  }; // struct Types
710 
711 
715  template <typename ADNumberType>
716  struct Numbers<ADNumberType,
717  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
718  NumberTypes::adolc_taped>>
719  {
730  0;
731 
735  // Note: This value is a limitation of ADOL-C, and not something that we
736  // have control over. See test adolc/helper_tape_index_01.cc for
737  // verification that we cannot use or exceed this value. This value is
738  // defined as TBUFNUM; see
739  // https://gitlab.com/adol-c/adol-c/blob/master/ADOL-C/include/adolc/internal/usrparms.h#L34
740 # ifdef __clang__
741  static const typename Types<ADNumberType>::tape_index max_tape_index =
742  TBUFNUM;
743 # else
744  // For some reason, the test adolc/helper_tape_index_01 indicates that
745  // ADOL-C does not reliably perform correct computations for the full
746  // range of tape indices when GCC is the compiler. So we limit this number
747  // according to the results of the test.
748  static const typename Types<ADNumberType>::tape_index max_tape_index =
749  TBUFNUM - 2;
750 # endif
751  }; // struct Numbers
752 
753 
761  template <typename ADNumberType>
762  struct TapedDrivers<
763  ADNumberType,
764  double,
765  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
766  NumberTypes::adolc_taped>>
767  {
768  using scalar_type = double;
769 
773  TapedDrivers();
774 
775 
781  bool
782  is_recording() const;
783 
785  active_tape_index() const;
786 
787  bool
788  keep_independent_values() const;
789 
790  bool
792  const typename Types<ADNumberType>::tape_index tape_index) const;
793 
794  void
796  const typename Types<ADNumberType>::tape_buffer_sizes in_obufsize,
797  const typename Types<ADNumberType>::tape_buffer_sizes in_lbufsize,
798  const typename Types<ADNumberType>::tape_buffer_sizes in_vbufsize,
799  const typename Types<ADNumberType>::tape_buffer_sizes in_tbufsize);
800 
801  void
802  start_taping(const typename Types<ADNumberType>::tape_index tape_index,
803  const bool keep_independent_values);
804 
805  void
806  stop_taping(
808  const bool write_tapes_to_file);
809 
810  std::vector<typename Types<ADNumberType>::tape_index>
812 
813  void
814  activate_tape(const typename Types<ADNumberType>::tape_index tape_index);
815 
816  bool
818  const typename Types<ADNumberType>::tape_index tape_index) const;
819 
820  bool
822 
823  void
824  remove_tape(const typename Types<ADNumberType>::tape_index tape_index);
825 
826  void
827  reset(const bool clear_registered_tapes);
828 
829  void
830  print(std::ostream &stream) const;
831 
832  void
834  const typename Types<ADNumberType>::tape_index tape_index,
835  std::ostream &stream) const;
836 
844  scalar_type
846  const std::vector<scalar_type> &independent_variables) const;
847 
848  void
850  const std::vector<scalar_type> &independent_variables,
852 
853  void
855  const std::vector<scalar_type> &independent_variables,
857 
865  void
867  const unsigned int n_dependent_variables,
868  const std::vector<scalar_type> &independent_variables,
869  Vector<scalar_type> &values) const;
870 
871  void
873  const unsigned int n_dependent_variables,
874  const std::vector<scalar_type> &independent_variables,
876 
879  protected:
885  typename Types<ADNumberType>::tape_index active_tape;
886 
892  bool keep_values;
893 
898  bool is_recording_flag;
899 
927  mutable std::map<typename Types<ADNumberType>::tape_index, int> status;
928 
935  bool use_stored_taped_buffer_sizes;
936 
940  typename Types<ADNumberType>::tape_buffer_sizes obufsize;
941 
945  typename Types<ADNumberType>::tape_buffer_sizes lbufsize;
946 
950  typename Types<ADNumberType>::tape_buffer_sizes vbufsize;
951 
955  typename Types<ADNumberType>::tape_buffer_sizes tbufsize;
956  };
957 
958 # else
959 
968  template <typename ADNumberType>
969  struct TapedDrivers<
970  ADNumberType,
971  double,
972  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
973  NumberTypes::adolc_taped>>
974  {
975  using scalar_type = double;
976 
982  bool
983  is_recording() const;
984 
986  active_tape_index() const;
987 
988  bool
989  keep_independent_values() const;
990 
991  bool
993  const typename Types<ADNumberType>::tape_index tape_index) const;
994 
995  void
1001 
1002  void
1003  start_taping(const typename Types<ADNumberType>::tape_index, const bool);
1004 
1005  void
1006  stop_taping(const typename Types<ADNumberType>::tape_index, const bool);
1007 
1008  std::vector<typename Types<ADNumberType>::tape_index>
1010 
1011  void
1013 
1014  bool
1015  requires_retaping(const typename Types<ADNumberType>::tape_index) const;
1016 
1017  bool
1019 
1020  void
1022 
1023  void
1024  reset(const bool);
1025 
1026  void
1027  print(std::ostream &stream) const;
1028 
1029  void
1031  std::ostream &) const;
1032 
1040  scalar_type
1041  value(const typename Types<ADNumberType>::tape_index,
1042  const std::vector<scalar_type> &) const;
1043 
1044  void
1046  const std::vector<scalar_type> &,
1047  Vector<scalar_type> &) const;
1048 
1049  void
1051  const std::vector<scalar_type> &,
1052  FullMatrix<scalar_type> &) const;
1053 
1061  void
1062  values(const typename Types<ADNumberType>::tape_index,
1063  const unsigned int,
1064  const std::vector<scalar_type> &,
1065  Vector<scalar_type> &) const;
1066 
1067  void
1069  const unsigned int,
1070  const std::vector<scalar_type> &,
1071  FullMatrix<scalar_type> &) const;
1072 
1074  };
1075 
1076 # endif // DEAL_II_WITH_ADOLC
1077 
1086  template <typename ADNumberType>
1087  struct TapedDrivers<
1088  ADNumberType,
1089  float,
1090  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
1091  NumberTypes::adolc_taped>>
1092  {
1093  using scalar_type = float;
1094 
1100  bool
1101  is_recording() const;
1102 
1104  active_tape_index() const;
1105 
1106  bool
1107  keep_independent_values() const;
1108 
1109  bool
1111  const typename Types<ADNumberType>::tape_index tape_index) const;
1112 
1113  void
1115  const typename Types<ADNumberType>::tape_buffer_sizes obufsize,
1116  const typename Types<ADNumberType>::tape_buffer_sizes lbufsize,
1117  const typename Types<ADNumberType>::tape_buffer_sizes vbufsize,
1118  const typename Types<ADNumberType>::tape_buffer_sizes tbufsize);
1119 
1120  void
1121  start_taping(const typename Types<ADNumberType>::tape_index tape_index,
1122  const bool keep_independent_values);
1123 
1124  void
1125  stop_taping(
1127  const bool write_tapes_to_file);
1128 
1129  std::vector<typename Types<ADNumberType>::tape_index>
1131 
1132  void
1133  activate_tape(const typename Types<ADNumberType>::tape_index tape_index);
1134 
1135  bool
1137  const typename Types<ADNumberType>::tape_index tape_index) const;
1138 
1139  bool
1141 
1142  void
1143  remove_tape(const typename Types<ADNumberType>::tape_index tape_index);
1144 
1145  void
1146  reset(const bool clear_registered_tapes);
1147 
1148  void
1149  print(std::ostream &stream) const;
1150 
1151  void
1153  const typename Types<ADNumberType>::tape_index tape_index,
1154  std::ostream &stream) const;
1155 
1163  scalar_type
1165  const std::vector<scalar_type> &independent_variables) const;
1166 
1167  void
1169  const std::vector<scalar_type> &independent_variables,
1170  Vector<scalar_type> &gradient) const;
1171 
1172  void
1174  const std::vector<scalar_type> &independent_variables,
1176 
1184  void
1186  const unsigned int n_dependent_variables,
1187  const std::vector<scalar_type> &independent_variables,
1188  Vector<scalar_type> &values) const;
1189 
1190  void
1192  const unsigned int n_dependent_variables,
1193  const std::vector<scalar_type> &independent_variables,
1195 
1198  private:
1202  std::vector<double>
1203  vector_float_to_double(const std::vector<float> &in) const;
1204 
1208  TapedDrivers<ADNumberType, double> taped_driver;
1209  };
1210 
1211 
1212  // ------------- TapelessDrivers -------------
1213 
1214 
1220  template <typename ADNumberType, typename ScalarType>
1221  struct TapelessDrivers<
1222  ADNumberType,
1223  ScalarType,
1224  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
1225  NumberTypes::sacado_rad ||
1226  ADNumberTraits<ADNumberType>::type_code ==
1227  NumberTypes::sacado_rad_dfad>>
1228  {
1232  TapelessDrivers();
1233 
1239  static void
1240  initialize_global_environment(const unsigned int n_independent_variables);
1241 
1249  void
1251 
1252  void
1254 
1255  bool
1257 
1265  ScalarType
1266  value(const std::vector<ADNumberType> &dependent_variables) const;
1267 
1268  void
1269  gradient(const std::vector<ADNumberType> &independent_variables,
1270  const std::vector<ADNumberType> &dependent_variables,
1271  Vector<ScalarType> &gradient) const;
1272 
1273  void
1274  hessian(const std::vector<ADNumberType> &independent_variables,
1275  const std::vector<ADNumberType> &dependent_variables,
1277 
1285  void
1286  values(const std::vector<ADNumberType> &dependent_variables,
1287  Vector<ScalarType> &values) const;
1288 
1289  void
1290  jacobian(const std::vector<ADNumberType> &independent_variables,
1291  const std::vector<ADNumberType> &dependent_variables,
1293 
1296  private:
1301  bool dependent_variable_marking_safe;
1302  };
1303 
1304 
1310  template <typename ADNumberType, typename ScalarType>
1311  struct TapelessDrivers<
1312  ADNumberType,
1313  ScalarType,
1314  std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
1315  NumberTypes::adolc_tapeless ||
1316  ADNumberTraits<ADNumberType>::type_code ==
1317  NumberTypes::sacado_dfad ||
1318  ADNumberTraits<ADNumberType>::type_code ==
1319  NumberTypes::sacado_dfad_dfad>>
1320  {
1324  TapelessDrivers();
1325 
1331  static void
1332  initialize_global_environment(const unsigned int n_independent_variables);
1333 
1341  void
1343 
1344  void
1346 
1347  bool
1349 
1357  ScalarType
1358  value(const std::vector<ADNumberType> &dependent_variables) const;
1359 
1360  void
1361  gradient(const std::vector<ADNumberType> &independent_variables,
1362  const std::vector<ADNumberType> &dependent_variables,
1363  Vector<ScalarType> &gradient) const;
1364 
1365  void
1366  hessian(const std::vector<ADNumberType> &independent_variables,
1367  const std::vector<ADNumberType> &dependent_variables,
1369 
1377  void
1378  values(const std::vector<ADNumberType> &dependent_variables,
1379  Vector<ScalarType> &values) const;
1380 
1381  void
1382  jacobian(const std::vector<ADNumberType> &independent_variables,
1383  const std::vector<ADNumberType> &dependent_variables,
1385 
1388  private:
1393  bool dependent_variable_marking_safe;
1394  };
1395 
1396  } // namespace AD
1397 } // namespace Differentiation
1398 
1399 
1400 #endif // DOXYGEN
1401 
1403 
1404 
1405 #endif
Definition: vector.h:110
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
static ::ExceptionBase & ExcRequiresADOLC()
static ::ExceptionBase & ExcSupportedDerivativeLevels(std::size_t arg1, std::size_t arg2)
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:540
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:495
static ::ExceptionBase & ExcRequiresADNumberSpecialization()
static const Types< ADNumberType >::tape_index max_tape_index
Definition: ad_drivers.h:126
static const Types< ADNumberType >::tape_index invalid_tape_index
Definition: ad_drivers.h:120
void gradient(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables, Vector< ScalarType > &gradient) const
Definition: ad_drivers.cc:208
bool is_registered_tape(const typename Types< ADNumberType >::tape_index tape_index) const
Definition: ad_drivers.cc:72
void stop_taping(const typename Types< ADNumberType >::tape_index active_tape_index, const bool write_tapes_to_file)
Definition: ad_drivers.cc:113
void remove_tape(const typename Types< ADNumberType >::tape_index tape_index)
Definition: ad_drivers.cc:162
void start_taping(const typename Types< ADNumberType >::tape_index tape_index, const bool keep_independent_values)
Definition: ad_drivers.cc:103
void hessian(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables, FullMatrix< ScalarType > &hessian) const
Definition: ad_drivers.cc:219
void set_tape_buffer_sizes(const typename Types< ADNumberType >::tape_buffer_sizes obufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes lbufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes vbufsize=64 *1024 *1024, const typename Types< ADNumberType >::tape_buffer_sizes tbufsize=64 *1024 *1024)
Definition: ad_drivers.cc:91
void activate_tape(const typename Types< ADNumberType >::tape_index tape_index)
Definition: ad_drivers.cc:133
bool last_action_requires_retaping() const
Definition: ad_drivers.cc:152
bool requires_retaping(const typename Types< ADNumberType >::tape_index tape_index) const
Definition: ad_drivers.cc:142
void print(std::ostream &stream) const
Definition: ad_drivers.cc:179
void print_tape_stats(const typename Types< ADNumberType >::tape_index tape_index, std::ostream &stream) const
Definition: ad_drivers.cc:187
ScalarType value(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables) const
Definition: ad_drivers.cc:197
Types< ADNumberType >::tape_index active_tape_index() const
Definition: ad_drivers.cc:63
void reset(const bool clear_registered_tapes)
Definition: ad_drivers.cc:171
std::vector< typename Types< ADNumberType >::tape_index > get_registered_tape_indices() const
Definition: ad_drivers.cc:123
void values(const typename Types< ADNumberType >::tape_index active_tape_index, const unsigned int n_dependent_variables, const std::vector< ScalarType > &independent_variables, Vector< ScalarType > &values) const
Definition: ad_drivers.cc:230
void jacobian(const typename Types< ADNumberType >::tape_index active_tape_index, const unsigned int n_dependent_variables, const std::vector< ScalarType > &independent_variables, FullMatrix< ScalarType > &jacobian) const
Definition: ad_drivers.cc:242
void gradient(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, Vector< ScalarType > &gradient) const
Definition: ad_drivers.cc:1475
void hessian(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, FullMatrix< ScalarType > &hessian) const
Definition: ad_drivers.cc:1486
void values(const std::vector< ADNumberType > &dependent_variables, Vector< ScalarType > &values) const
Definition: ad_drivers.cc:1497
void jacobian(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, FullMatrix< ScalarType > &jacobian) const
Definition: ad_drivers.cc:1507
static void initialize_global_environment(const unsigned int n_independent_variables)
Definition: ad_drivers.cc:1431
bool is_dependent_variable_marking_allowed() const
Definition: ad_drivers.cc:1456
ScalarType value(const std::vector< ADNumberType > &dependent_variables) const
Definition: ad_drivers.cc:1465
unsigned int tape_buffer_sizes
Definition: ad_drivers.h:103