Skip to content

mcsamplerGPU: prevent adaptive-proposal support truncation - #39

Merged
oshaughnessy-junior merged 1 commit into
rift_O4dfrom
codex/mcsampler-gpu-adaptive-support-fix
Aug 1, 2026
Merged

mcsamplerGPU: prevent adaptive-proposal support truncation#39
oshaughnessy-junior merged 1 commit into
rift_O4dfrom
codex/mcsampler-gpu-adaptive-support-fix

Conversation

@oshaughnessy-junior

Copy link
Copy Markdown
Owner

Context

PR #38 superseded #37 and landed the MC-error estimator, but the separate validated GPU adaptive-proposal fix ff0a04b was not included. This PR extracts only that commit onto current rift_O4d.

Changes

  • Keep every adapted histogram bin reachable with a minimum uniform-mixture floor.
  • Clamp right-edge samples to the final valid histogram bin.
  • Use tempered importance weights for proposal adaptation.
  • Correct n_adapt scaling so adaptation freezes at the requested point.

The original validation found a 2D Gaussian bias of -0.321 +/- 0.011 nats before the fix and -0.003 +/- 0.004 afterward, with proposal support restored from 56% to 100%.

Validation

  • python -m py_compile MonteCarloMarginalizeCode/Code/RIFT/integrators/mcsamplerGPU.py
  • test_mcsamplerEnsemble_extended.py --as-test --n-max 100000
  • test_mcsamplerEnsemble_extended.py --as-test --use-lnL --n-max 100000

Both focused sampler runs pass on CPU. This host has no CuPy device; the original commit records the GPU/device-level validation.

On a mild 2D Gaussian test (T4b, floor_level unset), the adapted sampler was
biased by -0.32 nats while every within-run error estimate read ~0.02: the
1D marginals of the drawn samples matched the claimed p_s exactly, but
E[prior/p_s] = 0.37, i.e. ~63% of the prior volume sat in histogram bins with
exactly zero proposal probability.  A zero bin is an absorbing state (it can
never be re-drawn), so the sampled support shrinks irreversibly and the
integral silently loses the mass outside it.

Four fixes:
- compute_hist: clamp the uniform-mixture floor to HIST_FLOOR_LEVEL_MIN=1e-2
  so no bin can reach zero probability (production ILE already passes 0.1;
  the clamp only binds for smaller/unset floors).
- integrate_log: build adaptation weights from the stored tempered importance
  weights exp(tempering_exp*lnL + ln p - ln p_s) so the weighted histogram
  estimates the fixed target L^beta * prior -- the documented contract
  (see integrate() and the ILE driver comment).  The old lnL+max(maxlnL,200)
  weights ignored tempering_exp and 1/p_s; being near-flat, each histogram
  replayed the previous proposal's sampling noise, a multiplicative random
  walk that collapsed the proposal onto a comb of surviving bins (61/100 per
  dim in the test) and drove the truncation above.
- integrate_log: n_adapt freeze test double-multiplied by n (n_adapt was
  already scaled at parse time), so adaptation never froze regardless of the
  requested chunk count; also scale the no-kwarg default consistently.
- pdf_from_hist: clamp bin index to n_bins-1 (right-edge sample previously
  indexed out of range).

Validation (2D Gaussian, n=2000, neff=1000, 16 runs/config): bias
-0.321 +/- 0.011 -> -0.003 +/- 0.004 for all n_adapt in {5..100} and
tempering_exp in {0, 0.1, 1.0}; final proposal support 56% -> 100%;
runs now reach neff~1000 instead of exhausting nmax at neff~350.
E[prior/p_s] over fresh draws from the adapted proposal: 0.373 -> 1.0002.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@oshaughnessy-junior
oshaughnessy-junior merged commit f5c8a83 into rift_O4d Aug 1, 2026
19 checks passed
@oshaughnessy-junior
oshaughnessy-junior deleted the codex/mcsampler-gpu-adaptive-support-fix branch August 13, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant