diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 54af9a0..a2442b1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,18 +1,33 @@ -# Workflow to run against the corresponding QuantLib release, -# testing if the build and tests are working fine -# Note: In addition to pushes/pull requests, this workflow -# can also be executed manually, and the repositories / branches -# for QuantLib and XAD can be provided in this case. +############################################################################## +# +# QuantLib-Risks-Cpp-Forge CI Workflow +# +# This workflow mirrors the original QuantLib-Risks-Cpp CI and additionally +# tests with Forge JIT acceleration on Linux and Windows. +# +# Jobs: +# - xad-linux: Original XAD tests (C++17, C++20, AAD ON/OFF) +# - xad-win: Original XAD tests (C++17, C++20, AAD ON/OFF) +# - xad-macos: Original XAD tests (C++17, C++20, AAD ON/OFF) +# - xad-linux-std-classes: Original XAD with QL_USE_STD_CLASSES +# - forge-linux: XAD + Forge JIT tests (C++17, Release/Debug) +# - forge-windows: XAD + Forge JIT tests (C++17, Release/Debug) +# +# Copyright (C) 2025 The QuantLib-Risks-Cpp-Forge Authors +# +# SPDX-License-Identifier: AGPL-3.0-or-later +# +############################################################################## + name: CI -on: - repository_dispatch: - types: [xad-ci-trigger] + +on: push: pull_request: workflow_dispatch: inputs: ql_repo: - description: Quantlib repository in / format + description: QuantLib repository in / format required: true default: lballabio/QuantLib ql_branch: @@ -27,15 +42,41 @@ on: description: Branch or tag for XAD repository required: true default: main - schedule: - - cron: '02 5 * * *' # 5:02 every day + forge_repo: + description: Forge repository in / format + required: true + default: da-roth/forge + forge_branch: + description: Branch or tag for Forge repository + required: true + default: main + xad_forge_repo: + description: xad-forge repository in / format + required: true + default: da-roth/xad-forge + xad_forge_branch: + description: Branch or tag for xad-forge repository + required: true + default: main + env: ql_repo: ${{ github.event.inputs.ql_repo || 'lballabio/QuantLib' }} ql_branch: ${{ github.event.inputs.ql_branch || 'master' }} xad_repo: ${{ github.event.inputs.xad_repo || 'auto-differentiation/xad' }} xad_branch: ${{ github.event.inputs.xad_branch || 'main' }} -jobs: + forge_repo: ${{ github.event.inputs.forge_repo || 'da-roth/forge' }} + forge_branch: ${{ github.event.inputs.forge_branch || 'main' }} + xad_forge_repo: ${{ github.event.inputs.xad_forge_repo || 'da-roth/xad-forge' }} + xad_forge_branch: ${{ github.event.inputs.xad_forge_branch || 'main' }} +jobs: + ############################################################################## + # Linux - Original XAD (mirrors QuantLib-Risks-Cpp) + # + # Note on disable_aad naming: This uses the original QuantLib-Risks-Cpp + # convention where QLRISKS_DISABLE_AAD=OFF means AAD is ENABLED (not disabled). + # The confusing double-negative is preserved for compatibility. + ############################################################################## xad-linux: strategy: fail-fast: false @@ -44,87 +85,99 @@ jobs: cxx: ["17", "20"] runs-on: ubuntu-latest container: ghcr.io/lballabio/quantlib-devenv:rolling + + name: Linux XAD C++${{ matrix.cxx }} AAD=${{ matrix.disable_aad == 'OFF' && 'ON' || 'OFF' }} + steps: - - uses: actions/checkout@v4 - with: - repository: ${{ env.ql_repo }} - ref: ${{ env.ql_branch }} - path: QuantLib - - uses: actions/checkout@v4 - with: - repository: ${{ env.xad_repo }} - ref: ${{ env.xad_branch }} - path: xad - - uses: actions/checkout@v4 - with: - path: QuantLib-Risks-Cpp - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2.12 - with: - key: linux-${{ matrix.disable_aad }} - max-size: 650M - - name: Setup - run: | - apt-get update \ - && apt install -y ccache ninja-build - - name: Configure - run: | - rm -rf ${{ github.workspace }}/install - cd QuantLib - mkdir build - cd build - cmake -G Ninja -DBOOST_ROOT=/usr \ - -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} \ - -DQLRISKS_DISABLE_AAD=${{ matrix.disable_aad }} \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../../xad;$(pwd)/../../QuantLib-Risks-Cpp" \ - -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ - -DQL_NULL_AS_FUNCTIONS=ON \ - -DCMAKE_INSTALL_PREFIX=$(pwd)/../../install \ - .. - - name: Compile - run: | - cd QuantLib/build - cmake --build . - - name: Test QuantLib - run: | - cd QuantLib/build - ./test-suite/quantlib-test-suite --log_level=message - - name: Test QuantLib-Risks - if: ${{ matrix.disable_aad == 'OFF' }} - run: | - cd QuantLib/build - ./QuantLib-Risks-Cpp/test-suite/quantlib-risks-test-suite --log_level=message - - name: Install - if: ${{ matrix.disable_aad == 'OFF' }} - run: | - cd QuantLib/build - cmake --install . - - name: Test Install - if: ${{ matrix.disable_aad == 'OFF' }} - run: | - mkdir installtest - cp QuantLib-Risks-Cpp/Examples/AdjointSwap/AdjointSwapXAD.cpp installtest - cd installtest - echo "cmake_minimum_required(VERSION 3.15.2)" > CMakeLists.txt - echo "project(QlTest LANGUAGES CXX)" >> CMakeLists.txt - echo "find_package(QuantLib-Risks REQUIRED)" >> CMakeLists.txt - echo "add_executable(AdjointSwapXAD AdjointSwapXAD.cpp)" >> CMakeLists.txt - echo "target_link_libraries(AdjointSwapXAD PRIVATE QuantLib::QuantLib)" >> CMakeLists.txt - echo "target_compile_features(AdjointSwapXAD PUBLIC cxx_std_17)" >> CMakeLists.txt - mkdir build - cd build - cmake -G Ninja -DBOOST_ROOT=/usr \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_PREFIX_PATH=$(pwd)/../../install \ - .. - cmake --build . - ./AdjointSwapXAD + - uses: actions/checkout@v4 + with: + repository: ${{ env.ql_repo }} + ref: ${{ env.ql_branch }} + path: QuantLib + + - uses: actions/checkout@v4 + with: + repository: ${{ env.xad_repo }} + ref: ${{ env.xad_branch }} + path: xad + + - uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: linux-xad-${{ matrix.cxx }}-${{ matrix.disable_aad }} + max-size: 650M + + - name: Setup + run: | + apt-get update && apt install -y ccache ninja-build + + - name: Configure + run: | + rm -rf ${{ github.workspace }}/install + cd QuantLib + mkdir build + cd build + cmake -G Ninja -DBOOST_ROOT=/usr \ + -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} \ + -DQLRISKS_DISABLE_AAD=${{ matrix.disable_aad }} \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../../xad;$(pwd)/../../QuantLib-Risks-Cpp-Forge" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + -DCMAKE_INSTALL_PREFIX=$(pwd)/../../install \ + .. + - name: Compile + run: | + cd QuantLib/build + cmake --build . + - name: Test QuantLib + run: | + cd QuantLib/build + ./test-suite/quantlib-test-suite --log_level=message + - name: Test QuantLib-Risks + if: ${{ matrix.disable_aad == 'OFF' }} + run: | + cd QuantLib/build + ./QuantLib-Risks-Cpp-Forge/test-suite/quantlib-risks-test-suite --log_level=message + - name: Install + if: ${{ matrix.disable_aad == 'OFF' }} + run: | + cd QuantLib/build + cmake --install . + + - name: Test Install + if: ${{ matrix.disable_aad == 'OFF' }} + run: | + mkdir installtest + cp QuantLib-Risks-Cpp-Forge/Examples/AdjointSwap/AdjointSwapXAD.cpp installtest + cd installtest + echo "cmake_minimum_required(VERSION 3.15.2)" > CMakeLists.txt + echo "project(QlTest LANGUAGES CXX)" >> CMakeLists.txt + echo "find_package(QuantLib-Risks REQUIRED)" >> CMakeLists.txt + echo "add_executable(AdjointSwapXAD AdjointSwapXAD.cpp)" >> CMakeLists.txt + echo "target_link_libraries(AdjointSwapXAD PRIVATE QuantLib::QuantLib)" >> CMakeLists.txt + echo "target_compile_features(AdjointSwapXAD PUBLIC cxx_std_17)" >> CMakeLists.txt + mkdir build + cd build + cmake -G Ninja -DBOOST_ROOT=/usr \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=$(pwd)/../../install \ + .. + cmake --build . + ./AdjointSwapXAD + + ############################################################################## + # Windows - Original XAD (mirrors QuantLib-Risks-Cpp) + ############################################################################## xad-win: strategy: fail-fast: false @@ -132,100 +185,117 @@ jobs: disable_aad: ["ON", "OFF"] cxx: ["17", "20"] runs-on: windows-2022 + + name: Windows XAD C++${{ matrix.cxx }} AAD=${{ matrix.disable_aad == 'OFF' && 'ON' || 'OFF' }} + env: vsvarsall: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat + steps: - - uses: actions/checkout@v3 - with: - repository: ${{ env.ql_repo }} - ref: ${{ env.ql_branch }} - path: QuantLib - - uses: actions/checkout@v3 - with: - repository: ${{ env.xad_repo }} - ref: ${{ env.xad_branch }} - path: xad - - uses: actions/checkout@v3 - with: - path: QuantLib-Risks-Cpp - - name: sccache - uses: hendrikmuhs/ccache-action@v1.2.12 - with: - key: windows-${{ matrix.disable_aad }} - variant: sccache - max-size: 650M - - name: Setup - run: | - choco install -y ninja - $Url = "https://downloads.sourceforge.net/project/boost/boost-binaries/1.84.0/boost_1_84_0-msvc-14.3-64.exe" - (New-Object System.Net.WebClient).DownloadFile($Url, "$RUNNER_TEMP\boost.exe") - Start-Process -Wait -FilePath "$RUNNER_TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=C:\local\boost" - - name: Configure - env: - BOOST_ROOT: C:\local\boost - shell: cmd - run: | - cd QuantLib - mkdir build - cd build - call "${{ env.vsvarsall }}" amd64 - cmake .. -G Ninja -DQLRISKS_DISABLE_AAD=${{ matrix.disable_aad }} ^ - -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} ^ - -DCMAKE_CXX_COMPILER_LAUNCHER=sccache ^ - -DCMAKE_BUILD_TYPE=Release ^ - -DQL_EXTERNAL_SUBDIRECTORIES="${{ github.workspace }}/xad;${{ github.workspace }}/QuantLib-Risks-Cpp" ^ - -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks ^ - -DQL_NULL_AS_FUNCTIONS=ON ^ - -DXAD_STATIC_MSVC_RUNTIME=ON ^ - -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install - - name: Build - shell: cmd - run: | - cd QuantLib\build - call "${{ env.vsvarsall }}" amd64 - cmake --build . - - name: Test QuantLib - shell: cmd - run: | - cd QuantLib\build - call "${{ env.vsvarsall }}" amd64 - .\test-suite\quantlib-test-suite --log_level=message - - name: Test QuantLib-Risks - if: ${{ matrix.disable_aad == 'OFF' }} - shell: cmd - run: | - cd QuantLib\build - call "${{ env.vsvarsall }}" amd64 - .\QuantLib-Risks-Cpp\test-suite\quantlib-risks-test-suite --log_level=message - - name: Install - if: ${{ matrix.disable_aad == 'OFF' }} - run: | - cd QuantLib/build - cmake --install . - - name: Test Install - if: ${{ matrix.disable_aad == 'OFF' }} - env: - BOOST_ROOT: C:\local\boost - shell: cmd - run: | - mkdir installtest - copy QuantLib-Risks-Cpp\Examples\AdjointSwap\AdjointSwapXAD.cpp installtest - cd installtest - echo cmake_minimum_required(VERSION 3.15.2) > CMakeLists.txt - echo project(QlTest LANGUAGES CXX) >> CMakeLists.txt - echo find_package(QuantLib-Risks REQUIRED) >> CMakeLists.txt - echo add_executable(AdjointSwapXAD AdjointSwapXAD.cpp) >> CMakeLists.txt - echo target_link_libraries(AdjointSwapXAD PRIVATE QuantLib::QuantLib) >> CMakeLists.txt - echo set_target_properties(AdjointSwapXAD PROPERTIES MSVC_RUNTIME_LIBRARY MultiThreaded) >> CMakeLists.txt - echo target_compile_features(AdjointSwapXAD PUBLIC cxx_std_17) >> CMakeLists.txt - mkdir build - cd build - call "${{ env.vsvarsall }}" amd64 - cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install .. - cmake --build . - AdjointSwapXAD.exe + - uses: actions/checkout@v4 + with: + repository: ${{ env.ql_repo }} + ref: ${{ env.ql_branch }} + path: QuantLib + + - uses: actions/checkout@v4 + with: + repository: ${{ env.xad_repo }} + ref: ${{ env.xad_branch }} + path: xad + - uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + - name: sccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: windows-xad-${{ matrix.cxx }}-${{ matrix.disable_aad }} + variant: sccache + max-size: 650M + + - name: Setup + run: | + choco install -y ninja + $Url = "https://downloads.sourceforge.net/project/boost/boost-binaries/1.86.0/boost_1_86_0-msvc-14.3-64.exe" + (New-Object System.Net.WebClient).DownloadFile($Url, "$RUNNER_TEMP\boost.exe") + Start-Process -Wait -FilePath "$RUNNER_TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=C:\local\boost" + + - name: Configure + env: + BOOST_ROOT: C:\local\boost + shell: cmd + run: | + cd QuantLib + mkdir build + cd build + call "${{ env.vsvarsall }}" amd64 + cmake .. -G Ninja -DQLRISKS_DISABLE_AAD=${{ matrix.disable_aad }} ^ + -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} ^ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DQL_EXTERNAL_SUBDIRECTORIES="${{ github.workspace }}/xad;${{ github.workspace }}/QuantLib-Risks-Cpp-Forge" ^ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks ^ + -DQL_NULL_AS_FUNCTIONS=ON ^ + -DXAD_STATIC_MSVC_RUNTIME=ON ^ + -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install + + - name: Build + shell: cmd + run: | + cd QuantLib\build + call "${{ env.vsvarsall }}" amd64 + cmake --build . + + - name: Test QuantLib + shell: cmd + run: | + cd QuantLib\build + call "${{ env.vsvarsall }}" amd64 + .\test-suite\quantlib-test-suite --log_level=message + + - name: Test QuantLib-Risks + if: ${{ matrix.disable_aad == 'OFF' }} + shell: cmd + run: | + cd QuantLib\build + call "${{ env.vsvarsall }}" amd64 + .\QuantLib-Risks-Cpp-Forge\test-suite\quantlib-risks-test-suite --log_level=message + + - name: Install + if: ${{ matrix.disable_aad == 'OFF' }} + run: | + cd QuantLib/build + cmake --install . + + - name: Test Install + if: ${{ matrix.disable_aad == 'OFF' }} + env: + BOOST_ROOT: C:\local\boost + shell: cmd + run: | + mkdir installtest + copy QuantLib-Risks-Cpp-Forge\Examples\AdjointSwap\AdjointSwapXAD.cpp installtest + cd installtest + echo cmake_minimum_required(VERSION 3.15.2) > CMakeLists.txt + echo project(QlTest LANGUAGES CXX) >> CMakeLists.txt + echo find_package(QuantLib-Risks REQUIRED) >> CMakeLists.txt + echo add_executable(AdjointSwapXAD AdjointSwapXAD.cpp) >> CMakeLists.txt + echo target_link_libraries(AdjointSwapXAD PRIVATE QuantLib::QuantLib) >> CMakeLists.txt + echo set_target_properties(AdjointSwapXAD PROPERTIES MSVC_RUNTIME_LIBRARY MultiThreaded) >> CMakeLists.txt + echo target_compile_features(AdjointSwapXAD PUBLIC cxx_std_17) >> CMakeLists.txt + mkdir build + cd build + call "${{ env.vsvarsall }}" amd64 + cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install .. + cmake --build . + AdjointSwapXAD.exe + + ############################################################################## + # macOS - Original XAD (mirrors QuantLib-Risks-Cpp) + # Note: Forge not supported on macOS ARM yet + ############################################################################## xad-macos: strategy: fail-fast: false @@ -233,134 +303,380 @@ jobs: disable_aad: ["ON", "OFF"] cxx: ["17", "20"] runs-on: macos-latest + + name: macOS XAD C++${{ matrix.cxx }} AAD=${{ matrix.disable_aad == 'OFF' && 'ON' || 'OFF' }} + steps: - - uses: actions/checkout@v4 - with: - repository: ${{ env.ql_repo }} - ref: ${{ env.ql_branch }} - path: QuantLib - - uses: actions/checkout@v4 - with: - repository: ${{ env.xad_repo }} - ref: ${{ env.xad_branch }} - path: xad - - uses: actions/checkout@v4 - with: - path: QuantLib-Risks-Cpp - - name: Setup - run: | - brew install boost - brew install ninja - brew install ccache - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2.12 - with: - key: macos-${{ matrix.disable_aad }} - max-size: 650M - - name: Configure - run: | - cd QuantLib - mkdir build - cd build - cmake -G Ninja -DBOOST_ROOT=/usr \ - -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} \ - -DQLRISKS_DISABLE_AAD=${{ matrix.disable_aad }} \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DQL_EXTERNAL_SUBDIRECTORIES="${{ github.workspace }}/xad;${{ github.workspace }}/QuantLib-Risks-Cpp" \ - -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ - -DQL_NULL_AS_FUNCTIONS=ON \ - -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install \ - .. - - name: Compile - run: | - cd QuantLib/build - cmake --build . - - name: Test QuantLib - run: | - cd QuantLib/build - ./test-suite/quantlib-test-suite --log_level=message - - name: Test QuantLib-Risks - if: ${{ matrix.disable_aad == 'OFF' }} - run: | - cd QuantLib/build - ./QuantLib-Risks-Cpp/test-suite/quantlib-risks-test-suite --log_level=message - - name: Install - if: ${{ matrix.disable_aad == 'OFF' }} - run: | - cd QuantLib/build - cmake --install . - - name: Test Install - if: ${{ matrix.disable_aad == 'OFF' }} - run: | - mkdir installtest - cp QuantLib-Risks-Cpp/Examples/AdjointSwap/AdjointSwapXAD.cpp installtest - cd installtest - echo "cmake_minimum_required(VERSION 3.15.2)" > CMakeLists.txt - echo "project(QlTest LANGUAGES CXX)" >> CMakeLists.txt - echo "find_package(QuantLib-Risks REQUIRED)" >> CMakeLists.txt - echo "add_executable(AdjointSwapXAD AdjointSwapXAD.cpp)" >> CMakeLists.txt - echo "target_link_libraries(AdjointSwapXAD PRIVATE QuantLib::QuantLib)" >> CMakeLists.txt - echo "target_compile_features(AdjointSwapXAD PUBLIC cxx_std_17)" >> CMakeLists.txt - mkdir build - cd build - cmake -G Ninja -DBOOST_ROOT=/usr \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install \ - .. - cmake --build . - ./AdjointSwapXAD + - uses: actions/checkout@v4 + with: + repository: ${{ env.ql_repo }} + ref: ${{ env.ql_branch }} + path: QuantLib + + - uses: actions/checkout@v4 + with: + repository: ${{ env.xad_repo }} + ref: ${{ env.xad_branch }} + path: xad + + - uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + - name: Setup + run: | + brew install boost ninja ccache + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: macos-xad-${{ matrix.cxx }}-${{ matrix.disable_aad }} + max-size: 650M + + - name: Configure + run: | + cd QuantLib + mkdir build + cd build + cmake -G Ninja \ + -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} \ + -DQLRISKS_DISABLE_AAD=${{ matrix.disable_aad }} \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DQL_EXTERNAL_SUBDIRECTORIES="${{ github.workspace }}/xad;${{ github.workspace }}/QuantLib-Risks-Cpp-Forge" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install \ + .. + + - name: Compile + run: | + cd QuantLib/build + cmake --build . + + - name: Test QuantLib + run: | + cd QuantLib/build + ./test-suite/quantlib-test-suite --log_level=message + + - name: Test QuantLib-Risks + if: ${{ matrix.disable_aad == 'OFF' }} + run: | + cd QuantLib/build + ./QuantLib-Risks-Cpp-Forge/test-suite/quantlib-risks-test-suite --log_level=message + + - name: Install + if: ${{ matrix.disable_aad == 'OFF' }} + run: | + cd QuantLib/build + cmake --install . + + - name: Test Install + if: ${{ matrix.disable_aad == 'OFF' }} + run: | + mkdir installtest + cp QuantLib-Risks-Cpp-Forge/Examples/AdjointSwap/AdjointSwapXAD.cpp installtest + cd installtest + echo "cmake_minimum_required(VERSION 3.15.2)" > CMakeLists.txt + echo "project(QlTest LANGUAGES CXX)" >> CMakeLists.txt + echo "find_package(QuantLib-Risks REQUIRED)" >> CMakeLists.txt + echo "add_executable(AdjointSwapXAD AdjointSwapXAD.cpp)" >> CMakeLists.txt + echo "target_link_libraries(AdjointSwapXAD PRIVATE QuantLib::QuantLib)" >> CMakeLists.txt + echo "target_compile_features(AdjointSwapXAD PUBLIC cxx_std_17)" >> CMakeLists.txt + mkdir build + cd build + cmake -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install \ + .. + cmake --build . + ./AdjointSwapXAD + + ############################################################################## + # Linux - Original XAD with QL_USE_STD_CLASSES (mirrors QuantLib-Risks-Cpp) + ############################################################################## xad-linux-std-classes: + runs-on: ubuntu-latest + container: ghcr.io/lballabio/quantlib-devenv:rolling + + name: Linux XAD std-classes + + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ env.ql_repo }} + ref: ${{ env.ql_branch }} + path: QuantLib + + - uses: actions/checkout@v4 + with: + repository: ${{ env.xad_repo }} + ref: ${{ env.xad_branch }} + path: xad + + - uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: | + apt-get update && apt install -y ccache ninja-build + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: linux-xad-std-classes + max-size: 650M + + - name: Configure + run: | + cd QuantLib + mkdir build + cd build + cmake -G Ninja -DBOOST_ROOT=/usr \ + -DQL_USE_STD_CLASSES=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../../xad;$(pwd)/../../QuantLib-Risks-Cpp-Forge" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + .. + + - name: Compile + run: | + cd QuantLib/build + cmake --build . + + - name: Test QuantLib + run: | + cd QuantLib/build + ./test-suite/quantlib-test-suite --log_level=message + + - name: Test QuantLib-Risks + run: | + cd QuantLib/build + ./QuantLib-Risks-Cpp-Forge/test-suite/quantlib-risks-test-suite --log_level=message + + ############################################################################## + # Linux - XAD + Forge JIT + # + # Forge accelerates AAD tape computations via JIT compilation, so these jobs + # only make sense with AAD enabled (QLRISKS_DISABLE_AAD=OFF). + # Tests C++17 and C++20 to match original XAD job coverage. + ############################################################################## + forge-linux: strategy: fail-fast: false + matrix: + build_type: ["Release", "Debug"] + cxx: ["17", "20"] runs-on: ubuntu-latest container: ghcr.io/lballabio/quantlib-devenv:rolling + + name: Linux Forge C++${{ matrix.cxx }} ${{ matrix.build_type }} + + steps: + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.ql_repo }} + ref: ${{ env.ql_branch }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.xad_repo }} + ref: ${{ env.xad_branch }} + path: xad + + - name: Checkout Forge + uses: actions/checkout@v4 + with: + repository: ${{ env.forge_repo }} + ref: ${{ env.forge_branch }} + path: forge + + - name: Checkout xad-forge + uses: actions/checkout@v4 + with: + repository: ${{ env.xad_forge_repo }} + ref: ${{ env.xad_forge_branch }} + path: xad-forge + + - name: Checkout QuantLib-Risks-Cpp-Forge + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: linux-forge-${{ matrix.build_type }} + max-size: 650M + + - name: Setup + run: | + apt-get update && apt-get install -y ninja-build ccache + + - name: Build Forge C API + run: | + cd forge + cmake -B build -S api/c \ + -G Ninja \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DCMAKE_INSTALL_PREFIX=$(pwd)/../install + cmake --build build --config ${{ matrix.build_type }} + cmake --install build --config ${{ matrix.build_type }} + + - name: Configure QuantLib with XAD + Forge + run: | + cd QuantLib + mkdir build + cd build + cmake -G Ninja -DBOOST_ROOT=/usr \ + -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DXAD_WARNINGS_PARANOID=OFF \ + -DXAD_ENABLE_JIT=ON \ + -DCMAKE_PREFIX_PATH=$(pwd)/../../install \ + -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../../xad;$(pwd)/../../xad-forge;$(pwd)/../../QuantLib-Risks-Cpp-Forge" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + -DQL_BUILD_TEST_SUITE=OFF \ + -DQL_BUILD_EXAMPLES=OFF \ + -DQL_BUILD_BENCHMARK=OFF \ + -DQLRISKS_DISABLE_AAD=OFF \ + -DQLRISKS_ENABLE_FORGE=ON \ + -DQLRISKS_USE_FORGE_CAPI=ON \ + -DXAD_FORGE_USE_CAPI=ON \ + -DQLRISKS_BUILD_TEST_SUITE=ON \ + -DQLRISKS_ENABLE_FORGE_TESTS=ON \ + .. + + - name: Build + run: | + cd QuantLib/build + cmake --build . + + - name: Test QuantLib-Risks + run: | + cd QuantLib/build + ./QuantLib-Risks-Cpp-Forge/test-suite/quantlib-risks-test-suite --log_level=message + + ############################################################################## + # Windows - XAD + Forge JIT + # + # Forge accelerates AAD tape computations via JIT compilation, so these jobs + # only make sense with AAD enabled (QLRISKS_DISABLE_AAD=OFF). + # Tests C++17 and C++20 to match original XAD job coverage. + ############################################################################## + forge-windows: + strategy: + fail-fast: false + matrix: + build_type: ["Release", "Debug"] + cxx: ["17", "20"] + runs-on: windows-2022 + + name: Windows Forge C++${{ matrix.cxx }} ${{ matrix.build_type }} + + env: + VSVARSALL: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat + steps: - - uses: actions/checkout@v4 - with: - repository: ${{ env.ql_repo }} - ref: ${{ env.ql_branch }} - path: QuantLib - - uses: actions/checkout@v4 - with: - repository: ${{ env.xad_repo }} - ref: ${{ env.xad_branch }} - path: xad - - uses: actions/checkout@v4 - with: - path: QuantLib-Risks-Cpp - - name: Setup - run: | - apt-get update \ - && apt install -y ccache ninja-build \ - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2.12 - with: - key: linux-std-classes - max-size: 650M - - name: Configure - run: | - cd QuantLib - mkdir build - cd build - cmake -G Ninja -DBOOST_ROOT=/usr \ - -DQL_USE_STD_CLASSES=ON \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../../xad;$(pwd)/../../QuantLib-Risks-Cpp" \ - -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ - -DQL_NULL_AS_FUNCTIONS=ON \ - .. - - name: Compile - run: | - cd QuantLib/build - cmake --build . - - name: Test QuantLib - run: | - cd QuantLib/build - ./test-suite/quantlib-test-suite --log_level=message - - name: Test QuantLib-Risks - run: | - cd QuantLib/build - ./QuantLib-Risks-Cpp/test-suite/quantlib-risks-test-suite --log_level=message + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.ql_repo }} + ref: ${{ env.ql_branch }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.xad_repo }} + ref: ${{ env.xad_branch }} + path: xad + + - name: Checkout Forge + uses: actions/checkout@v4 + with: + repository: ${{ env.forge_repo }} + ref: ${{ env.forge_branch }} + path: forge + + - name: Checkout xad-forge + uses: actions/checkout@v4 + with: + repository: ${{ env.xad_forge_repo }} + ref: ${{ env.xad_forge_branch }} + path: xad-forge + + - name: Checkout QuantLib-Risks-Cpp-Forge + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: choco install -y ninja + + - name: Setup Boost + run: | + $Url = "https://downloads.sourceforge.net/project/boost/boost-binaries/1.86.0/boost_1_86_0-msvc-14.3-64.exe" + (New-Object System.Net.WebClient).DownloadFile($Url, "$RUNNER_TEMP\boost.exe") + Start-Process -Wait -FilePath "$RUNNER_TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=C:\local\boost" + echo "BOOST_ROOT=C:\local\boost" >> $env:GITHUB_ENV + + - name: Build Forge C API + shell: cmd + run: | + cd forge + call "%VSVARSALL%" amd64 + cmake -B build -S api/c -G Ninja ^ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} ^ + -DFORGE_CAPI_BUILD_TESTS=OFF ^ + -DFORGE_CAPI_USE_STATIC_RUNTIME=ON ^ + -DCMAKE_INSTALL_PREFIX="%cd%\..\install" + cmake --build build --config ${{ matrix.build_type }} + cmake --install build --config ${{ matrix.build_type }} + + - name: Configure QuantLib with XAD + Forge + shell: cmd + run: | + cd QuantLib + call "%VSVARSALL%" amd64 + cmake -B build -G Ninja ^ + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} ^ + -DCMAKE_CXX_STANDARD=${{ matrix.cxx }} ^ + -DXAD_WARNINGS_PARANOID=OFF ^ + -DXAD_ENABLE_JIT=ON ^ + -DXAD_STATIC_MSVC_RUNTIME=ON ^ + -DCMAKE_PREFIX_PATH="%cd%\..\install" ^ + -DQL_EXTERNAL_SUBDIRECTORIES="%cd%\..\xad;%cd%\..\xad-forge;%cd%\..\QuantLib-Risks-Cpp-Forge" ^ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks ^ + -DQL_NULL_AS_FUNCTIONS=ON ^ + -DQL_BUILD_TEST_SUITE=OFF ^ + -DQL_BUILD_EXAMPLES=OFF ^ + -DQL_BUILD_BENCHMARK=OFF ^ + -DQLRISKS_DISABLE_AAD=OFF ^ + -DQLRISKS_ENABLE_FORGE=ON ^ + -DQLRISKS_USE_FORGE_CAPI=ON ^ + -DXAD_FORGE_USE_CAPI=ON ^ + -DQLRISKS_BUILD_TEST_SUITE=ON ^ + -DQLRISKS_ENABLE_FORGE_TESTS=ON + + - name: Build + shell: cmd + run: | + cd QuantLib\build + call "%VSVARSALL%" amd64 + cmake --build . --config ${{ matrix.build_type }} + + - name: Test QuantLib-Risks + shell: cmd + run: | + cd QuantLib\build + set PATH=%cd%\..\..\install\bin;%PATH% + QuantLib-Risks-Cpp-Forge\test-suite\quantlib-risks-test-suite.exe --log_level=message diff --git a/.github/workflows/ql-benchmarks.yaml b/.github/workflows/ql-benchmarks.yaml new file mode 100644 index 0000000..073f703 --- /dev/null +++ b/.github/workflows/ql-benchmarks.yaml @@ -0,0 +1,1692 @@ +############################################################################## +# +# QuantLib-Risks Benchmarks +# +# Compares different AD configurations for Swaption pricing: +# - QL + XAD: Original QuantLib-Risks-Cpp with XAD tape (baseline) +# - QL + XAD-Forge: QuantLib-Risks-Cpp-Forge with Forge JIT backends +# +# Jobs: +# - Linux/Windows, QL + XAD: True baseline (original repo, XAD tape) +# - Linux/Windows, QL + XAD-Forge: Forge JIT (runs XAD tape + JIT + JIT-AVX) +# - Decomposition: Detailed timing breakdown +# - Compare: Statistical comparison XAD vs XAD-Forge +# +# Type Overhead Measurement (pricing-only, no derivatives): +# - Linux/Windows, double vs AReal (no diff): Compares plain double vs xad::AReal on same hardware +# +# Dependencies: +# - QuantLib (lballabio/QuantLib) +# - XAD (auto-differentiation/xad) +# - QuantLib-Risks-Cpp (auto-differentiation/QuantLib-Risks-Cpp) [baseline] +# - xad-forge (da-roth/xad-forge) [Forge jobs] +# - Forge C API (da-roth/forge) [Forge jobs] +# +# Copyright (C) 2025 Xcelerit Computing Limited +# SPDX-License-Identifier: AGPL-3.0-or-later +# +############################################################################## + +name: QL Benchmarks + +on: + push: + paths: + - 'test-suite/swaption_benchmark*.cpp' + - 'test-suite/benchmark_main.cpp' + - 'test-suite/benchmark_utils.hpp' + - '.github/workflows/ql-benchmarks.yaml' + pull_request: + paths: + - 'test-suite/swaption_benchmark*.cpp' + - 'test-suite/benchmark_main.cpp' + - 'test-suite/benchmark_utils.hpp' + - '.github/workflows/ql-benchmarks.yaml' + workflow_dispatch: + inputs: + ql_repo: + description: 'QuantLib repository' + required: false + default: 'lballabio/QuantLib' + ql_branch: + description: 'QuantLib branch' + required: false + default: 'master' + xad_repo: + description: 'XAD repository' + required: false + default: 'auto-differentiation/xad' + xad_branch: + description: 'XAD branch' + required: false + default: 'main' + qlrisks_repo: + description: 'QuantLib-Risks-Cpp repository (for baseline)' + required: false + default: 'auto-differentiation/QuantLib-Risks-Cpp' + qlrisks_branch: + description: 'QuantLib-Risks-Cpp branch (for baseline)' + required: false + default: 'main' + forge_repo: + description: 'Forge repository' + required: false + default: 'da-roth/forge' + forge_branch: + description: 'Forge branch' + required: false + default: 'main' + xad_forge_repo: + description: 'xad-forge repository' + required: false + default: 'da-roth/xad-forge' + xad_forge_branch: + description: 'xad-forge branch' + required: false + default: 'main' + +env: + QL_REPO: ${{ github.event.inputs.ql_repo || 'lballabio/QuantLib' }} + QL_BRANCH: ${{ github.event.inputs.ql_branch || 'master' }} + XAD_REPO: ${{ github.event.inputs.xad_repo || 'auto-differentiation/xad' }} + XAD_BRANCH: ${{ github.event.inputs.xad_branch || 'main' }} + QLRISKS_REPO: ${{ github.event.inputs.qlrisks_repo || 'auto-differentiation/QuantLib-Risks-Cpp' }} + QLRISKS_BRANCH: ${{ github.event.inputs.qlrisks_branch || 'main' }} + FORGE_REPO: ${{ github.event.inputs.forge_repo || 'da-roth/forge' }} + FORGE_BRANCH: ${{ github.event.inputs.forge_branch || 'main' }} + XAD_FORGE_REPO: ${{ github.event.inputs.xad_forge_repo || 'da-roth/xad-forge' }} + XAD_FORGE_BRANCH: ${{ github.event.inputs.xad_forge_branch || 'main' }} + +jobs: + ############################################################################## + # Linux, QL + XAD (True Baseline) + # Uses original QuantLib-Risks-Cpp with XAD tape - no Forge code + ############################################################################## + linux-xad: + name: Linux, QL + XAD + runs-on: ubuntu-latest + container: + image: ghcr.io/lballabio/quantlib-devenv:rolling + + steps: + - name: Hardware Info + run: | + echo "===== CPU =====" + lscpu | grep -E "^(Model name|CPU\(s\)|Thread|Core|Socket|CPU max MHz)" + echo "===== Memory =====" + free -h + + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.QL_REPO }} + ref: ${{ env.QL_BRANCH }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_REPO }} + ref: ${{ env.XAD_BRANCH }} + path: xad + + - name: Checkout QuantLib-Risks-Cpp (Original) + uses: actions/checkout@v4 + with: + repository: ${{ env.QLRISKS_REPO }} + ref: ${{ env.QLRISKS_BRANCH }} + path: QuantLib-Risks-Cpp + + - name: Checkout QuantLib-Risks-Cpp-Forge (for benchmark code) + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: | + apt-get update + apt-get install -y ninja-build cmake + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: linux-ql-xad + max-size: 650M + + - name: Patch benchmark into original QuantLib-Risks-Cpp + run: | + # Copy standalone benchmark files from Forge repo to original + cp QuantLib-Risks-Cpp-Forge/test-suite/benchmark_main.cpp \ + QuantLib-Risks-Cpp/test-suite/ + cp QuantLib-Risks-Cpp-Forge/test-suite/PlatformInfo.hpp \ + QuantLib-Risks-Cpp/test-suite/ + cp QuantLib-Risks-Cpp-Forge/test-suite/utilities_xad.cpp \ + QuantLib-Risks-Cpp/test-suite/ + cp QuantLib-Risks-Cpp-Forge/test-suite/utilities_xad.hpp \ + QuantLib-Risks-Cpp/test-suite/ + + # Add standalone benchmark target to CMakeLists.txt + cat >> QuantLib-Risks-Cpp/test-suite/CMakeLists.txt << 'EOF' + + # Standalone benchmark (patched from QuantLib-Risks-Cpp-Forge) + add_executable(QuantLib-Risks_benchmark_standalone benchmark_main.cpp) + set_target_properties(QuantLib-Risks_benchmark_standalone PROPERTIES + OUTPUT_NAME "quantlib-risks-benchmark-standalone") + target_link_libraries(QuantLib-Risks_benchmark_standalone PRIVATE + ql_library + ${QL_THREAD_LIBRARIES}) + EOF + + - name: Configure QuantLib + run: | + cd QuantLib + cmake -B build -G Ninja -DBOOST_ROOT=/usr \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DXAD_WARNINGS_PARANOID=OFF \ + -DXAD_ENABLE_JIT=OFF \ + -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../xad;$(pwd)/../QuantLib-Risks-Cpp" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + -DQL_BUILD_TEST_SUITE=OFF \ + -DQL_BUILD_EXAMPLES=OFF \ + -DQL_BUILD_BENCHMARK=OFF \ + -DQLRISKS_DISABLE_AAD=OFF \ + -DQLRISKS_BUILD_TEST_SUITE=ON + + - name: Build + run: | + cd QuantLib/build + cmake --build . --target QuantLib-Risks_benchmark_standalone + + - name: Run Benchmark + run: | + cd QuantLib/build + ./QuantLib-Risks-Cpp/test-suite/quantlib-risks-benchmark-standalone + + ############################################################################## + # Linux, QL + XAD-Forge + # Uses QuantLib-Risks-Cpp-Forge with Forge JIT backends + # Runs all methods: XAD tape + JIT-Forge + JIT-ForgeAVX2 + ############################################################################## + linux-xad-forge: + name: Linux, QL + XAD-Forge + runs-on: ubuntu-latest + container: + image: ghcr.io/lballabio/quantlib-devenv:rolling + + steps: + - name: Hardware Info + run: | + echo "===== CPU =====" + lscpu | grep -E "^(Model name|CPU\(s\)|Thread|Core|Socket|CPU max MHz)" + echo "===== Memory =====" + free -h + + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.QL_REPO }} + ref: ${{ env.QL_BRANCH }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_REPO }} + ref: ${{ env.XAD_BRANCH }} + path: xad + + - name: Checkout Forge + uses: actions/checkout@v4 + with: + repository: ${{ env.FORGE_REPO }} + ref: ${{ env.FORGE_BRANCH }} + path: forge + + - name: Checkout xad-forge + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_FORGE_REPO }} + ref: ${{ env.XAD_FORGE_BRANCH }} + path: xad-forge + + - name: Checkout QuantLib-Risks-Cpp-Forge + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: | + apt-get update + apt-get install -y ninja-build cmake + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: linux-ql-xad-forge + max-size: 650M + + - name: Build Forge C API + run: | + cd forge + cmake -B build -S api/c -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DFORGE_CAPI_BUILD_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX=$(pwd)/../install + cmake --build build + cmake --install build + + - name: Configure QuantLib + run: | + cd QuantLib + cmake -B build -G Ninja -DBOOST_ROOT=/usr \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DXAD_WARNINGS_PARANOID=OFF \ + -DXAD_ENABLE_JIT=ON \ + -DCMAKE_PREFIX_PATH=$(pwd)/../install \ + -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../xad;$(pwd)/../xad-forge;$(pwd)/../QuantLib-Risks-Cpp-Forge" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + -DQL_BUILD_TEST_SUITE=OFF \ + -DQL_BUILD_EXAMPLES=OFF \ + -DQL_BUILD_BENCHMARK=OFF \ + -DQLRISKS_DISABLE_AAD=OFF \ + -DQLRISKS_ENABLE_FORGE=ON \ + -DQLRISKS_USE_FORGE_CAPI=ON \ + -DXAD_FORGE_USE_CAPI=ON \ + -DQLRISKS_BUILD_TEST_SUITE=OFF \ + -DQLRISKS_BUILD_BENCHMARK_STANDALONE=ON \ + -DQLRISKS_ENABLE_FORGE_TESTS=ON + + - name: Build + run: | + cd QuantLib/build + cmake --build . + + - name: Run Benchmark + run: | + cd QuantLib/build + export LD_LIBRARY_PATH=$(pwd)/../../install/lib:$LD_LIBRARY_PATH + ./QuantLib-Risks-Cpp-Forge/test-suite/quantlib-risks-benchmark-standalone + + ############################################################################## + # Windows, QL + XAD (True Baseline) + ############################################################################## + windows-xad: + name: Windows, QL + XAD + runs-on: windows-2022 + + env: + VSVARSALL: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat + + steps: + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.QL_REPO }} + ref: ${{ env.QL_BRANCH }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_REPO }} + ref: ${{ env.XAD_BRANCH }} + path: xad + + - name: Checkout QuantLib-Risks-Cpp (Original) + uses: actions/checkout@v4 + with: + repository: ${{ env.QLRISKS_REPO }} + ref: ${{ env.QLRISKS_BRANCH }} + path: QuantLib-Risks-Cpp + + - name: Checkout QuantLib-Risks-Cpp-Forge (for benchmark code) + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: choco install -y ninja + + - name: Setup Boost + run: | + $Url = "https://downloads.sourceforge.net/project/boost/boost-binaries/1.86.0/boost_1_86_0-msvc-14.3-64.exe" + (New-Object System.Net.WebClient).DownloadFile($Url, "$RUNNER_TEMP\boost.exe") + Start-Process -Wait -FilePath "$RUNNER_TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=C:\local\boost" + echo "BOOST_ROOT=C:\local\boost" >> $env:GITHUB_ENV + + - name: Patch benchmark into original QuantLib-Risks-Cpp + shell: pwsh + run: | + # Copy standalone benchmark files from Forge repo to original + Copy-Item "QuantLib-Risks-Cpp-Forge/test-suite/benchmark_main.cpp" "QuantLib-Risks-Cpp/test-suite/" + Copy-Item "QuantLib-Risks-Cpp-Forge/test-suite/PlatformInfo.hpp" "QuantLib-Risks-Cpp/test-suite/" + Copy-Item "QuantLib-Risks-Cpp-Forge/test-suite/utilities_xad.cpp" "QuantLib-Risks-Cpp/test-suite/" + Copy-Item "QuantLib-Risks-Cpp-Forge/test-suite/utilities_xad.hpp" "QuantLib-Risks-Cpp/test-suite/" + + # Add standalone benchmark target to CMakeLists.txt + $cmakeAddition = @" + + # Standalone benchmark (patched from QuantLib-Risks-Cpp-Forge) + add_executable(QuantLib-Risks_benchmark_standalone benchmark_main.cpp) + set_target_properties(QuantLib-Risks_benchmark_standalone PROPERTIES + OUTPUT_NAME "quantlib-risks-benchmark-standalone") + target_link_libraries(QuantLib-Risks_benchmark_standalone PRIVATE + ql_library + `${QL_THREAD_LIBRARIES}) + "@ + Add-Content -Path "QuantLib-Risks-Cpp/test-suite/CMakeLists.txt" -Value $cmakeAddition + + - name: Configure QuantLib + shell: cmd + run: | + cd QuantLib + call "%VSVARSALL%" amd64 + cmake -B build -G Ninja ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_CXX_STANDARD=17 ^ + -DXAD_WARNINGS_PARANOID=OFF ^ + -DXAD_ENABLE_JIT=OFF ^ + -DXAD_STATIC_MSVC_RUNTIME=ON ^ + -DQL_EXTERNAL_SUBDIRECTORIES="%cd%\..\xad;%cd%\..\QuantLib-Risks-Cpp" ^ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks ^ + -DQL_NULL_AS_FUNCTIONS=ON ^ + -DQL_BUILD_TEST_SUITE=OFF ^ + -DQL_BUILD_EXAMPLES=OFF ^ + -DQL_BUILD_BENCHMARK=OFF ^ + -DQLRISKS_DISABLE_AAD=OFF ^ + -DQLRISKS_BUILD_TEST_SUITE=ON + + - name: Build + shell: cmd + run: | + cd QuantLib\build + call "%VSVARSALL%" amd64 + cmake --build . --target QuantLib-Risks_benchmark_standalone --config Release + + - name: Run Benchmark + shell: cmd + run: | + cd QuantLib\build + QuantLib-Risks-Cpp\test-suite\quantlib-risks-benchmark-standalone.exe + + ############################################################################## + # Windows, QL + XAD-Forge + ############################################################################## + windows-xad-forge: + name: Windows, QL + XAD-Forge + runs-on: windows-2022 + + env: + VSVARSALL: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat + + steps: + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.QL_REPO }} + ref: ${{ env.QL_BRANCH }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_REPO }} + ref: ${{ env.XAD_BRANCH }} + path: xad + + - name: Checkout Forge + uses: actions/checkout@v4 + with: + repository: ${{ env.FORGE_REPO }} + ref: ${{ env.FORGE_BRANCH }} + path: forge + + - name: Checkout xad-forge + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_FORGE_REPO }} + ref: ${{ env.XAD_FORGE_BRANCH }} + path: xad-forge + + - name: Checkout QuantLib-Risks-Cpp-Forge + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: choco install -y ninja + + - name: Setup Boost + run: | + $Url = "https://downloads.sourceforge.net/project/boost/boost-binaries/1.86.0/boost_1_86_0-msvc-14.3-64.exe" + (New-Object System.Net.WebClient).DownloadFile($Url, "$RUNNER_TEMP\boost.exe") + Start-Process -Wait -FilePath "$RUNNER_TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=C:\local\boost" + echo "BOOST_ROOT=C:\local\boost" >> $env:GITHUB_ENV + + - name: Build Forge C API + shell: cmd + run: | + cd forge + call "%VSVARSALL%" amd64 + cmake -B build -S api/c -G Ninja ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DFORGE_CAPI_BUILD_TESTS=OFF ^ + -DFORGE_CAPI_USE_STATIC_RUNTIME=ON ^ + -DCMAKE_INSTALL_PREFIX="%cd%\..\install" + cmake --build build + cmake --install build + + - name: Configure QuantLib + shell: cmd + run: | + cd QuantLib + call "%VSVARSALL%" amd64 + cmake -B build -G Ninja ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_CXX_STANDARD=17 ^ + -DXAD_WARNINGS_PARANOID=OFF ^ + -DXAD_ENABLE_JIT=ON ^ + -DXAD_STATIC_MSVC_RUNTIME=ON ^ + -DCMAKE_PREFIX_PATH="%cd%\..\install" ^ + -DQL_EXTERNAL_SUBDIRECTORIES="%cd%\..\xad;%cd%\..\xad-forge;%cd%\..\QuantLib-Risks-Cpp-Forge" ^ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks ^ + -DQL_NULL_AS_FUNCTIONS=ON ^ + -DQL_BUILD_TEST_SUITE=OFF ^ + -DQL_BUILD_EXAMPLES=OFF ^ + -DQL_BUILD_BENCHMARK=OFF ^ + -DQLRISKS_DISABLE_AAD=OFF ^ + -DQLRISKS_ENABLE_FORGE=ON ^ + -DQLRISKS_USE_FORGE_CAPI=ON ^ + -DXAD_FORGE_USE_CAPI=ON ^ + -DQLRISKS_BUILD_TEST_SUITE=OFF ^ + -DQLRISKS_BUILD_BENCHMARK_STANDALONE=ON ^ + -DQLRISKS_ENABLE_FORGE_TESTS=ON + + - name: Build + shell: cmd + run: | + cd QuantLib\build + call "%VSVARSALL%" amd64 + cmake --build . --config Release + + - name: Run Benchmark + shell: cmd + run: | + cd QuantLib\build + set PATH=%cd%\..\..\install\bin;%PATH% + QuantLib-Risks-Cpp-Forge\test-suite\quantlib-risks-benchmark-standalone.exe + + ############################################################################## + # Performance Decomposition - Detailed timing breakdown (XAD-Forge) + ############################################################################## + decomposition: + name: Decomposition + runs-on: ubuntu-latest + container: + image: ghcr.io/lballabio/quantlib-devenv:rolling + + steps: + - name: Hardware Info + run: | + echo "===== CPU =====" + lscpu | grep -E "^(Model name|CPU\(s\)|Thread|Core|Socket|CPU max MHz)" + echo "===== Memory =====" + free -h + + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.QL_REPO }} + ref: ${{ env.QL_BRANCH }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_REPO }} + ref: ${{ env.XAD_BRANCH }} + path: xad + + - name: Checkout Forge + uses: actions/checkout@v4 + with: + repository: ${{ env.FORGE_REPO }} + ref: ${{ env.FORGE_BRANCH }} + path: forge + + - name: Checkout xad-forge + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_FORGE_REPO }} + ref: ${{ env.XAD_FORGE_BRANCH }} + path: xad-forge + + - name: Checkout QuantLib-Risks-Cpp-Forge + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: | + apt-get update + apt-get install -y ninja-build cmake + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: linux-decomposition + max-size: 650M + + - name: Build Forge C API + run: | + cd forge + cmake -B build -S api/c -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DFORGE_CAPI_BUILD_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX=$(pwd)/../install + cmake --build build + cmake --install build + + - name: Configure QuantLib + run: | + cd QuantLib + cmake -B build -G Ninja -DBOOST_ROOT=/usr \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DXAD_WARNINGS_PARANOID=OFF \ + -DXAD_ENABLE_JIT=ON \ + -DCMAKE_PREFIX_PATH=$(pwd)/../install \ + -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../xad;$(pwd)/../xad-forge;$(pwd)/../QuantLib-Risks-Cpp-Forge" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + -DQL_BUILD_TEST_SUITE=OFF \ + -DQL_BUILD_EXAMPLES=OFF \ + -DQL_BUILD_BENCHMARK=OFF \ + -DQLRISKS_DISABLE_AAD=OFF \ + -DQLRISKS_ENABLE_FORGE=ON \ + -DQLRISKS_USE_FORGE_CAPI=ON \ + -DXAD_FORGE_USE_CAPI=ON \ + -DQLRISKS_BUILD_TEST_SUITE=OFF \ + -DQLRISKS_BUILD_BENCHMARK_STANDALONE=ON \ + -DQLRISKS_ENABLE_FORGE_TESTS=ON + + - name: Build + run: | + cd QuantLib/build + cmake --build . + + - name: Run Performance Decomposition + run: | + cd QuantLib/build + export LD_LIBRARY_PATH=$(pwd)/../../install/lib:$LD_LIBRARY_PATH + ./QuantLib-Risks-Cpp-Forge/test-suite/quantlib-risks-benchmark-standalone --decomposition + + ############################################################################## + # Compare XAD vs XAD-Forge - Statistical comparison + ############################################################################## + compare: + name: Compare XAD vs XAD-Forge + runs-on: ubuntu-latest + container: + image: ghcr.io/lballabio/quantlib-devenv:rolling + + steps: + - name: Hardware Info + run: | + echo "===== CPU =====" + lscpu | grep -E "^(Model name|CPU\(s\)|Thread|Core|Socket|CPU max MHz)" + echo "===== Memory =====" + free -h + + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.QL_REPO }} + ref: ${{ env.QL_BRANCH }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_REPO }} + ref: ${{ env.XAD_BRANCH }} + path: xad + + - name: Checkout QuantLib-Risks-Cpp (Original) + uses: actions/checkout@v4 + with: + repository: ${{ env.QLRISKS_REPO }} + ref: ${{ env.QLRISKS_BRANCH }} + path: QuantLib-Risks-Cpp + + - name: Checkout Forge + uses: actions/checkout@v4 + with: + repository: ${{ env.FORGE_REPO }} + ref: ${{ env.FORGE_BRANCH }} + path: forge + + - name: Checkout xad-forge + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_FORGE_REPO }} + ref: ${{ env.XAD_FORGE_BRANCH }} + path: xad-forge + + - name: Checkout QuantLib-Risks-Cpp-Forge + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: | + apt-get update + apt-get install -y ninja-build cmake bc + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: linux-compare + max-size: 650M + + # --- Build QL + XAD (baseline) --- + - name: Patch benchmark into original QuantLib-Risks-Cpp + run: | + cp QuantLib-Risks-Cpp-Forge/test-suite/benchmark_main.cpp \ + QuantLib-Risks-Cpp/test-suite/ + cp QuantLib-Risks-Cpp-Forge/test-suite/PlatformInfo.hpp \ + QuantLib-Risks-Cpp/test-suite/ + cp QuantLib-Risks-Cpp-Forge/test-suite/utilities_xad.cpp \ + QuantLib-Risks-Cpp/test-suite/ + cp QuantLib-Risks-Cpp-Forge/test-suite/utilities_xad.hpp \ + QuantLib-Risks-Cpp/test-suite/ + + cat >> QuantLib-Risks-Cpp/test-suite/CMakeLists.txt << 'EOF' + + # Standalone benchmark (patched from QuantLib-Risks-Cpp-Forge) + add_executable(QuantLib-Risks_benchmark_standalone benchmark_main.cpp) + set_target_properties(QuantLib-Risks_benchmark_standalone PROPERTIES + OUTPUT_NAME "quantlib-risks-benchmark-standalone") + target_link_libraries(QuantLib-Risks_benchmark_standalone PRIVATE + ql_library + ${QL_THREAD_LIBRARIES}) + EOF + + - name: Configure QuantLib (QL + XAD) + run: | + cd QuantLib + cmake -B build-xad -G Ninja -DBOOST_ROOT=/usr \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DXAD_WARNINGS_PARANOID=OFF \ + -DXAD_ENABLE_JIT=OFF \ + -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../xad;$(pwd)/../QuantLib-Risks-Cpp" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + -DQL_BUILD_TEST_SUITE=OFF \ + -DQL_BUILD_EXAMPLES=OFF \ + -DQL_BUILD_BENCHMARK=OFF \ + -DQLRISKS_DISABLE_AAD=OFF \ + -DQLRISKS_BUILD_TEST_SUITE=ON + + - name: Build (QL + XAD) + run: | + cd QuantLib/build-xad + cmake --build . --target QuantLib-Risks_benchmark_standalone + + # --- Build QL + XAD-Forge --- + - name: Build Forge C API + run: | + cd forge + cmake -B build -S api/c -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DFORGE_CAPI_BUILD_TESTS=OFF \ + -DCMAKE_INSTALL_PREFIX=$(pwd)/../install + cmake --build build + cmake --install build + + - name: Configure QuantLib (QL + XAD-Forge) + run: | + cd QuantLib + cmake -B build-forge -G Ninja -DBOOST_ROOT=/usr \ + -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DXAD_WARNINGS_PARANOID=OFF \ + -DXAD_ENABLE_JIT=ON \ + -DCMAKE_PREFIX_PATH=$(pwd)/../install \ + -DQL_EXTERNAL_SUBDIRECTORIES="$(pwd)/../xad;$(pwd)/../xad-forge;$(pwd)/../QuantLib-Risks-Cpp-Forge" \ + -DQL_EXTRA_LINK_LIBRARIES=QuantLib-Risks \ + -DQL_NULL_AS_FUNCTIONS=ON \ + -DQL_BUILD_TEST_SUITE=OFF \ + -DQL_BUILD_EXAMPLES=OFF \ + -DQL_BUILD_BENCHMARK=OFF \ + -DQLRISKS_DISABLE_AAD=OFF \ + -DQLRISKS_ENABLE_FORGE=ON \ + -DQLRISKS_USE_FORGE_CAPI=ON \ + -DXAD_FORGE_USE_CAPI=ON \ + -DQLRISKS_BUILD_TEST_SUITE=OFF \ + -DQLRISKS_BUILD_BENCHMARK_STANDALONE=ON \ + -DQLRISKS_ENABLE_FORGE_TESTS=ON + + - name: Build (QL + XAD-Forge) + run: | + cd QuantLib/build-forge + cmake --build . + + # --- Run benchmarks multiple times --- + - name: Run Benchmark (QL + XAD) + run: | + set -e + cd QuantLib/build-xad + # warmup run + ./QuantLib-Risks-Cpp/test-suite/quantlib-risks-benchmark-standalone --quick + rm -f benchmark_xad.log || true + for i in $(seq 1 5) ; do \ + ./QuantLib-Risks-Cpp/test-suite/quantlib-risks-benchmark-standalone | tee -a benchmark_xad.log ; \ + done + + - name: Run Benchmark (QL + XAD-Forge) + run: | + set -e + cd QuantLib/build-forge + export LD_LIBRARY_PATH=$(pwd)/../../install/lib:$LD_LIBRARY_PATH + # warmup run + ./QuantLib-Risks-Cpp-Forge/test-suite/quantlib-risks-benchmark-standalone --quick + rm -f benchmark_forge.log || true + for i in $(seq 1 5) ; do \ + ./QuantLib-Risks-Cpp-Forge/test-suite/quantlib-risks-benchmark-standalone | tee -a benchmark_forge.log ; \ + done + + - name: Compare Results + id: compare + run: | + set -e + + echo "## Benchmark Comparison: QL + XAD vs QL + XAD-Forge" > benchmark_results.md + echo "" >> benchmark_results.md + echo "Comparing original QuantLib-Risks-Cpp (XAD tape) vs Forge repo (JIT + JIT-AVX)." >> benchmark_results.md + echo "" >> benchmark_results.md + echo "- Commit: \`${{ github.sha }}\`" >> benchmark_results.md + echo "- Runs: 5 (after warmup)" >> benchmark_results.md + echo "" >> benchmark_results.md + + echo "### QL + XAD (Baseline)" >> benchmark_results.md + echo "\`\`\`" >> benchmark_results.md + tail -80 QuantLib/build-xad/benchmark_xad.log >> benchmark_results.md || echo "No log available" >> benchmark_results.md + echo "\`\`\`" >> benchmark_results.md + echo "" >> benchmark_results.md + + echo "### QL + XAD-Forge" >> benchmark_results.md + echo "\`\`\`" >> benchmark_results.md + tail -80 QuantLib/build-forge/benchmark_forge.log >> benchmark_results.md || echo "No log available" >> benchmark_results.md + echo "\`\`\`" >> benchmark_results.md + + cat benchmark_results.md + + - name: Upload Results + uses: actions/upload-artifact@v4 + with: + name: benchmark-compare + path: benchmark_results.md + + ############################################################################## + # Linux, double vs AReal (no diff) + # Compares plain double vs xad::AReal on same hardware + # This measures the overhead of the XAD type system in passive mode + ############################################################################## + linux-type-overhead: + name: Linux, double vs AReal (no diff) + runs-on: ubuntu-latest + container: + image: ghcr.io/lballabio/quantlib-devenv:rolling + + steps: + - name: Hardware Info + run: | + echo "===== CPU =====" + lscpu | grep -E "^(Model name|CPU\(s\)|Thread|Core|Socket|CPU max MHz)" + echo "===== Memory =====" + free -h + + - name: Checkout QuantLib + uses: actions/checkout@v4 + with: + repository: ${{ env.QL_REPO }} + ref: ${{ env.QL_BRANCH }} + path: QuantLib + + - name: Checkout XAD + uses: actions/checkout@v4 + with: + repository: ${{ env.XAD_REPO }} + ref: ${{ env.XAD_BRANCH }} + path: xad + + - name: Checkout QuantLib-Risks-Cpp (Original) + uses: actions/checkout@v4 + with: + repository: ${{ env.QLRISKS_REPO }} + ref: ${{ env.QLRISKS_BRANCH }} + path: QuantLib-Risks-Cpp + + - name: Checkout QuantLib-Risks-Cpp-Forge (for benchmark code) + uses: actions/checkout@v4 + with: + path: QuantLib-Risks-Cpp-Forge + + - name: Setup + run: | + apt-get update + apt-get install -y ninja-build cmake + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.12 + with: + key: linux-type-overhead + max-size: 1G + + # ========================================================================= + # Build 1: QuantLib with plain double + # ========================================================================= + - name: Create pricing-only benchmark for plain double + run: | + mkdir -p QuantLib/test-suite-double + cat > QuantLib/test-suite-double/benchmark_double.cpp << 'EOFCPP' + /* + * Pricing-only benchmark using plain double (no XAD types) + */ + #include + #include + #include + #include + #include + #include + #include + #include + + using namespace QuantLib; + + std::string getCpuInfo() { + #ifdef __linux__ + FILE* fp = popen("grep 'model name' /proc/cpuinfo | head -1 | cut -d: -f2", "r"); + if (fp) { + char buf[256]; + if (fgets(buf, sizeof(buf), fp)) { + pclose(fp); + std::string s(buf); + s.erase(0, s.find_first_not_of(" \t\n")); + s.erase(s.find_last_not_of(" \t\n") + 1); + return s; + } + pclose(fp); + } + #endif + return "Unknown CPU"; + } + + double computeMean(const std::vector& v) { + if (v.empty()) return 0.0; + return std::accumulate(v.begin(), v.end(), 0.0) / v.size(); + } + + double computeStddev(const std::vector& v) { + if (v.size() < 2) return 0.0; + double mean = computeMean(v); + double sq_sum = 0.0; + for (auto x : v) sq_sum += (x - mean) * (x - mean); + return std::sqrt(sq_sum / (v.size() - 1)); + } + + ext::shared_ptr makeIndex(std::vector dates, const std::vector& rates) { + DayCounter dayCounter = Actual360(); + RelinkableHandle termStructure; + ext::shared_ptr index(new Euribor6M(termStructure)); + Date todaysDate = index->fixingCalendar().adjust(Date(4, September, 2005)); + Settings::instance().evaluationDate() = todaysDate; + dates[0] = index->fixingCalendar().advance(todaysDate, index->fixingDays(), Days); + termStructure.linkTo(ext::make_shared(dates, rates, dayCounter)); + return index; + } + + void runBenchmark(Size size, Size i_opt, Size j_opt, Size steps, int curveEndYears, + std::vector>& results) { + using Clock = std::chrono::high_resolution_clock; + using Duration = std::chrono::duration; + + Calendar calendar = TARGET(); + Date todaysDate(4, September, 2005); + Settings::instance().evaluationDate() = todaysDate; + Integer fixingDays = 2; + Date settlementDate = calendar.adjust(calendar.advance(todaysDate, fixingDays, Days)); + DayCounter dayCounter = Actual360(); + + std::vector baseZeroRates = {0.035, 0.0575}; + std::vector baseDates = {settlementDate, settlementDate + curveEndYears * Years}; + auto baseIndex = makeIndex(baseDates, baseZeroRates); + + ext::shared_ptr process( + new LiborForwardModelProcess(size, baseIndex)); + process->setCovarParam(ext::make_shared( + ext::make_shared( + process->fixingTimes(), 0.291, 1.483, 0.116, 0.00001), + ext::make_shared(size, 0.5))); + + std::vector