solprop.backends.numba_cpu.low_storage#

The low-storage RK4IP march’s register kernels and resident engine on numba_cpu.

SEP 24 phase 2 (docs/dev/seps/archive/sep-0024-low-storage-interaction-picture-runge-kutta.md, sections 4.3 and 6.6). NumbaLowStorage is the backend’s own LowStorageEngine: it holds the accumulator B and the stage register C beside the state A and, tabulating, the flow table, and makes a step’s four passes through the route’s own source pipeline with no Runge-Kutta buffer – no stage rows, accumulators, accept buffer, recycled stage, propagator pair or exponent.

Each pass is three parts:

  1. The input. One traversal reads one register, adds the modified noise draw at the pass’s position and writes the pipeline’s input: the padded modal spectrum, the general route’s coarse lab field, the Cartesian transverse scratch or the planar column volume. On the separable kinds the draw’s phase z Im D is formed per element from the operator’s one-dimensional arrays, so no rotated copy is held.

  2. The core. The route’s transforms, response columns and in-stage absorber, shared with the Runge-Kutta march (NumbaCpuBackend._free_pass and its siblings), leave the source in frequency.

  3. The finish. One traversal forms the source at each element (the prefactor, the window, the absorber term) and folds it into the registers with the half-step flows (define_bodies’ low_storage_fold). The flows come from the table or, on the separable kinds when recomputing, from the same per-element body that gives the prefactor. The last pass also writes one partial of the accepted state’s squared norm per column, summed by the engine.

The in-stage exchange (section 4.3). A Cartesian or line pass under an in-stage absorber evaluates twice from the same input, the material response and then the absorber’s term. The first finish folds the material source and, in the same traversal, re-forms the input in the transverse scratch from the register it came from, so the material output never needs a row of its own; the second finish folds the absorber’s term. The modal, general and planar routes form both terms from one input (the planar volume carries the absorber’s half), so their passes make one finish.

The elided stage register (Q4). A Cartesian or line pass that reads its input once – a material response and no in-stage absorber – needs no C: the finish of each of the first three passes writes the next pass’s input, noise and all, straight into the transverse scratch (S <- A + h/2 S + eta(z_m) and its siblings), which saves one state volume and the next pass’s input traversal (solprop.backends.memory.low_storage_stage_register()).

Kernels are specialised by closure constant where a flag decides what is read – the noise, the crop’s contiguity, the in-stage absorber term, the column threading – and take the pass, the fold mode, the term and the flow treatment as arguments: those branches are invariant over the traversal. The column loop is a prange in the parallel variants, which are never disk-cached (docs/dev/backends.md section 3.2); each element’s arithmetic is the same in either, and the norm is two-stage, one partial per column.

Functions

exponentiate_forward(exponent, out)

Form exp(dPhi) alone, from one real exp and one sincos.

exponentiate_terms(weights, terms, out)

Form exp(sum_t w_t Phi_t) per element, with no exponent array.

make_free_kernels(*, noise, parallel)

Compile the Cartesian and line routes' register input, finish and table.

make_modal_kernels(*, contiguous, noise, ...)

Compile the modal routes' register input and finish.

make_slab_kernels(*, noise, parallel)

Compile the hybrid planar route's register input, finish and table.

Classes

FreeKernels(input, fold, table)

The Cartesian and line routes' register input, finish and flow table.

ModalKernels(input, fold)

The modal and general routes' register input and finish.

NumbaLowStorage(backend, method)

The resident low-storage engine: the four register passes on the route's kernels.

SlabKernels(input, fold, table)

The hybrid planar route's register input, finish and flow table.

class solprop.backends.numba_cpu.low_storage.FreeKernels(input, fold, table)[source]#

Bases: NamedTuple

The Cartesian and line routes’ register input, finish and flow table.

Attributes:
inputcallable

One register plus the rotated noise, into the transverse scratch.

foldcallable

The material or absorber source folded into the registers, with the exchange’s re-formed input.

tablecallable

exp(distance D) at every element, one volume.

fold: Any#

Alias for field number 1

input: Any#

Alias for field number 0

table: Any#

Alias for field number 2

class solprop.backends.numba_cpu.low_storage.ModalKernels(input, fold)[source]#

Bases: NamedTuple

The modal and general routes’ register input and finish.

Attributes:
inputcallable

One register plus the drawn noise, padded onto the fine grid.

foldcallable

The source at each element folded into the registers.

fold: Any#

Alias for field number 1

input: Any#

Alias for field number 0

class solprop.backends.numba_cpu.low_storage.NumbaLowStorage(backend, method)[source]#

Bases: object

The resident low-storage engine: the four register passes on the route’s kernels.

numba_cpu’s LowStorageEngine (SEP 24 section 6.6): the backend’s state is A, updated in place, and this engine holds B, C (unless it is elided, Q4) and the flows, allocated at construction so that the backend’s ledger names them before the first step.

