bayesmithDocumentation0.10.0 source

bayesmith.dispatch.task

Source-derived signatures and contracts. See the reference index for coverage and conventions.

Module contract
The bridge: a Graph and its plan, projected into artifacts (§0 ruling 5).

This orchestration adapter and its private identity projection connect runtime
objects -- a :class:`~bayesmith.graph.graph.Graph`, an
:class:`~bayesmith.dispatch.plan.InferencePlan`, a JAX array -- to the
artifact protocol. :mod:`bayesmith.artifacts` imports
neither the graph layer nor JAX. The Graph-to-artifact boundary stays within
dispatch.

**A manifest is what the artifacts layer hashes; the Graph never crosses.**
:func:`graph_manifest` and :func:`data_manifest` are re-exported here from
:mod:`bayesmith.dispatch._task_identity`. They read a Graph and return
canonical values -- strings, tuples, numpy
arrays -- which :func:`~bayesmith.artifacts.identity.fingerprint` then digests.
The split is the whole of §0 ruling 4 at this seam: the layer that knows what a
node is does not know what a digest is, and the layer that takes digests never
sees a node.

**The slots are independent or they are not slots.** An observed value, a mask
bit and a Const move the DATA slot; a parent order, a plate, a declared
``linear_in``, a support and the module-and-qualname of an operator move the
GRAPH_STRUCTURE slot; the model's own text moves MODEL_SOURCE alone. An array's
shape and dtype travel with its bytes, in the data slot, rather than being
restated in the structure one -- two slots answering for one input is how a
matrix of invalidation rules becomes a table of coincidences.

**A callable has no canonical form, and ``repr`` is not a fallback.** An
operator is identified by its module and qualname. Where those are missing --
a function built by ``exec``, one typed into a REPL -- the manifest writes a
placeholder rather than an address, and :func:`compile_task` refuses unless the
caller pinned the model themselves with a ``ModelRef`` source digest. An
address changes on every restart and stays put across a genuine edit, so a
digest that degraded to one would be wrong in both directions at once.

**A refusal's code comes from a structured field.** The adapters below read
``NotGaussian.reason``, ``NotLogLinear.reason`` and the ``verdict`` class
variable that :mod:`bayesmith.diagnose.map`'s results carry; a human message
is stored as a message and parsed by nothing.
:class:`~bayesmith.errors.AffinityRefused` is absent from that table on
purpose: it says a declared affinity claim is FALSE, which is a fault in the
model, and a fault adapted into "this route does not apply" is a broken
declaration wearing the schema of an ordinary fallback.

**Nothing here decides a number.** :func:`execute_task` calls
:meth:`~bayesmith.dispatch.plan.InferencePlan.sample`,
:meth:`~bayesmith.dispatch.plan.InferencePlan.estimate`,
:func:`~bayesmith.diagnose.map.map_estimate` or :func:`~bayesmith.optimize.fit`
exactly once, with the key it was given and no extra split, and projects what
comes back. The runtime defaults are READ from the signatures that own them
rather than restated here, so a default cannot drift into a second home.

PRODUCER

Defined in bayesmith.dispatch.task, line 183.

PRODUCER = ProducerRef(package='bayesmith', version=__version__)

SUPPORTED_BACKENDS

Defined in bayesmith.dispatch.task, line 190.

SUPPORTED_BACKENDS: frozenset[str] = frozenset({'auto'})

SUPPORTED_TASK_KINDS

Defined in bayesmith.dispatch.task, line 342.

SUPPORTED_TASK_KINDS: frozenset[TaskKind] = frozenset({TaskKind.POSTERIOR, TaskKind.POINT_ESTIMATE, TaskKind.PREDICTIVE, TaskKind.SIMULATION, TaskKind.EVIDENCE})

MAP_METHODS

Defined in bayesmith.dispatch.task, line 363.

MAP_METHODS: tuple[str, ...] = ('newton', 'adam', 'gradient')

graph_manifest

Defined in bayesmith.dispatch._task_identity, line 120.

graph_manifest(graph: Graph, model_ref: ModelRef) -> dict[str, Any]
What the GRAPH_STRUCTURE slot is taken over: the declaration, no values.

The model's identifier travels with it because a structure is somebody's
structure -- two models that happen to declare the same shape are two
models -- while the source digest and the build arguments stay in the
MODEL_SOURCE slot, so reformatting a model does not read as restructuring
it.

data_manifest

Defined in bayesmith.dispatch._task_identity, line 178.

data_manifest(graph: Graph, extra_data: tuple[tuple[str, Any], ...]=()) -> dict[str, Any]
What the DATA slot is taken over: every Const, observation and mask.

In declaration order, which is the graph's own topological order, plus any
``extra_data`` the caller conditions on that the graph does not carry. The
bytes are what is hashed, so a single flipped bit is a different data set
-- and so is the same array at a different dtype, which is why the bytes
are hashed rather than the values.

model_identity_gap

Defined in bayesmith.dispatch._task_identity, line 202.

model_identity_gap(graph: Graph, model_ref: ModelRef) -> tuple[str, ...]
The nodes whose operator this package cannot identify, or ``()``.

Empty whenever the caller pinned the model's own source: a ``ModelRef``
carrying a ``source_digest`` identifies the whole text the callables were
written in, which is the explicit answer §0.3 offers where
``inspect.getsource`` cannot serve.

