|
From: Alexander S. <so...@co...> - 2015-02-09 17:37:17
|
Peter, Luigi, Ferdinando:
I am a bit late joining this discussion. I believe the approach
of choosing AD vs. non-AD mode globally at compile time that
you have discussed in the two messages quoted below may on the
balance be the best choice for a large scale C++ library such as
QuantLib. If we try to templatize nearly every class, in addition
to the obscure compiler warning problems noted by Peter we will
also see a major impact on compilation time, because a lot of
the code will recompile the moment we touch any class. Also, as
everyone noted earlier, this is not possible to do without a major
overhaul of the entire code (turning a lot of .cpp files to .hpp headers
and touching a lot of lines of code).
Also, if the ultimate goal is to be able to select which type is using
AD<double> and which type uses double, it may turn out that in
the end the only two settings that will compile will be all-AD or
no-AD settings, and the intermediate combinations will be hard
to make compile and work.
On the other hand, if we simply typedef Real to AD<double>
(for CppAD) or adouble (for ADOL-C), and also ensure that a
variable which has no tape pointer in it simply uses the internal
double, then C++ inlining will likely reduce any performance
impact. The advantage, as noted earlier in this thread, is that
this can be done with minimal changes to the code base and
hopefully can then be pulled into the master branch under
a compile time define.
Thanks to the great wisdom in using Real from the very
beginning, this worked well without massive code changes.
When I did the replacement and hit compile, it was about
150,000 line of C++ compiler errors (some lines of code
were generating many lines of errors). After some tweaking
which I committed to GitHub step by step, we are down to
about 1000 errors and I do not see any major showstoppers
in completing the conversion in a short period of time.
For now I defined all variables as AD<double> except Time,
but changed durations from Time to Real. I am currently
trying to see if we should bite the bullet and use Real for Time
as well, so we only have one type of double within the system.
My code is in the following repos (expect rapid changes):
Fork of Luigi's master, branch master-adjoint with changes:
https://github.com/compatibl/quantlib/commits/master-adjoint
Dependencies including a customized version of CppAD:
https://github.com/compatibl/quantlib-dependencies
To compile in adjoint mode, define QL_AD and put
dependencies\cpp in the include path.
Note that I had to make a minor change to CppAD.
This change to CppAD is in dependencies, so only this
version of CppAD wil work for now.
If I do not manage to find a workaround will ask Brad Bell
to pull my modification under a compile time define. It has
to do with a constructor of AD<double> from another type
with cast to double, which superseded the conversion we
needed for InterestRate to AD<double>. See commit log
for details.
I will keep posting to this thread as we progress on this.
Please let me know any comments, and please contact
me if you wish to contribute to further development of
this alternative approach, or use this repo. After the code
compiles and runs, only then the real work will begin
because the code will require considerable amount of
AD-specific optimizations to outperform the brute force
approach. But I am optimistic that it can be done with
QuantLib.
Best regards
Alexander Sokol
CompatibL
> On Sun, Jan 11, 2015 at 7:16am, Luigi Ballabio wrote:
>
> Hi Peter,
> you definitely need both double and CppAD<double>. I was wondering
> if you needed a given engine if both adjoint and not-adjoint
> implementation.
> If not, you might choose at compile time. Otherwise, we'd have to bite
> the bullet and templatize lots of stuff, as you're doing already.
>
> Luigi
>
> On Thu, Jan 8, 2015 at 8:56 PM, Peter Caspers wrote:
>
> I thought in a realistic application you would always need both
> worlds, CppAD<double> for adjoint greek engines and double for all the
> rest. I wonder what it would mean in terms of performance and memory
> if you replace double by CppAD<double> in general. I can maybe just
> stress test this a bit though.
> Peter
--
View this message in context: http://quantlib.10058.n7.nabble.com/Adjoint-Greeks-tp16147p16251.html
Sent from the quantlib-dev mailing list archive at Nabble.com.
|