qube.memory_budget module
Static memory-budget calculator for QUBE runs (harmonic and pixel-direct
paths). Also exposes the qube-memory-budget console script declared in
qube-qml’s pyproject.toml.
Predict QUBE pipeline memory consumption from basis dimensions.
Companion to the algebraic memory analysis in Paper I §6 — analogous to ECLIPSE_Memory.f90 but covering both QUBE pipeline paths.
Two paths are supported:
harmonic: Tegmark-style V projection + SMW kernel. Persistent state is dominated by
L(n_pix²),V_N_inv(n_modes × n_pix), andV_Ninv_VT(n_modes²).pixel-direct: Gjerløw-style direct pixel-space C^{-1}. No V, no SMW. Persistent state is dominated by
Cov_T(Core retains it; Core only nullifiesnoise_cov1for non-pixel-direct modes) andbasis._N(asfortranarray F-order copy).
For each path the calculator splits stage cost into:
Persistent state at stage exit (audit-backed, ~1% accurate at the calibration points below).
Transient state at stage peak (modelled where the algebra is known; assumed simultaneously alive at the peak — conservative when transients fire sequentially).
StageBudget.peak_bytes = persistent_bytes + Σ transient_bytes.
Allocator overhead, BLAS workspace, and the empirical
fisher.compute.derivative_cache transient (queue item E for the
harmonic path; ~``n_params × n_pix²`` for the pixel-direct path) are not
modelled in detail. Expect ~5–10% allocator/BLAS slack at production
scale, and an additive Python/numpy overhead floor (~0.2–0.5 GiB) that
dominates at small n_pix.
Calibration points:
Harmonic at eclipse-QU (n_pix=59136, n_modes=33274, lmax_signal=256, lmax=128; mem_eclipse_qu_20114986.out, commit d11ab0b): basis_setup persistent 57.21 GiB predicted vs 57.80 GiB measured; basis_setup peak 112.6 GiB predicted vs 113.2 GiB measured.
Pixel-direct at QU_nside64 fsky=0.1 (n_pix=9800, lmax=128, basis_lmax=256 default → switch implicit; mem_nc_20103507.out, commit ccabffd): basis_setup persistent (above covariance) 1.43 GiB predicted vs 1.44 GiB measured.
- class qube.memory_budget.BudgetConfig(n_pix, n_modes, lmax_signal, lmax=None, release_pixel_projector=True)[source]
Bases:
objectInputs to the QUBE harmonic-path budget.
- n_pix: total pixel count (2 × n_pix_observed for QU spin-2;
n_pix_observed for T spin-0; sum for TQU).
- n_modes: total mode count after V projection. The calculator does not
derive this from lmax_signal because mode counting depends on spin and m=0 exclusions.
- lmax_signal: signal-cov ceiling (Layer A; max ℓ in V), not the
parameter-grid lmax.
- lmax: inference window upper (Layer B). None or equal to
lmax_signal disables the switch optimisation. Below
lmax_signalactivates_compute_effective_noiseand addsT(separate fromV_Ninv_VT) plusS_fixedand the corr intermediate to basis_setup.- release_pixel_projector: True matches PR #16’s Fisher path (V freed
after SMW build). False reproduces the legacy keep-V behaviour.
- __init__(n_pix, n_modes, lmax_signal, lmax=None, release_pixel_projector=True)
- class qube.memory_budget.PixelDirectBudgetConfig(n_pix, lmax_signal, n_bins, n_params, has_switch=True)[source]
Bases:
objectInputs to the QUBE pixel-direct path budget.
n_pix: total pixel count (same convention as BudgetConfig). lmax_signal: signal-cov ceiling (Layer A). Used for the auto-picker
informational fields and to decide whether the implicit-switch S_fixed transient is allocated by Core (lmax_signal > params.lmax → switch implicit).
- n_bins: number of bandpower bins in the analysis. Drives the
per-parameter
cinv_times_dcbdict size during fisher_run.- n_params: number of derivative parameters.
n_bins × n_spectrain practice (e.g. n_bins=6 × 3 spectra = 18 at eclipse-QU). Used for the empirical fisher_run derivative-product transient.
- has_switch: True if Core’s
setup_computation_basisenters the S_fixed branch before discovering the path is pixel-direct (i.e. params.lmax < lmax_signal). At default benchmark configs (lmax_signal=4·nside, params.lmax=2·nside) this is True. The S_fixed buffer is allocated, populated, then dereferenced — but the allocator pool keeps it resident through basis_setup exit.
- __init__(n_pix, lmax_signal, n_bins, n_params, has_switch=True)
- class qube.memory_budget.StageBudget(name, persistent=<factory>, transient=<factory>)[source]
Bases:
objectMemory cost for one pipeline stage.
- __init__(name, persistent=<factory>, transient=<factory>)
- class qube.memory_budget.QUBEBudget(config, stages, path='harmonic')[source]
Bases:
objectFull pipeline budget across all four QUBE stages.
-
config:
BudgetConfig|PixelDirectBudgetConfig
-
stages:
list[StageBudget]
- __init__(config, stages, path='harmonic')
-
config: