fix: name the contract when V-dependent consumers run after release_pixel_projector - #47
Merged
Merged
Conversation
…r release_pixel_projector HarmonicBasis.release_pixel_projector() drops V, and its docstring already documented that get_covariance, get_inverse, to_basis, m-block compression and PICSLike do_cross must not run afterwards. The contract was documented but not enforced: _V_N_VT reads _V lazily, so a post-release caller passed None into matrix_mult and got 'ValueError: Input operand 0 does not have enough dimensions' — an unrelated linear-algebra error. Every V read on the harmonic path funnels through the _V accessor, so one guard there covers all of them. release_pixel_projector now flips a flag and drops any materialised _V_N_VT cache, so get_covariance fails the contract check instead of silently serving a primed cache. The Fisher hot path reads only _V_N_inv and _V_Ninv_VT and is unaffected; get_full_inverse and get_full_logdet are V-free too and keep working after release, which the tests now pin down.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #47 +/- ##
==========================================
+ Coverage 92.58% 92.63% +0.05%
==========================================
Files 40 40
Lines 5084 5092 +8
==========================================
+ Hits 4707 4717 +10
+ Misses 377 375 -2
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR improves diagnosability in cosmocore by enforcing the already-documented post-HarmonicBasis.release_pixel_projector() contract: V-dependent consumers now fail with a clear, contract-naming RuntimeError instead of an opaque NumPy matmul error.
Changes:
- Add a single guarded accessor for the pixel projector (
_V) that raises a descriptiveRuntimeErrorafterrelease_pixel_projector(). - Ensure any materialized
_V_N_VTcache is dropped on release so post-release V consumers fail deterministically and memory is freed. - Add regression tests covering post-release failures for key V consumers and confirming V-free consumers still work; document the behavior in the changelog.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/cosmoforge.cosmocore/cosmocore/basis/harmonic.py | Enforces the post-release contract via a guarded _V accessor and clears _V_N_VT cache on release. |
| src/cosmoforge.cosmocore/tests/test_harmonic_basis.py | Adds tests asserting V-dependent consumers raise post-release and V-free hot-path consumers remain usable. |
| docs/source/changelog.rst | Notes the clearer post-release RuntimeError behavior for harmonic V consumers. |
ggalloni
marked this pull request as ready for review
July 14, 2026 13:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #18 — HarmonicBasis: V-dependent consumers raise opaque numpy error after
release_pixel_projector().The bug
HarmonicBasis.release_pixel_projector()drops the pixel projector V. Its docstring already documented the contract:get_covariance,get_inverse,to_basis, m-block compression and PICSLike harmonicdo_crossmust not be invoked afterwards. The contract was documented but never enforced._V_N_VTreadsself._Vlazily, so a post-release caller passedNoneintomatrix_multand got:Reproduced before fixing — the new test failed with exactly that numpy error on
get_covariance,get_inverseandto_basis, andprojectorsilently returnedNone. This is a diagnosability fix, not a correctness one: nothing computed the wrong answer, the error just pointed at the wrong place.The fix
Every V read on the harmonic path funnels through the
_Vaccessor, so a single guard there covers all five consumers rather than five hand-written guards.release_pixel_projector()flips a flag;_Vraises aRuntimeErrorthat names the contract and says to skip the release if those consumers are needed downstream:Release also drops any materialised
_V_N_VTcache, soget_covariancefails the contract check deterministically instead of silently serving a primed cache — and frees an n_modes² buffer, which is what the method is for.Scope notes
_V_N_invand_V_Ninv_VT, so it is unaffected. All existing Fisher and PICSLike tests pass unmodified.get_full_inverseandget_full_logdetturned out to be V-free too — they work fine after release and are not part of the contract. The tests now pin that down so the guard can't creep over them.PixelBasisis untouched; release is a no-op there._V_N_VTstays lazy, per the issue's out-of-scope list.Verification
Reproduced the failing path end-to-end (build harmonic basis →
release_pixel_projector()→ call each consumer, mirroring whatqube/fisher.pythenpicslike.pydo to a shared basis manager), not just via the suite. All three suites green: cosmocore 539 passed, qube 172 passed / 10 skipped, picslike 99 passed / 2 skipped.