solprop.backends.events#

The records an execution session hands its service loop (SEP 47 section 5.3).

A session (solprop.backends.session.RunSession) owns the numerical state of one trajectory. It runs until an external service is needed or a bounded yield falls due, and reports what happened as a short batch of immutable events. Events are completed work or explicit service requests; none of them is a second live controller. Four kinds exist, and the set is closed:

  • ObservationReady: a requested plane, its statistics and, while the batch is pending, an export ticket for its field;

  • ServiceRequired: an operation the caller must complete before the session advances further, such as delivering a warning or persisting a snapshot;

  • Progress: a bounded yield’s accounting, with no field;

  • Terminal: the outcome of the run, its committed position and whether that position can be resumed.

A batch (EventBatch) carries a Receipt. Acknowledging the receipt releases the batch’s resources, invalidates its tickets and lets the session advance across the barrier the batch ended at. A receipt is good once: acknowledging it twice, or acknowledging an older one, is refused, so no barrier is crossed twice.

Attempts are delivered exactly once, in chunks. Every event carries the attempts (BackendHistory) and periodic statistics rows (StepStats, without a batch axis) made since the previous event, whatever its kind – not since the previous observation. Each attempt and each row is in exactly one event’s chunk, so a session buffers at most the attempts of one bounded advance, and a full buffer yields a Progress rather than discarding records (SEP 47 section 5.3). A row’s step indexes the attempts of its own chunk. Wall times count from the start of their chunk.

The consumer assembles what spans several events: a saved plane’s history is the chunks since the previous observation, its own last (join_attempts()); a running checkpoint’s is the chunks since the previous observation up to and including the snapshot’s, which it includes without consuming, so the next plane still receives them; a terminal checkpoint’s is the chunks since the previous observation up to and including the terminal event’s (SEP 47 section 5.5).

Module Attributes

Event

One of the four event kinds of SEP 47 section 5.3.

Functions

emit_warning(event, *[, stacklevel])

Emit a warning barrier's warning through Python's warning machinery.

join_attempts(chunks)

Assemble consecutive chunks of attempts and rows into one record.

Classes

Eligibility(*values)

Whether a terminal position can be persisted as a resumable checkpoint.

EventBatch(receipt[, events])

The events one call to advance produced, ending at a barrier.

ExportTicket(receipt, generation, z[, member])

Names one field that a session can export while its batch is pending.

GroupBatch(receipt, members[, outcome, error])

What one call to a group's advance produced: one common schedule window.

ObservationKind(*values)

Why an observation was made.

ObservationReady(z, kind, plane_index, ...)

A requested plane, observed.

Outcome(*values)

How a session ended.

Progress(z, history[, step_stats])

A bounded yield: the attempts since the previous event, with no field.

Receipt(session, sequence)

Identifies one pending batch of events.

ServiceKind(*values)

What a ServiceRequired event asks of the caller.

ServiceRequired(kind, z, message[, ...])

An external operation that must complete before the session advances.

Terminal(outcome, z, eligibility[, error, ...])

The end of a session.

class solprop.backends.events.Eligibility(*values)[source]#

Bases: Enum

Whether a terminal position can be persisted as a resumable checkpoint.

Attributes:
ELIGIBLEstr

The committed state is valid; a checkpoint there resumes the run.

POISONEDstr

An in-place step failed mid-flight and left no valid state at the last accepted position (the low-storage march, SEP 24); resume only from an earlier persisted state.

ELIGIBLE = 'eligible'#
POISONED = 'poisoned'#
solprop.backends.events.Event = solprop.backends.events.ObservationReady | solprop.backends.events.ServiceRequired | solprop.backends.events.Progress | solprop.backends.events.Terminal#

One of the four event kinds of SEP 47 section 5.3.

class solprop.backends.events.EventBatch(receipt, events=<factory>)[source]#

Bases: object

The events one call to advance produced, ending at a barrier.

Attributes:
receiptReceipt

Acknowledge it to release the batch and cross its barrier.

eventstuple

The events, in committed order. At most one carries a field-bearing observation or service request; the rest are field-free.

events: tuple[ObservationReady | ServiceRequired | Progress | Terminal, ...]#
receipt: Receipt#
property terminal: Terminal | None[source]#

Return the batch’s terminal event, if it ended the session.

Returns:
Terminal or None

The last event when it is terminal; None otherwise.

class solprop.backends.events.ExportTicket(receipt, generation, z, member=None)[source]#

Bases: object

Names one field that a session can export while its batch is pending.

A ticket keys an export by committed state generation, so that every consumer of the same payload – the output, a plane observer, a checkpoint – shares one detached result (SEP 47 section 5.4). It is valid until its batch is acknowledged.

Attributes:
receiptReceipt

The batch the ticket belongs to.