The flows. Tabulating a constant operator holds one volume, exp(h_t D / 2) for the key h_t of table_steps() (the step’s run’s mean, SEP 24 Q10), built from the operator’s origin as the host engine builds it and rebuilt only when the key changes. A varying modal operator’s P and Q are formed once per step into two held volumes. Recomputing, the Cartesian, line and planar finishes form exp(h D / 2) per element from the same body that gives the prefactor and hold nothing; a modal route forms the step’s P, then Q over it before pass 3, in one held scratch volume (low_storage_flow_scratch()). A modal flow is exponentiated per element from the terms of Phi (exponentiate_terms()), so no exponent array exists outside the ledger either.

The stiffness indicator (SEP 24 Q11, decided in phase 2) is not formed: stiffness is NaN, which silences the march’s warning. A resident engine holds F2 and F3 exactly but g1 and F2 only as 2 (C - A) / h, which on numpy_ref’s slopes agreed with the exact indicator to 1e-7 relative on a soliton and departed only on a nearly linear step, far below 2.785; but on the routes the march is for, the Cartesian and line kinds, C is elided (Q4) or the slope is split between the exchange’s two evaluations, and recovering it would take the volume the march exists to save. The phase 2 report records the measurement.

Parameters:
backendsolprop.backends.numba_cpu.backend.NumbaCpuBackend

The backend whose state, plans and route this engine steps.

methodsolprop.stepper.low_storage.LowStorageRungeKutta

The march.

Attributes:
stiffnessfloat

Always NaN: not formed on this backend.

atomicbool

Always False: each pass is its own compiled call, between which a signal may arrive.

close()[source]#

Release the registers and the flows.

held()[source]#

Return the bytes of every array the engine holds, by ledger row.

Returns:
dict

register_accumulator, register_stage and propagators (the table, a varying operator’s pair, or a recomputing modal route’s flow scratch), zero once close() ran.

reset()[source]#

Drop the flow table’s key: a resume builds it again from its own step.

step(z, dz)[source]#

Take one RK4IP step in four register passes, accepting it in place.

Parameters:
zfloat

Where the step starts, m.

dzfloat

The step, m, positive.

Returns:
float

The accepted state’s squared norm over the norm mask, before the boundary treatments.

class solprop.backends.numba_cpu.low_storage.SlabKernels(input, fold, table)[source]#

Bases: NamedTuple

The hybrid planar route’s register input, finish and flow table.

Attributes:
inputcallable

One register plus the rotated noise, into the column volume.

foldcallable

Both halves’ source folded into the registers.

tablecallable

exp(distance D) at every element, one volume.

fold: Any#

Alias for field number 1

input: Any#

Alias for field number 0

table: Any#

Alias for field number 2

solprop.backends.numba_cpu.low_storage.exponentiate_forward(exponent, out)[source]#

Form exp(dPhi) alone, from one real exp and one sincos.

Parameters:
exponentnumpy.ndarray

dPhi, complex, shape (n_columns, n_omega).

outnumpy.ndarray

Written with exp(dPhi); may be exponent itself.

solprop.backends.numba_cpu.low_storage.exponentiate_terms(weights, terms, out)[source]#

Form exp(sum_t w_t Phi_t) per element, with no exponent array.

The weighted sum is solprop.translate.stage.combine’s, accumulated element by element: a single term weighted by one is the term itself, and a single term’s product is one rounding, so a constant operator’s D (z1 - z0) is formed as there.

Parameters:
weightsnumpy.ndarray

The bundle’s phi_delta, float64, (n_terms,).

termsnumpy.ndarray

The terms of Phi, complex, (n_terms, n_columns, n_omega).

outnumpy.ndarray

Written with the flow, (n_columns, n_omega).

solprop.backends.numba_cpu.low_storage.make_free_kernels(*, noise, parallel)[source]#

Compile the Cartesian and line routes’ register input, finish and table.

Parameters:
noisebool

Whether the modified noise draw is added to every input.

parallelbool

Whether independent columns execute in parallel.

Returns:
FreeKernels

The compiled kernels.

solprop.backends.numba_cpu.low_storage.make_modal_kernels(*, contiguous, noise, absorber, parallel)[source]#

Compile the modal routes’ register input and finish.

Parameters:
contiguousbool

Whether the crop index is the leading block of the fine spectrum.

noisebool

Whether the modified noise draw is added to every input.

absorberbool

Whether the in-stage absorber’s term is added to the source.

parallelbool

Whether independent columns execute in parallel.

Returns:
ModalKernels

The compiled pair.

solprop.backends.numba_cpu.low_storage.make_slab_kernels(*, noise, parallel)[source]#

Compile the hybrid planar route’s register input, finish and table.

Parameters:
noisebool

Whether the modified noise draw is added to every input.

parallelbool

Whether independent columns execute in parallel.

Returns:
SlabKernels

The compiled kernels.