Skip to content

Extensibility

The extensibility API validates custom state-preserving transitions and builds conditioned SILVA equilibria from user-supplied initializer, transition, readout, and solver modules. See Extending SILVA for the equation-to-implementation derivation, family extension matrix, reproduction levels, and complete testing workflow.

Conditioned Equilibrium

Operational Contract

This API surface connects custom transition validation to the same SILVA experiment contract used by the learning pages and notebooks. Its central relation is

\[ T_\theta(z,c)\in\mathbb R^{B\times\cdots\times D}=\operatorname{shape}(z) \]
Part What must remain inspectable
State a caller-declared tensor state and condition bundle.
Condition one transition call preserves shape, device, dtype, finiteness, and a usable derivative path.
Diagnostic transition report followed by equilibrium residual and task gradient.
Replacement point the initializer, transition, readout, or complete conditioned equilibrium module.
Scale axes state shape, parameter count, solver, tolerance, backward mode, and condition size.

The relevant method lineage is recorded in the SILVA construction [1] and implicit-layer foundation [4]. Those references define the source mechanisms; this API exposes them through SILVA objects so a reader can inspect, replace, solve, differentiate, and scale the construction.

Complete Compact Study

Run the complete repository program below from the project root. The page uses the same file that is exercised by the test suite, so the displayed call is not an isolated fragment.

"""Inspect source-aware SILVA records and run a custom compact equilibrium."""

from __future__ import annotations

import torch
from torch import nn

from silva_networks import (
    SILVAConditionedEquilibrium,
    SILVAZeroInitializer,
    SolverConfig,
    audit_silva_reproduction_specs,
    silva_reproduction_spec,
    validate_silva_transition,
)


class AffineContractiveTransition(nn.Module):
    """Small replaceable transition with a declared contraction scale."""

    def __init__(self, input_dim: int, state_dim: int):
        super().__init__()
        self.source = nn.Linear(input_dim, state_dim)
        self.state = nn.Linear(state_dim, state_dim, bias=False)

    def forward(self, state: torch.Tensor, inputs: torch.Tensor) -> torch.Tensor:
        return torch.tanh(self.source(inputs) + 0.1 * self.state(state))


def main() -> None:
    """Run registry, transition-contract, equilibrium, and gradient checks."""

    torch.manual_seed(28)
    assert audit_silva_reproduction_specs() == ()
    for alias in ("fno_deq", "mignn", "pideq", "deq_ddim"):
        spec = silva_reproduction_spec(alias)
        print(spec.family, spec.source_relation, spec.verification_level)

    inputs = torch.randn(5, 2)
    state0 = torch.zeros(5, 4)
    transition = AffineContractiveTransition(2, 4)
    report = validate_silva_transition(transition, state0, inputs)
    assert report.valid

    model = SILVAConditionedEquilibrium(
        transition,
        SILVAZeroInitializer(4),
        readout=nn.Linear(4, 1),
        config=SolverConfig(
            solver="picard",
            max_iter=30,
            tol=1e-6,
            backward_mode="implicit",
            backward_solver="gmres",
            anderson_batch_dims=1,
        ),
    )
    result = model(inputs, return_result=True)
    result.output.square().mean().backward()

    assert result.output.shape == (5, 1)
    assert result.solver_result.residual < 1e-5
    assert all(parameter.grad is not None for parameter in model.parameters())
    print("transition report", report)
    print("equilibrium residual", result.solver_result.residual)


if __name__ == "__main__":
    main()
python examples/reproduction_registry.py

Measured Compact Output

silva_fno_deq paper-adaptation compact-verified
silva_monotone_graph_equilibrium paper-adaptation compact-verified
silva_physics_informed_equilibrium paper-adaptation compact-verified
diffusion_equilibrium paper-adaptation compact-verified
transition report SILVATransitionReport(state_shape=(5, 4), output_shape=(5, 4), preserves_shape=True, preserves_device=True, preserves_dtype=True, finite=True, differentiable=True, parameter_count=28)
equilibrium residual 1.095007249318769e-07

