solprop.backends.session#
The execution-session contract between solprop and a backend (SEP 47 section 5).
Python constructs and validates the scientific problem
(solprop.translate.problem.PropagationProblem) and resolves every run policy
into an immutable solprop.translate.run_request.RunRequest. A backend prepares
them once (SessionBackend.prepare(), which every backend offers as
Backend.prepare), and the prepared execution starts one
RunSession per trajectory. The session is the only owner of that trajectory’s
mutable numerical state: the field, the method’s history, the controller and monitor,
the counters and cursors, and the pending events. Python’s service loop
(solprop.driver.service) advances it, services the events it yields – files,
callbacks, warnings, progress – and acknowledges them:
prepared = backend.prepare(problem, request)
with prepared.start(start, stop=token) as session:
while not session.finished:
batch = session.advance(work_limit=256, deadline=0.1)
service(batch)
session.acknowledge(batch.receipt)
Yields are exact transport no-ops (SEP 47 section 5.1): the attempt bound, the deadline, the event capacity and the timing of acknowledgments change when control returns, never the numerical state or the control trace.
Event storage is bounded (SEP 47 section 5.3): every event delivers, exactly once,
the attempts and periodic rows made since the previous event – a yield’s
Progress as much as an observation, a snapshot or
the terminal event – and a row’s step indexes its own chunk’s attempts. A session
therefore buffers no more than one advance’s attempts, and the service loop, not the
session, assembles a plane’s or a checkpoint’s history from the chunks
(solprop.backends.events.join_attempts()). The status counts every attempt once,
as it is drained.
Control requests travel separately from the immutable request: a thread-safe
StopToken asks for a stop at the next safe boundary, and
RunSession.request_snapshot() latches a snapshot for the next eligible accepted
endpoint (SEP 47 section 5.5).
A GroupSession advances compatible trajectories through one common fixed
schedule, a window at a time, and reports each member’s own events and outcome (SEP 47
section 6.7). A backend prepares its own group the same way, from the group’s first
member (PreparedGroup):
prepared = members[0].prepare_group(members, problems, requests)
with prepared.start(starts, stop=token) as group:
...
SessionLedger is the lifecycle bookkeeping every Python session shares:
receipts, the pending barrier, closing and poisoning. It holds no numerical state.
Module Attributes
Attempts one |
|
Host seconds after which |
Functions
|
Refuse a group's inputs that no group implementation starts from. |
|
Refuse a group ticket presented for another member than the one it names. |
|
Return an integral, positive budget or chunk as an |
|
Return why no executor computes some of a problem's statistics, or |
Classes
|
Execution choices that are not part of the numerical problem. |
|
Compatible trajectories advanced together through one common fixed schedule. |
|
A backend's lowering of one problem and request, reusable across sessions. |
|
A backend's preparation of a group of compatible members (SEP 47 section 6.7). |
|
One trajectory's numerical execution, owned by its backend. |
|
A backend that prepares executions (SEP 47 section 6.1). |
The lifecycle bookkeeping of a Python session; no numerical state. |
|
|
Where a session is in its lifecycle. |
|
A compact, read-only view of a session, for reporting. |
|
Identifies a snapshot request until it is fulfilled or refused. |
|
Where a session starts: an initial state, or a checkpoint being resumed. |
A thread-safe request to stop a run at its next safe boundary. |
Exceptions
|
A session was used outside its lifecycle. |
- solprop.backends.session.DEFAULT_DEADLINE = 0.1#
Host seconds after which
advanceyields at its next safe boundary, s.
- solprop.backends.session.DEFAULT_WORK_LIMIT = 256#
Attempts one
advancemakes at most before yielding, as the native marches do.Python signal handlers run only between native calls, so a bounded return keeps a long run interruptible (SEP 47 section 5.5).
- class solprop.backends.session.ExecutionOptions(node_budget=None, node_chunk=None, backend_options=<factory>)[source]#
Bases:
objectExecution choices that are not part of the numerical problem.
Two runs may share their scientific description while differing in these (SEP 47 section 4.3). They are recorded as execution metadata, never compared by a restart.
- Attributes:
- node_budgetint or None
An explicit workspace budget for node chunks, bytes: any integral value (
operator.index, a NumPy integer too), held as anint.Noneleaves the backend’s automatic choice. An explicit budget is authoritative: the backend plans its chunk from it and no machine rule overrides it (solprop.backends.node_chunk.plan_node_chunk()).- node_chunkint or None
An exact node chunk, integral and held as an
int, which overrides both the budget and the automatic choice: a measurement’s or a test’s control, not a user setting. A backend takes at most every node, and on the planar kind whole transverse rows.- backend_optionscollections.abc.Mapping
Backend-specific execution options, passed through untouched (for example a native CPU execution record).
- Raises:
- solprop.exceptions.BackendError
If node_budget or node_chunk is given and is not a positive integer.
Examples
>>> from solprop.backends.session import ExecutionOptions >>> ExecutionOptions(node_budget=2**26).node_budget 67108864
- property budget: int | None[source]#
Return the explicit node budget as an
int, orNone.- Returns:
- int or None
node_budget, which construction already made anint.
- property chunk: int | None[source]#
Return the exact node chunk as an
int, orNone.- Returns:
- int or None
node_chunk, which construction already made anint.
- node_budget: int | SupportsIndex | None = None#
- node_chunk: int | SupportsIndex | None = None#
- class solprop.backends.session.GroupSession(*args, **kwargs)[source]#
Bases:
ProtocolCompatible trajectories advanced together through one common fixed schedule.
A group request is a sequence of independently translated member problems that pass the compatibility predicate a batched scan groups its points by; the common schedule’s maximum error norm is a diagnostic only (SEP 47 section 6.7). Each
advance()runs every member still running through the next common schedule window – to the next save plane – and reports each member’s own events (GroupBatch):with group: while not group.finished: batch = group.advance() service(batch) # each member's planes and outcome group.acknowledge(batch.receipt)
Failure. A boundary error, or a boundary warning raised as an error, ends that member alone with a
Terminal, and the others go on. A non-finite error norm, a step floor, a trial exception or an in-flight failure ends the group: every member still running ends with the same error. Members are stepped in turn, so earlier members may already have advanced the failed scheduled step: each terminal reports that member’s actual committed position and checkpoint eligibility, and no common cursor or rollback is invented. A group-wide stop request ends every running member at a common accepted endpoint.- acknowledge(receipt)[source]#
Release a window’s batch and allow advancing past it.
- Parameters:
- receiptsolprop.backends.events.Receipt
The batch’s receipt.
- execution_record(member)[source]#
Return one member’s execution facts.
- Parameters:
- memberint
The member’s index, from zero.
- Returns:
- collections.abc.Mapping
The member’s execution record.
- export(member, ticket, recipe, out=None)[source]#
Fill a destination with one member’s converted field at a pending ticket.
- Parameters:
- memberint
The member’s index, from zero.
- ticketsolprop.backends.events.ExportTicket
The member’s pending ticket.
- recipesolprop.backends.export.ExportRecipe
The conversion.
- outnumpy.ndarray or None, optional
The destination; a new array by default.
- Returns:
- numpy.ndarray
The filled destination.
- member_status(member)[source]#
Return one member’s committed position, counters and outcome.
- Parameters:
- memberint
The member’s index, from zero.
- Returns:
- SessionStatus
The member’s status.
- class solprop.backends.session.PreparedExecution(*args, **kwargs)[source]#
Bases:
ProtocolA backend’s lowering of one problem and request, reusable across sessions.
- start(start, *, listener=None, started=None, stop=None, owns=True)[source]#
Start a session from an initial state or a checkpoint.
- Parameters:
- startStart
The initial state or checkpoint the session starts from.
- listenercallable or None, optional
Called with each attempt’s end, length and acceptance as it is made, for a progress reporter; it observes only.
- startedcallable or None, optional
Called with the start, the end and the plane count when propagation begins.
- stopsolprop.log.StopFlag or None, optional
The run’s stop token.
- ownsbool, optional
Whether closing the session closes the backend.
- class solprop.backends.session.PreparedGroup(*args, **kwargs)[source]#
Bases:
ProtocolA backend’s preparation of a group of compatible members (SEP 47 section 6.7).
The group’s counterpart of
PreparedExecution: a backend returns it fromprepare_group(), and itsstart()opens the backend’s ownGroupSession, so thatsolprop.backends.sessions.start_group()names no backend.- start(starts, *, stop=None)[source]#
Start the group, each member from its entrance.
- Parameters:
- startscollections.abc.Sequence of Start
Each member’s entrance, in member order; the group takes their fields.
- stopsolprop.log.StopFlag or None, optional
A group-wide stop token.
- Returns:
- GroupSession
The started group, which owns the members once it is constructed; a start that fails leaves them to the caller.
- class solprop.backends.session.RunSession(*args, **kwargs)[source]#
Bases:
ProtocolOne trajectory’s numerical execution, owned by its backend.
See
solprop.backends.sessionfor the loop that drives it.- acknowledge(receipt)[source]#
Release a batch and allow advancing across its barrier.
- Parameters:
- receiptsolprop.backends.events.Receipt
The pending batch’s receipt.
- advance(*, work_limit=256, deadline=0.1)[source]#
Run until a barrier, the attempt bound or the deadline, and report it.
- Parameters:
- work_limitint, optional
Attempts before a yield.
- deadlinefloat, optional
Host seconds before a yield, s.
- continue_monitor(continuation)[source]#
Continue a resumed run’s boundary-monitor record, before it watches the run.
As
Start.monitor, for a service loop that reads the earlier execution’s record from its output after the session started.- Parameters:
- continuationcollections.abc.Mapping
The continuation, as
Start.monitorholds it.
- export(ticket, recipe, out=None)[source]#
Fill a destination with a pending observation’s converted field.
- Parameters:
- ticketsolprop.backends.events.ExportTicket
The pending observation’s ticket.
- recipesolprop.backends.export.ExportRecipe
The conversion.
- outnumpy.ndarray or None, optional
The destination; a new array by default.
- march_export_refusal()[source]#
Return why the method history cannot be exported, or
Nonewhen it can.
- march_snapshot(ticket)[source]#
Return the method history at a pending observation, when retained.
- Parameters:
- ticketsolprop.backends.events.ExportTicket
The pending observation’s ticket.
- march_snapshot_nbytes()[source]#
Return the size a method-history snapshot would have, without making it.
- noise_phase(ticket)[source]#
Return the noise phase at a pending observation, when a noise model runs.
- Parameters:
- ticketsolprop.backends.events.ExportTicket
The pending observation’s ticket.
- pending_ticket()[source]#
Return a ticket for the committed state after a failure outside the session.
Nonewhen nothing can be exported: the session is closed or poisoned, or no batch is pending to bind the ticket to.
- undelivered(ticket)[source]#
Deliver the attempts and rows made since the previous event, once.
For a terminal checkpoint after a failure outside the session, whose attempts no event delivered; empty when every attempt was delivered.
- Parameters:
- ticketsolprop.backends.events.ExportTicket
The checkpoint’s ticket.
- Returns:
- tuple
The attempts and the periodic rows.
- class solprop.backends.session.SessionBackend(*args, **kwargs)[source]#
Bases:
ProtocolA backend that prepares executions (SEP 47 section 6.1).
Every
Backendis one: it is built for a problem and a request (solprop.backends.registry.select()), andpreparebinds the problem and the request one run serves.
- exception solprop.backends.session.SessionError(*args, parameter=None, rule=None)[source]#
Bases:
BackendErrorA session was used outside its lifecycle.
Raised for a stale or foreign receipt, an advance across an unacknowledged barrier, use after close or after a terminal outcome, or an export with an expired ticket.
- class solprop.backends.session.SessionLedger[source]#
Bases:
objectThe lifecycle bookkeeping of a Python session; no numerical state.
It issues receipts, records the pending barrier, refuses stale or foreign receipts and advancing across an unacknowledged barrier, and remembers whether the session finished, failed or closed.
Examples
>>> from solprop.backends.session import SessionLedger >>> ledger = SessionLedger() >>> receipt = ledger.issue() >>> ledger.ticket_valid(receipt) True >>> ledger.acknowledge(receipt) >>> ledger.ticket_valid(receipt) False
- acknowledge(receipt)[source]#
Accept the pending batch’s receipt.
- Parameters:
- receiptsolprop.backends.events.Receipt
The receipt to acknowledge.
- Raises:
- SessionError
If the receipt is not the pending one: foreign, stale or repeated.
- check_advance()[source]#
Refuse to advance a session that is pending, finished or closed.
- Raises:
- SessionError
Naming the state that forbids it.
- check_ticket(ticket)[source]#
Refuse an export with an expired or foreign ticket.
- Parameters:
- ticketsolprop.backends.events.ExportTicket
The ticket presented.
- Raises:
- SessionError
If its batch is no longer pending.
- close()[source]#
Mark the session closed.
- Returns:
- bool
True the first time, False when it was already closed.
- property finished: bool[source]#
Return whether a terminal batch was issued.
- Returns:
- bool
True once the session yielded its terminal event.
- issue(*, outcome=None)[source]#
Issue the receipt of a new pending batch.
- Parameters:
- outcomesolprop.backends.events.Outcome or None, optional
The batch’s terminal outcome, when it ends the session.
- Returns:
- solprop.backends.events.Receipt
The batch’s receipt.
- class solprop.backends.session.SessionState(*values)[source]#
Bases:
EnumWhere a session is in its lifecycle.
- Attributes:
- READYstr
It can advance.
- PENDINGstr
A batch is out; it advances again once that batch is acknowledged.
- FINISHEDstr
It yielded a terminal event; nothing more can happen but close.
- CLOSEDstr
Its resources are released.
- CLOSED = 'closed'#
- FINISHED = 'finished'#
- PENDING = 'pending'#
- READY = 'ready'#
- class solprop.backends.session.SessionStatus(z, plane_index, attempts, rejected, state, outcome=None)[source]#
Bases:
objectA compact, read-only view of a session, for reporting.
- Attributes:
- zfloat
The committed position, m.
- plane_indexint
The next save plane to observe.
- attemptsint
Attempts made, accepted and rejected.
- rejectedint
Rejected attempts among them.
- stateSessionState
Lifecycle state.
- outcomesolprop.backends.events.Outcome or None
The terminal outcome, once finished.
- state: SessionState#
- class solprop.backends.session.SnapshotReceipt(request, coalesced)[source]#
Bases:
objectIdentifies a snapshot request until it is fulfilled or refused.
- Attributes:
- requestint
Sequence number of the request in its session, from 1.
- coalescedbool
Whether it joined an equivalent request still outstanding, so that one snapshot fulfils both (SEP 47 section 5.5 makes coalescing explicit).
- class solprop.backends.session.Start(field, z, noise=None, plane_index=0, march=None, ledgers=None, monitor=None, plane_pending=True, resume=False)[source]#
Bases:
objectWhere a session starts: an initial state, or a checkpoint being resumed.
A start is handed to one session, which takes its field (
take_field()): the session loads a copy made once at start, and the start forgets the array, so an input that nothing else holds – a runner’s caller’s array – is released before the first step rather than held through the run by every frame that passed the start along (SEP 47 section 5.4).- Attributes:
- fieldnumpy.ndarray or None
The state in internal amplitude units and the FFT convention, complex, shape
(n_modes, n_pol, n_omega);Noneonce a session took it. Mutating the caller’s array after the start changes nothing.- zfloat
Its position, m.
- noisesolprop.noise.NoiseRealisation or None
The run’s noise realisation, when a noise model is active.
- plane_indexint
The first save plane strictly beyond z.
- marchsolprop.output.schema.MarchSnapshot or None
A method history to restore, when resuming one that was retained.
- ledgerscollections.abc.Mapping or None
Persisted call ledgers to restore (TDSE and budgeted sources).
- monitorcollections.abc.Mapping or None
When resuming a monitored run, the monitor’s continuation:
"record", its persisted record;"plane", whether the resumed position is a saved plane;"unwatched", the spans the earlier executions left unwatched.- plane_pendingbool
Whether the plane at z is owed (the launch plane of a fresh run, or a resumed position whose plane was not saved).
- resumebool
Whether field was loaded from a plane the run already saved, so that an
inputnoise realisation is not added a second time.
- classmethod entrance(problem, *, noise=None)[source]#
Return the fresh start of a problem: its launch state, its launch plane owed.
- Parameters:
- problemsolprop.translate.problem.PropagationProblem
The translated problem.
- noisesolprop.noise.NoiseRealisation or None, optional
A realisation to carry instead of the one the problem was assembled with.
- Returns:
- Start
The start at
problem.initial.z, before the first save plane.
- march: MarchSnapshot | None = None#
- noise: NoiseRealisation | None = None#
- class solprop.backends.session.StopToken[source]#
Bases:
objectA thread-safe request to stop a run at its next safe boundary.
Setting it from any thread – a GUI’s stop button, a signal handler on the main thread, a scan’s supervisor – asks every session attached to it to finish the attempt in hand, complete that endpoint’s mandatory accounting, and end with
STOPPED(SEP 47 section 5.5). It implementssolprop.log.StopFlag.Examples
>>> from solprop.backends.session import StopToken >>> token = StopToken() >>> token.is_set() False >>> token.set() >>> token.is_set() True
- attach(listener)[source]#
Call listener whenever the token is set, and now if it already is.
Native sessions attach the store of their own atomic flag, so that a stop set from another thread reaches a march that holds no Python lock.
- Parameters:
- listenercallable
Called with no arguments. It must not raise and must not block.
- Returns:
- callable
Detaches the listener.
- solprop.backends.session.check_group(count, problems, requests, starts)[source]#
Refuse a group’s inputs that no group implementation starts from.
A group (
GroupSession) takes one problem, request and start per member, and starts every member at its entrance, with no method history or monitor record to continue (SEP 47 section 6.7).- Parameters:
- countint
The members given.
- problemscollections.abc.Sequence of solprop.translate.problem.PropagationProblem
Each member’s problem.
- requestscollections.abc.Sequence of solprop.translate.run_request.RunRequest
Each member’s run request.
- startscollections.abc.Sequence of Start
Each member’s start.
- Raises:
- SessionError
If the sequences differ in length or are empty, or if a start is not a fresh entrance whose launch plane is owed.
- solprop.exceptions.BackendError
If a member asks for statistics its problem does not carry (
statistics_unavailable()).
- solprop.backends.session.check_member_ticket(ticket, member)[source]#
Refuse a group ticket presented for another member than the one it names.
- Parameters:
- ticketsolprop.backends.events.ExportTicket
A ticket of a group’s pending batch.
- memberint
The member it is presented for.
- Raises:
- SessionError
If the ticket names another member, or none.
- solprop.backends.session.positive_count(name, value)[source]#
Return an integral, positive budget or chunk as an
int.- Parameters:
- namestr
"node_budget"or"node_chunk", for the message.- valueobject
Anything
operator.indexaccepts, such as anintor a NumPy integer.
- Returns:
- int
The value.
- Raises:
- solprop.exceptions.BackendError
If value is a
bool, not integral, or not positive.
Examples
>>> import numpy as np >>> from solprop.backends.session import positive_count >>> positive_count("node_budget", np.int64(2**26)) 67108864
Return why no executor computes some of a problem’s statistics, or
None.What the problem does not carry, refused by name before any session starts, on every executor (SEP 47 section 6.3), rather than at the first plane: a modal statistic of a spatial route, a spatial statistic of a modal one, the plasma integration diagnostics of a problem without the field-grid plasma column (SEP 18), and the electron density or the peak ionisation rate of a problem with no compiled plasma response. The messages are the reference’s at its first plane.
- Parameters:
- problemsolprop.translate.problem.PropagationProblem
The translated problem.
- namescollections.abc.Sequence of str
The statistics asked for, at planes or between them.
- Returns:
- str or None
The refusal, or
None.
Examples
>>> from solprop.backends.session import statistics_unavailable >>> from solprop.driver import Simulation >>> simulation = Simulation.from_gnlse( ... 0.11, 0.01, [0.0, 0.0, -1.183e-26], wavelength=835e-9, ... wavelength_limits=(500e-9, 2e-6), trange=1e-12, ... width=100e-15, peak_power=9.8, shape="sech", ... ) >>> problem = simulation.translate() >>> statistics_unavailable(problem, ["energy"]) is None True >>> statistics_unavailable(problem, ["beam_radius"]) "the 'beam_radius' statistic requires spatial geometry"