From a5eb4f22f3661f64c2a8a877f4225c29833a5387 Mon Sep 17 00:00:00 2001 From: chlookaburra Date: Fri, 9 Oct 2026 20:28:07 -0700 Subject: [PATCH] rename every pysvzerod instance to svzerod --- .github/scripts/record_release.sh | 2 +- .github/scripts/release_version.py | 12 ++--- .github/workflows/gui.yml | 2 +- .github/workflows/pypi.yml | 6 +-- .github/workflows/test_visualization.yml | 2 +- CMakeLists.txt | 46 +++++++++---------- README.md | 4 +- .../examples/closed_loop_Regazzoni/main.py | 4 +- .../closed_loop_Regazzoni/tuning_job.sh | 2 +- .../examples/closed_loop_Zingaro/main.py | 4 +- .../closed_loop_Zingaro/tuning_job.sh | 2 +- .../examples/right_heart_pa/main.py | 4 +- applications/svZeroDTuner/requirements.txt | 4 +- .../svzerodtuner/output_extractor.py | 6 +-- .../svZeroDTuner/svzerodtuner/simulation.py | 6 +-- .../svZeroDTuner/svzerodtuner/sv0d_tuner.py | 2 +- .../visualize_simulation.py | 4 +- applications/{pysvzerod.cpp => svzerod.cpp} | 6 +-- container/profiling/Dockerfile | 12 ++--- container/profiling/entrypoint.sh | 4 +- docs/PYPI_RELEASE.md | 4 +- docs/pages/developer_guide.md | 4 +- docs/pages/visualization.md | 2 +- pyproject.toml | 8 ++-- setup.py | 10 ++-- src/Assertions.h | 2 +- tests/compute_ref_sol.py | 4 +- tests/test_calibrator.py | 6 +-- tests/test_svzerodtuner.py | 6 +-- tests/utils.py | 14 +++--- 30 files changed, 97 insertions(+), 97 deletions(-) rename applications/{pysvzerod.cpp => svzerod.cpp} (97%) diff --git a/.github/scripts/record_release.sh b/.github/scripts/record_release.sh index 07a13dc8d..980bddc3d 100644 --- a/.github/scripts/record_release.sh +++ b/.github/scripts/record_release.sh @@ -42,7 +42,7 @@ else GIT_AUTHOR_NAME="github-actions[bot]" GIT_AUTHOR_EMAIL="41898282+github-actions[bot]@users.noreply.github.com" \ GIT_COMMITTER_NAME="github-actions[bot]" GIT_COMMITTER_EMAIL="41898282+github-actions[bot]@users.noreply.github.com" \ - git -c commit.gpgSign=false commit -m "Release pysvzerod $RELEASE_VERSION" + git -c commit.gpgSign=false commit -m "Release svzerod $RELEASE_VERSION" commit_sha=$(git rev-parse HEAD) git tag "$tag" "$commit_sha" if ! git push --atomic origin "HEAD:refs/heads/$DEFAULT_BRANCH" "refs/tags/$tag"; then diff --git a/.github/scripts/release_version.py b/.github/scripts/release_version.py index b2cc1ff4e..0ea1da1d4 100644 --- a/.github/scripts/release_version.py +++ b/.github/scripts/release_version.py @@ -18,8 +18,8 @@ VERSION = re.compile(r"(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)") INDEX_URLS = { - "pypi": "https://pypi.org/pypi/pysvzerod/{version}/json", - "testpypi": "https://test.pypi.org/pypi/pysvzerod/{version}/json", + "pypi": "https://pypi.org/pypi/svzerod/{version}/json", + "testpypi": "https://test.pypi.org/pypi/svzerod/{version}/json", } @@ -84,7 +84,7 @@ def set_version(path, version, expected_current): def check_metadata(content, version, filename): metadata = BytesParser().parsebytes(content) - for field, expected in (("Name", "pysvzerod"), ("Version", version)): + for field, expected in (("Name", "svzerod"), ("Version", version)): if metadata.get_all(field, []) != [expected]: raise ValueError(f"{filename}: expected exactly one {field}: {expected}") @@ -93,7 +93,7 @@ def inspect_distributions(dist, version): parse_version(version) paths = sorted(Path(dist).iterdir()) kinds = set() - prefix = f"pysvzerod-{version}" + prefix = f"svzerod-{version}" wheel_pattern = re.compile( re.escape(prefix) + r"-(?:[0-9][A-Za-z0-9_.]*-)?[A-Za-z0-9_.]+-[A-Za-z0-9_.]+-[A-Za-z0-9_.]+\.whl" ) @@ -223,13 +223,13 @@ def main(): print(args.version) elif args.command == "verify-dist": paths = inspect_distributions(args.dist, args.version) - print(f"Verified {len(paths)} distributions for pysvzerod {args.version}") + print(f"Verified {len(paths)} distributions for svzerod {args.version}") elif args.command == "check-index": check_index(args.index, args.dist, args.version) print(f"Existing {args.index} files match the candidate distributions") else: verify_index(args.index, args.dist, args.version, args.attempts, args.delay) - print(f"Verified all distributions on {args.index} for pysvzerod {args.version}") + print(f"Verified all distributions on {args.index} for svzerod {args.version}") except (OSError, ValueError, tarfile.TarError, zipfile.BadZipFile) as error: parser.exit(1, f"Error: {error}\n") diff --git a/.github/workflows/gui.yml b/.github/workflows/gui.yml index 2476ca71b..19d646e4f 100644 --- a/.github/workflows/gui.yml +++ b/.github/workflows/gui.yml @@ -31,7 +31,7 @@ jobs: enable-cache: true - name: Install Flask dependencies - # The GUI only needs Flask, not the compiled pysvzerod extension. + # The GUI only needs Flask, not the compiled svzerod extension. run: uv sync --no-install-project --no-default-groups --group gui - name: Start Flask Application diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 07364ab4f..807acd2a2 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -27,7 +27,7 @@ on: - pyproject.toml - MANIFEST.in - CMakeLists.txt - - applications/pysvzerod.cpp + - applications/svzerod.cpp permissions: contents: read @@ -115,7 +115,7 @@ jobs: - name: Build and verify source distribution run: | uv build --sdist - uv build --wheel dist/pysvzerod-*.tar.gz --out-dir /tmp/sdist-wheel + uv build --wheel dist/svzerod-*.tar.gz --out-dir /tmp/sdist-wheel uvx twine check --strict dist/*.tar.gz - uses: actions/upload-artifact@v4 with: @@ -374,7 +374,7 @@ jobs: uses: softprops/action-gh-release@v2 with: tag_name: v${{ needs.prepare_release.outputs.release_version }} - name: pysvzerod ${{ needs.prepare_release.outputs.release_version }} + name: svzerod ${{ needs.prepare_release.outputs.release_version }} target_commitish: ${{ steps.record.outputs.commit_sha }} generate_release_notes: ${{ steps.release.outputs.exists != 'true' }} overwrite_files: false diff --git a/.github/workflows/test_visualization.yml b/.github/workflows/test_visualization.yml index ada74d04a..b9f8649f3 100644 --- a/.github/workflows/test_visualization.yml +++ b/.github/workflows/test_visualization.yml @@ -21,7 +21,7 @@ jobs: - name: Install dependencies # The dirgraph test only needs the Python dev tooling, not the compiled - # pysvzerod extension, so skip building the project. + # svzerod extension, so skip building the project. run: uv sync --no-install-project --no-default-groups --group dev - name: Install Graphviz diff --git a/CMakeLists.txt b/CMakeLists.txt index 8266eb8fd..9e601b0d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,16 +176,16 @@ add_executable(svzerodcalibrator applications/svzerodcalibrator.cpp ) # ----------------------------------------------------------------------------- -# Setup building of the pysvzerod Python extension module. +# Setup building of the svzerod Python extension module. # ----------------------------------------------------------------------------- # Replace EXCLUDE_FROM_ALL with SHARED to test building the Python # shared library. -pybind11_add_module(pysvzerod applications/pysvzerod.cpp) -set(PYSVZEROD_VERSION "dev" CACHE STRING "Python package version") -target_compile_definitions(pysvzerod PRIVATE PYSVZEROD_VERSION="${PYSVZEROD_VERSION}") +pybind11_add_module(svzerod applications/svzerod.cpp) +set(SVZEROD_VERSION "dev" CACHE STRING "Python package version") +target_compile_definitions(svzerod PRIVATE SVZEROD_VERSION="${SVZEROD_VERSION}") if(WIN32 AND "${CMAKE_GENERATOR}" STREQUAL "MinGW Makefiles") - message(STATUS ">> Applying static‑link flags to pysvzerod") + message(STATUS ">> Applying static‑link flags to svzerod") include(CheckCXXCompilerFlag) set(_static_flags @@ -199,20 +199,20 @@ if(WIN32 AND "${CMAKE_GENERATOR}" STREQUAL "MinGW Makefiles") list(APPEND _static_flags -static-libwinpthread) else() find_package(Threads REQUIRED) - target_link_libraries(pysvzerod PRIVATE Threads::Threads) + target_link_libraries(svzerod PRIVATE Threads::Threads) endif() # apply to compile *and* link foreach(_f IN LISTS _static_flags) - target_compile_options(pysvzerod PRIVATE ${_f}) + target_compile_options(svzerod PRIVATE ${_f}) # CMake ≥3.13: - target_link_options (pysvzerod PRIVATE ${_f}) + target_link_options (svzerod PRIVATE ${_f}) endforeach() # verify in the configure log for static compilation: - get_target_property(_ccopts pysvzerod COMPILE_OPTIONS) - message(STATUS ">>> pysvzerod COMPILE_OPTIONS = ${_ccopts}") - get_target_property(_lnkopts pysvzerod LINK_OPTIONS) - message(STATUS ">>> pysvzerod LINK_OPTIONS = ${_lnkopts}") + get_target_property(_ccopts svzerod COMPILE_OPTIONS) + message(STATUS ">>> svzerod COMPILE_OPTIONS = ${_ccopts}") + get_target_property(_lnkopts svzerod LINK_OPTIONS) + message(STATUS ">>> svzerod LINK_OPTIONS = ${_lnkopts}") endif() # ----------------------------------------------------------------------------- @@ -241,7 +241,7 @@ target_include_directories(svzerodcalibrator PUBLIC ${CMAKE_SOURCE_DIR}/src/solve ) -target_include_directories(pysvzerod PUBLIC +target_include_directories(svzerod PUBLIC ${CMAKE_SOURCE_DIR}/src/algebra ${CMAKE_SOURCE_DIR}/src/model ${CMAKE_SOURCE_DIR}/src/optimize @@ -259,13 +259,13 @@ target_link_libraries(svzerodsolver PRIVATE nlohmann_json::nlohmann_json) target_link_libraries(svzerodcalibrator PRIVATE Eigen3::Eigen) target_link_libraries(svzerodcalibrator PRIVATE nlohmann_json::nlohmann_json) -target_link_libraries(pysvzerod PRIVATE Eigen3::Eigen) -target_link_libraries(pysvzerod PRIVATE nlohmann_json::nlohmann_json) -target_link_libraries(pysvzerod PRIVATE pybind11_json) -target_link_libraries(pysvzerod PRIVATE svzero_algebra_library) -target_link_libraries(pysvzerod PRIVATE svzero_model_library) -target_link_libraries(pysvzerod PRIVATE svzero_optimize_library) -target_link_libraries(pysvzerod PRIVATE svzero_solve_library) +target_link_libraries(svzerod PRIVATE Eigen3::Eigen) +target_link_libraries(svzerod PRIVATE nlohmann_json::nlohmann_json) +target_link_libraries(svzerod PRIVATE pybind11_json) +target_link_libraries(svzerod PRIVATE svzero_algebra_library) +target_link_libraries(svzerod PRIVATE svzero_model_library) +target_link_libraries(svzerod PRIVATE svzero_optimize_library) +target_link_libraries(svzerod PRIVATE svzero_solve_library) # Create distribution @@ -289,12 +289,12 @@ add_custom_target(codecheck COMMAND npm run check COMMAND find ${SDIR}/*.h ${SDIR}/*.cpp | xargs clang-format -style=file:${PROJECT_SOURCE_DIR}/.clang-format --dry-run --Werror) -set_target_properties(pysvzerod PROPERTIES +set_target_properties(svzerod PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/python ) # standard install target locations -install(TARGETS pysvzerod +install(TARGETS svzerod LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_LIBDIR}" @@ -302,7 +302,7 @@ install(TARGETS pysvzerod # append correct suffix for windows python runtime files if (WIN32) - set_target_properties(pysvzerod PROPERTIES + set_target_properties(svzerod PROPERTIES PREFIX "" SUFFIX ".pyd" ) diff --git a/README.md b/README.md index c934078bd..eb32d9984 100755 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ You can find more information under the following links: Install the Python bindings from PyPI with: ```sh -python -m pip install pysvzerod +python -m pip install svzerod ``` -Use `pysvzerod.simulate("model.json")` to run a model from Python. The package +Use `svzerod.simulate("model.json")` to run a model from Python. The package also installs the `svzerodsolver` and `svzerodcalibrator` commands. diff --git a/applications/svZeroDTuner/examples/closed_loop_Regazzoni/main.py b/applications/svZeroDTuner/examples/closed_loop_Regazzoni/main.py index d166ee440..e7d29c722 100644 --- a/applications/svZeroDTuner/examples/closed_loop_Regazzoni/main.py +++ b/applications/svZeroDTuner/examples/closed_loop_Regazzoni/main.py @@ -16,7 +16,7 @@ import sys import numpy as np import pandas as pd -import pysvzerod +import svzerod # Add src to path sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..')) @@ -51,7 +51,7 @@ def run_baseline(config_file): # Run baseline simulation try: - solver = pysvzerod.Solver(config_file) + solver = svzerod.Solver(config_file) solver.run() print("✓ Simulation completed successfully\n") except Exception as e: diff --git a/applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_job.sh b/applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_job.sh index 39b4a8539..b2f51c107 100644 --- a/applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_job.sh +++ b/applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_job.sh @@ -51,7 +51,7 @@ module load cmake # Relative paths (submit from this directory) VENV_DIR="../../venv" REQUIREMENTS="../../requirements.txt" -SVZEROD_ROOT="../../../.." # svZeroDSolver repo root (for pip install -e pysvzerod) +SVZEROD_ROOT="../../../.." # svZeroDSolver repo root (for pip install -e svzerod) # Check if virtual environment exists and has Python; if not, create and install if [[ ! -f "$VENV_DIR/bin/python" ]]; then diff --git a/applications/svZeroDTuner/examples/closed_loop_Zingaro/main.py b/applications/svZeroDTuner/examples/closed_loop_Zingaro/main.py index 8da54a741..d9ade4344 100644 --- a/applications/svZeroDTuner/examples/closed_loop_Zingaro/main.py +++ b/applications/svZeroDTuner/examples/closed_loop_Zingaro/main.py @@ -16,7 +16,7 @@ import sys import numpy as np import pandas as pd -import pysvzerod +import svzerod # Add src to path sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..')) @@ -51,7 +51,7 @@ def run_baseline(config_file): # Run baseline simulation try: - solver = pysvzerod.Solver(config_file) + solver = svzerod.Solver(config_file) solver.run() print("✓ Simulation completed successfully\n") except Exception as e: diff --git a/applications/svZeroDTuner/examples/closed_loop_Zingaro/tuning_job.sh b/applications/svZeroDTuner/examples/closed_loop_Zingaro/tuning_job.sh index 224c8ed05..51d8d0c97 100644 --- a/applications/svZeroDTuner/examples/closed_loop_Zingaro/tuning_job.sh +++ b/applications/svZeroDTuner/examples/closed_loop_Zingaro/tuning_job.sh @@ -51,7 +51,7 @@ module load cmake # Relative paths (submit from this directory) VENV_DIR="../../venv" REQUIREMENTS="../../requirements.txt" -SVZEROD_ROOT="../../../.." # svZeroDSolver repo root (for pip install -e pysvzerod) +SVZEROD_ROOT="../../../.." # svZeroDSolver repo root (for pip install -e svzerod) # Check if virtual environment exists and has Python; if not, create and install if [[ ! -f "$VENV_DIR/bin/python" ]]; then diff --git a/applications/svZeroDTuner/examples/right_heart_pa/main.py b/applications/svZeroDTuner/examples/right_heart_pa/main.py index 8c0e9a11d..200cddd5c 100644 --- a/applications/svZeroDTuner/examples/right_heart_pa/main.py +++ b/applications/svZeroDTuner/examples/right_heart_pa/main.py @@ -15,7 +15,7 @@ import sys import numpy as np import pandas as pd -import pysvzerod +import svzerod # Add src to path sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..')) @@ -42,7 +42,7 @@ def run_baseline(config_file): print() try: - solver = pysvzerod.Solver(config_file) + solver = svzerod.Solver(config_file) solver.run() print("\u2713 Simulation completed successfully\n") except Exception as e: diff --git a/applications/svZeroDTuner/requirements.txt b/applications/svZeroDTuner/requirements.txt index 1472bdc73..96f9c21bc 100644 --- a/applications/svZeroDTuner/requirements.txt +++ b/applications/svZeroDTuner/requirements.txt @@ -4,5 +4,5 @@ pandas>=1.3.0 pyyaml>=6.0 matplotlib>=3.5.0 -# pysvzerod is a requirement, but it is not available on PyPI, so we need to -#install it from source using "pip install -e ." from the svZeroDSolver repo root +# svzerod is also required. Install it from PyPI with "pip install svzerod", +# or from source using "pip install -e ." from the svZeroDSolver repo root. diff --git a/applications/svZeroDTuner/svzerodtuner/output_extractor.py b/applications/svZeroDTuner/svzerodtuner/output_extractor.py index 5836253e3..33bc98ff0 100644 --- a/applications/svZeroDTuner/svzerodtuner/output_extractor.py +++ b/applications/svZeroDTuner/svzerodtuner/output_extractor.py @@ -8,7 +8,7 @@ import numpy as np import pandas as pd from typing import Union, Literal, Optional -import pysvzerod +import svzerod class OutputExtractor: @@ -19,12 +19,12 @@ class OutputExtractor: Supports extraction of time series or scalar metrics (min, max, mean). """ - def __init__(self, solver: pysvzerod.Solver): + def __init__(self, solver: svzerod.Solver): """ Initialize output extractor with a solver instance. Args: - solver: pysvzerod.Solver instance (must have run() called) + solver: svzerod.Solver instance (must have run() called) """ self.solver = solver self._result_df = None diff --git a/applications/svZeroDTuner/svzerodtuner/simulation.py b/applications/svZeroDTuner/svzerodtuner/simulation.py index cc5202d25..56837f681 100644 --- a/applications/svZeroDTuner/svzerodtuner/simulation.py +++ b/applications/svZeroDTuner/svzerodtuner/simulation.py @@ -6,7 +6,7 @@ """ import numpy as np -import pysvzerod +import svzerod from typing import List, Dict, Any, Tuple from .parameter_handler import ParameterHandler @@ -17,7 +17,7 @@ def run_simulation( param_handler: ParameterHandler, parameters: List[Dict[str, Any]], param_values: np.ndarray, -) -> Tuple[pysvzerod.Solver, OutputExtractor]: +) -> Tuple[svzerod.Solver, OutputExtractor]: """ Run sv0D simulation with given parameter values. @@ -42,7 +42,7 @@ def run_simulation( param_handler.set_parameter(name, value) config_dict = param_handler.get_config() - solver = pysvzerod.Solver(config_dict) + solver = svzerod.Solver(config_dict) solver.run() extractor = OutputExtractor(solver) return solver, extractor diff --git a/applications/svZeroDTuner/svzerodtuner/sv0d_tuner.py b/applications/svZeroDTuner/svzerodtuner/sv0d_tuner.py index 616cb9a14..81ac90d75 100644 --- a/applications/svZeroDTuner/svzerodtuner/sv0d_tuner.py +++ b/applications/svZeroDTuner/svzerodtuner/sv0d_tuner.py @@ -97,7 +97,7 @@ def __init__(self, config_file: str): def __getstate__(self): """ Make tuner pickle-safe for multiprocessing objective dispatch. - `pysvzerod.Solver`/extractor instances are runtime-only and not pickleable. + `svzerod.Solver`/extractor instances are runtime-only and not pickleable. """ state = self.__dict__.copy() state["solver"] = None diff --git a/applications/svZeroDVisualization/visualize_simulation.py b/applications/svZeroDVisualization/visualize_simulation.py index 347541764..66e1f44a5 100644 --- a/applications/svZeroDVisualization/visualize_simulation.py +++ b/applications/svZeroDVisualization/visualize_simulation.py @@ -3,7 +3,7 @@ import sys import argparse -import pysvzerod +import svzerod import pandas as pd import matplotlib.pyplot as plt import networkx as nx @@ -27,7 +27,7 @@ ''' def dirgraph(filepath, output_dir, export_csv): - solver = pysvzerod.Solver(filepath) + solver = svzerod.Solver(filepath) solver.run() results = pd.DataFrame(solver.get_full_result()) diff --git a/applications/pysvzerod.cpp b/applications/svzerod.cpp similarity index 97% rename from applications/pysvzerod.cpp rename to applications/svzerod.cpp index b11ac6792..c8b54c943 100644 --- a/applications/pysvzerod.cpp +++ b/applications/svzerod.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the // University of California, and others. SPDX-License-Identifier: BSD-3-Clause /** - * @file pysvzerod.cpp + * @file svzerod.cpp * @brief Python interface for svZeroDSolver */ #include @@ -15,8 +15,8 @@ namespace py = pybind11; -PYBIND11_MODULE(pysvzerod, m) { - m.attr("__version__") = PYSVZEROD_VERSION; +PYBIND11_MODULE(svzerod, m) { + m.attr("__version__") = SVZEROD_VERSION; using Solver = Solver; py::class_(m, "Solver") .def(py::init([](py::dict& config) { diff --git a/container/profiling/Dockerfile b/container/profiling/Dockerfile index 49ee0ddc2..9dee1ddb6 100644 --- a/container/profiling/Dockerfile +++ b/container/profiling/Dockerfile @@ -20,13 +20,13 @@ RUN apt-get -q update && \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -COPY . /opt/pysvzerod +COPY . /opt/svzerod -RUN mkdir -p /opt/pysvzerod-build/relwithdebinfo && \ - cd /opt/pysvzerod-build/relwithdebinfo && \ - cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo /opt/pysvzerod && \ +RUN mkdir -p /opt/svzerod-build/relwithdebinfo && \ + cd /opt/svzerod-build/relwithdebinfo && \ + cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo /opt/svzerod && \ cmake --build . --target svzerodsolver WORKDIR /opt/data -RUN chmod +x /opt/pysvzerod/container/profiling/entrypoint.sh -ENTRYPOINT ["/opt/pysvzerod/container/profiling/entrypoint.sh"] +RUN chmod +x /opt/svzerod/container/profiling/entrypoint.sh +ENTRYPOINT ["/opt/svzerod/container/profiling/entrypoint.sh"] diff --git a/container/profiling/entrypoint.sh b/container/profiling/entrypoint.sh index 39d01f0e9..b65563797 100644 --- a/container/profiling/entrypoint.sh +++ b/container/profiling/entrypoint.sh @@ -1,5 +1,5 @@ #! /bin/bash export LIBPROFILER=$(find /usr/lib -name "libprofiler.so") -LD_PRELOAD=$LIBPROFILER CPUPROFILE=/opt/main.prof CPUPROFILE_FREQUENCY=100000 /opt/pysvzerod-build/relwithdebinfo/svzerodsolver $@ /opt/output.csv -google-pprof --pdf /opt/pysvzerod-build/relwithdebinfo/svzerodsolver /opt/main.prof > profiling_report.pdf +LD_PRELOAD=$LIBPROFILER CPUPROFILE=/opt/main.prof CPUPROFILE_FREQUENCY=100000 /opt/svzerod-build/relwithdebinfo/svzerodsolver $@ /opt/output.csv +google-pprof --pdf /opt/svzerod-build/relwithdebinfo/svzerodsolver /opt/main.prof > profiling_report.pdf diff --git a/docs/PYPI_RELEASE.md b/docs/PYPI_RELEASE.md index 3149aef34..6ace34a41 100644 --- a/docs/PYPI_RELEASE.md +++ b/docs/PYPI_RELEASE.md @@ -1,4 +1,4 @@ -# Publishing pysvzerod +# Publishing svzerod ## Run a release @@ -22,7 +22,7 @@ successful PyPI release updates `pyproject.toml`, creates a `vX.Y` tag, and creates a GitHub release with notes and the packages attached. Do not update versions or create release tags manually. -The uploaded package reports its version through `pysvzerod.__version__`. +The uploaded package reports its version through `svzerod.__version__`. TestPyPI uploads leave the repository version unchanged and do not create a GitHub release. Pull requests and tags never publish packages automatically. diff --git a/docs/pages/developer_guide.md b/docs/pages/developer_guide.md index c74645596..768c21a16 100644 --- a/docs/pages/developer_guide.md +++ b/docs/pages/developer_guide.md @@ -7,7 +7,7 @@ svZeroDSolver is written in a highly modular manner to enable reuse of code for many different applications. It is divided into a header based library in the `src` directory and a collection of different applications in the `applications` folder. Each application is written for a different use-case of svZeroDSolver, namely: * svZerodSolver in `svzerodsolver.cpp` -* Python API in `pysvzerod.cpp` +* Python API in `svzerod.cpp` * svZeroDCalibrator in `svzerodcalibrator.cpp` * svZeroDVisualization for visualizing 0D models and results * svZeroDGUI for creating new 0D models grahically. @@ -33,7 +33,7 @@ cmake --build . # Install with uv -We use [uv](https://docs.astral.sh/uv/) to manage the Python environment and to build the `pysvzerod` Python extension. After [installing uv](https://docs.astral.sh/uv/getting-started/installation/), execute this command in the root folder to create a virtual environment in `.venv`, install all dependencies (including the development tooling), and build the current source: +We use [uv](https://docs.astral.sh/uv/) to manage the Python environment and to build the `svzerod` Python extension. After [installing uv](https://docs.astral.sh/uv/getting-started/installation/), execute this command in the root folder to create a virtual environment in `.venv`, install all dependencies (including the development tooling), and build the current source: ```bash uv sync ``` diff --git a/docs/pages/visualization.md b/docs/pages/visualization.md index a6392b4b9..fe04815f0 100644 --- a/docs/pages/visualization.md +++ b/docs/pages/visualization.md @@ -18,7 +18,7 @@ svZeroDVisualization is built using a robust architecture that includes: We use [uv](https://docs.astral.sh/uv/) to manage the Python environment (see the [Developer Guide](@ref developer_guide) for an overview). From the repository root, the following command creates a virtual environment in `.venv`, builds the -`pysvzerod` extension, and installs the visualization dependencies (`dash`, +`svzerod` extension, and installs the visualization dependencies (`dash`, `plotly`) together with the shared dependencies (`pandas`, `numpy`, `matplotlib`, `networkx`): ```bash diff --git a/pyproject.toml b/pyproject.toml index 41b871db5..ea08969f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools >= 77", "wheel", "cmake_setuptools", "cmake >= 3.18", "n build-backend = "setuptools.build_meta" [project] -name = "pysvzerod" +name = "svzerod" version = "3.1" description = "A fast C++ application for working with 0D models." readme = "README.md" @@ -22,8 +22,8 @@ Source = "https://github.com/SimVascular/svZeroDSolver" Issues = "https://github.com/SimVascular/svZeroDSolver/issues" [project.scripts] -svzerodsolver = "pysvzerod:run_simulation_cli" -svzerodcalibrator = "pysvzerod:run_calibration_cli" +svzerodsolver = "svzerod:run_simulation_cli" +svzerodcalibrator = "svzerod:run_calibration_cli" # Development tooling. Installed by default with `uv sync`; install with pip via # `pip install -e . --group dev` (pip >= 25.1). Consolidates the dependencies @@ -52,7 +52,7 @@ viz = [ "plotly", ] -# The importable artifact is the compiled `pysvzerod` extension module, built by +# The importable artifact is the compiled `svzerod` extension module, built by # CMake via setup.py (ext_modules). There are no pure-Python packages to ship, # so disable setuptools auto-discovery (which would otherwise error on the # multiple top-level directories or wrongly pick up `tests`). diff --git a/setup.py b/setup.py index cf5444635..ae9ce6147 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ def build_extension(self, ext): ext.sourcedir, # Match CMake's Python headers and extension suffix to pip's interpreter. "-DPython_EXECUTABLE=" + sys.executable, - "-DPYSVZEROD_VERSION=" + self.distribution.get_version(), + "-DSVZEROD_VERSION=" + self.distribution.get_version(), "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=" + output_dir, "-DCMAKE_BUILD_TYPE=" + build_type, ] @@ -69,20 +69,20 @@ def run(self): # ------------------------------------------------- build_temp = os.path.abspath(self.build_temp) search_root = os.path.join(build_temp, "python") - dest_dir = os.path.dirname(self.get_ext_fullpath("pysvzerod")) + dest_dir = os.path.dirname(self.get_ext_fullpath("svzerod")) for root, _, files in os.walk(search_root): for f in files: - if f.startswith("pysvzerod") and f.endswith((".so", ".pyd", ".dll", ".dylib")): + if f.startswith("svzerod") and f.endswith((".so", ".pyd", ".dll", ".dylib")): src = os.path.join(root, f) os.makedirs(dest_dir, exist_ok=True) shutil.copy2(src, os.path.join(dest_dir, f)) print(f"[INFO] copied {src} -> {dest_dir}") return - raise RuntimeError("pysvzerod binary not found in build tree") + raise RuntimeError("svzerod binary not found in build tree") setup( - ext_modules=[CMakeExtension("pysvzerod")], + ext_modules=[CMakeExtension("svzerod")], cmdclass={"build_ext": CustomCMakeBuild}, ) diff --git a/src/Assertions.h b/src/Assertions.h index cf00663d4..69258d6e5 100644 --- a/src/Assertions.h +++ b/src/Assertions.h @@ -13,7 +13,7 @@ /** * @brief Report a violated Eigen assertion * - * Eigen asserts via assert(), which aborts the process. Inside the pysvzerod + * Eigen asserts via assert(), which aborts the process. Inside the svzerod * extension module that would tear down the Python interpreter, so throw * instead: pybind11 surfaces the exception and only the current call fails. * diff --git a/tests/compute_ref_sol.py b/tests/compute_ref_sol.py index f401215e5..1de3e9f39 100644 --- a/tests/compute_ref_sol.py +++ b/tests/compute_ref_sol.py @@ -1,6 +1,6 @@ import os import json -import pysvzerod +import svzerod import argparse import sys @@ -19,7 +19,7 @@ def compute_reference_solution(testname): # testfiles.remove("steadyFlow_calibration.json") # compute result - result = pysvzerod.simulate(json.load(open(os.path.join(this_file_dir, 'cases', testname)))) + result = svzerod.simulate(json.load(open(os.path.join(this_file_dir, 'cases', testname)))) # save result result_filename = os.path.join(this_file_dir, 'cases', 'results', 'result_' + testname) diff --git a/tests/test_calibrator.py b/tests/test_calibrator.py index 6e7dbb5b1..1b02851cd 100644 --- a/tests/test_calibrator.py +++ b/tests/test_calibrator.py @@ -4,7 +4,7 @@ import numpy as np import pytest -from .utils import execute_pysvzerod, RTOL_PRES +from .utils import execute_svzerod, RTOL_PRES this_file_dir = os.path.abspath(os.path.dirname(__file__)) @@ -12,7 +12,7 @@ def test_steady_flow_calibration(): testfile = os.path.join(this_file_dir, "cases", "steadyFlow_calibration.json") - result, _ = execute_pysvzerod(testfile, "calibrator") + result, _ = execute_svzerod(testfile, "calibrator") calibrated_parameters = result["vessels"][0]["zero_d_element_values"] @@ -52,7 +52,7 @@ def test_calibration_vmr(test_case): with open(reference_file) as ff: reference = json.load(ff) - result, _ = execute_pysvzerod(test, "calibrator") + result, _ = execute_svzerod(test, "calibrator") for i, vessel in enumerate(reference["vessels"]): for key, value in vessel["zero_d_element_values"].items(): diff --git a/tests/test_svzerodtuner.py b/tests/test_svzerodtuner.py index e5daa44cd..e8546768f 100644 --- a/tests/test_svzerodtuner.py +++ b/tests/test_svzerodtuner.py @@ -63,7 +63,7 @@ def test_parameter_handler_rejects_unknown_parameter_names(tmp_path): def test_sensitivity_analyzer_validates_parameter_names_up_front(tmp_path): - sys.modules.setdefault("pysvzerod", types.SimpleNamespace(Solver=object)) + sys.modules.setdefault("svzerod", types.SimpleNamespace(Solver=object)) sensitivity_module = importlib.import_module( "applications.svZeroDTuner.svzerodtuner.sensitivity" ) @@ -149,7 +149,7 @@ def test_config_handler_rejects_reversed_time_series_target_range(tmp_path): def test_sensitivity_results_use_screening_labels_and_filenames(tmp_path, monkeypatch): - sys.modules.setdefault("pysvzerod", types.SimpleNamespace(Solver=object)) + sys.modules.setdefault("svzerod", types.SimpleNamespace(Solver=object)) sensitivity_module = importlib.import_module( "applications.svZeroDTuner.svzerodtuner.sensitivity" ) @@ -186,7 +186,7 @@ def test_sensitivity_results_use_screening_labels_and_filenames(tmp_path, monkey def test_sensitivity_run_resets_sample_data_each_time(monkeypatch): - sys.modules.setdefault("pysvzerod", types.SimpleNamespace(Solver=object)) + sys.modules.setdefault("svzerod", types.SimpleNamespace(Solver=object)) sensitivity_module = importlib.import_module( "applications.svZeroDTuner.svzerodtuner.sensitivity" ) diff --git a/tests/utils.py b/tests/utils.py index 8b57ad32a..edb6c2cac 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -10,15 +10,15 @@ # (run executables instead of Python interface, much slower) from pytest import coverage -import pysvzerod +import svzerod this_file_dir = os.path.abspath(os.path.dirname(__file__)) RTOL_PRES = 1.0e-7 RTOL_FLOW = 1.0e-7 -def execute_pysvzerod(testfile, mode): - """Execute pysvzerod (via Python interface or executable). +def execute_svzerod(testfile, mode): + """Execute svzerod (via Python interface or executable). Args: testfile: Path to the input file. @@ -46,9 +46,9 @@ def execute_pysvzerod(testfile, mode): else: # run via Python binding (fast) if mode == "solver": - result = pysvzerod.simulate(config) + result = svzerod.simulate(config) elif mode == "calibrator": - result = pysvzerod.calibrate(config) + result = svzerod.calibrate(config) return result, config @@ -132,7 +132,7 @@ def run_with_reference( ): - res, config = execute_pysvzerod(test_config, "solver") + res, config = execute_svzerod(test_config, "solver") output_variable_based = config["simulation_parameters"].get("output_variable_based", False) @@ -160,7 +160,7 @@ def run_test_case_by_name(name, output_variable_based=False, folder="."): testfile = os.path.join(this_file_dir, "cases", name + ".json") # run test - result, config = execute_pysvzerod(testfile, "solver") + result, config = execute_svzerod(testfile, "solver") if not output_variable_based: output = {