Interpret the Output

The transition report verifies the mechanical contract before a solver is involved. The subsequent residual then verifies the numerical fixed point, keeping module validity and solver convergence as separate checks.

For a controlled experiment, retain the compact call as a regression case and change one scale axis at a time. Record the resolved constructor, data source and split, preprocessing, seed, forward and backward solver settings, task metric, normalized residual, iteration count, runtime, peak memory, and any failed convergence case. A larger run becomes evidence only when its own resolved configuration and outputs are archived; the compact output above is evidence for the executable mechanism and its stated invariants.

Bases: Module

Build a SILVA family from user-supplied modules.

The transition must implement

\[ z^{+}=T_\theta(z, x),\qquad T_\theta:\mathcal Z\times\mathcal X\to\mathcal Z. \]

initializer maps the condition to an initial state and readout maps the converged state to the task output. This small wrapper is the common construction path beneath article-specific source, operator, and readout choices.

Source code in src/silva_networks/extensibility.py
class SILVAConditionedEquilibrium(nn.Module):
    r"""Build a SILVA family from user-supplied modules.

    The transition must implement

    $$
    z^{+}=T_\theta(z, x),\qquad T_\theta:\mathcal Z\times\mathcal X\to\mathcal Z.
    $$

    ``initializer`` maps the condition to an initial state and ``readout`` maps
    the converged state to the task output. This small wrapper is the common
    construction path beneath article-specific source, operator, and readout
    choices.
    """

    def __init__(
        self,
        transition: nn.Module,
        initializer: nn.Module,
        *,
        readout: nn.Module | None = None,
        config: SolverConfig | None = None,
    ):
        super().__init__()
        self.transition = transition
        self.initializer = initializer
        self.readout = readout or nn.Identity()
        self.config = config or SolverConfig(
            solver="anderson",
            max_iter=30,
            tol=1e-5,
            backward_mode="implicit",
            anderson_batch_dims=1,
        )

    def forward(
        self,
        condition: Tensor,
        *,
        z0: Tensor | None = None,
        return_result: bool = False,
    ) -> Tensor | SILVAConditionedOutput:
        if not condition.is_floating_point():
            raise TypeError("condition must have a floating-point dtype")
        initial = self.initializer(condition) if z0 is None else z0
        if not isinstance(initial, Tensor):
            raise TypeError("initializer must return a torch.Tensor")
        if initial.device != condition.device or initial.dtype != condition.dtype:
            raise ValueError("initial state must match condition device and dtype")

        def fixed_map(state: Tensor) -> Tensor:
            return self.transition(state, condition)

        result = solve_equilibrium(
            fixed_map,
            initial,
            self.config,
            params=tuple(self.transition.parameters()),
            tensors=(condition,),
        )
        output = self.readout(result.z)
        if not isinstance(output, Tensor):
            raise TypeError("readout must return a torch.Tensor")
        if return_result:
            return SILVAConditionedOutput(output, result.z, result)
        return output

Decoded output, equilibrium state, and solver diagnostics.

Source code in src/silva_networks/extensibility.py
@dataclass
class SILVAConditionedOutput:
    """Decoded output, equilibrium state, and solver diagnostics."""

    output: Tensor
    state: Tensor
    solver_result: SolverResult

Bases: Module

Create a zero equilibrium state from a conditioning tensor.

Source code in src/silva_networks/extensibility.py
class SILVAZeroInitializer(nn.Module):
    """Create a zero equilibrium state from a conditioning tensor."""

    def __init__(self, state_dim: int):
        super().__init__()
        if state_dim < 1:
            raise ValueError("state_dim must be positive")
        self.state_dim = state_dim

    def forward(self, condition: Tensor) -> Tensor:
        if condition.dim() < 1:
            raise ValueError("condition must include a batch dimension")
        return condition.new_zeros(*condition.shape[:-1], self.state_dim)

Transition Validation

Observed properties of one transition evaluation.

