deal.II version GIT relicensing-2167-g9622207b8f 2024-11-21 12:40:00+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\}}\)
Loading...
Searching...
No Matches
ad_drivers.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2018 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_differentiation_ad_ad_drivers_h
16#define dealii_differentiation_ad_ad_drivers_h
17
18#include <deal.II/base/config.h>
19
21#include <deal.II/base/types.h>
22
25
27#include <deal.II/lac/vector.h>
28
29#ifdef DEAL_II_WITH_ADOLC
30
31# include <adolc/internal/usrparms.h>
32
33#endif // DEAL_II_WITH_ADOLC
34
35#include <limits>
36#include <vector>
37
38
40
41
42namespace Differentiation
43{
44 namespace AD
45 {
57 "This function is called in a class that is expected to be specialized "
58 "for auto-differentiable numbers.");
59
65 "This function is only available if deal.II is compiled with ADOL-C.");
66
77 std::size_t,
78 std::size_t,
79 << "The number of derivative levels that this auto-differentiable number type supports is "
80 << arg1
81 << ", but to perform the intended operation the number must support at least "
82 << arg2 << " levels.");
83
91 template <typename ADNumberType, typename T = void>
92 struct Types
93 {
97 using tape_index = unsigned int;
98
102 using tape_buffer_sizes = unsigned int;
103 }; // struct Types
104
105
110 template <typename ADNumberType, typename T = void>
111 struct Numbers
112 {
117 // Note: We stipulate in the documentation for the helper classes that the
118 // valid tape index range is (invalid_tape_index,max_tape_index).
120 0u;
121
126 std::numeric_limits<typename Types<ADNumberType>::tape_index>::max();
127 }; // struct Numbers
128
129
145 template <typename ADNumberType, typename ScalarType, typename T = void>
147 {
148 // This dummy class definition safely supports compilation
149 // against tapeless numbers or taped number types that have
150 // not yet been implemented.
151
161 bool
162 is_recording() const;
163
169 active_tape_index() const;
170
175 bool
177 const typename Types<ADNumberType>::tape_index tape_index) const;
178
183 bool
185
211 void
213 const typename Types<ADNumberType>::tape_buffer_sizes obufsize = 64 *
214 1024 *
215 1024,
216 const typename Types<ADNumberType>::tape_buffer_sizes lbufsize = 64 *
217 1024 *
218 1024,
219 const typename Types<ADNumberType>::tape_buffer_sizes vbufsize = 64 *
220 1024 *
221 1024,
222 const typename Types<ADNumberType>::tape_buffer_sizes tbufsize = 64 *
223 1024 *
224 1024);
225
234 void
235 start_taping(const typename Types<ADNumberType>::tape_index tape_index,
236 const bool keep_independent_values);
237
246 void
249 const bool write_tapes_to_file);
250
254 std::vector<typename Types<ADNumberType>::tape_index>
256
271 void
272 activate_tape(const typename Types<ADNumberType>::tape_index tape_index);
273
311 bool
313 const typename Types<ADNumberType>::tape_index tape_index) const;
314
348 bool
350
354 void
355 remove_tape(const typename Types<ADNumberType>::tape_index tape_index);
356
363 void
364 reset(const bool clear_registered_tapes);
365
374 void
375 print(std::ostream &stream) const;
376
384 void
386 const typename Types<ADNumberType>::tape_index tape_index,
387 std::ostream &stream) const;
388
406 ScalarType
408 const std::vector<ScalarType> &independent_variables) const;
409
423 void
425 const std::vector<ScalarType> &independent_variables,
427
441 void
443 const std::vector<ScalarType> &independent_variables,
445
465 void
467 const unsigned int n_dependent_variables,
468 const std::vector<ScalarType> &independent_variables,
470
489 void
491 const unsigned int n_dependent_variables,
492 const std::vector<ScalarType> &independent_variables,
494
496 };
497
498
499
515 template <typename ADNumberType, typename ScalarType, typename T = void>
517 {
518 // This dummy class definition safely supports compilation
519 // against taped numbers or tapeless number types that have
520 // not yet been implemented.
521
544 static void
545 initialize_global_environment(const unsigned int n_independent_variables);
546
558 void
560
565 void
567
572 bool
574
590 ScalarType
591 value(const std::vector<ADNumberType> &dependent_variables) const;
592
606 void
607 gradient(const std::vector<ADNumberType> &independent_variables,
608 const std::vector<ADNumberType> &dependent_variables,
610
624 void
625 hessian(const std::vector<ADNumberType> &independent_variables,
626 const std::vector<ADNumberType> &dependent_variables,
628
645 void
646 values(const std::vector<ADNumberType> &dependent_variables,
648
666 void
667 jacobian(const std::vector<ADNumberType> &independent_variables,
668 const std::vector<ADNumberType> &dependent_variables,
670
672 };
673
674 } // namespace AD
675} // namespace Differentiation
676
677
678
679/* --------------------- inline and template functions --------------------- */
680
681
682#ifndef DOXYGEN
683
684namespace Differentiation
685{
686 namespace AD
687 {
688# ifdef DEAL_II_WITH_ADOLC
689
693 template <typename ADNumberType>
694 struct Types<ADNumberType,
695 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
696 NumberTypes::adolc_taped>>
697 {
702 using tape_index = unsigned short;
703
707 using tape_buffer_sizes = unsigned int;
708 }; // struct Types
709
710
714 template <typename ADNumberType>
715 struct Numbers<ADNumberType,
716 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
717 NumberTypes::adolc_taped>>
718 {
729 0;
730
734 // Note: This value is a limitation of ADOL-C, and not something that we
735 // have control over. See test adolc/helper_tape_index_01.cc for
736 // verification that we cannot use or exceed this value. This value is
737 // defined as TBUFNUM; see
738 // https://gitlab.com/adol-c/adol-c/blob/master/ADOL-C/include/adolc/internal/usrparms.h#L34
739# ifdef __clang__
740 static const typename Types<ADNumberType>::tape_index max_tape_index =
741 TBUFNUM;
742# else
743 // For some reason, the test adolc/helper_tape_index_01 indicates that
744 // ADOL-C does not reliably perform correct computations for the full
745 // range of tape indices when GCC is the compiler. So we limit this number
746 // according to the results of the test.
747 static const typename Types<ADNumberType>::tape_index max_tape_index =
748 TBUFNUM - 2;
749# endif
750 }; // struct Numbers
751
752
760 template <typename ADNumberType>
761 struct TapedDrivers<
762 ADNumberType,
763 double,
764 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
765 NumberTypes::adolc_taped>>
766 {
767 using scalar_type = double;
768
772 TapedDrivers();
773
774
780 bool
781 is_recording() const;
782
784 active_tape_index() const;
785
786 bool
788
789 bool
791 const typename Types<ADNumberType>::tape_index tape_index) const;
792
793 void
795 const typename Types<ADNumberType>::tape_buffer_sizes in_obufsize,
796 const typename Types<ADNumberType>::tape_buffer_sizes in_lbufsize,
797 const typename Types<ADNumberType>::tape_buffer_sizes in_vbufsize,
798 const typename Types<ADNumberType>::tape_buffer_sizes in_tbufsize);
799
800 void
801 start_taping(const typename Types<ADNumberType>::tape_index tape_index,
802 const bool keep_independent_values);
803
804 void
807 const bool write_tapes_to_file);
808
809 std::vector<typename Types<ADNumberType>::tape_index>
811
812 void
813 activate_tape(const typename Types<ADNumberType>::tape_index tape_index);
814
815 bool
817 const typename Types<ADNumberType>::tape_index tape_index) const;
818
819 bool
821
822 void
823 remove_tape(const typename Types<ADNumberType>::tape_index tape_index);
824
825 void
826 reset(const bool clear_registered_tapes);
827
828 void
829 print(std::ostream &stream) const;
830
831 void
833 const typename Types<ADNumberType>::tape_index tape_index,
834 std::ostream &stream) const;
835
843 scalar_type
845 const std::vector<scalar_type> &independent_variables) const;
846
847 void
849 const std::vector<scalar_type> &independent_variables,
851
852 void
854 const std::vector<scalar_type> &independent_variables,
856
864 void
866 const unsigned int n_dependent_variables,
867 const std::vector<scalar_type> &independent_variables,
868 Vector<scalar_type> &values) const;
869
870 void
872 const unsigned int n_dependent_variables,
873 const std::vector<scalar_type> &independent_variables,
875
878 protected:
884 typename Types<ADNumberType>::tape_index active_tape;
885
891 bool keep_values;
892
897 bool is_recording_flag;
898
926 mutable std::map<typename Types<ADNumberType>::tape_index, int> status;
927
934 bool use_stored_taped_buffer_sizes;
935
940
945
950
955 };
956
957# else
958
967 template <typename ADNumberType>
968 struct TapedDrivers<
969 ADNumberType,
970 double,
971 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
972 NumberTypes::adolc_taped>>
973 {
974 using scalar_type = double;
975
981 bool
982 is_recording() const;
983
985 active_tape_index() const;
986
987 bool
989
990 bool
992 const typename Types<ADNumberType>::tape_index tape_index) const;
993
994 void
1000
1001 void
1002 start_taping(const typename Types<ADNumberType>::tape_index, const bool);
1003
1004 void
1005 stop_taping(const typename Types<ADNumberType>::tape_index, const bool);
1006
1007 std::vector<typename Types<ADNumberType>::tape_index>
1009
1010 void
1012
1013 bool
1015
1016 bool
1018
1019 void
1021
1022 void
1023 reset(const bool);
1024
1025 void
1026 print(std::ostream &stream) const;
1027
1028 void
1030 std::ostream &) const;
1031
1039 scalar_type
1041 const std::vector<scalar_type> &) const;
1042
1043 void
1045 const std::vector<scalar_type> &,
1046 Vector<scalar_type> &) const;
1047
1048 void
1050 const std::vector<scalar_type> &,
1051 FullMatrix<scalar_type> &) const;
1052
1060 void
1062 const unsigned int,
1063 const std::vector<scalar_type> &,
1064 Vector<scalar_type> &) const;
1065
1066 void
1068 const unsigned int,
1069 const std::vector<scalar_type> &,
1070 FullMatrix<scalar_type> &) const;
1071
1073 };
1074
1075# endif // DEAL_II_WITH_ADOLC
1076
1085 template <typename ADNumberType>
1086 struct TapedDrivers<
1087 ADNumberType,
1088 float,
1089 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
1090 NumberTypes::adolc_taped>>
1091 {
1092 using scalar_type = float;
1093
1099 bool
1100 is_recording() const;
1101
1103 active_tape_index() const;
1104
1105 bool
1107
1108 bool
1110 const typename Types<ADNumberType>::tape_index tape_index) const;
1111
1112 void
1114 const typename Types<ADNumberType>::tape_buffer_sizes obufsize,
1115 const typename Types<ADNumberType>::tape_buffer_sizes lbufsize,
1116 const typename Types<ADNumberType>::tape_buffer_sizes vbufsize,
1117 const typename Types<ADNumberType>::tape_buffer_sizes tbufsize);
1118
1119 void
1120 start_taping(const typename Types<ADNumberType>::tape_index tape_index,
1121 const bool keep_independent_values);
1122
1123 void
1126 const bool write_tapes_to_file);
1127
1128 std::vector<typename Types<ADNumberType>::tape_index>
1130
1131 void
1132 activate_tape(const typename Types<ADNumberType>::tape_index tape_index);
1133
1134 bool
1136 const typename Types<ADNumberType>::tape_index tape_index) const;
1137
1138 bool
1140
1141 void
1142 remove_tape(const typename Types<ADNumberType>::tape_index tape_index);
1143
1144 void
1145 reset(const bool clear_registered_tapes);
1146
1147 void
1148 print(std::ostream &stream) const;
1149
1150 void
1152 const typename Types<ADNumberType>::tape_index tape_index,
1153 std::ostream &stream) const;
1154
1162 scalar_type
1164 const std::vector<scalar_type> &independent_variables) const;
1165
1166 void
1168 const std::vector<scalar_type> &independent_variables,
1170
1171 void
1173 const std::vector<scalar_type> &independent_variables,
1175
1183 void
1185 const unsigned int n_dependent_variables,
1186 const std::vector<scalar_type> &independent_variables,
1187 Vector<scalar_type> &values) const;
1188
1189 void
1191 const unsigned int n_dependent_variables,
1192 const std::vector<scalar_type> &independent_variables,
1194
1197 private:
1201 std::vector<double>
1202 vector_float_to_double(const std::vector<float> &in) const;
1203
1207 TapedDrivers<ADNumberType, double> taped_driver;
1208 };
1209
1210
1211 // ------------- TapelessDrivers -------------
1212
1213
1219 template <typename ADNumberType, typename ScalarType>
1220 struct TapelessDrivers<
1221 ADNumberType,
1222 ScalarType,
1223 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
1224 NumberTypes::sacado_rad ||
1225 ADNumberTraits<ADNumberType>::type_code ==
1226 NumberTypes::sacado_rad_dfad>>
1227 {
1231 TapelessDrivers();
1232
1238 static void
1239 initialize_global_environment(const unsigned int n_independent_variables);
1240
1248 void
1250
1251 void
1253
1254 bool
1256
1264 ScalarType
1265 value(const std::vector<ADNumberType> &dependent_variables) const;
1266
1267 void
1268 gradient(const std::vector<ADNumberType> &independent_variables,
1269 const std::vector<ADNumberType> &dependent_variables,
1271
1272 void
1273 hessian(const std::vector<ADNumberType> &independent_variables,
1274 const std::vector<ADNumberType> &dependent_variables,
1276
1284 void
1285 values(const std::vector<ADNumberType> &dependent_variables,
1286 Vector<ScalarType> &values) const;
1287
1288 void
1289 jacobian(const std::vector<ADNumberType> &independent_variables,
1290 const std::vector<ADNumberType> &dependent_variables,
1292
1295 private:
1300 bool dependent_variable_marking_safe;
1301 };
1302
1303
1309 template <typename ADNumberType, typename ScalarType>
1310 struct TapelessDrivers<
1311 ADNumberType,
1312 ScalarType,
1313 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
1314 NumberTypes::adolc_tapeless ||
1315 ADNumberTraits<ADNumberType>::type_code ==
1316 NumberTypes::sacado_dfad ||
1317 ADNumberTraits<ADNumberType>::type_code ==
1318 NumberTypes::sacado_dfad_dfad>>
1319 {
1323 TapelessDrivers();
1324
1330 static void
1331 initialize_global_environment(const unsigned int n_independent_variables);
1332
1340 void
1342
1343 void
1345
1346 bool
1348
1356 ScalarType
1357 value(const std::vector<ADNumberType> &dependent_variables) const;
1358
1359 void
1360 gradient(const std::vector<ADNumberType> &independent_variables,
1361 const std::vector<ADNumberType> &dependent_variables,
1363
1364 void
1365 hessian(const std::vector<ADNumberType> &independent_variables,
1366 const std::vector<ADNumberType> &dependent_variables,
1368
1376 void
1377 values(const std::vector<ADNumberType> &dependent_variables,
1378 Vector<ScalarType> &values) const;
1379
1380 void
1381 jacobian(const std::vector<ADNumberType> &independent_variables,
1382 const std::vector<ADNumberType> &dependent_variables,
1384
1387 private:
1392 bool dependent_variable_marking_safe;
1393 };
1394
1395 } // namespace AD
1396} // namespace Differentiation
1397
1398
1399#endif // DOXYGEN
1400
1402
1403
1404#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
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:534
#define DeclExceptionMsg(Exception, defaulttext)
Definition exceptions.h:489
STL namespace.
static const Types< ADNumberType >::tape_index max_tape_index
Definition ad_drivers.h:125
static const Types< ADNumberType >::tape_index invalid_tape_index
Definition ad_drivers.h:119
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:71
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:90
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:62
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:102