diff --git a/utilities/CMakeLists.txt b/utilities/CMakeLists.txt index 2dd0cd05fb..76b6aad338 100644 --- a/utilities/CMakeLists.txt +++ b/utilities/CMakeLists.txt @@ -12,3 +12,4 @@ foreach(current IN LISTS EXECUTABLE_SOURCES) endforeach() add_subdirectory(external-interface) +add_subdirectory(cost_analysis) diff --git a/utilities/cost_analysis/CMakeLists.txt b/utilities/cost_analysis/CMakeLists.txt new file mode 100644 index 0000000000..131767ac7c --- /dev/null +++ b/utilities/cost_analysis/CMakeLists.txt @@ -0,0 +1,35 @@ +include(FindOrFetchCLI11) +include(FindOrFetchJSON) + +add_executable(cost_analysis cost_analysis.cpp report.cpp) +set_target_properties(cost_analysis PROPERTIES + CXX_SCAN_FOR_MODULES OFF + RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +target_link_libraries(cost_analysis PRIVATE + SeQuant::mbpt nlohmann_json::nlohmann_json CLI11::CLI11) +target_set_warning_flags(cost_analysis) + +foreach(NAME IN ITEMS "ccsd_r2" "df_r1") + # --omit-revision drops the volatile git-revision line so a plain + # compare_files suffices; the tool writes the report next to the driver. + add_test( + NAME "sequant/cost_analysis/${NAME}/generate" + COMMAND cost_analysis --driver "${CMAKE_CURRENT_LIST_DIR}/examples/${NAME}.json" --omit-revision) + set_tests_properties("sequant/cost_analysis/${NAME}/generate" + PROPERTIES FIXTURES_SETUP "COST_ANALYSIS_${NAME}") + + add_test( + NAME "sequant/cost_analysis/${NAME}/verify" + COMMAND "${CMAKE_COMMAND}" -E compare_files "${NAME}.md" "${NAME}.md.expected" + WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/examples") + set_tests_properties("sequant/cost_analysis/${NAME}/verify" + PROPERTIES FIXTURES_REQUIRED "COST_ANALYSIS_${NAME}") +endforeach() + +# ccsd_r2 exercises --dump_tree; diff the tree dump against its fixture. +add_test( + NAME "sequant/cost_analysis/ccsd_r2/dump_tree" + COMMAND "${CMAKE_COMMAND}" -E compare_files "R2.tree.txt" "R2.tree.txt.expected" + WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/examples") +set_tests_properties("sequant/cost_analysis/ccsd_r2/dump_tree" + PROPERTIES FIXTURES_REQUIRED "COST_ANALYSIS_ccsd_r2") diff --git a/utilities/cost_analysis/README.md b/utilities/cost_analysis/README.md new file mode 100644 index 0000000000..7c495f78f6 --- /dev/null +++ b/utilities/cost_analysis/README.md @@ -0,0 +1,118 @@ +# Cost analysis + +A standalone utility that estimates the cost of evaluating a tensor equation +without running it. It reads a serialized equation, optimizes and binarizes it, +then writes a Markdown report on the largest intermediates, the most expensive +contractions, peak storage, total operation count, and (optionally) cache reuse. +Figures are symbolic `AsyCost` polynomials in the index-space sizes; memory and +storage are additionally evaluated to megabytes at the driver's sizes (element +width follows the field: 8 bytes real, 16 bytes complex). Operation counts are +reported symbolically only. + +The optimize/binarize step mirrors the choices MPQC's `SeQuantEngine` makes +(symmetrizer stripping, per-summand factorization, volatile-leaf weighting, +cache gating), so the estimates track what a real MPQC evaluation would do. + +## Build & run + +Built as part of SeQuant (target `cost_analysis`). It takes a single argument, a +[JSON](https://www.json.org/) _driver_: + +```bash +cost_analysis --driver examples/ccsd_r2.json +``` + +Paths inside the driver (`equation_file`, `output.path`) — and the `dump_tree` +`.tree.txt` files — are resolved/written relative to the driver's own +directory, not the invocation directory. The final "Report written to …" line +prints the absolute path so the output is easy to locate. + +## Driver + +| Block | Key | Meaning | Default | +|---|---|---|---| +| `context` | `spbasis` | `spinor` or `spinfree` | `spinor` | +| | `field` | `real` or `complex` | `real` | +| | `convention` | registry: `min_sr`/`sr`/`mr`/`f12` | `sr` | +| | `aux` | factorization spaces to register: `["df"]` (Κ) and/or `["thc"]` (L) | none | +| `sizes` | `