dendra-solvers 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. dendra_solvers-0.3.1/CHANGELOG.md +14 -0
  2. dendra_solvers-0.3.1/CONTRIBUTING.md +76 -0
  3. dendra_solvers-0.3.1/MANIFEST.in +6 -0
  4. dendra_solvers-0.3.1/PKG-INFO +75 -0
  5. dendra_solvers-0.3.1/README.md +52 -0
  6. dendra_solvers-0.3.1/pyproject.toml +52 -0
  7. dendra_solvers-0.3.1/setup.cfg +4 -0
  8. dendra_solvers-0.3.1/setup.py +178 -0
  9. dendra_solvers-0.3.1/src/dendra_solvers/__init__.py +2179 -0
  10. dendra_solvers-0.3.1/src/dendra_solvers/_dhs_cpu.cpp +229 -0
  11. dendra_solvers-0.3.1/src/dendra_solvers/_dhs_cpu_bt.cpp +299 -0
  12. dendra_solvers-0.3.1/src/dendra_solvers/_dhs_cpu_multi.cpp +339 -0
  13. dendra_solvers-0.3.1/src/dendra_solvers/_pcr_cpu.cpp +127 -0
  14. dendra_solvers-0.3.1/src/dendra_solvers/_stable_adapters.py +38 -0
  15. dendra_solvers-0.3.1/src/dendra_solvers/_thomas_cpu_bt.cpp +199 -0
  16. dendra_solvers-0.3.1/src/dendra_solvers/_thomas_cpu_bt_spd_fwd.cpp +307 -0
  17. dendra_solvers-0.3.1/src/dendra_solvers/_thomas_cpu_bt_spd_solve_with_chol.cpp +179 -0
  18. dendra_solvers-0.3.1/src/dendra_solvers/_thomas_cpu_t.cpp +93 -0
  19. dendra_solvers-0.3.1/src/dendra_solvers/_thomas_cpu_tridiag_spd.cpp +218 -0
  20. dendra_solvers-0.3.1/src/dendra_solvers/bindings.cpp +140 -0
  21. dendra_solvers-0.3.1/src/dendra_solvers/dhs_validation.h +90 -0
  22. dendra_solvers-0.3.1/src/dendra_solvers/parallel_utils.h +51 -0
  23. dendra_solvers-0.3.1/src/dendra_solvers/stable_utils.h +64 -0
  24. dendra_solvers-0.3.1/src/dendra_solvers.egg-info/SOURCES.txt +34 -0
  25. dendra_solvers-0.3.1/tests/__init__.py +0 -0
  26. dendra_solvers-0.3.1/tests/reference_utils.py +234 -0
  27. dendra_solvers-0.3.1/tests/test_backward_contracts.py +504 -0
  28. dendra_solvers-0.3.1/tests/test_block_reference.py +218 -0
  29. dendra_solvers-0.3.1/tests/test_dhs.py +143 -0
  30. dendra_solvers-0.3.1/tests/test_dhs_reference.py +208 -0
  31. dendra_solvers-0.3.1/tests/test_dispatch_contracts.py +220 -0
  32. dendra_solvers-0.3.1/tests/test_stable_abi_contracts.py +222 -0
  33. dendra_solvers-0.3.1/tests/test_thomas_solve_t.py +74 -0
  34. dendra_solvers-0.3.1/tests/test_torch_func_contracts.py +1603 -0
  35. dendra_solvers-0.3.1/tests/test_tridiagonal_reference.py +168 -0
  36. dendra_solvers-0.3.1/tests/test_validation_contracts.py +194 -0
  37. dendra_solvers-0.3.1/tests/test_vmap_contracts.py +596 -0
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ Release notes are generated from conventional commits by Commitizen.
4
+
5
+ ## v0.3.1 (2026-09-24)
6
+
7
+ ### Fix
8
+
9
+ - **release**: verify automatic version increment
10
+
11
+ ## v0.3.0
12
+
13
+ Baseline version before automated release notes. Earlier changes are recorded
14
+ in the Git history.
@@ -0,0 +1,76 @@
1
+ # Contributing
2
+
3
+ Internal development currently takes place on GitLab. Keep changes focused and
4
+ include tests for changes to solver behavior. See the [README](README.md#testing)
5
+ for building the extension and running the solver tests.
6
+
7
+ ## Development tools
8
+
9
+ From a checkout, install the development dependency group in a Python 3.11+
10
+ environment (release-tooling CI uses Python 3.12):
11
+
12
+ ```sh
13
+ python -m pip install --upgrade pip
14
+ python -m pip install --group dev
15
+ ```
16
+
17
+ This installs the pinned Commitizen version and pytest without building the
18
+ extension. Installing and testing the solver itself still requires the source
19
+ build steps in the README.
20
+
21
+ ## Commit messages and versions
22
+
23
+ Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) so
24
+ Commitizen can produce useful changelog entries and choose version increments.
25
+ The subject should describe the change, for example:
26
+
27
+ ```text
28
+ fix(solvers): preserve gradients for broadcast inputs
29
+ feat(solvers): support an additional solver variant
30
+ docs: clarify source installation requirements
31
+ ```
32
+
33
+ You can create a commit interactively with `cz commit`, or write the message
34
+ yourself. If a merge request is squash-merged, its final squash commit message
35
+ must follow the same convention. Check the most recent commit with:
36
+
37
+ ```sh
38
+ cz check --rev-range HEAD~1..HEAD
39
+ ```
40
+
41
+ The project stays on `0.x.y` versions during initial development:
42
+
43
+ | Change | Version effect |
44
+ | --- | --- |
45
+ | `fix:`, `perf:`, or `refactor:` | Patch increment, such as `0.3.0` → `0.3.1` |
46
+ | `feat:` | Minor increment, such as `0.3.0` → `0.4.0` |
47
+ | A breaking change marked with `!` or a `BREAKING CHANGE:` footer | Minor increment while the project remains below `1.0` |
48
+ | `docs:`, `test:`, `ci:`, `build:`, or `chore:` without a breaking change | No automatic version increment |
49
+
50
+ Here, “pre-1.0” means versions such as `0.3.1`; it does not add Python package
51
+ prerelease suffixes such as `a1`, `b1`, or `rc1`.
52
+
53
+ GitLab CI updates `pyproject.toml`, `CHANGELOG.md`, and the corresponding version
54
+ tag after the main-branch checks pass and a version increment is warranted.
55
+ Contributors normally leave version changes and release tags to CI.
56
+
57
+ Maintainers must enable same-project job-token pushes in GitLab and allow the
58
+ triggering user to update the default branch and version tags. CI also requires
59
+ an existing `v<current-version>` tag at a tested commit containing that package
60
+ version. For this integration, establish `v0.3.0` once after the selected
61
+ baseline commit passes its build and test jobs; CI will not invent that tag.
62
+
63
+ ## Testing release tooling
64
+
65
+ The release tooling tests use temporary Git repositories and the pinned
66
+ Commitizen installation. They do not require the native solver extension:
67
+
68
+ ```sh
69
+ python -m pytest tools/tests -q -ra
70
+ ```
71
+
72
+ Run the solver suite separately after building the extension:
73
+
74
+ ```sh
75
+ python -m pytest -q -ra
76
+ ```
@@ -0,0 +1,6 @@
1
+ include README.md
2
+ include CHANGELOG.md CONTRIBUTING.md
3
+ recursive-include src/dendra_solvers *.cpp *.h
4
+ recursive-include tests *.py
5
+ recursive-exclude src *.egg-info/*
6
+ global-exclude __pycache__ *.py[cod] .DS_Store
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.4
2
+ Name: dendra-solvers
3
+ Version: 0.3.1
4
+ Summary: Fast implicit solvers (CPU) for cable models, written in C++.
5
+ Classifier: Development Status :: 3 - Alpha
6
+ Classifier: Intended Audience :: Science/Research
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3 :: Only
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Programming Language :: C++
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: Microsoft :: Windows
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: torch>=2.12.0
23
+
24
+ # dendra-solvers
25
+
26
+ C++ PyTorch extensions for fast, differentiable implicit solvers in Dendra.
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install dendra-solvers
32
+ ```
33
+
34
+ Python 3.10+ and PyTorch 2.12+ are required. When a compatible wheel is
35
+ available, installation does not require a compiler. Stable-ABI wheels work
36
+ across supported Python and PyTorch versions on the same operating system and
37
+ CPU architecture.
38
+
39
+ For an HPC environment or custom PyTorch build, install PyTorch first and build
40
+ the extension against that installation:
41
+
42
+ ```bash
43
+ python -m pip install "torch>=2.12.0" "setuptools>=70.1,<82" ninja wheel
44
+ MAX_JOBS=1 python -m pip install --no-build-isolation --no-cache-dir \
45
+ --no-deps --no-binary=dendra-solvers dendra-solvers
46
+ ```
47
+
48
+ The build uses the C++ standard selected by your installed PyTorch. Use a
49
+ C++20-capable compiler for current PyTorch releases. Stable-ABI builds do not
50
+ need rebuilding just because PyTorch is upgraded; see
51
+ [installation and clean rebuilds](docs/installation.md) for wheel availability,
52
+ source builds, and upgrading older installations.
53
+
54
+ Useful build options:
55
+
56
+ - `DENDRA_NATIVE=1` enables host-specific compiler optimizations. Do not use it
57
+ for redistributable builds.
58
+ - `DENDRA_OMP=1` enables OpenMP when its runtime is available.
59
+ - `MAX_JOBS=1` limits compilation concurrency on memory-constrained systems.
60
+
61
+ ## Testing
62
+
63
+ For a development checkout:
64
+
65
+ ```bash
66
+ python -m pip install "torch>=2.12.0" "setuptools>=70.1,<82" ninja wheel numpy pytest
67
+ MAX_JOBS=1 python -m pip install -v --no-build-isolation --no-deps -e .
68
+ python -c "import dendra_solvers._ext as ext; print(ext.__file__)"
69
+ python -m pytest -q -ra
70
+ ```
71
+
72
+ Solver contracts and PyTorch transform usage are documented in [`docs/`](docs/).
73
+
74
+ See [Contributing](CONTRIBUTING.md) for development tools, commit conventions,
75
+ and versioning.
@@ -0,0 +1,52 @@
1
+ # dendra-solvers
2
+
3
+ C++ PyTorch extensions for fast, differentiable implicit solvers in Dendra.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install dendra-solvers
9
+ ```
10
+
11
+ Python 3.10+ and PyTorch 2.12+ are required. When a compatible wheel is
12
+ available, installation does not require a compiler. Stable-ABI wheels work
13
+ across supported Python and PyTorch versions on the same operating system and
14
+ CPU architecture.
15
+
16
+ For an HPC environment or custom PyTorch build, install PyTorch first and build
17
+ the extension against that installation:
18
+
19
+ ```bash
20
+ python -m pip install "torch>=2.12.0" "setuptools>=70.1,<82" ninja wheel
21
+ MAX_JOBS=1 python -m pip install --no-build-isolation --no-cache-dir \
22
+ --no-deps --no-binary=dendra-solvers dendra-solvers
23
+ ```
24
+
25
+ The build uses the C++ standard selected by your installed PyTorch. Use a
26
+ C++20-capable compiler for current PyTorch releases. Stable-ABI builds do not
27
+ need rebuilding just because PyTorch is upgraded; see
28
+ [installation and clean rebuilds](docs/installation.md) for wheel availability,
29
+ source builds, and upgrading older installations.
30
+
31
+ Useful build options:
32
+
33
+ - `DENDRA_NATIVE=1` enables host-specific compiler optimizations. Do not use it
34
+ for redistributable builds.
35
+ - `DENDRA_OMP=1` enables OpenMP when its runtime is available.
36
+ - `MAX_JOBS=1` limits compilation concurrency on memory-constrained systems.
37
+
38
+ ## Testing
39
+
40
+ For a development checkout:
41
+
42
+ ```bash
43
+ python -m pip install "torch>=2.12.0" "setuptools>=70.1,<82" ninja wheel numpy pytest
44
+ MAX_JOBS=1 python -m pip install -v --no-build-isolation --no-deps -e .
45
+ python -c "import dendra_solvers._ext as ext; print(ext.__file__)"
46
+ python -m pytest -q -ra
47
+ ```
48
+
49
+ Solver contracts and PyTorch transform usage are documented in [`docs/`](docs/).
50
+
51
+ See [Contributing](CONTRIBUTING.md) for development tools, commit conventions,
52
+ and versioning.
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ requires = ["setuptools>=70.1,<82", "ninja", "torch>=2.12.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "dendra-solvers"
7
+ version = "0.3.1"
8
+ description = "Fast implicit solvers (CPU) for cable models, written in C++."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = ["torch>=2.12.0"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Intended Audience :: Science/Research",
15
+ "Intended Audience :: Developers",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
23
+ "Programming Language :: C++",
24
+ "Operating System :: POSIX :: Linux",
25
+ "Operating System :: MacOS",
26
+ "Operating System :: Microsoft :: Windows",
27
+ "Topic :: Scientific/Engineering",
28
+ ]
29
+
30
+ [dependency-groups]
31
+ # Install development tools without building the native extension.
32
+ dev = ["commitizen==4.16.3", "pytest>=8"]
33
+
34
+ [tool.commitizen]
35
+ name = "cz_conventional_commits"
36
+ version_provider = "pep621"
37
+ version_scheme = "pep440"
38
+ tag_format = "v$version"
39
+ annotated_tag = true
40
+ update_changelog_on_bump = true
41
+ changelog_file = "CHANGELOG.md"
42
+ bump_message = "build(release): bump version to $new_version"
43
+ major_version_zero = true
44
+
45
+ [tool.setuptools]
46
+ package-dir = {"" = "src"}
47
+
48
+ [tool.setuptools.packages.find]
49
+ where = ["src"]
50
+
51
+ [tool.pytest.ini_options]
52
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,178 @@
1
+ # setup.py
2
+ import os
3
+ import platform
4
+ import sys
5
+ import subprocess
6
+
7
+ from setuptools import setup
8
+
9
+ try:
10
+ from torch.utils.cpp_extension import BuildExtension, CppExtension
11
+ except Exception as e:
12
+ raise RuntimeError(
13
+ "dendra-solvers needs PyTorch to build C++ extensions. "
14
+ "Install torch first (matching the version you want to use) and "
15
+ "re-run `pip install dendra-solvers --no-build-isolation`."
16
+ ) from e
17
+
18
+ # -----------------------------------------------------------------------------
19
+ # Sources
20
+ # -----------------------------------------------------------------------------
21
+ sources = [
22
+ "src/dendra_solvers/_thomas_cpu_bt.cpp",
23
+ "src/dendra_solvers/_thomas_cpu_bt_spd_fwd.cpp",
24
+ "src/dendra_solvers/_thomas_cpu_bt_spd_solve_with_chol.cpp",
25
+ "src/dendra_solvers/_thomas_cpu_tridiag_spd.cpp",
26
+ "src/dendra_solvers/_thomas_cpu_t.cpp",
27
+ "src/dendra_solvers/_pcr_cpu.cpp",
28
+ "src/dendra_solvers/_dhs_cpu.cpp",
29
+ "src/dendra_solvers/_dhs_cpu_bt.cpp",
30
+ "src/dendra_solvers/_dhs_cpu_multi.cpp",
31
+ "src/dendra_solvers/bindings.cpp",
32
+ ]
33
+
34
+ # Base compile/link args
35
+ #
36
+ # This project uses a PyTorch C++ extension. On Windows the compiler is MSVC
37
+ # (cl.exe), which does *not* understand GCC/Clang-only flags (e.g. -Wno-...,
38
+ # -ffast-math). Passing those flags causes hard build failures.
39
+ #
40
+ # We therefore select MSVC-compatible flags on Windows and keep the existing
41
+ # GCC/Clang flags on other platforms.
42
+ # Leave the C++ language standard to PyTorch's BuildExtension, which supplies
43
+ # the minimum required by the installed torch headers. An explicit standard
44
+ # here overrides that default and can break builds against newer PyTorch.
45
+
46
+ is_windows = (os.name == "nt")
47
+
48
+ if is_windows:
49
+ # MSVC (cl.exe)
50
+ # NOTE: distutils/BuildExtension typically add /O2 for Release builds; we
51
+ # include it here for clarity. /fp:fast approximates -ffast-math.
52
+ base_cxx_args = ["/O2", "/fp:fast"]
53
+ # If a Visual Studio Developer Command Prompt (or vcvars*.bat) has already
54
+ # activated the VC environment, PyTorch expects DISTUTILS_USE_SDK=1 so distutils
55
+ # doesn't try to "activate" MSVC again. PyTorch raises this as a UserWarning
56
+ # exception and aborts the build if missing.
57
+ vc_env_active = any(k in os.environ for k in ("VSCMD_VER", "VisualStudioVersion", "VSINSTALLDIR"))
58
+ if vc_env_active:
59
+ os.environ.setdefault("DISTUTILS_USE_SDK", "1")
60
+ # Some distutils toolchains also consult MSSdk; harmless if unused.
61
+ os.environ.setdefault("MSSdk", "1")
62
+ else:
63
+ # GCC / Clang
64
+ base_cxx_args = [
65
+ "-O3",
66
+ "-ffast-math",
67
+ "-fno-math-errno",
68
+ "-fno-trapping-math",
69
+ "-fstrict-aliasing",
70
+ "-Wno-nan-infinity-disabled",
71
+ ]
72
+
73
+
74
+ is_darwin = (sys.platform == "darwin")
75
+ is_arm64 = (platform.machine() == "arm64")
76
+ use_native = os.environ.get("DENDRA_NATIVE", "0") == "1"
77
+
78
+ if is_darwin and is_arm64:
79
+ # Clang on arm64 ignores -march; use -mcpu (enables M1/M2/M3 specific pipes, FMA, etc.)
80
+ base_cxx_args += ["-ffp-contract=fast"]
81
+ if use_native:
82
+ base_cxx_args += ["-mcpu=native"]
83
+ # Keep the runtime target consistent to avoid conservative codegen / linker warnings.
84
+ os.environ.setdefault("MACOSX_DEPLOYMENT_TARGET", "14.0")
85
+ elif use_native and os.name != "nt":
86
+ # Enable host-tuned code on opt-in builds; default wheels stay portable.
87
+ base_cxx_args += ["-march=native"]
88
+
89
+ extra_compile_args = {"cxx": list(base_cxx_args)}
90
+ extra_link_args = []
91
+ include_dirs = []
92
+ library_dirs = []
93
+ define_macros = [
94
+ # Only expose the stable APIs available in our minimum supported releases.
95
+ ("TORCH_TARGET_VERSION", "0x020c000000000000"),
96
+ ("Py_LIMITED_API", "0x030A0000"),
97
+ ]
98
+
99
+ # ----------------------------------------------------------------------------
100
+ # MSVC compatibility
101
+ # ----------------------------------------------------------------------------
102
+ # The solver kernels use GCC/Clang's `__restrict__` qualifier. MSVC uses
103
+ # `__restrict` instead, and will otherwise parse it as an identifier, leading
104
+ # to confusing syntax errors (e.g., 'missing ")" before identifier D').
105
+ if is_windows:
106
+ define_macros.append(("__restrict__", "__restrict"))
107
+
108
+ # -----------------------------------------------------------------------------
109
+ # Optional OpenMP (enable with: DENDRA_OMP=1)
110
+ # -----------------------------------------------------------------------------
111
+ use_openmp = os.environ.get("DENDRA_OMP", "0") == "1"
112
+
113
+ def _brew_prefix(pkg, default):
114
+ try:
115
+ return subprocess.check_output(["brew", "--prefix", pkg], text=True).strip()
116
+ except Exception:
117
+ return default
118
+
119
+ if use_openmp:
120
+ if sys.platform == "darwin":
121
+ libomp_prefix = _brew_prefix("libomp", "/opt/homebrew/opt/libomp")
122
+
123
+ # Only libomp, not brew llvm (avoids libc++ header/runtime mismatches)
124
+ include_dirs += [f"{libomp_prefix}/include"]
125
+ library_dirs += [f"{libomp_prefix}/lib"]
126
+
127
+ # If using Apple clang, use -Xpreprocessor -fopenmp
128
+ extra_compile_args["cxx"] += ["-Xpreprocessor", "-fopenmp"]
129
+ extra_link_args += ["-lomp"]
130
+
131
+ # Ensure the runtime can find libomp
132
+ extra_link_args += [f"-Wl,-rpath,{libomp_prefix}/lib"]
133
+
134
+ define_macros.append(("DENDRA_USE_OMP", "1"))
135
+
136
+ elif os.name == "nt":
137
+ # MSVC (Visual Studio). If you use LLVM toolchain on Windows you can switch this.
138
+ # Newer MSVC supports /openmp:llvm; classic is /openmp (no tasking features).
139
+ extra_compile_args["cxx"] += ["/openmp"]
140
+ define_macros.append(("DENDRA_USE_OMP", "1"))
141
+ else:
142
+ # Linux / other Unix with GCC/Clang that support OpenMP out of the box
143
+ extra_compile_args["cxx"] += ["-fopenmp"]
144
+ extra_link_args += ["-fopenmp"]
145
+ define_macros.append(("DENDRA_USE_OMP", "1"))
146
+
147
+ # -----------------------------------------------------------------------------
148
+ # Extension
149
+ # -----------------------------------------------------------------------------
150
+ ext_modules = [
151
+ CppExtension(
152
+ name="dendra_solvers._ext",
153
+ sources=sources,
154
+ depends=[
155
+ "src/dendra_solvers/stable_utils.h",
156
+ "src/dendra_solvers/parallel_utils.h",
157
+ "src/dendra_solvers/dhs_validation.h",
158
+ ],
159
+ extra_compile_args=extra_compile_args,
160
+ extra_link_args=extra_link_args,
161
+ include_dirs=include_dirs,
162
+ library_dirs=library_dirs,
163
+ define_macros=define_macros,
164
+ language="c++",
165
+ py_limited_api=True,
166
+ )
167
+ ]
168
+
169
+ # -----------------------------------------------------------------------------
170
+ # Setup
171
+ # -----------------------------------------------------------------------------
172
+ # Package metadata lives in pyproject.toml. Keeping setup.py focused on the
173
+ # PyTorch extension avoids duplicate/overwritten metadata during PEP 517 builds.
174
+ setup(
175
+ ext_modules=ext_modules,
176
+ cmdclass={"build_ext": BuildExtension},
177
+ options={"bdist_wheel": {"py_limited_api": "cp310"}},
178
+ )