generationint

The committed state generation (or dense observation) the field is taken from.

zfloat

Position of that state, m.

memberint or None

The group member whose field it names (a GroupSession’s ticket, whose members share one batch and generation); None for a lone session’s.

generation: int#
member: int | None = None#
receipt: Receipt#
z: float#
class solprop.backends.events.GroupBatch(receipt, members, outcome=None, error=None)[source]#

Bases: object

What one call to a group’s advance produced: one common schedule window.

A group (solprop.backends.session.GroupSession) advances its members through one shared fixed schedule. Each member keeps its own events: its observations, with its own attempts and statistics and a ticket for its field, and its own terminal outcome (SEP 47 section 6.7).

Attributes:
receiptReceipt

Acknowledge it to release the window and advance to the next.

memberstuple of tuple

Each member’s events in member order, in committed order; empty for a member that ended in an earlier window.

outcomeOutcome or None

The group’s own outcome when the batch ends it: COMPLETED once the schedule is run, whatever each member’s outcome; FAILED or STOPPED when a group-wide failure or stop ended every member still running. None otherwise.

errorBaseException or None

A group-wide failure’s primary error, carried also by each such member’s Terminal; None otherwise.

error: BaseException | None = None#
members: tuple[tuple[ObservationReady | ServiceRequired | Progress | Terminal, ...], ...]#
outcome: Outcome | None = None#
receipt: Receipt#
class solprop.backends.events.ObservationKind(*values)[source]#

Bases: Enum

Why an observation was made.

Attributes:
LAUNCHstr

The entrance plane, before the first step.

PLANEstr

A requested save plane, reached exactly or interpolated (dense output).

STEPstr

The endpoint of every step_planes-th accepted step.

NATURALstr

A natural stop short of the requested plane (SEP 14), saved as a plane.

LAUNCH = 'launch'#
NATURAL = 'natural'#
PLANE = 'plane'#
STEP = 'step'#
class solprop.backends.events.ObservationReady(z, kind, plane_index, history, step_stats, stats, summary, ticket)[source]#

Bases: object

A requested plane, observed.

Attributes:
zfloat

Position of the plane, m.

kindObservationKind

Why it was observed.

plane_indexint

The index of the save plane this observation answers, into the request’s save planes; -1 for the launch plane.

historysolprop.backends.protocol.BackendHistory

Every attempt since the previous event, accepted and rejected: the last chunk of the plane’s history (module docstring).

step_statssolprop.backends.protocol.StepStats

The periodic statistics rows sampled since the previous event, likewise.

statscollections.abc.Mapping

The plane’s statistics by catalogue name, without a row or batch axis.

summarysolprop.backends.protocol.StepSummary

The cost and tolerance of the propagation that reached this plane.

ticketExportTicket

The plane’s field, exportable while this batch is pending.

history: BackendHistory#
kind: ObservationKind#
plane_index: int#
stats: Mapping[str, ndarray]#
step_stats: StepStats#
summary: StepSummary#
ticket: ExportTicket#
z: float#
class solprop.backends.events.Outcome(*values)[source]#

Bases: Enum

How a session ended.

Attributes:
COMPLETEDstr

Every requested plane was observed and the final checks passed.

STOPPEDstr

A stop request was honoured at a safe boundary.

FAILEDstr

Propagation failed; Terminal.error carries the diagnostic.

COMPLETED = 'completed'#
FAILED = 'failed'#
STOPPED = 'stopped'#
class solprop.backends.events.Progress(z, history, step_stats=<factory>)[source]#

Bases: object

A bounded yield: the attempts since the previous event, with no field.

Attributes:
zfloat

Committed position, m.

historysolprop.backends.protocol.BackendHistory

The attempts made since the previous event, delivered here once; the consumer keeps them for the next plane (module docstring). Delivery changes nothing numerical.

step_statssolprop.backends.protocol.StepStats

The periodic rows sampled since the previous event, likewise.

history: BackendHistory#
step_stats: StepStats#
z: float#
class solprop.backends.events.Receipt(session, sequence)[source]#

Bases: object

Identifies one pending batch of events.

Attributes:
sessionint

The issuing session’s identity, so that a receipt cannot be acknowledged on another session.

sequenceint

The batch’s position in its session, from 1, strictly increasing.

sequence: int#
session: int#
class solprop.backends.events.ServiceKind(*values)[source]#

Bases: Enum

What a ServiceRequired event asks of the caller.

Attributes:
WARNINGstr

Emit a warning through Python’s warning machinery. Under the caller’s warning filters it may become an exception, so it is a barrier before propagation continues (SEP 47 section 5.5).

SNAPSHOTstr

Persist a running checkpoint at this accepted endpoint and copy the snapshot the caller requested (SEP 47 section 5.5).