input_fingerprints

Defined in bayesmith.dispatch._task_identity, line 226.

input_fingerprints(graph: Graph, task: Task, *, model_ref: ModelRef, extra_data: tuple[tuple[str, Any], ...]=()) -> FingerprintBundle
The four slots every artifact has, taken over this graph and this task.

``compilation``, ``evaluation`` and ``environment`` are left empty here:
nothing has been compiled, judged or run yet, and a slot holding a digest
of something that has not happened is worse than an empty one.

node_scope

Defined in bayesmith.dispatch.task, line 382.

node_scope(name: str) -> ScopeRef
The scope of a verdict about one node.

plan_ref

Defined in bayesmith.dispatch.task, line 391.

plan_ref(record: InferencePlanRecord) -> ArtifactRef
The version reference to a plan record: id AND revision (§0.2).

refusal_from_verdict

Defined in bayesmith.dispatch.task, line 678.

refusal_from_verdict(verdict: Any, *, task: Task, model_ref: ModelRef, fingerprints: FingerprintBundle, artifact_type: ArtifactKind=ArtifactKind.PLAN) -> Refusal
The typed :class:`~bayesmith.artifacts.refusal.Refusal` for a verdict.

By exact type, never by ``isinstance``: a subclass carries state this table
cannot see, and :class:`~bayesmith.errors.AffinityRefused` is exactly such a
subclass in the direction that matters -- adapting it would downgrade a
contradicted declaration into an ordinary "this route does not apply".

PlannedTask

Defined in bayesmith.dispatch.task, line 757.

class PlannedTask
task: Task
analysis: AnalysisReport
record: InferencePlanRecord
runtime_plan: InferencePlan | ProposalRuntimePlan = dataclasses.field(compare=False, repr=False)
A task, what compiling it concluded, and the plan that will run it.

``runtime_plan`` is out of the identity (``compare=False``) and out of the
repr: it is the live equinox module, and two plans compiled from one graph
are the same PLANNED TASK even though the objects underneath them are two.
It is also the one field here that is not an artifact, which is why it is
named for what it is rather than hidden behind a friendlier word.

compile_task

Defined in bayesmith.dispatch.task, line 1954.

compile_task(graph: Graph, task: Task, *, model_ref: ModelRef, key: jax.Array | None=None, extra_data: tuple[tuple[str, Any], ...]=()) -> PlannedTask | Refusal
Compile a task against a graph: a :class:`PlannedTask`, or a Refusal.

The refusals are verdicts a caller can branch on -- a task kind this
release does not answer, a backend it cannot dispatch to, an option it
would otherwise ignore, an operator it cannot identify, a point estimate
with no solve to be the estimate of. What is NOT a refusal is a fault: a
:class:`~bayesmith.errors.GraphError` or
:class:`~bayesmith.errors.StructureError` raised while the graph is read
travels out of here as an exception, because a contradicted declaration is
a broken model rather than a route that does not apply.

Args:
    graph: the model.
    task: one of the five §0.4 tasks.
    model_ref: what the graph was built from. Never the callable itself (§0
        ruling 4); see :func:`model_identity_gap` for when its
        ``source_digest`` is required rather than optional.
    key: PRNG key for the compile-time probes, passed through to
        :func:`~bayesmith.dispatch.plan.compile`. ``None`` leaves that
        function's own default in place, so a task compiled without a key
        and a graph compiled directly agree block for block.
    extra_data: data the caller conditions on that the graph does not
        carry, hashed into the DATA slot.

execute_task

Defined in bayesmith.dispatch.task, line 3104.

execute_task(planned: PlannedTask, *, key: jax.Array | None=None, source_posterior: PosteriorResult | None=None) -> Result | Refusal
Run a compiled task and project what came back into a Result.

One call to one seam, with the key it was given and no extra split, timed
from just before to just after. Nothing here decides a number: the method,
the tolerance, the budget and the fallback policy were all fixed by
:func:`compile_task` and by the plan it holds.

Args:
    planned: what :func:`compile_task` produced.
    key: the PRNG key a posterior, predictive or simulation run draws
        from. Required there, and unused by a point estimate -- which
        splits nothing, so its run record carries no seed rather than one
        it never consumed.
    source_posterior: the :class:`~bayesmith.artifacts.results.PosteriorResult`
        a predictive task pushes forward. Required for a predictive task
        and for a simulation task whose parameter source is a posterior
        result; in both, its id/revision and its data/graph/model
        fingerprints are checked against the task's before anything is
        generated.

Returns:
    A :class:`~bayesmith.artifacts.results.PosteriorResult`,
    :class:`~bayesmith.artifacts.results.PointEstimateResult`,
    :class:`~bayesmith.artifacts.results.PredictiveResult`,
    :class:`~bayesmith.artifacts.results.SimulationResult` or
    :class:`~bayesmith.artifacts.results.EvidenceResult`, or a
    :class:`~bayesmith.artifacts.refusal.Refusal` where the method turned
    out not to apply. A genuine execution failure --
    :class:`~bayesmith.errors.ConvergenceError` above all -- is raised, not
    refused: a run that broke is an ERROR for a workflow to mark, and
    filing it as "this method does not apply" would lose that distinction.

Type a concept or API name.