Reference documentation for deal.II version 9.5.0
\(\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\}}\)
Loading...
Searching...
No Matches
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
43namespace 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
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
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
685namespace 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
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
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
941
946
951
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
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
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
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
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
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
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,
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,
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,
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
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
static ::ExceptionBase & ExcSupportedDerivativeLevels(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcRequiresADNumberSpecialization()
static ::ExceptionBase & ExcRequiresADOLC()
#define DeclException2(Exception2, type1, type2, outsequence)
Definition exceptions.h:533
#define DeclExceptionMsg(Exception, defaulttext)
Definition exceptions.h:488
STL namespace.
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
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)
void remove_tape(const typename Types< ADNumberType >::tape_index tape_index)
void start_taping(const typename Types< ADNumberType >::tape_index tape_index, const bool keep_independent_values)
void hessian(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables, FullMatrix< ScalarType > &hessian) const
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)
bool requires_retaping(const typename Types< ADNumberType >::tape_index tape_index) const
void print(std::ostream &stream) const
void print_tape_stats(const typename Types< ADNumberType >::tape_index tape_index, std::ostream &stream) const
ScalarType value(const typename Types< ADNumberType >::tape_index active_tape_index, const std::vector< ScalarType > &independent_variables) const
Types< ADNumberType >::tape_index active_tape_index() const
Definition ad_drivers.cc:63
void reset(const bool clear_registered_tapes)
std::vector< typename Types< ADNumberType >::tape_index > get_registered_tape_indices() const
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
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
void gradient(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, Vector< ScalarType > &gradient) const
void hessian(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, FullMatrix< ScalarType > &hessian) const
void values(const std::vector< ADNumberType > &dependent_variables, Vector< ScalarType > &values) const
void jacobian(const std::vector< ADNumberType > &independent_variables, const std::vector< ADNumberType > &dependent_variables, FullMatrix< ScalarType > &jacobian) const
static void initialize_global_environment(const unsigned int n_independent_variables)
ScalarType value(const std::vector< ADNumberType > &dependent_variables) const
unsigned int tape_buffer_sizes
Definition ad_drivers.h:103