Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[draft] Introduce the ADValue class for templated traceless forward mode #64

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

cgraeser
Copy link
Contributor

@cgraeser cgraeser commented Nov 1, 2024

This was initially developed within the Dune module dune-fufem (https://gitlab.dune-project.org/fufem/dune-fufem).

The class adolc::ADValue<T, maxOrder,dim> implementes a traceless forward mode templated with respect to the underlying type T, the maximal tracked derivative order maxOrder and the domain dimension dim. Currently only maxOrder<=2 is implemented.

Using the special value dynamicDim allows to use a runtime dimension. In the latter case the default is to use std::vector as storage. If support for boost::pool is activated, this is used instead.

Notable differences to adtl::adouble are:

  • Being able to use other types that T=double e.g. allows for low/high precision or interval arithmetics.
  • Support for second order derivatives. The interface is also flexible for later implementation of higher order.
  • Fixing the dimension at compile time allows the compiler to do better optimization and generate faster code. Furthermore this guarantees thread-safety (x) by construction and allows to use different dimensions at the same time within a single program.
  • In the dynamic dimension case, the dimension is set per variable, which allows to have different dimensions at the same time. This is implemented by using one boost:pools per dimension instead of a single one for a globally fixed dimension. This also avoids the memory leaks of adtl::adouble when changing the global dimension. Since the pools are thread_local instead of global, this again provides thread-safety (X).

The last point could probably also be implemented for adtl::adouble.

(x) "Thread-safety" hear does not mean that concurrent access to a single ADValue object is safe. Instead if means that concurrent accesss to different objects in different threads is safe and not prone to race-conditions due to internally used global variables.

@cgraeser
Copy link
Contributor Author

cgraeser commented Nov 1, 2024

This is marked as draft, because there are several things that need to be discussed, details that may need to be changed, and features that may need to be added. This includes the following topics:

  • Naming: While the class is placed in the namespace adolc, the naming of types uses CamelCase while adolc uses lower case elsewhere.
  • User interface: This needs to be discussed. This in particular involves the was ADValues are created and initialized and derivatives are read. Currently the whole stored jet is exposed publicly. I'd propose to only expose individual partial derivatives in order to be more flexible for changing the internal data structure later on, e.g. to use a Taylor-based implementation for higher order.
  • Size policy for dynamic mode: Currently the dynamic mode carefully traces and adjusts internal dimensions. This allows to do arithmetics with default constructed values (with internal size=0). While the performance loss seems to be negligible, one may alternatively declare mixing dimensions UB to simplify the code and maybe improve performance.
  • Nonlinear functions: Only a small collection is implemented so far. But there's a simple interface to add more. Furthermore no special care has been taken for 'reasonable' return values in kinks or singularities.
  • Tests: Missing so far.
  • Benchmarks against existing AdolC modes may be useful.
  • Documentation only exists as Doxygen class docs but no manual style descriptive text or examples.
  • C++ standard: Currently this uses C++20 (for spaceship operator) but this could be easily downgraded to C++17 (maybe even C++14) at the expense of some more boiler-plate code.
  • Build system integration: This is currently a single self-contained header not using any other parts of AdolC. Thus the USE_BOOST_POOL macro has to be set manually so far.

This was initially developed within the Dune module
dune-fufem (https://gitlab.dune-project.org/fufem/dune-fufem).

The class `adolc::ADValue<T, maxOrder,dim>` implementes a traceless
forward mode templated with respect to the underlying type `T`,
the maximal tracked derivative order `maxOrder` and the domain
dimension `dim`. Currently only `maxOrder<=2` is implemented.

Using the special value `dynamicDim` allows to use a runtime dimension.
In the latter case the default is to use `std::vector` as storage.
If support for `boost::pool` is activated, this is used instead.

Notable differences to `adtl::adouble` are:

* Being able to use other types that `T=double` e.g. allows for
  low/high precision or interval arithmetics.
* Support for second order derivatives. The interface is also
  flexible for later implementation of higher order.
* Fixing the dimension at compile time allows the compiler to
  do better optimization and generate faster code. Furthermore
  this guarantees thread-safety (x) by construction and allows
  to use different dimensions at the same time within a single
  program.
* In the dynamic dimension case, the dimension is set per variable,
  which allows to have different dimensions at the same time. This
  is implemented by using one `boost:pool`s per dimension instead
  of a single one for a globally fixed dimension. This also avoids
  the memory leaks of `adtl::adouble` when changing the global
  dimension. Since the pools are `thread_local` instead of global,
  this again provides thread-safety (X).

The last point could probably also be implemented for `adtl::adouble`.

(x) "Thread-safety" hear does _not_ mean that concurrent access
to a single `ADValue` object is safe. Instead if means that concurrent
accesss to different objects in different threads is safe and not
prone to race-conditions due to internally used global variables.
@cgraeser cgraeser force-pushed the feature/templated-traceless-forward branch from 3cd17ca to 263ff71 Compare November 1, 2024 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant