solprop.backends.host.driver#
The reference’s step loop, with the kernels left abstract (SEP 47).
March, replay, landing, controller bookkeeping, history, the noise model and the seam’s
set_initial/propagate_to/observe/close do not depend on how a stage is
evaluated: they touch the state and HostDriver._trial_step and nothing
else. Written once here, they are the step control of every NumPy reference backend.
The reference owns this loop since SEP 47 phase 2: HostDriver is a copy of
the inherited driver the native bridge still runs on
(solprop.backends.driver.StepDriver), so that the reference shares stateless
numerical modules – the controller cores, tableaux, coefficient evaluation and stage
tables – with that bridge, and transitionally the session lifecycle and the host
engines (the exceptions solprop.backends.host records). The copies started
identical; their decisions on identical inputs stay bit-identical (the decision traces
of tests/backends).
What a backend supplies is _trial_step, _apply_mask and stats, plus
_finish when it has boundary treatments of its own; two optional hooks,
_begin_plane and _on_accepted_step, are where a backend scores whatever a plane
or an accepted step leaves behind. The march owns the periodic statistics schedule.
Its default storage hooks call stats and retain host rows.
Module Attributes
Rows a plane's statistics buffer holds before it first has to grow. |
Functions
|
Return whether a march at |
|
Return how far a replayed schedule's edge may sit from a target it lands on, m. |
Classes
|
The interaction-picture step loop, with the stage evaluation left to a subclass. |
- class solprop.backends.host.driver.HostDriver(problem, request, *, grid=None, modes=None, profiles=None, options=None)[source]#
-
The interaction-picture step loop, with the stage evaluation left to a subclass.
A subclass supplies
_trial_stepand_apply_maskand gets the whole ofsolprop.backends.protocol.Backend’s marching behaviour: adaptive stepping with the controller ofdocs/dev/stepper.mdsection 3, replay of a contract’s fixed schedule, landing exactly on save planes and hard kinks, the step history, and both noise models,inputandmodified.The controller’s state is its own proposal, never the clipped or stretched step that was executed, and what the history and a rejection see is the norm the proposal would have scored while what decides acceptance is the error the executed step committed. Both are section 3’s, and both matter: the first costs a run hundreds of steps if it is got wrong, the second throws away short landing steps that were accurate.
- Parameters:
- problemsolprop.translate.problem.PropagationProblem
The validated problem to step. The subclass refuses what it cannot execute before calling this constructor.
- requestsolprop.translate.run_request.RunRequest
The run’s policies: the method, the error control, the itinerary, the planes and the statistics (SEP 47 section 5.2). The subclass checks it with the problem (
solprop.translate.problem.validate_run()) before calling this constructor; a session started on this backend serves a request that differs from it only in one run’s start, retention, monitor and history (for_run()).- gridsolprop.grid.TimeGrid, optional
The grid the state lives on, which the statistics need and the contract does not carry.
- modescollections.abc.Sequence, optional
The propagated modes, in state order, for the statistics that need them.
- profilescollections.abc.Mapping, optional
The z-profiles keyed by statistic name.
- optionssolprop.backends.session.ExecutionOptions, optional
The run’s execution options: an explicit node budget or an exact node chunk, from which the node chunk is planned here, before anything is allocated (
solprop.backends.node_chunk.plan_node_chunk()).Nonefor the automatic choice.
- Attributes:
- namestr
The registry name, set by the subclass and used in every log line.
- max_batchint
How many problems the backend steps at once.
- propagator_default{‘tabulate’, ‘recompute’}
What this backend resolves the contract’s
"auto"propagator mode to. The default suits a backend that evaluates two complex exponentials per stage; one that takes both signs from a singleexpandsincosoverrides it.- helperssolprop._helpers.Helpers
The implementation of the per-stage and per-step scalar evaluations – the stage tables’ Clenshaw rows and the Adams basis – which the driver, march and engines pass down rather than choosing one (SEP 29 section 6.6):
PLAIN, the uncompiled forms, for the NumPy reference.- observes_fresh_fieldbool
Whether
_observed_fieldmakes a new array at every call and keeps no reference to it, so thatobserve()can say its field is owned (solprop.backends.protocol.Observation.field_owned).Falseby default: the array-backed state is observed as it is, frozen, and left behind by the next step.
- attach_monitor(monitor)[source]#
Watch the time window’s edges from here on, starting with the current state.
The launch is recorded now; every committed step is then accounted at the same point as the periodic statistics rows (
_take_step_stats), on every march, after the state is finished and the position advanced.- Parameters:
- monitorsolprop.monitor.BoundaryMonitor
A monitor with nothing recorded.
- Raises:
- BackendError
If the monitor’s weights do not match the grid, or its columns the state.
- available_device_memory()[source]#
Return None for host execution; device backends report free bytes.
- Returns:
- int or None
None for the shared host implementation.
- property chunk_plan: NodeChunkPlan[source]#
Return the node-chunk plan and what chose it.
- Returns:
- solprop.backends.node_chunk.NodeChunkPlan
The plan made at construction.
- clear_halt()[source]#
Withdraw a halt requested with
request_halt(), once it is serviced.
- property closed: bool[source]#
Return whether the backend has released its buffers, as a failure may.
- Returns:
- bool
Truewhen it can run no other input.
- drain_attempts()[source]#
Drain the attempts recorded since the last observation, with no field.
For a state left in flight, which
observe()refuses: the attempts and periodic rows recorded before the abandoned step, drained once, as an observation drains them.- Returns:
- solprop.backends.protocol.Observation
The attempts and rows at
position, with no field.
- edge_memory(space)[source]#
Return what reading the edge holds in the state’s memory space.
What
solprop.driver.estimate.estimate()adds: it attaches no monitor.- Parameters:
- spaceobject
The run’s transverse grid.
- Returns:
- int
Zero by default: a read on the host holds nothing beside the state there.
- halt_ahead()[source]#
Halt the next march at the endpoint a dense observation held, if short.
The execution session’s snapshot latch beside interpolated planes (SEP 47 section 5.5): the march stands ahead of the plane it observed, at the end of the step that crossed it. When the next march restores that endpoint and the latch is set, it returns there at once, unless a step plane is owed there first or the target is another plane the step crossed, so that the snapshot is taken at that endpoint rather than wait for a step that crosses no plane.
- property halted: bool[source]#
Return whether the last march stopped at a requested halt short of its end.
- Returns:
- bool
True while the halt latch of
request_halt()or the yield check ofset_halt_check()stopped it.
- helpers: Helpers = Helpers(name='plain')#
- property holding_plane: bool[source]#
Return whether a dense observation holds the state between endpoints.
- Returns:
- bool
True while this driver’s own (a Runge-Kutta march’s) or its Adams march’s observation holds an interpolated plane, the march ahead of it.
- property in_flight: tuple[float, float] | None[source]#
Return the low-storage step a failure abandoned in flight, or
None.- Returns:
- tuple of float or None
The step’s start and length, m, while the state is neither of its ends (
solprop.backends.low_storage).
- march_export_refusal()[source]#
Return why this backend’s Adams march cannot carry its history, or
None.- Returns:
- str or None
The reason (
solprop.backends.host.adams.HostAdamsMarch.export_refusal()), orNonefor a march that exports and installs its history and for the Runge-Kutta and low-storage marches, which keep none.
- march_snapshot()[source]#
Return the Adams march’s state at the accepted position, for a resume.
- Returns:
- solprop.output.schema.MarchSnapshot or None
The snapshot, or
Nonefor the Runge-Kutta and low-storage marches and wherever the Adams march has nothing a resume could continue (solprop.backends.host.adams.HostAdamsMarch.snapshot()).
- Raises:
- BackendError
If a low-storage step was abandoned in flight.
- march_snapshot_nbytes(z)[source]#
Return the bytes
march_snapshot()would copy at z, copying nothing.- Parameters:
- zfloat
The position the snapshot is wanted at, m.
- Returns:
- int or None
The state and every engine row, or
Nonewhere a snapshot would beNoneor stand somewhere other than z.
- Raises:
- BackendError
If a low-storage step was abandoned in flight.
- metadata()[source]#
Return what this execution was, for the run’s record.
A saved run has to say what produced it: the thread configuration alone was measured to move one step by a factor of nine, so a result whose execution is not recorded is not reproducible. The base record is the name and the resolved propagator mode and, for Adams runs, cumulative logical source calls; the low-storage march’s evaluations are physical,
source_evaluations, neverresponse_calls(SEP 24 section 5); a backend with pools, plans or wisdom adds them.- Returns:
- dict
JSON-serialisable scalars, keyed by name.
- property node_chunk: int[source]#
Return the nodes a response pass of this backend holds at once.
- Returns:
- int
The planned chunk (
chunk_plan).
- observe(*, field=True)[source]#
Return the state at the current position, as host arrays.
The field is in the lab frame and the FFT convention (
spectral_convention = "fft"): the output layer conjugates it on the way to disk and the processing accessors on the way to a user. The step history covers everything since the previous call.With
field=False(SEP 22 section 5.1) neither the field nor the noise phase crosses to the host – a device backend copies nothing – and the observation carriesNonefor both. Nothing scans the field for finiteness then: the step loop accepts only finite error norms and a replay raises on a non-finite one. The spatial collar diagnostic, which reads the field, is not evaluated; the backend counts such planes inmetadata()and logs the first.- Parameters:
- fieldbool, optional
Whether the field and the noise phase cross to the host. Default
True.
- Returns:
- Observation
The field, the noise phase and the step history.
- Raises:
- BackendError
If the backend is closed or no initial state was loaded.
- property position: float[source]#
Return where the march stands, m.
- Returns:
- float
The committed state’s position, or the end of a step a group took but neither validated nor recorded, which leaves the state in flight (
in_flight).
- prepare(problem, request)[source]#
Prepare a run of this backend for one problem and request (SEP 47 5.2).
The backend lowered the method, the error control, the itinerary, the planes and the statistics where it was built; preparing binds the problem and the request a run serves – this backend’s own, or one run’s adaptation of it (
for_run()) – and each start of the result opens the reference’s own session (HostSession).- Parameters:
- problemsolprop.translate.problem.PropagationProblem
The translated problem: this backend’s, or one derived from it with another input (
solprop.driver.simulation.check_derived_problem()).- requestsolprop.translate.run_request.RunRequest
The run’s request.
- Returns:
- solprop.backends.session.PreparedExecution
The prepared execution.
- prepare_group(members, problems, requests)[source]#
Prepare a group of compatible members of this backend (SEP 47 section 6.7).
The reference’s own group (
HostGroupSession): its members advance in lockstep through one fixed schedule on the reference’s group runner (HostGrouporNumpyBatchBackend, chosen bysolprop.backends.registry.select_batch()).- Parameters:
- memberssequence of solprop.backends.protocol.Backend
One constructed backend per member, this one first.
- problemssequence of solprop.translate.problem.PropagationProblem
Each member’s independently translated problem.
- requestssequence of solprop.translate.run_request.RunRequest
Each member’s run request.
- Returns:
- solprop.backends.session.PreparedGroup
The prepared group.
- propagate_to(z)[source]#
Step the state to a position, landing on it exactly.
Adaptive by default and a replay when the contract carries a schedule. Either way the embedded estimate is computed and recorded every step, so a schedule too coarse for the tolerance it is scaled by is reported rather than silent (
docs/dev/stepper.mdsection 8). The low-storage march has no estimate: it replays its schedule and records 0.0, “not estimated” (SEP 24 section 6.3).- Parameters:
- zfloat
The save plane to reach, m, at or ahead of the current position and inside the operator table.
- Returns:
- StepSummary
What the call cost and achieved.
- Raises:
- BackendError
If the backend is closed, no initial state was loaded, a low-storage step was abandoned in flight, or
zis behind the current position or outside the table.- ConvergenceError
If the controller asks for a step below the contract’s
dz_min, or a replayed step’s error norm, or the low-storage march’s state, is not finite.
- reads_transverse_edge: bool = False#
Whether this backend reads a free-space run’s transverse edge on the host (SEP 40 section 5.3). A backend that does not leaves the run
unwatched, and says so before the first step.
- property request: RunRequest[source]#
Return the request this backend was built for.
- Returns:
- solprop.translate.run_request.RunRequest
Its method, error control, itinerary, planes and statistics; a run adapts it with
for_run().
- request_halt()[source]#
Stop the march at the next accepted endpoint short of its target.
The execution session’s snapshot latch (SEP 47 section 5.5):
propagate_toreturns at the end of the next accepted step, as at a natural stop, without counting it as one, so the session can service a snapshot there. An endpoint on the target itself is observed as the plane, and the latch stays set for the session to find.
- restore_call_ledgers(logical, atomic=None)[source]#
Restore shared Adams call counts without restoring numerical history.
Non-TDSE backends inherit logical budget persistence while refusing atomic counts. The caller first loads the saved field, which resets Adams history; the next source evaluation charges startup against these cumulative counts. A Runge-Kutta or low-storage march keeps no logical ledger, so nothing is installed for it.
- Parameters:
- logicalmapping
Persisted logical response counts; empty on ordinary RK runs.
- atomicmapping or None, optional
Persisted atomic counts; absent on non-TDSE runs.
- Raises:
- BackendError
If this backend is handed counters it does not implement.
- restore_march(snapshot)[source]#
Continue the Adams march from a snapshot at the loaded position.
Called after
set_initial()at the snapshot’s position. The state is replaced by the snapshot’s own, exactly as the interrupted run held it.- Parameters:
- snapshotsolprop.output.schema.MarchSnapshot
The snapshot a file holds.
- Returns:
- str or None
Nonewhen the history was continued, otherwise why the march starts afresh, as a resume did before snapshots were kept.
- set_halt_check(check)[source]#
Ask check at every accepted endpoint whether to halt there.
The execution session’s bounded yield (SEP 47 section 5.1): when check returns True the halt latch of
request_halt()is set, so the march returns at that endpoint. It is asked only at safe boundaries and changes nothing the march computes.- Parameters:
- checkcallable or None
Returns whether a yield is due;
Noneasks nothing.
- set_initial(field, noise, *, z=0.0, resume=False)[source]#
Load a state and the noise realisation at a position.
The state is masked to the active band once here, as the scaffold does: the operator and the prefactor are exactly zero outside it, so out-of-band content would neither propagate nor decay and would sit in the error norm for the whole run. The traditional
inputnoise model adds its realisation to the state at the run’s launch position and never again; themodifiedmodel keeps it apart and adds it at every stage, so the propagating field never carries it.A resume loads a state from a plane the run already saved, so it already carries whatever the
inputmodel added at the launch and must not be given a second realisation, and a replayed schedule continues from the edge that plane sits on. A z past the launch is always one. Position cannot tell for a file holding only its launch plane, which comes back at the launch itself: its caller says so with resume. The launch is the entrance unless the run starts inside the guide (SEP 37: an interior launch withinputnoise takes its draw there). The controller starts afresh fromdz_initeither way (docs/dev/stepper.mdsection 3).Everything else a march reads is restored too, so that a backend loaded again after a run – a
SimulationRunner’s, or after a failed run – repeats a fresh backend’s run (SEP 22 section 4.7): a dense observation’s look-ahead, an Adams march’s call ledger and last-rejection flag, a low-storage march’s source-evaluation count and the boundary monitor, with the collar it may have rested, here, and the quadrature alarm, whose value the entrance plane’squadrature_errorreads before any march, in the overrides of the backends that keep one. A resume restores its ledger afterwards (restore_call_ledgers()).Loading is the one entry that clears a low-storage step abandoned in flight (SEP 24 section 6.2): the state it holds is replaced, and the march’s flow table is rebuilt from the next step.
- Parameters:
- fieldnumpy.ndarray
The state in the canonical layout, complex, shape
(n_modes, n_pol, n_omega), in the square root of watts and the FFT convention.- noisesolprop.noise.NoiseRealisation or None
The realisation to carry along the run, or
Noneto take the one the problem was assembled with.- zfloat, optional
The position the state belongs to, m. Zero, the entrance, by default.
- resumebool, optional
Whether field came back from a saved plane of this run, and so never takes the
inputdraw, whatever z.Falseby default.
- Raises:
- BackendError
If the backend is closed, the field does not match the contract’s shape, z lies outside the operator table, or a schedule is being replayed and z is not one of its edges.
- set_progress(reporter)[source]#
Attach the reporter every attempted step is reported to.
The next call to
propagate_to()announces the run to it. Attaching a reporter changes nothing the propagation computes – the calls are observers, made after the step is decided – so a run with one is bitwise the run without.- Parameters:
- reportersolprop.log.ProgressReporter
Where the step events go;
solprop.log.NullReporterturns them off.
- set_stop(flag)[source]#
Attach the flag the march polls, or detach it with
None.A run polls its own flag before each trial (SEP 41, S17), where the state is the last accepted one, so a stop abandons nothing but the trial not yet taken. Polling changes nothing the propagation computes.
- Parameters:
- flagsolprop.log.StopFlag or None
Any object with an
is_set()method, such as athreading.Event.
- abstractmethod stats(spec)[source]#
Compute the requested statistics in one fused pass.
Declared here, not only on
solprop.backends.protocol.Backend, because the shared step loop calls it through the default row-storage hook. A device backend shares its statistic evaluator between this method and its device row-storage hook.- Parameters:
- specsolprop.stats.StatsSpec
Which statistics and which windows.
- Returns:
- dict
Small host arrays keyed by statistic name, without a batch axis.
- timing_probe(start)[source]#
Load a start and return single trials of this run’s march from it.
The start’s field, noise, position and resume flag are loaded as by
set_initial(); its method history, ledgers and monitor continuation are not read. A Runge-Kutta trial leaves the loaded state alone; a low-storage march’s step advances the discarded registers in place, so a backend probed so is closed afterwards (SEP 47 section 6.6).- Parameters:
- startsolprop.backends.session.Start
Where the trials start; its field is taken.
- Returns:
- solprop.backends.protocol.TimingProbe
The probe.
- solprop.backends.host.driver.INITIAL_STEP_STATS_CAPACITY = 64#
Rows a plane’s statistics buffer holds before it first has to grow.
- solprop.backends.host.driver.reached(position, target)[source]#
Return whether a march at
positionhas arrived attarget.- Parameters:
- positionfloat
Current position, m.
- targetfloat
Position being marched to, m.
- Returns:
- bool
True when no further step is due.
Examples
>>> from solprop.backends.host.driver import reached >>> reached(0.5, 1.0), reached(1.0, 1.0) (False, True)
- solprop.backends.host.driver.replay_tolerance(schedule, position)[source]#
Return how far a replayed schedule’s edge may sit from a target it lands on, m.
A schedule’s edges are the running sum of its steps, and a sum of
nrounded steps can drift from the position they were chosen to reach by aboutnulps:FixedSchedule(np.full(160, L / 160))ends 12 ulps short ofL. The slack is thereforeLANDING_ULPSor the step count, whichever is larger, in ulps of the larger of the position and the schedule’s length – still far inside the1e-9of the length thatvalidate()allows an edge to miss a save plane by, so no step is ever skipped.- Parameters:
- schedulesolprop.stepper.schedule.FixedSchedule
The schedule being replayed.
- positionfloat
The position the edge is compared with, m.
- Returns:
- float
The slack, m.
Examples
>>> import numpy as np >>> from solprop.backends.host.driver import replay_tolerance >>> from solprop.stepper.schedule import FixedSchedule >>> schedule = FixedSchedule(np.full(160, 1e-3 / 160)) >>> bool(1e-3 - schedule.z_end <= replay_tolerance(schedule, 1e-3)) True