Repository navigation
fix: Nautilus live-point guard and HDF5 checkpoint format for D >= 91 - #1698
Merged
Merged
Conversation
…int opt-out
- check_model override (also run at the top of run(ctx)): SearchException
(NAUTILUS_N_LIVE_MESSAGE) before any likelihood call unless
n_live > prior_count and, when set, n_points_min >= prior_count + 1.
- _large_attribute_hdf5(): around Sampler construction and call_search on
both execution paths, nautilus.sampler.h5py is a proxy whose File defaults
to libver=('v108', 'latest'), so ellipsoid bounds at n_dim >= 91 fit in
the checkpoint. Remove once nautilus fixes it upstream.
- checkpoint: bool = True constructor argument; False passes no filepath
(resume-less mode, not an identifier field). Conformance golden updated.
Refs #1697
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ellipsoid write/read round trip through the proxied File, a strict-xfail control in nautilus's default format, a D=100 search.fit that writes a checkpoint which a fresh nautilus Sampler resumes, and guard tests with zero likelihood calls. Refs #1697 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #1697 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
At D = 100, Nautilus failed before sampling in two ways (found by the
correlated_ndpilot, autofit_inference#18). This PR adds a fail-fast live-point guard, a run-scoped workaround for nautilus's HDF5 checkpoint format, and acheckpoint=Falseopt-out.Root causes (nautilus-sampler 1.0.5, h5py 3.13.0 / HDF5 1.14.6)
Ellipsoid.compute(nautilus/bounds/basic.py:298-300) raisesValueError: Number of points must be larger than number dimensions.Nothing checks this up front, son_live <= n_dimruns start and then die at the first bound.Ellipsoid.write(nautilus/bounds/basic.py:404-407) storesA,BandB_inv(n_dim**2float64 each) as HDF5 attributes.Sampler.writecreates the file withh5py.File(filepath, 'x')(nautilus/sampler.py:1270), which uses HDF5's earliest file format, where an object-header message is capped at 64 KiB. Fromn_dim = 91the first write after an ellipsoid bound (sampler.py:431-439) raisesOSError: Unable to synchronously create attribute (object header message is too large).What changed (
autofit/non_linear/search/nest/nautilus/search.py)NAUTILUS_N_LIVE_MESSAGEplus aNautilus.check_modeloverride, run byfitand again at the top ofrun(ctx). It raisesSearchExceptionbefore any likelihood call unlessn_live > prior_countand, when set,n_points_min >= prior_count + 1._large_attribute_hdf5()swapsnautilus.sampler.h5pyfor a thin proxy whoseFiledefaults tolibver=('v108', 'latest')when the caller passes none. Everything else delegates to the real h5py. It wrapsSampler(...)construction andcall_searchin bothfit_x1_cpuandfit_multiprocessing, and restores the real module infinally. Checkpoint and resume work at any D. It is commented for removal once nautilus fixes this upstream.checkpoint: bool = Trueconstructor argument.Falsemakescheckpoint_filereturn None, so nautilus writes nothing. This is a resume-less mode. It is not an identifier field, because only__identifier_fields__enter the identifier. The conformance constructor golden is updated.run(ctx)no longer callsPath(None)when there is no checkpoint file.docs/design/checkpointing.md(with anUpstream issue: <link pending>line), the Nautilus docstring (n_live/n_points_minfloor,checkpoint), anddocs/cookbooks/search.md.Tests (
test_autofit/non_linear/search/nest/test_nautilus.py)Ellipsoid.compute(rng.random((300, 100)))is written through the proxiedFile, reopened'r+'and read withEllipsoid.read.BandB_invare unchanged.raises=OSError) writes the same bound in nautilus's default format. It will XPASS, and so fail, once nautilus is fixed, which is the cue to remove the workaround.nautilus.sampler.h5pywhen an exception is raised inside it.search.fit→run(ctx)→fit_x1_cpupath, withNautilus(n_live=101, n_networks=1, n_batch=101, n_like_max=404, seed=1)and directory output. The fit stops at its first full update (after the checkpoint write that follows an ellipsoid bound). A fresh nautilusSampleron the same file then resumes with a matchingn_likeand at least 2 bounds. It takes about 2 s. Without the workaround it fails with the upstreamOSError(checked by hand).nautilus.sampler.NautilusBoundwith a fast stand-in. It is a realEllipsoidfitted to the live set, written with the sameEllipsoid.writeattributes, but it samples from the unit cube instead of rejection-sampling. nautilus's real bound at D = 100 with about 100 live points rejection-samples an enlarged ellipsoid against the unit cube at near-zero acceptance. It did not finish within 80 s, even withneural_network_kwargs={'max_iter': 5}orn_live=200. The real-sampler witness (corr_gaussian_d100n_live_200) stays with autofit_inference.n_live=100on a 100-parameter model raises the named error with the analysis likelihood counter at 0 and the backend never entered.n_points_min=50raises.n_live=101(andn_points_min=101) passes.run(ctx)repeats the guard.checkpoint=False→checkpoint_file is None, andcheckpointis not an identifier field.Local runs:
test_nautilus.pygives 25 passed and 1 xfailed.test_autofit/non_linear/searchplustest_autofit/database/identifiergives 1114 passed and 1 xfailed under-n 4. The 7 tests that failed under xdist all race on sharedtest_autofit/outputdirectories (FileNotFoundErroron output PNGs and dills in emcee, zeus and dynesty). They pass when rerun serially (131 passed). The full suite was not run locally (it takes more than 10 min); CI runs it.Closes #1697
Upstream issue draft (human posts)
Title: Checkpoint write fails for n_dim ≥ 91: object header message is too large
Body:
🤖 Generated with Claude Code