From 99e75f8733874d53b1ed40ee5cbfd1e34028a644 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 10:07:17 +0200 Subject: [PATCH 01/24] Make benchmarks work properly with OpRegistry PR #456 introduced operator registries but forgot to update the benchmark codes. This commit ensures that were needed we now set up a default registry to ensure the benchmarks can run as before. --- benchmarks/coupled_cluster.cpp | 3 +++ benchmarks/wick.cpp | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/benchmarks/coupled_cluster.cpp b/benchmarks/coupled_cluster.cpp index d5168ee4c5..6fe702caaf 100644 --- a/benchmarks/coupled_cluster.cpp +++ b/benchmarks/coupled_cluster.cpp @@ -1,5 +1,6 @@ #include +#include #include static constexpr std::size_t maxRank = 10; @@ -10,6 +11,8 @@ using namespace sequant::mbpt; static void cc_full_derivation(benchmark::State &state) { const std::size_t rank = state.range(0); + set_default_mbpt_context({.op_registry_ptr = make_minimal_registry()}); + for (auto _ : state) { CC cc(rank); auto equations = cc.t(); diff --git a/benchmarks/wick.cpp b/benchmarks/wick.cpp index 48cd4e375c..8e162ef48f 100644 --- a/benchmarks/wick.cpp +++ b/benchmarks/wick.cpp @@ -148,7 +148,8 @@ VacAvPair get_mbpt_expr(std::size_t i) { static void mbpt_vac_av(benchmark::State &state, bool csv) { auto ctx = sequant::mbpt::set_scoped_default_mbpt_context( - mbpt::Context({.csv = csv ? CSV::Yes : CSV::No})); + mbpt::Context({.csv = csv ? CSV::Yes : CSV::No, + .op_registry_ptr = make_minimal_registry()})); VacAvPair input = get_mbpt_expr(state.range(0)); From 6ecb2c86107dd222c6ac5b0b045880e29bf726c7 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 10:08:44 +0200 Subject: [PATCH 02/24] Update tracked dependency versions --- external/versions.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/external/versions.cmake b/external/versions.cmake index 5e9cd164fd..e7325b8210 100644 --- a/external/versions.cmake +++ b/external/versions.cmake @@ -11,12 +11,12 @@ set(SEQUANT_TRACKED_LIBPERM_TAG cada3e185549896203cf4d0c7f26ea22c7de428f) set(SEQUANT_TRACKED_POLYMORPHICVARIANT_TAG 010c69786104c07c5faccffe0e99f99de5a69fd8) -set(SEQUANT_TRACKED_UTFCPP_TAG v4.0.6) +set(SEQUANT_TRACKED_UTFCPP_TAG v4.1.1) -set(SEQUANT_TRACKED_CLI11_TAG v2.5.0) +set(SEQUANT_TRACKED_CLI11_TAG v2.7.2) set(SEQUANT_OLDEST_CLI11_VERSION 2) -set(SEQUANT_TRACKED_SPDLOG_TAG v1.15.3) +set(SEQUANT_TRACKED_SPDLOG_TAG v1.17.0) set(SEQUANT_TRACKED_JSON_TAG v3.12.0) set(SEQUANT_OLDEST_JSON_VERSION 3) @@ -27,13 +27,13 @@ set(SEQUANT_OLDEST_JSON_VERSION 3) # Recent stdlibs have removed this class when using C++17 (e.g. Apple Clang 15) set(SEQUANT_OLDEST_BOOST_VERSION 1.81) -set(SEQUANT_TRACKED_CATCH2_TAG v3.9.1) +set(SEQUANT_TRACKED_CATCH2_TAG v3.15.3) set(SEQUANT_OLDEST_CATCH2_VERSION 3.3) -set(SEQUANT_TRACKED_GOOGLEBENCHMARK_TAG v1.9.4) +set(SEQUANT_TRACKED_GOOGLEBENCHMARK_TAG v1.9.5) set(SEQUANT_OLDEST_GOOGLEBENCHMARK_VERSION 1.9.3) -set(SEQUANT_TRACKED_PYBIND11_TAG v3.0.1) +set(SEQUANT_TRACKED_PYBIND11_TAG v3.1.0) set(SEQUANT_OLDEST_PYBIND11_VERSION 3) # oldest Doxygen we can tolerate ... doxygen-awesome-css requires doxygen 1.9.1 - 1.9.4 or 1.9.6 - 1.14.0, so just use 1.9.6 as the minimum From 30ad4015c64f3266e83327e164218da66ebe4886 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 10:22:06 +0200 Subject: [PATCH 03/24] Support restricting benchmarks to a 'quick' subset --- benchmarks/CMakeLists.txt | 12 ++++++++++++ benchmarks/coupled_cluster.cpp | 4 ++++ benchmarks/wick.cpp | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index 4bc71463cf..5215cbd9dc 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -13,6 +13,18 @@ add_executable(sequant_benchmarks set_target_properties(sequant_benchmarks PROPERTIES CXX_SCAN_FOR_MODULES OFF) +option(SEQUANT_QUICK_BENCHMARKS "Whether to exclude computational expensive benchmarks" OFF) + +# Running benchmarks in Debug mode doesn't make a lot of sense but in case someone does, +# we at least want to exclude benchmarks that are likely to take forever in this setup +if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR SEQUANT_QUICK_BENCHMARKS) + target_compile_definitions(sequant_benchmarks + PRIVATE + SEQUANT_BENCH_MAX_CC_RANK=3 + SEQUANT_BENCH_MAX_WICK_INPUTS=2 + ) +endif() + # The benchmark implementations contain a bunch of same-name symbol definition that # ought to be local to the individual translation unit. Hence, we must not combine # all of them into a single translation unit. diff --git a/benchmarks/coupled_cluster.cpp b/benchmarks/coupled_cluster.cpp index 6fe702caaf..431d4084b8 100644 --- a/benchmarks/coupled_cluster.cpp +++ b/benchmarks/coupled_cluster.cpp @@ -3,7 +3,11 @@ #include #include +#ifdef SEQUANT_BENCH_MAX_CC_RANK +static constexpr std::size_t maxRank = SEQUANT_BENCH_MAX_CC_RANK; +#else static constexpr std::size_t maxRank = 10; +#endif using namespace sequant; using namespace sequant::mbpt; diff --git a/benchmarks/wick.cpp b/benchmarks/wick.cpp index 8e162ef48f..648d69dbd3 100644 --- a/benchmarks/wick.cpp +++ b/benchmarks/wick.cpp @@ -13,7 +13,11 @@ using namespace sequant; using namespace sequant::mbpt; +#ifdef SEQUANT_BENCH_MAX_WICK_INPUTS +static constexpr std::size_t nInputs = SEQUANT_BENCH_MAX_WICK_INPUTS; +#else static constexpr std::size_t nInputs = 5; +#endif template ExprPtr get_op_sequence(std::size_t i) { From 620b3fb51544e5486a971249a5d2cd8a7cf9f392 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 10:24:30 +0200 Subject: [PATCH 04/24] Run benchmarks as part of CI This is to ensure that future changes don't break them again --- .github/workflows/cmake.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 286dfca43e..e161ad5466 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -121,7 +121,7 @@ jobs: # Note the current convention is to use the -S and -B options here to specify source # and build directories, but this is only available with CMake 3.13 and higher. # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE $BUILD_CONFIG + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE $BUILD_CONFIG -DSEQUANT_QUICK_BENCHMARKS=ON - name: Build @@ -136,6 +136,12 @@ jobs: shell: bash run: ctest --output-on-failure -R "^sequant" + - name: Ensure benchmarks not broken + if: ${{ !matrix.valgrind }} + working-directory: ${{github.workspace}}/build + shell: bash + run: ./benchmarks/sequant_benchmarks --benchmark_dry_run=true + - name: Test (+ Valgrind) if: ${{ matrix.valgrind }} working-directory: ${{github.workspace}}/build From 34f95f9d421fd349616c56861c53347f766131e3 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 11:46:21 +0200 Subject: [PATCH 05/24] Also skip running the benchmarks in builds with sanitizers --- .github/workflows/cmake.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index e161ad5466..e4ab80e003 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -137,7 +137,7 @@ jobs: run: ctest --output-on-failure -R "^sequant" - name: Ensure benchmarks not broken - if: ${{ !matrix.valgrind }} + if: ${{ !matrix.valgrind && !matrix.sanitize }} working-directory: ${{github.workspace}}/build shell: bash run: ./benchmarks/sequant_benchmarks --benchmark_dry_run=true From 231ede52ad6f0c80617b805ee39da7693e24f3fe Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 11:50:41 +0200 Subject: [PATCH 06/24] Update used action images --- .github/workflows/benchmark_compare.yml | 16 ++++++++-------- .github/workflows/cmake.yml | 6 +++--- .github/workflows/docs.yml | 4 ++-- .github/workflows/formatting_check.yml | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/benchmark_compare.yml b/.github/workflows/benchmark_compare.yml index 0f31a48582..6f3dc5bd30 100644 --- a/.github/workflows/benchmark_compare.yml +++ b/.github/workflows/benchmark_compare.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Get PR details id: pr - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const pullRequestNumber = context.eventName === 'workflow_dispatch' @@ -60,7 +60,7 @@ jobs: }; - name: Create status check - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const prData = ${{ steps.pr.outputs.result }}; @@ -75,7 +75,7 @@ jobs: }); - name: Checkout base repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: fetch-depth: 0 @@ -96,7 +96,7 @@ jobs: echo "timestamp=$(date -u +'%Y-%m-%d-%H;%M;%S')" >> $GITHUB_OUTPUT - name: Setup ccache cache files - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ${{github.workspace}}/build/.ccache key: benchmark-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }} @@ -114,7 +114,7 @@ jobs: - name: Upload Results if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: benchmark-data-${{ github.run_id }} path: | @@ -125,7 +125,7 @@ jobs: - name: Post Results if: success() - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const fs = require('fs'); @@ -156,7 +156,7 @@ jobs: - name: Update status check - Success if: success() - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const prData = ${{ steps.pr.outputs.result }}; @@ -172,7 +172,7 @@ jobs: - name: Notify on Failure if: failure() - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const prData = ${{ steps.pr.outputs.result }}; diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index e4ab80e003..f153c8fb16 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -63,14 +63,14 @@ jobs: -DSEQUANT_PYTHON=${{ !matrix.valgrind && !matrix.sanitize }} -DSEQUANT_ASSERT_BEHAVIOR=${{ matrix.valgrind && 'IGNORE' || 'THROW' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: free up disk space on Ubuntu runner if: ${{ matrix.os == 'ubuntu-24.04' }} uses: jlumbroso/free-disk-space@main - name: Setup Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v7 with: python-version: '3.x' @@ -106,7 +106,7 @@ jobs: run: echo "timestamp=$(date -u +'%Y-%m-%d-%H-%M-%S')" >> $GITHUB_OUTPUT - name: Setup ccache cache files - uses: actions/cache@v5 + uses: actions/cache@v6 with: path: ${{github.workspace}}/build/.ccache key: ${{ matrix.config.name }}-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ff35a34f2a..f8fdc24e65 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,8 +16,8 @@ jobs: -DSEQUANT_BUILD_DOCS=ON -DSEQUANT_BUILD_DOCS_API_BREATHEEXHALE=ON steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: '>=3.9' # Breathe needs 3.9 or later cache: 'pip' diff --git a/.github/workflows/formatting_check.yml b/.github/workflows/formatting_check.yml index d74b45bc51..5eebd01ace 100644 --- a/.github/workflows/formatting_check.yml +++ b/.github/workflows/formatting_check.yml @@ -7,7 +7,7 @@ jobs: name: "Check formatting" runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Install clang-format-17 run: | From 687609a11fc3d86adec4b769816fba5880e7838c Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 16:46:16 +0200 Subject: [PATCH 07/24] Ensure we build tests with normal warning settings --- tests/unit/CMakeLists.txt | 8 ++++++++ tests/unit/test_optimize.cpp | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 3411d2ee0e..b481363714 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -28,6 +28,7 @@ set(symb_test_sources ) add_library(unit_tests-sequant-symb-obj OBJECT ${symb_test_sources}) +target_set_warning_flags(unit_tests-sequant-symb-obj) set_target_properties(unit_tests-sequant-symb-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-symb-obj PUBLIC SeQuant::symb SeQuant::bliss @@ -43,6 +44,7 @@ set(eval_test_sources "test_eval_node.cpp" ) add_library(unit_tests-sequant-eval-obj OBJECT ${eval_test_sources}) +target_set_warning_flags(unit_tests-sequant-eval-obj) set_target_properties(unit_tests-sequant-eval-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-obj PUBLIC SeQuant::eval @@ -59,6 +61,7 @@ set(optimize_test_sources "test_optimize.cpp" ) add_library(unit_tests-sequant-optimize-obj OBJECT ${optimize_test_sources}) +target_set_warning_flags(unit_tests-sequant-optimize-obj) set_target_properties(unit_tests-sequant-optimize-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-optimize-obj PUBLIC SeQuant::optimize SeQuant::bliss @@ -75,6 +78,7 @@ set(export_test_sources "test_export_python.cpp" ) add_library(unit_tests-sequant-export-obj OBJECT ${export_test_sources}) +target_set_warning_flags(unit_tests-sequant-export-obj) set_target_properties(unit_tests-sequant-export-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-export-obj PUBLIC SeQuant::export SeQuant::optimize @@ -93,6 +97,7 @@ set(mbpt_test_sources ) add_library(unit_tests-sequant-mbpt-obj OBJECT ${mbpt_test_sources}) +target_set_warning_flags(unit_tests-sequant-mbpt-obj) set_target_properties(unit_tests-sequant-mbpt-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-mbpt-obj PUBLIC SeQuant::mbpt @@ -109,6 +114,7 @@ if (SEQUANT_HAS_TILEDARRAY) "test_cache_manager.cpp" ) add_library(unit_tests-sequant-eval-ta-obj OBJECT ${eval_ta_test_sources}) + target_set_warning_flags(unit_tests-sequant-eval-ta-obj) set_target_properties(unit_tests-sequant-eval-ta-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-ta-obj PUBLIC SeQuant::eval::ta SeQuant::mbpt @@ -129,6 +135,7 @@ if (SEQUANT_HAS_BTAS) list(APPEND eval_btas_test_sources "test_cache_manager.cpp") endif() add_library(unit_tests-sequant-eval-btas-obj OBJECT ${eval_btas_test_sources}) + target_set_warning_flags(unit_tests-sequant-eval-btas-obj) set_target_properties(unit_tests-sequant-eval-btas-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-btas-obj PUBLIC SeQuant::eval::btas SeQuant::mbpt @@ -145,6 +152,7 @@ endif() if (SEQUANT_HAS_TAPP) set(eval_tapp_test_sources "test_eval_tapp.cpp") add_library(unit_tests-sequant-eval-tapp-obj OBJECT ${eval_tapp_test_sources}) + target_set_warning_flags(unit_tests-sequant-eval-tapp-obj) set_target_properties(unit_tests-sequant-eval-tapp-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-tapp-obj PUBLIC SeQuant::eval::tapp SeQuant::mbpt diff --git a/tests/unit/test_optimize.cpp b/tests/unit/test_optimize.cpp index 77087722f7..04c07453e7 100644 --- a/tests/unit/test_optimize.cpp +++ b/tests/unit/test_optimize.cpp @@ -727,7 +727,7 @@ TEST_CASE("optimize", "[optimize]") { container::svector targets; auto aux = opt::detail::batchable_index_list(net, is_batchable); std::size_t const m = aux.size(); - auto batch_fn = [batch](Index const&) -> std::size_t { return batch; }; + auto batch_fn = [](Index const&) -> std::size_t { return batch; }; opt::detail::PeakBatchedModel model{idxsz, is_batchable, batch_fn, /*is_volatile_leaf=*/{}}; auto ctx = model.build_context(net, targets); @@ -769,7 +769,7 @@ TEST_CASE("optimize", "[optimize]") { container::svector targets; auto aux = opt::detail::batchable_index_list(net, is_batchable); auto vmask = opt::detail::leaf_volatile_mask(net, {}); - auto batch_fn = [batch](Index const&) -> std::size_t { return batch; }; + auto batch_fn = [](Index const&) -> std::size_t { return batch; }; auto tables = opt::detail::sliced_footprints( net, targets, idxsz, is_batchable, batch_fn, aux); // open_aux[s] via the SAME detail helper the DP uses, so DP and oracle @@ -811,7 +811,7 @@ TEST_CASE("optimize", "[optimize]") { container::svector targets; // recompute the chosen tree's peak by simulation over the pr // back-pointers (independent of the DP's max/+ recurrence): - auto batch_fn = [batch](Index const&) -> std::size_t { return batch; }; + auto batch_fn = [](Index const&) -> std::size_t { return batch; }; double recon = opt::detail::reconstructed_batched_peak( net, targets, idxsz, is_batchable, batch_fn, {}); double dp = opt::detail::peak_cost_batched(net, targets, idxsz, @@ -2342,7 +2342,7 @@ TEST_CASE("fast_flops equals flops_of over all bipartitions (parity)", std::function const ip_off = {}; bool composite_inner_checked = false; - for (std::wstring const term : + for (std::wstring const &term : {std::wstring(L"g{μ̃1;μ̃2;Κ1} C{a1;μ̃1} C{μ̃2;a2} t{a1;i1}"), std::wstring(L"g{i1;a1;Κ1} g{i2;a2;Κ1} t{a1;i1} t{a2;i2}")}) { for (auto const* ip : {&ip_on, &ip_off}) { From e2d9e0cf88a3819e93276ff3afd2f62a3911d849 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 18:50:26 +0200 Subject: [PATCH 08/24] Enable use of LTO --- CMakeLists.txt | 1 + benchmarks/CMakeLists.txt | 3 +++ cmake/compiler.cmake | 22 +++++++++++++++++++++ tests/integration/CMakeLists.txt | 1 + tests/unit/CMakeLists.txt | 15 +++++++++++--- utilities/CMakeLists.txt | 1 + utilities/cost_analysis/CMakeLists.txt | 1 + utilities/external-interface/CMakeLists.txt | 1 + 8 files changed, 42 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f119f10dbc..99113bdc2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ macro(sequant_add_library _module) get_target_property(_type SeQuant-${_module} TYPE) if (NOT _type STREQUAL "INTERFACE_LIBRARY") target_set_warning_flags(SeQuant-${_module}) + target_set_optimization_flags(SeQuant-${_module}) endif() endmacro() diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index 5215cbd9dc..5f854bc81f 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -11,6 +11,9 @@ add_executable(sequant_benchmarks "wick.cpp" ) +target_set_warning_flags(sequant_benchmarks) +target_set_optimization_flags(sequant_benchmarks) + set_target_properties(sequant_benchmarks PROPERTIES CXX_SCAN_FOR_MODULES OFF) option(SEQUANT_QUICK_BENCHMARKS "Whether to exclude computational expensive benchmarks" OFF) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 1a3b8f9cde..e9ec6bb8e0 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -60,3 +60,25 @@ function(target_set_warning_flags TARGET) target_compile_options("${TARGET}" PRIVATE "-Wno-unused-lambda-capture") endif() endfunction() + + +include(CheckIPOSupported) + +check_ipo_supported(RESULT COMPILER_SUPPORTS_IPO) + +function(target_set_optimization_flags TARGET) + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + return() + endif() + + __check_gnu_like_compiler() + + if (COMPILER_SUPPORTS_IPO AND (NOT DEFINED SEQUANT_LTO OR SEQUANT_LTO)) + set_target_properties("${TARGET}" PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON) + + if (IS_GNU_LIKE_COMPILER) + # This (should) ensures that the object files can still be linked without LTO + target_compile_options("${TARGET}" PRIVATE -ffat-lto-objects) + endif() + endif() +endfunction() diff --git a/tests/integration/CMakeLists.txt b/tests/integration/CMakeLists.txt index cbb387ae94..7f3d30cde9 100644 --- a/tests/integration/CMakeLists.txt +++ b/tests/integration/CMakeLists.txt @@ -56,6 +56,7 @@ foreach(current IN LISTS TEST_CASES) endif() target_set_warning_flags("${test_name}") + target_set_optimization_flags("${test_name}") set(variant_names "") diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index b481363714..0211312677 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -29,6 +29,7 @@ set(symb_test_sources add_library(unit_tests-sequant-symb-obj OBJECT ${symb_test_sources}) target_set_warning_flags(unit_tests-sequant-symb-obj) +target_set_optimization_flags(unit_tests-sequant-symb-obj) set_target_properties(unit_tests-sequant-symb-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-symb-obj PUBLIC SeQuant::symb SeQuant::bliss @@ -45,6 +46,7 @@ set(eval_test_sources ) add_library(unit_tests-sequant-eval-obj OBJECT ${eval_test_sources}) target_set_warning_flags(unit_tests-sequant-eval-obj) +target_set_optimization_flags(unit_tests-sequant-eval-obj) set_target_properties(unit_tests-sequant-eval-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-obj PUBLIC SeQuant::eval @@ -62,6 +64,7 @@ set(optimize_test_sources ) add_library(unit_tests-sequant-optimize-obj OBJECT ${optimize_test_sources}) target_set_warning_flags(unit_tests-sequant-optimize-obj) +target_set_optimization_flags(unit_tests-sequant-optimize-obj) set_target_properties(unit_tests-sequant-optimize-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-optimize-obj PUBLIC SeQuant::optimize SeQuant::bliss @@ -79,6 +82,7 @@ set(export_test_sources ) add_library(unit_tests-sequant-export-obj OBJECT ${export_test_sources}) target_set_warning_flags(unit_tests-sequant-export-obj) +target_set_optimization_flags(unit_tests-sequant-export-obj) set_target_properties(unit_tests-sequant-export-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-export-obj PUBLIC SeQuant::export SeQuant::optimize @@ -98,6 +102,7 @@ set(mbpt_test_sources add_library(unit_tests-sequant-mbpt-obj OBJECT ${mbpt_test_sources}) target_set_warning_flags(unit_tests-sequant-mbpt-obj) +target_set_optimization_flags(unit_tests-sequant-mbpt-obj) set_target_properties(unit_tests-sequant-mbpt-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-mbpt-obj PUBLIC SeQuant::mbpt @@ -114,7 +119,8 @@ if (SEQUANT_HAS_TILEDARRAY) "test_cache_manager.cpp" ) add_library(unit_tests-sequant-eval-ta-obj OBJECT ${eval_ta_test_sources}) - target_set_warning_flags(unit_tests-sequant-eval-ta-obj) + target_set_warning_flags(unit_tests-sequant-eval-ta-obj) + target_set_optimization_flags(unit_tests-sequant-eval-ta-obj) set_target_properties(unit_tests-sequant-eval-ta-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-ta-obj PUBLIC SeQuant::eval::ta SeQuant::mbpt @@ -135,7 +141,8 @@ if (SEQUANT_HAS_BTAS) list(APPEND eval_btas_test_sources "test_cache_manager.cpp") endif() add_library(unit_tests-sequant-eval-btas-obj OBJECT ${eval_btas_test_sources}) - target_set_warning_flags(unit_tests-sequant-eval-btas-obj) + target_set_warning_flags(unit_tests-sequant-eval-btas-obj) + target_set_optimization_flags(unit_tests-sequant-btas-ta-obj) set_target_properties(unit_tests-sequant-eval-btas-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-btas-obj PUBLIC SeQuant::eval::btas SeQuant::mbpt @@ -152,7 +159,8 @@ endif() if (SEQUANT_HAS_TAPP) set(eval_tapp_test_sources "test_eval_tapp.cpp") add_library(unit_tests-sequant-eval-tapp-obj OBJECT ${eval_tapp_test_sources}) - target_set_warning_flags(unit_tests-sequant-eval-tapp-obj) + target_set_warning_flags(unit_tests-sequant-eval-tapp-obj) + target_set_optimization_flags(unit_tests-sequant-tapp-ta-obj) set_target_properties(unit_tests-sequant-eval-tapp-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-tapp-obj PUBLIC SeQuant::eval::tapp SeQuant::mbpt @@ -251,6 +259,7 @@ if (SEQUANT_INTERNAL_SKIP_LONG_TESTS) endif() target_set_warning_flags(unit_tests-sequant) +target_set_optimization_flags(unit_tests-sequant) if (SEQUANT_TESTS) catch_discover_tests( diff --git a/utilities/CMakeLists.txt b/utilities/CMakeLists.txt index 76b6aad338..eeedd38a39 100644 --- a/utilities/CMakeLists.txt +++ b/utilities/CMakeLists.txt @@ -9,6 +9,7 @@ foreach(current IN LISTS EXECUTABLE_SOURCES) target_link_libraries(${name} SeQuant) target_set_warning_flags("${name}") + target_set_optimization_flags("${name}") endforeach() add_subdirectory(external-interface) diff --git a/utilities/cost_analysis/CMakeLists.txt b/utilities/cost_analysis/CMakeLists.txt index 9501acabaa..ea4c23b449 100644 --- a/utilities/cost_analysis/CMakeLists.txt +++ b/utilities/cost_analysis/CMakeLists.txt @@ -8,6 +8,7 @@ set_target_properties(cost_analysis PROPERTIES target_link_libraries(cost_analysis PRIVATE SeQuant::mbpt nlohmann_json::nlohmann_json CLI11::CLI11) target_set_warning_flags(cost_analysis) +target_set_optimization_flags(cost_analysis) # The tool writes its report (and any dump-tree file) next to the driver, so # the tests run against a build-tree copy of examples/ rather than the source diff --git a/utilities/external-interface/CMakeLists.txt b/utilities/external-interface/CMakeLists.txt index cb1071235d..2cb0c0133c 100644 --- a/utilities/external-interface/CMakeLists.txt +++ b/utilities/external-interface/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(external_interface ) target_set_warning_flags(external_interface) +target_set_optimization_flags(external_interface) foreach(DRIVER IN ITEMS "ccsd" "nevpt2") add_test( From 2d3cafdce9103bb2a096aa31765bf256af10fda9 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 18:58:41 +0200 Subject: [PATCH 09/24] fix formatting --- tests/unit/test_optimize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_optimize.cpp b/tests/unit/test_optimize.cpp index 04c07453e7..2fce6a18ae 100644 --- a/tests/unit/test_optimize.cpp +++ b/tests/unit/test_optimize.cpp @@ -2342,7 +2342,7 @@ TEST_CASE("fast_flops equals flops_of over all bipartitions (parity)", std::function const ip_off = {}; bool composite_inner_checked = false; - for (std::wstring const &term : + for (std::wstring const& term : {std::wstring(L"g{μ̃1;μ̃2;Κ1} C{a1;μ̃1} C{μ̃2;a2} t{a1;i1}"), std::wstring(L"g{i1;a1;Κ1} g{i2;a2;Κ1} t{a1;i1} t{a2;i2}")}) { for (auto const* ip : {&ip_on, &ip_off}) { From ea7b3bc608f22db4e63874c2374b5eb76cda7d7b Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 18:59:09 +0200 Subject: [PATCH 10/24] Fix warning about discarded return value --- tests/unit/test_cache_manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_cache_manager.cpp b/tests/unit/test_cache_manager.cpp index f2680480c1..940da1db23 100644 --- a/tests/unit/test_cache_manager.cpp +++ b/tests/unit/test_cache_manager.cpp @@ -242,7 +242,7 @@ TEST_CASE("cache_manager_persistent", "[cache_manager]") { // A persistent entry is never drained: arbitrarily many accesses all return // the stored data (unlike an NP entry, whose data is released after its // max_life-th access). - man.store(p, eval_result(20)); + (void)man.store(p, eval_result(20)); for (int i = 0; i < 10; ++i) { auto r = man.access(p); REQUIRE(r); @@ -252,7 +252,7 @@ TEST_CASE("cache_manager_persistent", "[cache_manager]") { // reset() clears the non-persistent entry but keeps the persistent one, so // the latter's data survives across evaluations (e.g. CC iterations). - man.store(np, eval_result(10)); + (void)man.store(np, eval_result(10)); man.reset(); REQUIRE(man.access(np) == nullptr); // NP cleared by reset auto rp = man.access(p); // P survives reset From b2ddf359d15d2b14d3146a0de3b7c162d95b30f4 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 19:00:44 +0200 Subject: [PATCH 11/24] Fix target names --- tests/unit/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 0211312677..c0ea4d510e 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -142,7 +142,7 @@ if (SEQUANT_HAS_BTAS) endif() add_library(unit_tests-sequant-eval-btas-obj OBJECT ${eval_btas_test_sources}) target_set_warning_flags(unit_tests-sequant-eval-btas-obj) - target_set_optimization_flags(unit_tests-sequant-btas-ta-obj) + target_set_optimization_flags(unit_tests-sequant-eval-btas-obj) set_target_properties(unit_tests-sequant-eval-btas-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-btas-obj PUBLIC SeQuant::eval::btas SeQuant::mbpt @@ -160,7 +160,7 @@ if (SEQUANT_HAS_TAPP) set(eval_tapp_test_sources "test_eval_tapp.cpp") add_library(unit_tests-sequant-eval-tapp-obj OBJECT ${eval_tapp_test_sources}) target_set_warning_flags(unit_tests-sequant-eval-tapp-obj) - target_set_optimization_flags(unit_tests-sequant-tapp-ta-obj) + target_set_optimization_flags(unit_tests-sequant-eval-tapp-obj) set_target_properties(unit_tests-sequant-eval-tapp-obj PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(unit_tests-sequant-eval-tapp-obj PUBLIC SeQuant::eval::tapp SeQuant::mbpt From 02b08f9a37f128340987a6c1898ea1c9d59c26b7 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 19:10:17 +0200 Subject: [PATCH 12/24] Explicit check for validity of fat-lto option --- cmake/compiler.cmake | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index e9ec6bb8e0..4c76fa22b7 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -62,21 +62,25 @@ function(target_set_warning_flags TARGET) endfunction() -include(CheckIPOSupported) - -check_ipo_supported(RESULT COMPILER_SUPPORTS_IPO) function(target_set_optimization_flags TARGET) if (CMAKE_BUILD_TYPE STREQUAL "Debug") return() endif() + include(CheckCXXCompilerFlag) + include(CheckIPOSupported) + + check_ipo_supported(RESULT COMPILER_SUPPORTS_IPO) + __check_gnu_like_compiler() if (COMPILER_SUPPORTS_IPO AND (NOT DEFINED SEQUANT_LTO OR SEQUANT_LTO)) set_target_properties("${TARGET}" PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON) - if (IS_GNU_LIKE_COMPILER) + check_cxx_compiler_flag("-ffat-lto-objects" FAT_LTO_SUPPORTED) + + if (FAT_LTO_SUPPORTED) # This (should) ensures that the object files can still be linked without LTO target_compile_options("${TARGET}" PRIVATE -ffat-lto-objects) endif() From 52c34cbcab4abf4970c08e3fcc1cbdef6cc389d0 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 20:43:19 +0200 Subject: [PATCH 13/24] Specify language --- cmake/compiler.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 4c76fa22b7..edc41fe986 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -71,7 +71,7 @@ function(target_set_optimization_flags TARGET) include(CheckCXXCompilerFlag) include(CheckIPOSupported) - check_ipo_supported(RESULT COMPILER_SUPPORTS_IPO) + check_ipo_supported(RESULT COMPILER_SUPPORTS_IPO LANGUAGES CXX) __check_gnu_like_compiler() From 20ad7f1eae622d2a8d501cac0ffd54b46d9edc63 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sat, 22 Aug 2026 20:44:02 +0200 Subject: [PATCH 14/24] Fix warning about missing field initializers --- SeQuant/core/eval/eval.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SeQuant/core/eval/eval.hpp b/SeQuant/core/eval/eval.hpp index 96e3ffbea9..5609603c6e 100644 --- a/SeQuant/core/eval/eval.hpp +++ b/SeQuant/core/eval/eval.hpp @@ -557,7 +557,8 @@ ResultPtr evaluate(Node const& node, // bool checked; Stage stage = Stage::Enter; bool store_after = false; - ResultPtr left, right; + ResultPtr left = {}; + ResultPtr right = {}; }; // Finalize a freshly computed Phase-B result: if this Checked node needs From ab7b2aabe6458308dc9a3655444fc1a9ff2d106a Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 09:49:21 +0200 Subject: [PATCH 15/24] Revamp LTO handling --- cmake/compiler.cmake | 58 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index edc41fe986..9b01ae31a7 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -68,21 +68,57 @@ function(target_set_optimization_flags TARGET) return() endif() - include(CheckCXXCompilerFlag) - include(CheckIPOSupported) - - check_ipo_supported(RESULT COMPILER_SUPPORTS_IPO LANGUAGES CXX) + get_target_property(TARGET_TYPE "${TARGET}" TYPE) - __check_gnu_like_compiler() + if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY") + message(WARNING "target_set_optimization_flags is not intended to be used on interface targets") + return() + endif() - if (COMPILER_SUPPORTS_IPO AND (NOT DEFINED SEQUANT_LTO OR SEQUANT_LTO)) - set_target_properties("${TARGET}" PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON) + include(CheckCXXCompilerFlag) + include(CheckIPOSupported) - check_cxx_compiler_flag("-ffat-lto-objects" FAT_LTO_SUPPORTED) + check_ipo_supported(RESULT CMAKE_SUPPORTS_COMPILER_LTO LANGUAGES CXX) + + check_cxx_compiler_flag("-flto" LTO_FLAG_SUPPORTED) + check_cxx_compiler_flag("-flto=auto" LTO_AUTO_SUPPORTED) + check_cxx_compiler_flag("-flto;-ffat-lto-objects" FAT_LTO_FLAG_SUPPORTED) + + if (DEFINED SEQUANT_LTO) + # Always honor explicit user choice + set(ENABLE_LTO ${SEQUANT_LTO}) + elseif(TARGET_TYPE STREQUAL "STATIC_LIBRARY" OR TARGET_TYPE STREQUAL "OBJECT_LIBRARY") + # For static/object libraries we only want to enable LTO by default, if we can create + # "fat" object files. Those can still be linked without LTO and hence shouldn't + # break any downstream use. + set(ENABLE_LTO ${LTO_FLAG_SUPPORTED}) + elseif(LTO_FLAG_SUPPORTED OR CMAKE_SUPPORTS_COMPILER_LTO) + # Anything but static/object libraries is also linked by us and + # hence enabling LTO doesn't affect downstream compatibility + set(ENABLE_LTO ON) + endif() - if (FAT_LTO_SUPPORTED) - # This (should) ensures that the object files can still be linked without LTO - target_compile_options("${TARGET}" PRIVATE -ffat-lto-objects) + if (ENABLE_LTO) + if (LTO_FLAG_SUPPORTED) + # We prefer to manually set the LTO flag(s) rather than CMake doing it for us + # due to https://gitlab.kitware.com/cmake/cmake/-/work_items/23136 + # On some compilers, the thin LTO type requested by CMake is incompatible + # with explicitly asking for fat LTO object files. + # Besides, it seems like full LTO achieves quite a bit better optimizations + # with Clang. + if (LTO_AUTO_SUPPORTED) + target_compile_options("${TARGET}" PRIVATE -flto=auto) + target_link_options("${TARGET}" PRIVATE -flto=auto) + else() + target_compile_options("${TARGET}" PRIVATE -flto) + target_link_options("${TARGET}" PRIVATE -flto) + endif() + + if (FAT_LTO_FLAG_SUPPORTED) + target_compile_options("${TARGET}" PRIVATE -ffat-lto-objects) + endif() + else() + set_target_properties("${TARGET}" PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON) endif() endif() endfunction() From cec4f130cb3b88768ae6fb315048fc528728e7ed Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 09:59:43 +0200 Subject: [PATCH 16/24] Fix warning about unused variable --- SeQuant/domain/mbpt/op.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SeQuant/domain/mbpt/op.cpp b/SeQuant/domain/mbpt/op.cpp index 50f7b295d4..171981c375 100644 --- a/SeQuant/domain/mbpt/op.cpp +++ b/SeQuant/domain/mbpt/op.cpp @@ -580,14 +580,14 @@ ExprPtr OpMaker::operator()( if (!dep && csv) { if (opclass == OpClass::Ex) { if constexpr (assert_enabled()) { - for (auto&& s : cre_spaces_) { + for ([[maybe_unused]] const auto& s : cre_spaces_) { SEQUANT_ASSERT(isr->contains_unoccupied(s)); } } dep = UseDepIdx::Bra; } else if (opclass == OpClass::Deex) { if constexpr (assert_enabled()) { - for (auto&& s : ann_spaces_) { + for ([[maybe_unused]] const auto& s : ann_spaces_) { SEQUANT_ASSERT(isr->contains_unoccupied(s)); } } From 5a6165b32803101257556ba68215a751658a1f8a Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 11:09:55 +0200 Subject: [PATCH 17/24] Also set optimization flags on SeQuant::bliss --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99113bdc2e..59a4bbc67f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,6 +273,7 @@ add_library(SeQuant-bliss set_target_properties(SeQuant-bliss PROPERTIES EXPORT_NAME bliss) set_target_properties(SeQuant-bliss PROPERTIES CXX_SCAN_FOR_MODULES OFF) add_library(SeQuant::bliss ALIAS SeQuant-bliss) +target_set_optimization_flags(SeQuant-bliss) target_link_libraries(SeQuant-bliss PUBLIC range-v3::range-v3 Boost::headers) if (SEQUANT_USE_SYSTEM_BOOST_HASH) target_compile_definitions(SeQuant-bliss PUBLIC SEQUANT_USE_SYSTEM_BOOST_HASH=1) From a1f13406ec7345623001c667a00acd861b3f5992 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 11:10:10 +0200 Subject: [PATCH 18/24] Make LTO check more robust by skipping linking Clang seems to require some sort of special treatment for convincing the check_cxx_compiler_flag that the flag is actually supported if linking is involved. For now, we simply disable linking under the assumption that if the compiler supports the flag, we will encounter a linker that can handle LTO. --- cmake/compiler.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 9b01ae31a7..dd5c067085 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -80,6 +80,7 @@ function(target_set_optimization_flags TARGET) check_ipo_supported(RESULT CMAKE_SUPPORTS_COMPILER_LTO LANGUAGES CXX) + set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") check_cxx_compiler_flag("-flto" LTO_FLAG_SUPPORTED) check_cxx_compiler_flag("-flto=auto" LTO_AUTO_SUPPORTED) check_cxx_compiler_flag("-flto;-ffat-lto-objects" FAT_LTO_FLAG_SUPPORTED) From 6886e8dc34c975ed73d0ea62e04d2c1e8d3799b2 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 15:17:23 +0200 Subject: [PATCH 19/24] Document SEQUANT_LTO --- doc/user/getting_started/installing.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/user/getting_started/installing.rst b/doc/user/getting_started/installing.rst index d4822c02f8..e1389b1c12 100644 --- a/doc/user/getting_started/installing.rst +++ b/doc/user/getting_started/installing.rst @@ -110,6 +110,9 @@ Useful CMake Variables - ``ABORT`` in ``Debug`` mode, ``IGNORE`` otherwise - Controls how assertions within SeQuant's code are handled. Valid options are ``ABORT``, ``THROW`` and ``IGNORE``. The latter disables assertions, whereas the former keep them active and either abort the program or throw an exception on violation respectively. + * - SEQUANT_LTO + - `ON` if the compiler supportes "fat" LTO objects, `OFF` otherwise + - Controls whether SeQuant will be built with link-time optimizations (LTO) Configuring and Building From 7460c7ecd9d7a0cbf54e1be4e03f6206a26e837c Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 15:18:56 +0200 Subject: [PATCH 20/24] Use correct CMake variable --- cmake/compiler.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index dd5c067085..971e48dd51 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -92,7 +92,7 @@ function(target_set_optimization_flags TARGET) # For static/object libraries we only want to enable LTO by default, if we can create # "fat" object files. Those can still be linked without LTO and hence shouldn't # break any downstream use. - set(ENABLE_LTO ${LTO_FLAG_SUPPORTED}) + set(ENABLE_LTO ${FAT_LTO_FLAG_SUPPORTED}) elseif(LTO_FLAG_SUPPORTED OR CMAKE_SUPPORTS_COMPILER_LTO) # Anything but static/object libraries is also linked by us and # hence enabling LTO doesn't affect downstream compatibility From 803ac19a18f3c428e033b4edbdb67c3173bf84b2 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 15:21:46 +0200 Subject: [PATCH 21/24] Add optimization flags to more targets --- python/CMakeLists.txt | 1 + tests/integration/eval/CMakeLists.txt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index d73a050b86..e1f6f5c323 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -13,6 +13,7 @@ endif() pybind11_add_module(python-sequant MODULE src/sequant/_sequant.cc) target_link_libraries(python-sequant PRIVATE SeQuant) +target_set_optimization_flags(python-sequant) target_include_directories(python-sequant PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include") set_target_properties( diff --git a/tests/integration/eval/CMakeLists.txt b/tests/integration/eval/CMakeLists.txt index c7e315b6a7..f9ecdb64d8 100644 --- a/tests/integration/eval/CMakeLists.txt +++ b/tests/integration/eval/CMakeLists.txt @@ -23,6 +23,7 @@ if (SEQUANT_HAS_TILEDARRAY) ) set_target_properties(eval_ta PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(eval_ta PRIVATE eval_shared tiledarray) + target_set_optimization_flags(eval_ta) set(test_name "sequant/integration/eval_ta") add_test( @@ -42,6 +43,7 @@ if (SEQUANT_HAS_BTAS) ) set_target_properties(eval_btas PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(eval_btas PRIVATE eval_shared BTAS::BTAS) + target_set_optimization_flags(eval_btas) set(test_name "sequant/integration/eval_btas") add_test( @@ -61,6 +63,7 @@ if (SEQUANT_HAS_TAPP) ) set_target_properties(eval_tapp PROPERTIES CXX_SCAN_FOR_MODULES OFF) target_link_libraries(eval_tapp PRIVATE eval_shared tapp::reference) + target_set_optimization_flags(eval_tapp) set(test_name "sequant/integration/eval_tapp") add_test( From 73ca17fe402dfbb7c4a9549e298b21309c9a1f3b Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 15:32:30 +0200 Subject: [PATCH 22/24] Prefix cache variables with SEQUANT_ --- cmake/compiler.cmake | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 971e48dd51..5bc42fae8b 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -81,9 +81,9 @@ function(target_set_optimization_flags TARGET) check_ipo_supported(RESULT CMAKE_SUPPORTS_COMPILER_LTO LANGUAGES CXX) set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") - check_cxx_compiler_flag("-flto" LTO_FLAG_SUPPORTED) - check_cxx_compiler_flag("-flto=auto" LTO_AUTO_SUPPORTED) - check_cxx_compiler_flag("-flto;-ffat-lto-objects" FAT_LTO_FLAG_SUPPORTED) + check_cxx_compiler_flag("-flto" SEQUANT_LTO_FLAG_SUPPORTED) + check_cxx_compiler_flag("-flto=auto" SEQUANT_LTO_AUTO_SUPPORTED) + check_cxx_compiler_flag("-flto;-ffat-lto-objects" SEQUANT_FAT_LTO_FLAG_SUPPORTED) if (DEFINED SEQUANT_LTO) # Always honor explicit user choice @@ -92,22 +92,22 @@ function(target_set_optimization_flags TARGET) # For static/object libraries we only want to enable LTO by default, if we can create # "fat" object files. Those can still be linked without LTO and hence shouldn't # break any downstream use. - set(ENABLE_LTO ${FAT_LTO_FLAG_SUPPORTED}) - elseif(LTO_FLAG_SUPPORTED OR CMAKE_SUPPORTS_COMPILER_LTO) + set(ENABLE_LTO ${SEQUANT_FAT_LTO_FLAG_SUPPORTED}) + elseif(SEQUANT_LTO_FLAG_SUPPORTED OR CMAKE_SUPPORTS_COMPILER_LTO) # Anything but static/object libraries is also linked by us and # hence enabling LTO doesn't affect downstream compatibility set(ENABLE_LTO ON) endif() if (ENABLE_LTO) - if (LTO_FLAG_SUPPORTED) + if (SEQUANT_LTO_FLAG_SUPPORTED) # We prefer to manually set the LTO flag(s) rather than CMake doing it for us # due to https://gitlab.kitware.com/cmake/cmake/-/work_items/23136 # On some compilers, the thin LTO type requested by CMake is incompatible # with explicitly asking for fat LTO object files. # Besides, it seems like full LTO achieves quite a bit better optimizations # with Clang. - if (LTO_AUTO_SUPPORTED) + if (SEQUANT_LTO_AUTO_SUPPORTED) target_compile_options("${TARGET}" PRIVATE -flto=auto) target_link_options("${TARGET}" PRIVATE -flto=auto) else() @@ -115,7 +115,7 @@ function(target_set_optimization_flags TARGET) target_link_options("${TARGET}" PRIVATE -flto) endif() - if (FAT_LTO_FLAG_SUPPORTED) + if (SEQUANT_FAT_LTO_FLAG_SUPPORTED) target_compile_options("${TARGET}" PRIVATE -ffat-lto-objects) endif() else() From e976a19e4568a22d39e53aa82fdd456463047a55 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 15:35:39 +0200 Subject: [PATCH 23/24] Move ctx setup to main --- benchmarks/coupled_cluster.cpp | 3 --- benchmarks/main.cpp | 4 ++++ benchmarks/wick.cpp | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/benchmarks/coupled_cluster.cpp b/benchmarks/coupled_cluster.cpp index 431d4084b8..63be09e748 100644 --- a/benchmarks/coupled_cluster.cpp +++ b/benchmarks/coupled_cluster.cpp @@ -1,6 +1,5 @@ #include -#include #include #ifdef SEQUANT_BENCH_MAX_CC_RANK @@ -15,8 +14,6 @@ using namespace sequant::mbpt; static void cc_full_derivation(benchmark::State &state) { const std::size_t rank = state.range(0); - set_default_mbpt_context({.op_registry_ptr = make_minimal_registry()}); - for (auto _ : state) { CC cc(rank); auto equations = cc.t(); diff --git a/benchmarks/main.cpp b/benchmarks/main.cpp index 820ab9a74b..76a4eb5915 100644 --- a/benchmarks/main.cpp +++ b/benchmarks/main.cpp @@ -2,6 +2,7 @@ #include #include +#include #include using namespace sequant; @@ -17,6 +18,9 @@ int main(int argc, char *argv[]) { .vacuum = Vacuum::SingleProduct}); set_default_context(fermi_ctx); + mbpt::Context mbpt_ctx({.op_registry_ptr = mbpt::make_minimal_registry()}); + mbpt::set_default_mbpt_context(std::move(mbpt_ctx)); + Context bose_einstein_ctx = Context( {.index_space_registry_shared_ptr = idxreg, .vacuum = Vacuum::Physical}); diff --git a/benchmarks/wick.cpp b/benchmarks/wick.cpp index 648d69dbd3..353e9e20e4 100644 --- a/benchmarks/wick.cpp +++ b/benchmarks/wick.cpp @@ -152,8 +152,7 @@ VacAvPair get_mbpt_expr(std::size_t i) { static void mbpt_vac_av(benchmark::State &state, bool csv) { auto ctx = sequant::mbpt::set_scoped_default_mbpt_context( - mbpt::Context({.csv = csv ? CSV::Yes : CSV::No, - .op_registry_ptr = make_minimal_registry()})); + mbpt::Context({.csv = csv ? CSV::Yes : CSV::No})); VacAvPair input = get_mbpt_expr(state.range(0)); From 192a1501a3d9d11a19c7ccea2bc1258084e66b66 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Mon, 24 Aug 2026 17:29:05 +0200 Subject: [PATCH 24/24] Don't completely overwrite ctx --- benchmarks/wick.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/benchmarks/wick.cpp b/benchmarks/wick.cpp index 353e9e20e4..20d58516d7 100644 --- a/benchmarks/wick.cpp +++ b/benchmarks/wick.cpp @@ -151,8 +151,9 @@ VacAvPair get_mbpt_expr(std::size_t i) { } static void mbpt_vac_av(benchmark::State &state, bool csv) { - auto ctx = sequant::mbpt::set_scoped_default_mbpt_context( - mbpt::Context({.csv = csv ? CSV::Yes : CSV::No})); + auto base = mbpt::get_default_mbpt_context(); + base.set(csv ? CSV::Yes : CSV::No); + auto ctx = sequant::mbpt::set_scoped_default_mbpt_context(base); VacAvPair input = get_mbpt_expr(state.range(0));