Source code in src/silva_networks/extensibility.py
@dataclass(frozen=True)
class SILVATransitionReport:
    """Observed properties of one transition evaluation."""

    state_shape: tuple[int, ...]
    output_shape: tuple[int, ...]
    preserves_shape: bool
    preserves_device: bool
    preserves_dtype: bool
    finite: bool
    differentiable: bool
    parameter_count: int

    @property
    def valid(self) -> bool:
        """Whether the transition satisfies the SILVA tensor contract."""

        return (
            self.preserves_shape
            and self.preserves_device
            and self.preserves_dtype
            and self.finite
            and self.differentiable
        )

valid property

valid

Whether the transition satisfies the SILVA tensor contract.

Evaluate shape, device, dtype, finiteness, and gradient compatibility.

A SILVA transition maps an equilibrium state back into the same tensor space. Conditions may have different shapes, but they must remain explicit arguments so the solver and implicit backward pass can track them.

Source code in src/silva_networks/extensibility.py
def inspect_silva_transition(
    transition: Callable[..., Tensor],
    state: Tensor,
    *conditions: Tensor,
) -> SILVATransitionReport:
    """Evaluate shape, device, dtype, finiteness, and gradient compatibility.

    A SILVA transition maps an equilibrium state back into the same tensor
    space. Conditions may have different shapes, but they must remain explicit
    arguments so the solver and implicit backward pass can track them.
    """

    if not isinstance(state, Tensor):
        raise TypeError("state must be a torch.Tensor")
    probe = state.detach().clone()
    if probe.is_floating_point() or probe.is_complex():
        probe.requires_grad_(True)
    output = transition(probe, *conditions)
    if not isinstance(output, Tensor):
        raise TypeError("transition must return a torch.Tensor")
    differentiable = bool(output.requires_grad)
    if differentiable:
        gradient = torch.autograd.grad(
            output.sum(),
            probe,
            allow_unused=True,
            retain_graph=False,
        )[0]
        differentiable = gradient is not None and bool(torch.isfinite(gradient).all())
    parameters = transition.parameters() if isinstance(transition, nn.Module) else ()
    return SILVATransitionReport(
        state_shape=tuple(state.shape),
        output_shape=tuple(output.shape),
        preserves_shape=output.shape == state.shape,
        preserves_device=output.device == state.device,
        preserves_dtype=output.dtype == state.dtype,
        finite=bool(torch.isfinite(output).all()),
        differentiable=differentiable,
        parameter_count=sum(parameter.numel() for parameter in parameters),
    )

Return a transition report or raise for a violated SILVA contract.

Source code in src/silva_networks/extensibility.py
def validate_silva_transition(
    transition: Callable[..., Tensor],
    state: Tensor,
    *conditions: Tensor,
) -> SILVATransitionReport:
    """Return a transition report or raise for a violated SILVA contract."""

    report = inspect_silva_transition(transition, state, *conditions)
    failures = []
    if not report.preserves_shape:
        failures.append(
            f"shape changed from {report.state_shape} to {report.output_shape}"
        )
    if not report.preserves_device:
        failures.append("device changed")
    if not report.preserves_dtype:
        failures.append("dtype changed")
    if not report.finite:
        failures.append("output contains a non-finite value")
    if not report.differentiable:
        failures.append("output is not differentiable with respect to the state")
    if failures:
        raise ValueError("invalid SILVA transition: " + "; ".join(failures))
    return report

Extension Contract

A custom transition is accepted when it returns a finite differentiable tensor with the same shape, device, and dtype as its input state. Family-specific wrappers may add invariants such as positivity, graph equivariance, boundary conditions, or multiscale structure. Passing the generic contract therefore does not replace the domain-specific tests described in each family tutorial.

Where to Go Next

Question Page
How is a complete custom family derived and tested? Extending SILVA
Where are all public signatures listed? API Reference
Which runnable program demonstrates custom modules? Custom Layers
How are compact and scaled validations executed? Run Everything