Skip to content

Commit f2e6d56

Browse files
committed
perf(lu): restore checked factorization throughput
- Move LU and LDLT non-finite factor checks out of cubic update loops while preserving completed-storage validation before factors escape. - Borrow factor rows and finite vector arrays in solve, dot, and norm paths to avoid avoidable copies. - Refresh v0.4.2 release artifacts, LU solve benchmark docs, and release workflow docs. - Preserve README benchmark table spacing in the Criterion plot updater.
1 parent fb71485 commit f2e6d56

12 files changed

Lines changed: 199 additions & 198 deletions

CHANGELOG.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [Unreleased]
8+
## [0.4.2] - 2026-06-04
99

1010
### Added
1111

@@ -73,6 +73,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7373
- Document that LU and LDLT solve_vec reject non-finite RHS entries with LaError::NonFinite metadata.
7474
- Cite the Bareiss reference in the exact solve helper docs and describe exact-arithmetic growth and complexity.
7575
- Cover finite proof defaults and non-finite RHS solve boundaries in unit tests.
76+
- Clarify finite solve and norm guarantees [`fb71485`](https://github.com/acgetchell/la-stack/commit/fb71485cac0b464b2fa9ee949140a558b7738781)
77+
78+
- State that LU and LDLT solve_vec use floating-point substitution without a certified absolute rounding-error bound.
79+
- Clarify that inf_norm reports NonFinite for unchecked stored NaN/∞ as well as row-sum overflow.
80+
- Exercise the unchecked finite-proof fixture path directly in exact tests.
7681

7782
### Fixed
7883

@@ -100,6 +105,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
100105
- Measure exact random percentile benchmarks over repeated corpus timings and cumulative input sets.
101106
- Tighten Codecov status thresholds and extend benchmark workflow timeout.
102107
- Keep Semgrep constructor fixtures aligned with public API guardrails.
108+
- Revalidate public compute inputs [`ffca00e`](https://github.com/acgetchell/la-stack/commit/ffca00e9dd6fde5e57c8064f69807a76e45a469e)
109+
110+
- Parse Matrix and Vector storage into private finite proof-bearing types at public compute boundaries.
111+
- Reject unchecked non-finite storage before LU, LDLT, determinant, norm, dot, and exact-arithmetic paths can proceed.
112+
- Keep unchecked proof-wrapper constructors crate-private for internal paths with local finiteness proofs.
113+
- Document the private proof-bearing invariant model in the API overview and roadmap.
103114

104115
### Maintenance
105116

@@ -606,6 +617,6 @@ Older releases are archived by minor series:
606617
- [0.2.x](docs/archive/changelog/0.2.md)
607618
- [0.1.x](docs/archive/changelog/0.1.md)
608619

609-
[Unreleased]: https://github.com/acgetchell/la-stack/compare/v0.4.1...HEAD
620+
[0.4.2]: https://github.com/acgetchell/la-stack/compare/v0.4.1...v0.4.2
610621
[0.4.1]: https://github.com/acgetchell/la-stack/compare/v0.4.0...v0.4.1
611622
[0.4.0]: https://github.com/acgetchell/la-stack/compare/v0.3.0...v0.4.0

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "la-stack"
3-
version = "0.4.1"
3+
version = "0.4.2"
44
edition = "2024"
55
rust-version = "1.96"
66
license = "BSD-3-Clause"

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,14 @@ Summary (median time; lower is better). The “la-stack vs nalgebra/faer” colu
316316

317317
| D | la-stack median (ns) | nalgebra median (ns) | faer median (ns) | la-stack vs nalgebra | la-stack vs faer |
318318
|---:|--------------------:|--------------------:|----------------:|---------------------:|----------------:|
319-
| 2 | 2.173 | 4.448 | 139.923 | +51.2% | +98.4% |
320-
| 3 | 13.989 | 34.607 | 180.026 | +59.6% | +92.2% |
321-
| 4 | 27.580 | 48.435 | 203.163 | +43.1% | +86.4% |
322-
| 5 | 53.517 | 75.935 | 274.375 | +29.5% | +80.5% |
323-
| 8 | 134.859 | 162.859 | 371.463 | +17.2% | +63.7% |
324-
| 16 | 635.775 | 576.171 | 846.189 | -10.3% | +24.9% |
325-
| 32 | 2,704.570 | 2,731.740 | 2,589.494 | +1.0% | -4.4% |
326-
| 64 | 17,381.460 | 13,744.505 | 11,276.642 | -26.5% | -54.1% |
319+
| 2 | 2.585 | 4.486 | 137.653 | +42.4% | +98.1% |
320+
| 3 | 12.204 | 22.990 | 182.618 | +46.9% | +93.3% |
321+
| 4 | 27.228 | 51.660 | 208.181 | +47.3% | +86.9% |
322+
| 5 | 53.141 | 68.714 | 272.117 | +22.7% | +80.5% |
323+
| 8 | 141.279 | 162.225 | 348.216 | +12.9% | +59.4% |
324+
| 16 | 626.561 | 574.115 | 854.941 | -9.1% | +26.7% |
325+
| 32 | 2,862.795 | 2,709.532 | 2,806.698 | -5.7% | -2.0% |
326+
| 64 | 19,703.239 | 14,388.285 | 12,085.453 | -36.9% | -63.0% |
327327

328328
<!-- BENCH_TABLE:lu_solve:median:new:END -->
329329

docs/RELEASING.md

Lines changed: 71 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
# Releasing la-stack
22

3-
This guide documents the exact commands for performing a clean release using a
4-
dedicated release PR, followed by tagging, publishing to crates.io, and
5-
creating a GitHub release.
3+
This guide documents the release flow for `vX.Y.Z`: prepare a dedicated
4+
release PR, merge it, create the final annotated tag from the generated
5+
changelog, publish to crates.io, and create the GitHub release.
6+
7+
The release changelog is generated with `git-cliff --tag` through
8+
`just changelog-unreleased`, so no temporary local tag is needed.
69

710
Applies to versions vX.Y.Z. Prefer updating documentation before publishing
811
to crates.io.
@@ -25,7 +28,7 @@ Verify your git remotes:
2528
git remote -v
2629
```
2730

28-
Ensure your local main is up to date before beginning:
31+
Ensure your local `main` is up to date before beginning:
2932

3033
```bash
3134
git checkout main
@@ -36,49 +39,50 @@ git pull --ff-only
3639

3740
## Step 1: Create a clean release PR
3841

39-
This PR should primarily include: version bumps, changelog updates, and
40-
documentation updates. All major code changes should already be on main.
42+
This PR should primarily include version bumps, changelog updates, benchmark
43+
comparison updates, and documentation updates. All major code changes should
44+
already be on `main`.
4145

42-
**Exception:** Small, critical fixes discovered during the release process
43-
(e.g., documentation errors, script bugs, formatting issues) may be included
44-
but should be minimal and release-critical only.
46+
Small, critical fixes discovered during the release process may be included,
47+
but keep them minimal and release-critical.
4548

4649
1. Create the release branch
4750

4851
```bash
49-
git checkout -b release/$TAG
52+
git checkout -b "release/$TAG"
5053
```
5154

5255
2. Bump versions
5356

54-
Preferred (if cargo-edit is installed):
57+
Preferred, if `cargo-edit` is installed:
5558

5659
```bash
57-
# Bump package version in Cargo.toml
58-
cargo set-version $VERSION
60+
cargo set-version "$VERSION"
5961
```
6062

61-
Alternative: edit `Cargo.toml` manually (update `version = "..."` under
62-
`[package]`).
63+
Alternative: edit `Cargo.toml` manually and update `version = "..."` under
64+
`[package]`.
6365

64-
Update references in documentation (search, then manually edit as needed):
66+
Review version references in documentation:
6567

6668
```bash
67-
# List occurrences of version-like strings to review
6869
rg -n "\bv?[0-9]+\.[0-9]+\.[0-9]+\b" README.md docs/ || true
6970
```
7071

71-
3. Generate changelog using a temporary local tag (DO NOT PUSH this tag)
72+
3. Generate the release changelog
7273

7374
```bash
74-
# Create a temporary annotated tag locally to enable changelog generation
75-
# Do not push this tag; it will be recreated later after merge
76-
git tag -a "$TAG" -m "la-stack $TAG"
77-
78-
# Generate changelog (git-cliff + post-processing)
79-
just changelog
75+
# Generates CHANGELOG.md as though TAG already exists, then applies
76+
# markdown hygiene and archives completed minor release series.
77+
just changelog-unreleased "$TAG"
8078
```
8179

80+
`just changelog-unreleased` runs
81+
`GIT_CLIFF_OFFLINE=true git-cliff --tag "$TAG" -o CHANGELOG.md`, then
82+
`postprocess-changelog`, then `archive-changelog`. The root changelog keeps
83+
Unreleased plus the active minor series; older completed minor series live
84+
under `docs/archive/changelog/`.
85+
8286
4. Run benchmarks and update the README comparison table
8387

8488
```bash
@@ -101,7 +105,14 @@ just bench-save-baseline $TAG
101105
This baseline can be compared against in future optimization work.
102106
See `docs/BENCHMARKING.md` for the full comparison workflow.
103107

104-
6. Stage and commit release artifacts
108+
6. Validate the release branch
109+
110+
```bash
111+
just ci
112+
cargo publish --locked --dry-run
113+
```
114+
115+
7. Stage and commit release artifacts
105116

106117
```bash
107118
git add Cargo.toml Cargo.lock CHANGELOG.md README.md docs/
@@ -114,7 +125,7 @@ git commit -m "chore(release): release $TAG
114125
- Update documentation for release"
115126
```
116127

117-
7. Push the branch and open a PR
128+
8. Push the branch and open a PR
118129

119130
```bash
120131
git push -u origin "release/$TAG"
@@ -124,64 +135,46 @@ PR metadata:
124135

125136
- Title: chore(release): release $TAG
126137
- Description: Clean release PR with version bump, changelog, and
127-
documentation updates. No code changes.
138+
documentation updates. No feature work.
128139

129-
Note: Do NOT push the temporary tag created in step 3.
140+
### Handling fixes discovered during the release process
130141

131-
### Handling fixes discovered during release process
142+
If you discover issues after generating the changelog:
132143

133-
If you discover issues (bugs, formatting problems, etc.) after creating the
134-
changelog:
135-
136-
1. **For critical fixes that must be in this release:**
144+
1. For critical fixes that must be in this release, make and commit the fix,
145+
then regenerate the release changelog:
137146

138147
```bash
139-
# Make your fixes
140-
# Run code quality tools
141-
# Commit the fixes
142-
git add .
143-
git commit -m "fix: [description of fix]"
144-
145-
# Delete the temporary tag and regenerate changelog
146-
git tag -d "$TAG"
147-
git tag -a "$TAG" -m "la-stack $TAG"
148-
just changelog
149-
150-
# Commit updated changelog
151-
git add CHANGELOG.md
148+
just changelog-unreleased "$TAG"
149+
git add CHANGELOG.md docs/archive/changelog/
152150
git commit -m "docs: update changelog with release fixes"
153151
```
154152

155-
2. **For non-critical fixes:**
156-
- Document them as known issues in the release notes
157-
- Include them in the next release
158-
- This avoids the changelog regeneration loop
153+
2. For non-critical fixes, document them as known issues in the release notes
154+
or include them in the next release.
159155

160156
---
161157

162158
## Step 2: After the PR is merged into main
163159

164-
1. Sync your local main to the merge commit
160+
1. Sync your local `main` to the merge commit
165161

166162
```bash
167163
git checkout main
168164
git pull --ff-only
169165
```
170166

171-
2. Recreate the final annotated tag using the changelog content
167+
2. Create the final annotated tag using the changelog content
172168

173169
```bash
174-
# Remove the temporary local tag if it exists
175-
git tag -d "$TAG" 2>/dev/null || true
176-
177-
# Create the final annotated tag with the changelog section as the tag message
178-
# Note: For large changelogs (>125KB), this automatically creates an annotated
179-
# tag with a reference message pointing to CHANGELOG.md instead of the full
180-
# content
170+
# Creates the annotated tag from the matching CHANGELOG.md section.
171+
# Archived versions are read from docs/archive/changelog/ automatically.
172+
# For large changelogs (>125KB), the tag message points to the changelog
173+
# section instead of embedding the full content.
181174
just tag "$TAG"
182175
```
183176

184-
3. (Optional) Verify tag message content
177+
3. Optional: verify the tag message content
185178

186179
```bash
187180
git tag -l --format='%(contents)' "$TAG"
@@ -193,32 +186,35 @@ git tag -l --format='%(contents)' "$TAG"
193186
git push origin "$TAG"
194187
```
195188

196-
5. Create the GitHub release with notes from the tag annotation
189+
5. Publish to crates.io
197190

198191
```bash
199-
# Requires GitHub CLI (gh) and authenticated session
200-
gh release create "$TAG" --notes-from-tag
192+
# Publish the crate (ensure docs are already updated on main via the PR)
193+
cargo publish --locked
201194
```
202195

203-
6. Publish to crates.io
196+
6. Create the GitHub release with notes from the tag annotation
204197

205198
```bash
206-
# Sanity check before publishing
207-
cargo publish --locked --dry-run
208-
209-
# Publish the crate (ensure docs are already updated on main via the PR)
210-
cargo publish --locked
199+
# Requires GitHub CLI (gh) and authenticated session
200+
gh release create "$TAG" --title "$TAG" --notes-from-tag
211201
```
212202

203+
Always set the GitHub release title to the exact tag string, including the
204+
leading `v`.
205+
213206
---
214207

215208
## Notes and tips
216209

217-
- Never push the temporary tag created for changelog generation; only push
218-
the final tag after the PR is merged.
219-
- Keep the release PR strictly to version + changelog + documentation to
220-
maintain a clean history.
210+
- Do not create a temporary local release tag for changelog generation; use
211+
`just changelog-unreleased "$TAG"`.
212+
- Keep the release PR scoped to version, changelog, archive, benchmark
213+
comparison, and documentation changes.
214+
- `just changelog` regenerates the current changelog from existing tags and may
215+
update `docs/archive/changelog/`.
216+
- `just changelog-unreleased "$TAG"` is for release PR preparation before the
217+
final tag exists.
218+
- `just tag "$TAG"` is for the final post-merge annotated tag.
221219
- If multiple crates or files reference the version, confirm all of them are
222220
updated consistently.
223-
- For future convenience, parts of this document can be automated into a
224-
release script.
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
D,la_stack,la_lo,la_hi,nalgebra,na_lo,na_hi,faer,fa_lo,fa_hi
2-
2,2.172623282439358,2.165444772092298,2.185506739324025,4.448408979470227,4.439782928520427,4.459719277058991,139.9226022608816,139.06474375246668,140.51212151197308
3-
3,13.989121746672993,13.955023991167852,14.013050521832692,34.606732435908626,33.499470537742226,34.761521044572746,180.02609852620088,179.59708359326262,180.8791974100286
4-
4,27.58037208037632,27.526517442670773,27.627054765320764,48.435129151777026,48.360737894391505,48.549664199225454,203.162599789916,202.79373021936047,203.32348086504715
5-
5,53.5167292278733,53.2079241828104,53.645503456564526,75.93470878300764,75.4146378575776,76.19896610821027,274.374828180443,272.8463967468175,275.1594136908799
6-
8,134.8587910191369,134.33353258195461,135.23630002147613,162.85903692402766,162.5110280122886,163.16671953470214,371.4632572777341,369.98617150369097,373.2859170186846
7-
16,635.7754523403698,630.758052532669,638.095305070158,576.1714016094243,575.8381924198251,577.8533527696793,846.1888291695698,843.6908420833043,847.8866115184559
8-
32,2704.5696137095592,2696.7101307744565,2715.9278532608696,2731.7404900064475,2726.3126052188554,2735.1429635561008,2589.4939744827334,2587.8085641182724,2594.9184784361632
9-
64,17381.45994623656,17346.594885060753,17418.868905879215,13744.504879275653,13711.504555743551,13761.18247949234,11276.642192271553,11263.305944055945,11293.149440751858
2+
2,2.585300857336246,2.582809844321982,2.586669800817735,4.486088257090016,4.479229681572247,4.492362317908142,137.6529309582465,137.31998885139873,137.93586339517975
3+
3,12.203757609083176,12.183054403617847,12.224101270062874,22.990257557091617,22.91154128675699,23.12912235259086,182.61806110946827,181.880047375976,183.37040632194638
4+
4,27.227520807109173,27.202299533674857,27.266723521091606,51.66011127074051,51.555715086488036,51.840625331770724,208.18091469437718,207.68326634854134,209.09477296109242
5+
5,53.14134517762996,53.09941497989714,53.281547651078945,68.71356228143745,68.56318667878111,68.77114355114793,272.1171465104768,270.47097586206894,274.01601221264366
6+
8,141.2790253849833,140.95206481826406,141.68049543712607,162.22478601970167,161.86865626610683,162.56549560477754,348.21559402824914,347.18022267396856,349.1754040441267
7+
16,626.5606138541871,624.4956536182669,627.6291586692258,574.1147371436412,572.7849165188117,575.6888051044084,854.9407805348176,853.314408186121,859.1660992820005
8+
32,2862.794789510007,2860.7804785793915,2864.5392419175027,2709.532471877147,2702.3908894171072,2716.620725916311,2806.6981316154734,2802.5897840011316,2814.7045584045586
9+
64,19703.238514957266,19501.774005848587,19923.90512820513,14388.28538961039,14376.077992277993,14407.440476190477,12085.452737127373,12070.825515947467,12098.666085946574

0 commit comments

Comments
 (0)