solprop.backends.memory#
Byte counts and sizes the backends share for their memory ledgers.
A backend names every buffer it holds in
memory_ledger(). numpy_ref’s ledger takes
its rows from reference_base_memory() and adams_memory(), and mlx sizes
its compiled graphs from mlx_graph_bytes() and mlx_stage_bytes(). The native
adapter decides its low-storage registers and z-table slots here too.
Module Attributes
Bytes a step's lazy graph may hold before |
|
The spatial statistics that synthesise the magnetic closure in time (SEP 34). |
Functions
|
Return the Adams march's history rows |
|
Return how many flow volumes a compiled backend's low-storage march holds. |
|
Return whether a backend's low-storage march holds the stage register |
|
Return whether |
|
Return the |
|
Return the |
|
Return one stage's live-graph bytes on the |
|
Return the reference backend's rows outside the general route and the flow. |
|
Return the reference's base rows for a single-precision problem. |
|
Return the position slots the native CPU build holds for a z table. |
- solprop.backends.memory.LOCAL_FLUX_STATISTICS = frozenset({'beam_radius', 'fwhm_r', 'on_axis_intensity', 'peak_intensity'})#
The spatial statistics that synthesise the magnetic closure in time (SEP 34).
- solprop.backends.memory.MLX_GRAPH_BUDGET = 1073741824#
Bytes a step’s lazy graph may hold before
mlxevaluates stages as it forms them.Below it the whole step is one graph, evaluated with its norm; above it each stage and each running integral is evaluated as it is formed, which bounds the live graph to one stage (SEP 33 section 6.3).
- solprop.backends.memory.adams_memory(problem)[source]#
Return the Adams march’s history rows
numpy_refholds for a problem.Empty without an Adams integrator, and on the general path, whose history is a list of arrays.
- Parameters:
- problemsolprop.translate.problem.KernelProblem
The translated problem.
- Returns:
- dict
Row name to bytes.
Examples
>>> from solprop.backends.memory import adams_memory >>> from solprop.grid import EnvelopeGrid >>> from solprop.nonlinear.gnlse import problem_from >>> from solprop.pulses import SechPulse >>> from solprop.stepper import PIController >>> from solprop.stepper.multistep import Multistep >>> from solprop.translate.problem import assemble >>> grid = EnvelopeGrid.from_limits(1.0, 835e-9, (500e-9, 2e-6), 1e-12) >>> gnlse = problem_from([0.0, 0.0, -1.183e-26], omega_ref=grid.omega0, ... gamma=0.11, shock=False) >>> start = SechPulse(wavelength=835e-9, width=100e-15, peak_power=9.8).build(grid) >>> problem = assemble(grid, gnlse.mode, [gnlse.kerr], start, ... controller=PIController(rtol=1e-8, atol=1e-16), ... save_planes=[0.01], dz_max=0.01, dz_init=1e-3, ... density=1.0, shock=False, prefactor_index=1.0, ... integrator=Multistep(order=4)) >>> adams_memory(problem) == {"adams_store": 6 * 16 * grid.n_omega} True
- solprop.backends.memory.low_storage_flows(problem, backend)[source]#
Return how many flow volumes a compiled backend’s low-storage march holds.
The one predicate the engines share (SEP 24 section 4.3): with
propagator_mode="auto"resolved for this march asStepDriver._propagator_moderesolves it on a CPU, a tabulated constant operator – every separable one included, whosephi_representationis"separable"– holds one volume,exp(h_t D / 2); a tabulated varying operator holds the step’sPandQ; recomputing holds none. A native device build resolves"auto"to recomputing and holds none, which this CPU count over-states by the table.- Parameters:
- problemsolprop.translate.problem.KernelProblem
The translated problem.
- backendstr
A registry name; every backend that runs the march counts the same.
- Returns:
- int
0, 1 or 2 volumes of one state’s size.
Examples
>>> from solprop.backends.memory import low_storage_flows >>> from solprop.grid import EnvelopeGrid >>> from solprop.nonlinear.gnlse import problem_from >>> from solprop.pulses import SechPulse >>> from solprop.stepper import PIController >>> from solprop.translate.problem import assemble >>> grid = EnvelopeGrid.from_limits(1.0, 835e-9, (500e-9, 2e-6), 1e-12) >>> gnlse = problem_from([0.0, 0.0, -1.183e-26], omega_ref=grid.omega0, ... gamma=0.11, shock=False) >>> start = SechPulse(wavelength=835e-9, width=100e-15, peak_power=9.8).build(grid) >>> problem = assemble(grid, gnlse.mode, [gnlse.kerr], start, ... controller=PIController(rtol=1e-8, atol=1e-16), ... save_planes=[0.01], dz_max=0.01, dz_init=1e-3, ... density=1.0, shock=False, prefactor_index=1.0) >>> low_storage_flows(problem, "native") # a constant operator's table 1
- solprop.backends.memory.low_storage_stage_register(problem, backend)[source]#
Return whether a backend’s low-storage march holds the stage register
C.SEP 24 Q4: Kokkos, from phase 3, elides it on the Cartesian and line routes where a pass reads its input once – a material response and no in-stage absorber – since each finish can write the next pass’s input straight into the transverse scratch. Under an in-stage absorber the exchange re-forms the input from
Cfor the absorber’s evaluation, so it is held; the modal and planar routes andnumpy_refhold it.- Parameters:
- problemsolprop.translate.problem.KernelProblem
The translated problem.
- backendstr
A registry name.
- Returns:
- bool
Whether
Cis held, one state’s bytes.
Examples
>>> from solprop.backends.memory import low_storage_stage_register >>> from solprop.grid import EnvelopeGrid >>> from solprop.nonlinear.gnlse import problem_from >>> from solprop.pulses import SechPulse >>> from solprop.stepper import PIController >>> from solprop.translate.problem import assemble >>> grid = EnvelopeGrid.from_limits(1.0, 835e-9, (500e-9, 2e-6), 1e-12) >>> gnlse = problem_from([0.0, 0.0, -1.183e-26], omega_ref=grid.omega0, ... gamma=0.11, shock=False) >>> start = SechPulse(wavelength=835e-9, width=100e-15, peak_power=9.8).build(grid) >>> problem = assemble(grid, gnlse.mode, [gnlse.kerr], start, ... controller=PIController(rtol=1e-8, atol=1e-16), ... save_planes=[0.01], dz_max=0.01, dz_init=1e-3, ... density=1.0, shock=False, prefactor_index=1.0) >>> low_storage_stage_register(problem, "native") # a modal route holds C True
- solprop.backends.memory.mlx_bounded(stages, stage)[source]#
Return whether
mlxevaluates each stage as it is formed.- Parameters:
- stagesint
The tableau’s stage count.
- stageint
One stage’s live-graph bytes.
- Returns:
- bool
True when a whole step’s graph would exceed
MLX_GRAPH_BUDGET.
- solprop.backends.memory.mlx_graph_bytes(problem)[source]#
Return the
mlxbackend’s live-graph row for a problem, bytes.- Parameters:
- problemsolprop.translate.problem.KernelProblem
A single-precision problem on a fibre, radial or Cartesian route.
- Returns:
- int
mlx_step_graphofmlx_rows().
- solprop.backends.memory.mlx_rows(problem, rows)[source]#
Return the
mlxbackend’s device rows beside the oracle’s host rows.SEP 33 section 6.3: the device copies of the narrowed tables, the operator’s and the prefactor’s terms as double-float pairs, and the live graph. Where a step’s graph would exceed
MLX_GRAPH_BUDGETthe backend evaluates each stage as it is formed and each running integral as it is scanned, so at most one stage’s working rows (_PER_STAGE_ROWS, twice, for the graph’s temporaries), a scan’s2 ceil(log2 n_to) + 4arrays over the node chunk, and the stages and their propagators are live at once; below it, a whole step’s seven stages of rows are, the scans’ levels released as they go. Measured against MLX’s own peak.- Parameters:
- problemsolprop.translate.problem.KernelProblem
A single-precision problem on a fibre, radial or Cartesian route.
- rowsdict
Its single-precision reference rows.
- Returns:
- dict
mlx_tables,mlx_termsandmlx_step_graph, bytes.
- solprop.backends.memory.mlx_stage_bytes(problem)[source]#
Return one stage’s live-graph bytes on the
mlxbackend.- Parameters:
- problemsolprop.translate.problem.KernelProblem
A single-precision problem on a fibre, radial or Cartesian route.
- Returns:
- int
Twice the per-stage working rows, with a scan’s levels.
- solprop.backends.memory.reference_base_memory(problem, *, tabulating, embedded, noise, statistics_weight, spatial_absorber)[source]#
Return the reference backend’s rows outside the general route and the flow.
numpy_ref’smemory_ledgerreturns these rows. What one step has resident at its peak (the reference allocates its buffers per pass); the space-domain rows are sized bytransform.node_chunk, not by the node count.Method-aware (SEP 24 section 6.5). The Runge-Kutta march holds the tableau’s stage rows, two accumulators and the propagator pair or the six fractions’ pairs. The low-storage march holds none of them: two registers beside the state (
register_accumulatorandregister_stage) and, tabulating, the flow table inpropagators– one volume ofexp(h D / 2)on a constant operator, the step’sPandQon a varying one, nothing when recomputing.- Parameters:
- problemsolprop.translate.problem.KernelProblem
The translated problem.
- tabulatingbool
Whether the Runge-Kutta march’s propagators are tabulated (six distinct exponent pairs held) or recomputed (one pair); the low-storage march counts its flows by
low_storage_flows().- embeddedbool
Whether the quadrature has an embedded coarse projection of its own.
- noisebool
Whether a noise field is loaded.
- statistics_weightint
Bytes of the statistics power weight, non-negative.
- spatial_absorberint
Bytes of the composed radial absorber matrix, non-negative.
- Returns:
- dict
Buffer name to bytes, every row named even when it is zero.
- solprop.backends.memory.single_precision_rows(problem, rows)[source]#
Return the reference’s base rows for a single-precision problem.
SEP 33 section 6.1: the element sizes follow the precision. Every buffer the single-precision path holds in binary32 is half the reference’s; the rows of
_BINARY64_ROWSstay as they are; the narrowed copies of the source tables and the binary64 state the statistics widen are added.- Parameters:
- problemsolprop.translate.problem.KernelProblem
A single-precision problem.
- rowsdict
The reference’s rows, bytes.
- Returns:
- dict
The rows, bytes, with
single_tablesandsingle_widened_stateadded.
- solprop.backends.memory.z_table_slots(problem)[source]#
Return the position slots the native CPU build holds for a z table.
SEP 29 section 6.6: the native backend evaluates a z table at each native call’s distinct positions into term slots of the state’s size, which the stage weights then select. A Runge-Kutta trial reads the step’s start, its stage nodes and its end, so the tableau’s distinct fractions with 0 and 1; the low-storage march reads the start, the midpoint and the end, and a constant operator’s table interval, five at most; an Adams call reads two.
- Parameters:
- problemsolprop.translate.problem.KernelProblem
The translated problem.
- Returns:
- int
The slot count, at least two;
Phi’s and the prefactor’s tables share them.
Examples
>>> from solprop.backends.memory import z_table_slots >>> from solprop.grid import EnvelopeGrid >>> from solprop.nonlinear.gnlse import problem_from >>> from solprop.pulses import SechPulse >>> from solprop.stepper import PIController >>> from solprop.translate.problem import assemble >>> grid = EnvelopeGrid.from_limits(1.0, 835e-9, (500e-9, 2e-6), 1e-12) >>> gnlse = problem_from([0.0, 0.0, -1.183e-26], omega_ref=grid.omega0, ... gamma=0.11, shock=False) >>> start = SechPulse(wavelength=835e-9, width=100e-15, peak_power=9.8).build(grid) >>> problem = assemble(grid, gnlse.mode, [gnlse.kerr], start, ... controller=PIController(rtol=1e-8, atol=1e-16), ... save_planes=[0.01], dz_max=0.01, dz_init=1e-3, ... density=1.0, shock=False, prefactor_index=1.0) >>> z_table_slots(problem) # DOPRI5: 0, 1/5, 3/10, 4/5, 8/9 and 1 6