We have bindings for AdolC in dune. Unfortunately the lack of thread-safety of the tape-based mode prohibits its use in thread-parallel assembly. On the other hand traceless forward mode with adtl::adouble has several drawbacks that cannot easily be fixed by patching it. As a remedy I implemented my own forward mode class. If there is interest, I'd happily propose it for inclusion in AdolC.
Here's a rough sketch on the approach:
- The core is a class template
ADValue<T, maxOrder, dim> for storing a AD-aware value. T is the raw type (fixed to double in adtl::adouble), maxOrder is the order of computed derivatives, dim is the domain dimension.
- Currently
maxOrder<=2 is supported (adtl::adouble supports a single derivative only), but the interface is allows for later extension.
- Importantly, the dimension can be a compile time constant, such that all computations happen on the stack.
- By using the special value
dynamicDim as template parameter (i.e. ADValue<T, maxOrder, dynamicDim>), one can switch to a dynamic mode as used in adtl::adouble. As far the latter this supports simple allocation (via std::vector) and boost::pool to manage the storage.
- The used approach provides some thread safety guarantees: With compile time size all computations happen on the stack. With dynamic size an can isolate evaluation contexts. Strictly speaking this does not imply that the
ADValue is threadsafe, but it allows to do evaluations (with local variables) in concurrent threads without race conditions due to global variables.
In adtl::adouble is roughly equivalent to ADValue<double,1,dynamicDim>.
In my tests (with complicated nested function but small dimension), using a compile time dimension is about twice as fast as adtl::adouble with boost::pool. In another test I used this to compute the 1st and 2nd order derivatives for a Newton step of a quasilinear PDE (minimal surface). Here the performance is exactly the same as if the derivatives are handwritten.
Notice that the above obviously cannot be achieved by patching adtl::adouble. Hence adding this would mean to add a new templated class.
We have bindings for AdolC in dune. Unfortunately the lack of thread-safety of the tape-based mode prohibits its use in thread-parallel assembly. On the other hand traceless forward mode with
adtl::adoublehas several drawbacks that cannot easily be fixed by patching it. As a remedy I implemented my own forward mode class. If there is interest, I'd happily propose it for inclusion in AdolC.Here's a rough sketch on the approach:
ADValue<T, maxOrder, dim>for storing a AD-aware value.Tis the raw type (fixed to double inadtl::adouble),maxOrderis the order of computed derivatives,dimis the domain dimension.maxOrder<=2is supported (adtl::adoublesupports a single derivative only), but the interface is allows for later extension.dynamicDimas template parameter (i.e.ADValue<T, maxOrder, dynamicDim>), one can switch to a dynamic mode as used inadtl::adouble. As far the latter this supports simple allocation (viastd::vector) andboost::poolto manage the storage.ADValueis threadsafe, but it allows to do evaluations (with local variables) in concurrent threads without race conditions due to global variables.In
adtl::adoubleis roughly equivalent toADValue<double,1,dynamicDim>.In my tests (with complicated nested function but small dimension), using a compile time dimension is about twice as fast as
adtl::adoublewithboost::pool. In another test I used this to compute the 1st and 2nd order derivatives for a Newton step of a quasilinear PDE (minimal surface). Here the performance is exactly the same as if the derivatives are handwritten.Notice that the above obviously cannot be achieved by patching
adtl::adouble. Hence adding this would mean to add a new templated class.