SNAPSHOT = 'snapshot'#
WARNING = 'warning'#
class solprop.backends.events.ServiceRequired(kind, z, message, category=None, ticket=None, history=None, step_stats=None, warning=None)[source]#

Bases: object

An external operation that must complete before the session advances.

Attributes:
kindServiceKind

What is asked.

zfloat

The committed position the request arises at, m.

messagestr

For a warning, its text; otherwise a short description.

categorytype[Warning] or None

For a warning, its category; None otherwise.

ticketExportTicket or None

For a snapshot, the committed field to persist; for a warning, the committed field a failure checkpoint persists should the warning be raised; None otherwise.

historysolprop.backends.protocol.BackendHistory or None

For a snapshot or a warning, the attempts since the previous event: the last chunk of a checkpoint’s history there, which includes the chunks since the previous observation without consuming them (SEP 47 section 5.5). None otherwise.

step_statssolprop.backends.protocol.StepStats or None

For a snapshot or a warning, the periodic rows since the previous event, likewise.

warningWarning or None

For a warning, the instance to emit, with every attribute its issuer gives it (emit_warning()); None to emit category with message.

category: type[Warning] | None = None#
history: BackendHistory | None = None#
kind: ServiceKind#
message: str#
step_stats: StepStats | None = None#
ticket: ExportTicket | None = None#
warning: Warning | None = None#
z: float#
class solprop.backends.events.Terminal(outcome, z, eligibility, error=None, ticket=None, history=None, step_stats=None)[source]#

Bases: object

The end of a session.

Attributes:
outcomeOutcome

How it ended.

zfloat

The last committed position, m.

eligibilityEligibility

Whether a checkpoint at z would resume the run.

errorBaseException or None

The primary failure, for Outcome.FAILED; None otherwise.

ticketExportTicket or None

The committed field at z, exportable for a terminal checkpoint while the batch is pending; None when the state is poisoned.

historysolprop.backends.protocol.BackendHistory or None

The attempts since the previous event: the last chunk of a terminal checkpoint’s history, which carries every chunk since the previous observation (module docstring). Delivered also for a poisoned state, whose attempts before the abandoned one were made all the same.

step_statssolprop.backends.protocol.StepStats or None

The periodic rows since the previous event, likewise.

eligibility: Eligibility#
error: BaseException | None = None#
history: BackendHistory | None = None#
outcome: Outcome#
step_stats: StepStats | None = None#
ticket: ExportTicket | None = None#
z: float#
solprop.backends.events.emit_warning(event, *, stacklevel=2)[source]#

Emit a warning barrier’s warning through Python’s warning machinery.

The caller’s filters apply: one that raises it raises it here, at the barrier, and the run ends at that committed endpoint (SEP 47 section 5.5). The warning is the event’s own instance where it carries one, so that it reaches the filters and the caller exactly as its issuer would have warned.

Parameters:
eventServiceRequired

A ServiceKind.WARNING request.

stacklevelint, optional

As for warnings.warn(), counted from the caller of this function.

Raises:
ValueError

If event is not a warning.

Examples

>>> import warnings
>>> from solprop.backends.events import ServiceKind, ServiceRequired, emit_warning
>>> event = ServiceRequired(ServiceKind.WARNING, 0.0, "edge", UserWarning)
>>> with warnings.catch_warnings(record=True) as caught:
...     warnings.simplefilter("always")
...     emit_warning(event)
>>> str(caught[0].message)
'edge'
solprop.backends.events.join_attempts(chunks)[source]#

Assemble consecutive chunks of attempts and rows into one record.

The consumer’s half of exactly-once chunked delivery (module docstring): a plane’s or a checkpoint’s history is its chunks in delivery order. Each row’s step is offset by the attempts of the chunks before its own, and each chunk’s wall times by the last wall time assembled before it, so the record reads as one span.

Parameters:
chunksiterable

(history, rows) per event, in delivery order; None for an event that carries none.

Returns:
tuple

The assembled history and rows (rows without a batch axis).

Examples

>>> import numpy as np
>>> from solprop.backends.events import join_attempts
>>> from solprop.backends.protocol import BackendHistory, StepStats
>>> def chunk(z, wall):
...     n = len(z)
...     history = BackendHistory(np.array(z), np.full(n, 0.1), np.zeros(n),
...                              np.ones(n, bool), np.array(wall))
...     rows = StepStats(np.array(z[-1:]), np.array([n - 1]),
...                      {"energy": np.array([1.0])})
...     return history, rows
>>> first, second = chunk([0.1, 0.2], [1.0, 2.0]), chunk([0.3], [1.0])
>>> history, rows = join_attempts([first, second])
>>> history.wall_time.tolist(), rows.step.tolist()
([1.0, 2.0, 3.0], [1, 2])