-
Notifications
You must be signed in to change notification settings - Fork 48
Add JITGraph + IJITBackend interface and expression recording (XAD_ENABLE_JIT) #190
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
Add JITGraph + IJITBackend interface and expression recording (XAD_ENABLE_JIT) #190
Conversation
auto-differentiation-dev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for this - it’s very close now. There are just a few minor comments left to address.
If you have a chance, it would be great to have the new JIT feature reflected in the README.md in whatever way you think fits best. Given the scope of your contribution and the fact that it will likely bump XAD to version 2.0, this might be a good opportunity to adjust the README more broadly if you feel it makes sense.
da-roth
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback! I hope I addressed all the comments (also updated the PR in the docs).
Regarding the README:
- Added JIT Backend Support to Key Features
Also in a seperate commit (afa12b62784e3289e4f61f2ee243915804ae883a9), I added
- Added xad-forge to related projects — which provides the forge-based JIT backends as a separate repository (the one that can be used later in quantlib-risks-cpp).
Let me know if you'd prefer to not mention it here - I wouldn't really mind if not. If so, I'd just revert that commit.
auto-differentiation-dev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the updates, everything looks great now 👍
The README changes make sense, including the mention of xad-forge, so no need to revert that commit.
We're very happy with where this landed and will go ahead and merge the PR. Thanks again for the solid contribution.
Feel free to open a PR on QuantLib-Risks-Cpp when you're ready. We'll be glad to help there in any way we can.
55b9084
into
auto-differentiation:main
|
Awesome work, congrats on your first merged pull request! |
Comments regarding the discussion in #70 (comment)
Regarding your XAD integration points:
Zero overhead when JIT is not wanted: I’ve added a compile-time CMake option XAD_ENABLE_JIT (default OFF). When it’s OFF, the JIT-related headers and code paths are not compiled/installed, and all JIT-specific logic is behind #ifdef XAD_ENABLE_JIT. Concretely, the JIT headers are only added to public_headers when enabled, and the main include XAD.hpp only includes JIT headers under the same flag.
I also modified the benchmark workflow that compares the same codebase built with XAD_ENABLE_JIT=OFF vs ON to quantify any compile-time-flag overhead.
Backend factory / configuration ergonomics: I implemented JITCompiler::setBackend(std::unique_ptr) (and a constructor taking std::unique_ptr), so users can supply backends with arbitrary constructor parameters/configuration and retain full control (move ownership into XAD). If you prefer the std::forward-style factory API as well, I can add that on top, but the unique_ptr setter seemed like the simplest flexible baseline.
Tests / coverage: I’ve added dedicated JIT tests (JIT_test.cpp, ExpressionMathJit_test.cpp) and extended test helpers with JIT-specific helpers.
On CI: I updated the main CI workflow to build/test with XAD_ENABLE_JIT=ON, and added a separate CI workflow that validates XAD_ENABLE_JIT=OFF to ensure the “no-JIT” configuration stays clean.
PR description:
New files added
.github/workflows/benchmarks-jit-on-off.yml: Checks out the PR once, builds it twice (XAD_ENABLE_JIT=OFFvsXAD_ENABLE_JIT=ON), runssamples/LiborSwaptionPricerfor both builds, and posts a PR comment comparing timings (this measures the impact of the compile-time flag; it does not necessarily exercise runtime JIT unless the sample activates JIT)..github/workflows/ci-jit-off.yml: Dedicated workflow that builds/tests withXAD_ENABLE_JIT=OFF(to validate “JIT disabled” configuration).src/XAD/JITGraph.hpp: DefinesJITOpCodeplus theJITGraphdata structure (nodes, operands, constants, inputs/outputs).src/XAD/JITBackendInterface.hpp: DefinesIJITBackendinterface for pluggable graph execution backends.src/XAD/JITGraphInterpreter.hpp: Reference backend implementingIJITBackendby interpreting theJITGraph(forward + backward).src/XAD/JITOpCodeTraits.hpp: Maps existing XAD operator/functor types toJITOpCodevalues.src/XAD/JITExprTraits.hpp: Helper traits/utilities for recording expressions into aJITGraph(e.g., constants, scalar-constant ops, ldexp handling).src/XAD/JITCompiler.hpp: JIT “tape-like” recorder/executor: tracks inputs/outputs, records expression graphs, compiles via backend, supports forward/backward evaluation.src/XAD/ABool.hpp: Trackable boolean helper for JIT-recorded comparisons/conditionals (records compare nodes and supportsIf(trueVal,falseVal)selection).test/JIT_test.cpp: Unit tests forJITCompilerlifecycle, recording/compile/forward/backward behavior, backend swapping, etc. (compiled whenXAD_ENABLE_JIT=ON).test/ExpressionMathJit_test.cpp: JIT-focused math operation tests (compiled whenXAD_ENABLE_JIT=ON).Existing files modified
.github/workflows/ci.yml: Main CI configures builds with-DXAD_ENABLE_JIT=ON(i.e. the PR path is validated in CI with JIT compiled in). A separate workflow (ci-jit-off.yml) validatesXAD_ENABLE_JIT=OFF.cmake/XADSetupOptions.cmake: Adds CMake optionXAD_ENABLE_JIT(default OFF) and a status message when enabled.src/CMakeLists.txt: Adds the new JIT headers topublic_headersonly whenXAD_ENABLE_JITis enabled.src/XAD/Config.hpp.in: Adds#cmakedefine XAD_ENABLE_JITto generate the compile-time flag inConfig.hpp.src/XAD/XAD.hpp: WhenXAD_ENABLE_JITis enabled, includes the JIT public headers (JITCompiler.hpp,ABool.hpp).src/XAD/BinaryExpr.hpp: WhenXAD_ENABLE_JITis enabled, addsrecordJIT(JITGraph&)so binary expressions can record themselves into aJITGraph.src/XAD/UnaryExpr.hpp: WhenXAD_ENABLE_JITis enabled, addsrecordJIT(JITGraph&)so unary expressions can record themselves into aJITGraph, including dispatch for:ldexp-style ops using an “immediate” exponentsrc/XAD/UnaryOperators.hpp: Adds JIT-only includes (guarded byXAD_ENABLE_JIT) needed for JIT comparison/conditional support.src/XAD/Literals.hpp: Integrates JIT intoARealliteral type:ARealcan participate in graph recording.recordJIT(JITGraph&)for literals/AD variables and plumbing so expression construction/assignment can record to an active JIT graph when there is no active tape and aJITCompileris active.Scalar == nested_type) and avoids instantiating the JIT derivative path for higher-order AD types.test/CMakeLists.txt: Adds JIT tests (JIT_test.cpp,ExpressionMathJit_test.cpp) only whenXAD_ENABLE_JITis enabled.test/TestHelpers.hpp: Adds JIT-only helper functions (mathTest_jit,mathTest2_jit) used by the new JIT math tests.