Description
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 inadtl::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 inadtl::adouble
. As far the latter this supports simple allocation (viastd::vector
) andboost::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.