Skip to content

contracts

contracts

Backend capability contracts and prepared-session vocabulary.

This module is the single source of truth for how Q2MM talks to a computational backend (MM or reference). It defines:

  • :class:BackendRole / :class:Capability / :class:BackendInfo / :class:BackendProvenance — the vocabulary a backend uses to declare what it can do. Capabilities and functional forms both default to empty; every backend must explicitly enumerate every operation and functional form it supports.
  • Immutable, typed preparation and evaluation requests, and typed, canonical-unit results. Requests defensively copy their arrays to read-only in __post_init__; results defensively copy and shape-validate their arrays in __post_init__, so direct construction is safe regardless of the producing backend. Every result carries an explicit unit enum and a :class:BackendProvenance.
  • Typed errors: :class:BackendUnavailableError, :class:BackendConfigurationError, :class:PreparationError, :class:UnsupportedCapabilityError, :class:EvaluationError — there is no broad silent fallback.
  • The :class:Backend / :class:PreparedBackend lifecycle protocols and the :class:AbstractPreparedBackend base that enforces capability checks, request-family/role validation, and full-vector dimension validation. A concrete backend exposes only info and prepare (plus clearly backend-specific serialization/config); the prepared session is the only evaluation surface.
  • Side-effect-free registry :class:BackendDescriptor (which carries static capability and functional-form ceilings) / :class:DependencyProbe plumbing used by :mod:q2mm.backends.registry.

Canonical unit contracts (results always carry these units):

  • MM energy: kcal/mol (:attr:EnergyUnit.KCAL_PER_MOL); reference energy: Hartree (:attr:EnergyUnit.HARTREE) — must match :class:BackendRole.
  • Geometry: Å (:attr:LengthUnit.ANGSTROM).
  • Hessian: Hartree/Bohr² (:attr:HessianUnit.HARTREE_PER_BOHR2).
  • Frequency: cm⁻¹ (:attr:FrequencyUnit.INVERSE_CM).
  • Parameter gradients have length exactly len(ParameterLayout).

These contracts are the stable public authoring surface for BACKEND_API_VERSION == 1.

BackendRole

Bases: str, Enum

Whether a backend computes molecular-mechanics or reference data.

Capability

Bases: str, Enum

A discrete operation a backend may declare that it supports.

A backend that lists a capability in its :class:BackendInfo must implement the corresponding prepared-session method; a backend that does not list it must raise :class:UnsupportedCapabilityError when the method is called.

EnergyUnit

Bases: str, Enum

Explicit canonical energy unit for a result.

LengthUnit

Bases: str, Enum

Explicit canonical length unit for coordinates.

HessianUnit

Bases: str, Enum

Explicit canonical Hessian unit (atomic units).

FrequencyUnit

Bases: str, Enum

Explicit canonical vibrational-frequency unit.

CoordinateGradientUnit

Bases: str, Enum

Explicit canonical Cartesian coordinate-gradient unit.

BackendProvenance dataclass

BackendProvenance(backend: str, role: BackendRole, version: str = '', details: Mapping[str, object] = dict())

Immutable record of which backend produced a result and how.

Parameters:

Name Type Description Default
backend str

Registry key of the backend (e.g. "openmm", "jax").

required
role BackendRole

Whether the producing backend is MM or reference.

required
version str

Backend library version string if known (else "").

''
details Mapping[str, object]

Structured JSON-safe implementation, model, calculator, configuration, driver, platform, native-provenance, schema, or conversion details.

dict()

BackendInfo dataclass

BackendInfo(name: str, role: BackendRole, capabilities: frozenset[Capability] = frozenset(), functional_forms: frozenset[str] = frozenset(), provenance: BackendProvenance | None = None)

Immutable capability declaration for a backend.

Both :attr:capabilities and :attr:functional_forms default to the empty set: a backend must explicitly declare every operation and every functional form it supports. Nothing is inferred.

Parameters:

Name Type Description Default
name str

Human-readable backend name (e.g. "OpenMM").

required
role BackendRole

MM or reference.

required
capabilities frozenset[Capability]

Operations the backend supports.

frozenset()
functional_forms frozenset[str]

:class:~q2mm.models.forcefield.FunctionalForm values (as strings) the backend can evaluate. Empty for reference backends, which do not consume force fields.

frozenset()
provenance BackendProvenance | None

Canonical provenance stamped onto every result.

None

supports

supports(capability: Capability) -> bool

Return True if capability is declared by this backend.

Source code in q2mm/backends/contracts.py
def supports(self, capability: Capability) -> bool:
    """Return ``True`` if *capability* is declared by this backend."""
    return capability in self.capabilities

supports_form

supports_form(form: str) -> bool

Return True if functional-form string form is supported.

Source code in q2mm/backends/contracts.py
def supports_form(self, form: str) -> bool:
    """Return ``True`` if functional-form string *form* is supported."""
    return form in self.functional_forms

matches

matches(other: BackendInfo) -> bool

Return True if role, capabilities, and functional forms agree.

Compares :attr:role, :attr:capabilities, and :attr:functional_forms only; the human-readable :attr:name and the :attr:provenance are intentionally ignored. Descriptor loading checks the runtime provenance's registry key/role separately (see :meth:BackendDescriptor.load).

Source code in q2mm/backends/contracts.py
def matches(self, other: BackendInfo) -> bool:
    """Return ``True`` if role, capabilities, and functional forms agree.

    Compares :attr:`role`, :attr:`capabilities`, and
    :attr:`functional_forms` only; the human-readable :attr:`name` and the
    :attr:`provenance` are intentionally ignored.  Descriptor loading checks
    the runtime provenance's registry key/role separately (see
    :meth:`BackendDescriptor.load`).
    """
    return (
        self.role is other.role
        and self.capabilities == other.capabilities
        and self.functional_forms == other.functional_forms
    )

BackendError

Bases: RuntimeError

Base class for all typed backend errors.

BackendUnavailableError

Bases: BackendError

A backend's native dependencies are not installed/importable.

BackendConfigurationError

Bases: BackendError

A backend is installed but mis-configured (bad option, missing path).

PreparationError

Bases: BackendError

Building a prepared session for a training case failed.

UnsupportedCapabilityError

UnsupportedCapabilityError(backend: str, capability: Capability)

Bases: BackendError

A prepared session was asked for an operation it does not declare.

Source code in q2mm/backends/contracts.py
def __init__(self, backend: str, capability: Capability) -> None:
    self.backend = backend
    self.capability = capability
    super().__init__(f"Backend {backend!r} does not support capability {capability.value!r}.")

EvaluationError

Bases: BackendError

A prepared-session evaluation failed at runtime.

PreparationRequest dataclass

PreparationRequest(case_id: str, molecule: Molecule, force_field: ForceField | None = None, options: Mapping[str, object] = dict())

Immutable request to build a prepared session for one training case.

Parameters:

Name Type Description Default
case_id str

Stable, non-empty identifier for the training case. Exactly one prepared session is built per case_id.

required
molecule Molecule

The molecule (with reference geometry) to prepare.

required
force_field ForceField | None

Base force field (MM backends only; None for reference). The prepared session derives its :class:ParameterLayout from this force field and owns both.

None
options Mapping[str, object]

Backend-specific preparation options (string keys). Copied to an immutable mapping proxy (keys preserved, values deep-frozen) so caller mutation after construction has no effect.

dict()

EnergyRequest dataclass

EnergyRequest(parameters: ndarray)

Single-point energy for a full parameter vector.

MinimizationRequest dataclass

MinimizationRequest(parameters: ndarray, max_iterations: int | None = None, tolerance: float | None = None)

Energy-minimize (relax) the geometry for a full parameter vector.

Parameters:

Name Type Description Default
parameters ndarray

Full parameter vector.

required
max_iterations int | None

Maximum minimizer iterations, or None to use the backend's native default (preserves per-backend defaults).

None
tolerance float | None

Convergence tolerance in the backend's native units, or None to use the backend's native default.

None

HessianRequest dataclass

HessianRequest(parameters: ndarray)

Cartesian Hessian for a full parameter vector.

FrequencyRequest dataclass

FrequencyRequest(parameters: ndarray, on_error: str = 'raise')

Vibrational frequencies for a full parameter vector.

Parameters:

Name Type Description Default
parameters ndarray

Full parameter vector.

required
on_error str

Forwarded to :func:~q2mm.models.hessian.hessian_to_frequencies.

'raise'

ParameterGradientRequest dataclass

ParameterGradientRequest(parameters: ndarray)

Energy plus analytical dE/dp for a full parameter vector.

HessianJacobianRequest dataclass

HessianJacobianRequest(parameters: ndarray)

Hessian plus its analytical dH/dp Jacobian for a full vector.

BatchedEnergyRequest dataclass

BatchedEnergyRequest(parameter_matrix: ndarray)

Energies for a batch of full parameter vectors.

Parameters:

Name Type Description Default
parameter_matrix ndarray

Shape (batch, len(layout)) parameter vectors.

required

BatchedHessianRequest dataclass

BatchedHessianRequest(parameters: ndarray)

Cartesian Hessians for a batch of topology-compatible prepared cases.

Carries one full parameter vector applied to every case in the batch; the batch object owns the compatible cases and their coordinates. No force field crosses this boundary.

Parameters:

Name Type Description Default
parameters ndarray

Full parameter vector (length len(layout)).

required

ReferenceEnergyRequest dataclass

ReferenceEnergyRequest()

Single-point reference energy request.

ReferenceHessianRequest dataclass

ReferenceHessianRequest()

Reference Hessian request.

ReferenceFrequencyRequest dataclass

ReferenceFrequencyRequest()

Reference vibrational-frequency request.

ReferenceGeometryOptimizationRequest dataclass

ReferenceGeometryOptimizationRequest(opt_type: str = 'min')

Reference geometry optimization request.

Parameters:

Name Type Description Default
opt_type str

"min" for a minimum, "ts" for a transition state.

'min'

ReferenceCoordinateGradientRequest dataclass

ReferenceCoordinateGradientRequest()

Reference Cartesian coordinate-gradient request.

EnergyResult dataclass

EnergyResult(energy: float, unit: EnergyUnit, provenance: BackendProvenance)

Single-point energy in a canonical unit.

Parameters:

Name Type Description Default
energy float

Energy value.

required
unit EnergyUnit

Explicit canonical unit (kcal/mol for MM, Hartree for reference).

required
provenance BackendProvenance

Producing backend.

required

GeometryResult dataclass

GeometryResult(energy: float, energy_unit: EnergyUnit, symbols: tuple[str, ...], coordinates: ndarray, coordinate_unit: LengthUnit, provenance: BackendProvenance)

Optimized geometry and its energy.

Parameters:

Name Type Description Default
energy float

Energy at the optimized geometry.

required
energy_unit EnergyUnit

Canonical energy unit.

required
symbols tuple[str, ...]

Element symbols, length N.

required
coordinates ndarray

(N, 3) coordinates (read-only, defensive copy).

required
coordinate_unit LengthUnit

Canonical length unit (Å).

required
provenance BackendProvenance

Producing backend.

required

HessianResult dataclass

HessianResult(hessian: ndarray, unit: HessianUnit, provenance: BackendProvenance)

Cartesian Hessian in atomic units.

Parameters:

Name Type Description Default
hessian ndarray

(3N, 3N) Hessian (read-only, defensive copy).

required
unit HessianUnit

Canonical Hessian unit.

required
provenance BackendProvenance

Producing backend.

required

hessian_provenance property

hessian_provenance: HessianProvenance

Return molecule-level atomic-unit provenance for this Hessian.

FrequencyResult dataclass

FrequencyResult(frequencies: ndarray, unit: FrequencyUnit, provenance: BackendProvenance)

Vibrational frequencies.

Parameters:

Name Type Description Default
frequencies ndarray

Array of frequencies (read-only, defensive copy). Values are finite; a fully-penalized region uses the finite :data:~q2mm.models.hessian.PENALTY_FREQUENCY sentinel (still finite), never NaN/Inf.

required
unit FrequencyUnit

Canonical frequency unit.

required
provenance BackendProvenance

Producing backend.

required

ParameterGradientResult dataclass

ParameterGradientResult(energy: float, gradient: ndarray, unit: EnergyUnit, provenance: BackendProvenance)

Energy plus analytical parameter gradient.

Parameters:

Name Type Description Default
energy float

Energy value.

required
gradient ndarray

dE/dp of length exactly len(layout) (read-only copy).

required
unit EnergyUnit

Canonical energy unit borne by energy and gradient.

required
provenance BackendProvenance

Producing backend.

required

CoordinateGradientResult dataclass

CoordinateGradientResult(gradient: ndarray, unit: CoordinateGradientUnit, provenance: BackendProvenance)

Reference Cartesian coordinate gradient in Hartree/Bohr.

HessianJacobianResult dataclass

HessianJacobianResult(hessian: ndarray, jacobian: ndarray, unit: HessianUnit, provenance: BackendProvenance)

Hessian plus its analytical parameter Jacobian.

Parameters:

Name Type Description Default
hessian ndarray

(3N, 3N) Hessian (read-only copy).

required
jacobian ndarray

(3N, 3N, len(layout)) Jacobian (read-only copy).

required
unit HessianUnit

Canonical Hessian unit borne by both.

required
provenance BackendProvenance

Producing backend.

required

BatchedEnergyResult dataclass

BatchedEnergyResult(energies: ndarray, unit: EnergyUnit, provenance: BackendProvenance)

Energies for a batch of parameter vectors.

Parameters:

Name Type Description Default
energies ndarray

(batch,) energies (read-only copy).

required
unit EnergyUnit

Canonical energy unit.

required
provenance BackendProvenance

Producing backend.

required

BatchedHessianResult dataclass

BatchedHessianResult(case_ids: tuple[str, ...], hessians: ndarray, unit: HessianUnit, provenance: BackendProvenance)

Cartesian Hessians for a batch of topology-compatible cases.

Produced by a typed batch object (e.g. PreparedJaxBatch) evaluated for one full parameter vector. Each row corresponds to one prepared case, in the same order as :attr:case_ids.

Parameters:

Name Type Description Default
case_ids tuple[str, ...]

Stable case IDs, one per batched case (order matches rows).

required
hessians ndarray

(n_cases, 3N, 3N) Hessians (read-only copy).

required
unit HessianUnit

Canonical Hessian unit.

required
provenance BackendProvenance

Producing backend.

required

PreparedBackend

Bases: Protocol

One prepared session for one stable training case.

A prepared session owns its molecule, base force field, parameter layout, and any reusable native state. Evaluation requests carry validated full parameter vectors/matrices; the session never accepts a ForceField or a native handle across the boundary. Any operation not declared in :attr:info raises :class:UnsupportedCapabilityError.

info property

Backend capability declaration.

case_id property

case_id: str

Stable training-case identifier.

molecule property

molecule: Molecule

The molecule owned by this session.

energy

Single-point energy.

Source code in q2mm/backends/contracts.py
def energy(self, request: EnergyRequest | ReferenceEnergyRequest) -> EnergyResult:
    """Single-point energy."""
    ...

minimize

minimize(request: MinimizationRequest) -> GeometryResult

Energy-minimize (MM).

Source code in q2mm/backends/contracts.py
def minimize(self, request: MinimizationRequest) -> GeometryResult:
    """Energy-minimize (MM)."""
    ...

optimize_geometry

Geometry-optimize a reference structure.

Source code in q2mm/backends/contracts.py
def optimize_geometry(self, request: ReferenceGeometryOptimizationRequest) -> GeometryResult:
    """Geometry-optimize a reference structure."""
    ...

hessian

Cartesian Hessian.

Source code in q2mm/backends/contracts.py
def hessian(self, request: HessianRequest | ReferenceHessianRequest) -> HessianResult:
    """Cartesian Hessian."""
    ...

frequencies

Vibrational frequencies.

Source code in q2mm/backends/contracts.py
def frequencies(self, request: FrequencyRequest | ReferenceFrequencyRequest) -> FrequencyResult:
    """Vibrational frequencies."""
    ...

parameter_gradient

parameter_gradient(request: ParameterGradientRequest) -> ParameterGradientResult

Energy plus parameter gradient (MM).

Source code in q2mm/backends/contracts.py
def parameter_gradient(self, request: ParameterGradientRequest) -> ParameterGradientResult:
    """Energy plus parameter gradient (MM)."""
    ...

coordinate_gradient

Compute a reference Cartesian coordinate gradient.

Source code in q2mm/backends/contracts.py
def coordinate_gradient(self, request: ReferenceCoordinateGradientRequest) -> CoordinateGradientResult:
    """Compute a reference Cartesian coordinate gradient."""
    ...

hessian_parameter_jacobian

hessian_parameter_jacobian(request: HessianJacobianRequest) -> HessianJacobianResult

Hessian plus its parameter Jacobian (MM).

Source code in q2mm/backends/contracts.py
def hessian_parameter_jacobian(self, request: HessianJacobianRequest) -> HessianJacobianResult:
    """Hessian plus its parameter Jacobian (MM)."""
    ...

batched_energy

batched_energy(request: BatchedEnergyRequest) -> BatchedEnergyResult

Energies for a batch of vectors (MM).

Source code in q2mm/backends/contracts.py
def batched_energy(self, request: BatchedEnergyRequest) -> BatchedEnergyResult:
    """Energies for a batch of vectors (MM)."""
    ...

Backend

Bases: Protocol

A backend factory that prepares per-case sessions.

A concrete backend exposes only :attr:info and :meth:prepare as its generic surface (plus clearly backend-specific serialization/config where unavoidable). All evaluation happens through the returned :class:PreparedBackend.

info property

Backend capability declaration.

prepare

prepare(request: PreparationRequest) -> PreparedBackend

Build a prepared session for one training case.

Source code in q2mm/backends/contracts.py
def prepare(self, request: PreparationRequest) -> PreparedBackend:
    """Build a prepared session for one training case."""
    ...

PreparedHessianBatch

Bases: Protocol

A typed batch of topology-compatible prepared cases (Hessian batching).

The batch shares one compiled/native evaluation kernel internally while each member case keeps its own coordinates/native state. Its only evaluation surface is :meth:hessians, which takes a typed :class:BatchedHessianRequest (one full parameter vector applied to every member) and returns a typed :class:BatchedHessianResult.

case_ids property

case_ids: tuple[str, ...]

Stable case IDs of the batched members, in result-row order.

hessians

Per-case Cartesian Hessians for one full parameter vector.

Source code in q2mm/backends/contracts.py
def hessians(self, request: BatchedHessianRequest) -> BatchedHessianResult:
    """Per-case Cartesian Hessians for one full parameter vector."""
    ...

HessianBatchPreparer

Bases: Protocol

Optional backend surface that groups prepared sessions into batches.

A backend declaring :attr:Capability.BATCHED_HESSIAN must implement this protocol. It groups topology-compatible prepared sessions into typed :class:PreparedHessianBatch objects; the concrete grouping/compilation is backend-specific and never crosses this boundary.

prepare_hessian_batches

prepare_hessian_batches(sessions: Sequence[PreparedBackend]) -> list[PreparedHessianBatch]

Group sessions into topology-compatible Hessian batches.

Source code in q2mm/backends/contracts.py
def prepare_hessian_batches(self, sessions: Sequence[PreparedBackend]) -> list[PreparedHessianBatch]:
    """Group *sessions* into topology-compatible Hessian batches."""
    ...

AbstractPreparedBackend

AbstractPreparedBackend(*, info: BackendInfo, case_id: str, molecule: Molecule, force_field: ForceField | None, layout: ParameterLayout | None)

Bases: ABC

Base that enforces capability, request-family, and vector validation.

Concrete prepared sessions override the _energy / _minimize / … hooks for the capabilities they declare. The public methods verify the capability is declared, that the request family matches the backend role, that request parameter vectors have exactly len(layout) finite entries, and that returned energy units match the role.

Source code in q2mm/backends/contracts.py
def __init__(
    self,
    *,
    info: BackendInfo,
    case_id: str,
    molecule: Molecule,
    force_field: ForceField | None,
    layout: ParameterLayout | None,
) -> None:
    if not isinstance(case_id, str) or not case_id:
        raise PreparationError("Prepared session case_id must be a non-empty string.")
    self._info = info
    self._case_id = case_id
    self._molecule = molecule
    self._force_field = force_field
    self._layout = layout

info property

Immutable capability declaration for the owning backend.

case_id property

case_id: str

Stable training-case identifier this session was prepared for.

molecule property

molecule: Molecule

The molecule owned by this prepared session.

force_field property

force_field: ForceField

The base force field owned by this prepared session.

layout property

The parameter layout derived from the base force field.

energy

Single-point energy in the backend's canonical unit.

Source code in q2mm/backends/contracts.py
def energy(self, request: EnergyRequest | ReferenceEnergyRequest) -> EnergyResult:
    """Single-point energy in the backend's canonical unit."""
    self._require(Capability.ENERGY)
    self._require_exact_request(
        request,
        mm_type=EnergyRequest,
        reference_type=ReferenceEnergyRequest,
        operation="energy",
    )
    return self._validate_energy_result(self._energy(request))

minimize

minimize(request: MinimizationRequest) -> GeometryResult

Energy-minimize (relax) the geometry (MM).

Source code in q2mm/backends/contracts.py
def minimize(self, request: MinimizationRequest) -> GeometryResult:
    """Energy-minimize (relax) the geometry (MM)."""
    self._require(Capability.MINIMIZE)
    self._require_exact_request(
        request,
        mm_type=MinimizationRequest,
        reference_type=None,
        operation="minimize",
    )
    return self._validate_geometry_result(self._minimize(request), op="minimize")

optimize_geometry

Geometry-optimize the reference structure.

Source code in q2mm/backends/contracts.py
def optimize_geometry(self, request: ReferenceGeometryOptimizationRequest) -> GeometryResult:
    """Geometry-optimize the reference structure."""
    self._require(Capability.GEOMETRY_OPTIMIZATION)
    self._require_exact_request(
        request,
        mm_type=None,
        reference_type=ReferenceGeometryOptimizationRequest,
        operation="optimize_geometry",
    )
    return self._validate_geometry_result(self._optimize_geometry(request), op="optimize_geometry")

hessian

Cartesian Hessian in Hartree/Bohr².

Source code in q2mm/backends/contracts.py
def hessian(self, request: HessianRequest | ReferenceHessianRequest) -> HessianResult:
    """Cartesian Hessian in Hartree/Bohr²."""
    self._require(Capability.HESSIAN)
    self._require_exact_request(
        request,
        mm_type=HessianRequest,
        reference_type=ReferenceHessianRequest,
        operation="hessian",
    )
    return self._validate_hessian_result(self._hessian(request))

frequencies

Vibrational frequencies in cm⁻¹.

Source code in q2mm/backends/contracts.py
def frequencies(self, request: FrequencyRequest | ReferenceFrequencyRequest) -> FrequencyResult:
    """Vibrational frequencies in cm⁻¹."""
    self._require(Capability.FREQUENCIES)
    self._require_exact_request(
        request,
        mm_type=FrequencyRequest,
        reference_type=ReferenceFrequencyRequest,
        operation="frequencies",
    )
    return self._validate_frequency_result(self._frequencies(request))

parameter_gradient

parameter_gradient(request: ParameterGradientRequest) -> ParameterGradientResult

Energy plus analytical parameter gradient (MM).

Source code in q2mm/backends/contracts.py
def parameter_gradient(self, request: ParameterGradientRequest) -> ParameterGradientResult:
    """Energy plus analytical parameter gradient (MM)."""
    self._require(Capability.PARAMETER_GRADIENT)
    self._require_exact_request(
        request,
        mm_type=ParameterGradientRequest,
        reference_type=None,
        operation="parameter_gradient",
    )
    return self._validate_param_grad_result(self._parameter_gradient(request))

coordinate_gradient

Compute a reference Cartesian coordinate gradient in Hartree/Bohr.

Source code in q2mm/backends/contracts.py
def coordinate_gradient(self, request: ReferenceCoordinateGradientRequest) -> CoordinateGradientResult:
    """Compute a reference Cartesian coordinate gradient in Hartree/Bohr."""
    self._require(Capability.COORDINATE_GRADIENT)
    self._require_exact_request(
        request,
        mm_type=None,
        reference_type=ReferenceCoordinateGradientRequest,
        operation="coordinate_gradient",
    )
    return self._validate_coordinate_gradient_result(self._coordinate_gradient(request))

hessian_parameter_jacobian

hessian_parameter_jacobian(request: HessianJacobianRequest) -> HessianJacobianResult

Hessian plus its analytical parameter Jacobian (MM).

Source code in q2mm/backends/contracts.py
def hessian_parameter_jacobian(self, request: HessianJacobianRequest) -> HessianJacobianResult:
    """Hessian plus its analytical parameter Jacobian (MM)."""
    self._require(Capability.HESSIAN_PARAMETER_JACOBIAN)
    self._require_exact_request(
        request,
        mm_type=HessianJacobianRequest,
        reference_type=None,
        operation="hessian_parameter_jacobian",
    )
    return self._validate_hess_jac_result(self._hessian_parameter_jacobian(request))

batched_energy

batched_energy(request: BatchedEnergyRequest) -> BatchedEnergyResult

Energies for a batch of full parameter vectors (MM).

Source code in q2mm/backends/contracts.py
def batched_energy(self, request: BatchedEnergyRequest) -> BatchedEnergyResult:
    """Energies for a batch of full parameter vectors (MM)."""
    self._require(Capability.BATCHED_ENERGY)
    self._require_exact_request(
        request,
        mm_type=BatchedEnergyRequest,
        reference_type=None,
        operation="batched_energy",
    )
    n_rows = int(np.asarray(request.parameter_matrix).shape[0])
    return self._validate_batched_energy_result(self._batched_energy(request), n_rows=n_rows)

DependencyProbe dataclass

DependencyProbe(modules: tuple[str, ...] = (), executables: tuple[str, ...] = ())

Cheap, side-effect-free availability probe for a backend.

Only importlib.util.find_spec (for Python modules) and shutil.which (for executables) are used. No backend is constructed, no device is enumerated, and no CUDA/XLA/OpenMM platform is initialized.

Parameters:

Name Type Description Default
modules tuple[str, ...]

Importable module names that must resolve.

()
executables tuple[str, ...]

Executable names that must be found on PATH.

()

check

check() -> tuple[bool, str]

Return (healthy, reason) without importing or constructing.

Source code in q2mm/backends/contracts.py
def check(self) -> tuple[bool, str]:
    """Return ``(healthy, reason)`` without importing or constructing."""
    missing_modules = [m for m in self.modules if self._module_missing(m)]
    if missing_modules:
        return False, f"missing Python module(s): {', '.join(missing_modules)}"
    missing_exes = [e for e in self.executables if shutil.which(e) is None]
    if missing_exes:
        return False, f"missing executable(s): {', '.join(missing_exes)}"
    return True, ""

BackendDescriptor dataclass

BackendDescriptor(name: str, role: BackendRole, capability_ceiling: frozenset[Capability], functional_form_ceiling: frozenset[str], factory: str, probe: DependencyProbe = DependencyProbe(), backend_api_version: int = BACKEND_API_VERSION)

Validated, lazily-loadable description of a backend.

Static ceilings advertise what an installation may support without importing it. A loaded backend's :class:BackendInfo is authoritative and may declare any exact subset of those ceilings.

Parameters:

Name Type Description Default
name str

Registry key (e.g. "openmm", "jax-md").

required
role BackendRole

Backend role.

required
capability_ceiling frozenset[Capability]

Potential capabilities for any runtime instance.

required
functional_form_ceiling frozenset[str]

Potential functional forms for any runtime instance.

required
factory str

Import string "pkg.module:Attribute" naming a zero-arg callable (typically the backend class) that returns a :class:Backend.

required
probe DependencyProbe

Cheap dependency probe used for listing only.

DependencyProbe()
backend_api_version int

Backend API version this descriptor targets.

BACKEND_API_VERSION

is_available

is_available() -> tuple[bool, str]

Return (healthy, reason) via the cheap probe only (catalog use).

Source code in q2mm/backends/contracts.py
def is_available(self) -> tuple[bool, str]:
    """Return ``(healthy, reason)`` via the cheap probe only (catalog use)."""
    return self.probe.check()

load

load(**kwargs: object) -> Backend

Import the factory and construct the backend.

This is the only place that triggers a real import of the backend module. The probe is not consulted here — explicit configuration (e.g. an explicit Tinker directory) must be honoured even when a generic PATH probe is unhealthy. The constructor is responsible for raising typed :class:BackendUnavailableError / :class:BackendConfigurationError when the backend truly cannot run.

Parameters:

Name Type Description Default
**kwargs object

Forwarded to the factory callable.

{}

Returns:

Name Type Description
Backend Backend

The constructed, validated backend.

Raises:

Type Description
BackendUnavailableError

If the backend module cannot be imported or the backend reports itself unavailable.

BackendConfigurationError

If the factory attribute is missing, construction fails, or the runtime info disagrees with the static descriptor info.

Source code in q2mm/backends/contracts.py
def load(self, **kwargs: object) -> Backend:
    """Import the factory and construct the backend.

    This is the only place that triggers a real import of the backend
    module.  The probe is **not** consulted here — explicit configuration
    (e.g. an explicit Tinker directory) must be honoured even when a
    generic PATH probe is unhealthy.  The constructor is responsible for
    raising typed :class:`BackendUnavailableError` /
    :class:`BackendConfigurationError` when the backend truly cannot run.

    Args:
        **kwargs: Forwarded to the factory callable.

    Returns:
        Backend: The constructed, validated backend.

    Raises:
        BackendUnavailableError: If the backend module cannot be imported
            or the backend reports itself unavailable.
        BackendConfigurationError: If the factory attribute is missing,
            construction fails, or the runtime info disagrees with the
            static descriptor info.

    """
    module_path, _, attr = self.factory.partition(":")
    try:
        module = importlib.import_module(module_path)
    except ImportError as exc:
        raise BackendUnavailableError(f"Backend {self.name!r} could not be imported: {exc}") from exc
    try:
        factory = getattr(module, attr)
    except AttributeError as exc:
        raise BackendConfigurationError(
            f"Backend {self.name!r} factory {attr!r} not found in {module_path!r}."
        ) from exc
    try:
        backend: Backend = factory(**kwargs)
    except (BackendUnavailableError, BackendConfigurationError):
        raise
    except Exception as exc:  # noqa: BLE001 - normalize to typed config error
        raise BackendConfigurationError(f"Backend {self.name!r} failed to construct: {exc}") from exc

    # Structural protocol validation: the factory must return a Backend
    # (an object exposing ``info`` and ``prepare``).
    if not isinstance(backend, Backend):
        raise BackendConfigurationError(
            f"Backend {self.name!r} factory returned {type(backend).__name__}, "
            "which does not satisfy the Backend protocol (needs 'info' and 'prepare')."
        )
    runtime_info = backend.info
    if not isinstance(runtime_info, BackendInfo):
        raise BackendConfigurationError(
            f"Backend {self.name!r} .info is {type(runtime_info).__name__}, expected BackendInfo."
        )
    if runtime_info.role is not self.role:
        raise BackendConfigurationError(
            f"Backend {self.name!r} runtime role {runtime_info.role.value!r} does not match "
            f"descriptor role {self.role.value!r}."
        )
    capability_overclaims = runtime_info.capabilities - self.capability_ceiling
    if capability_overclaims:
        raise BackendConfigurationError(
            f"Backend {self.name!r} runtime capabilities "
            f"{sorted(capability.value for capability in capability_overclaims)} exceed descriptor "
            f"capability_ceiling {sorted(capability.value for capability in self.capability_ceiling)}."
        )
    form_overclaims = runtime_info.functional_forms - self.functional_form_ceiling
    if form_overclaims:
        raise BackendConfigurationError(
            f"Backend {self.name!r} runtime functional forms {sorted(form_overclaims)} exceed descriptor "
            f"functional_form_ceiling {sorted(self.functional_form_ceiling)}."
        )
    # Runtime provenance must identify the same backend key and role
    # (the human display name may differ, but the registry key must match).
    prov = runtime_info.provenance
    if prov is None:
        raise BackendConfigurationError(f"Backend {self.name!r} runtime info carries no provenance.")
    if prov.backend != self.name:
        raise BackendConfigurationError(
            f"Backend {self.name!r} runtime provenance.backend {prov.backend!r} does not match "
            f"descriptor name {self.name!r}."
        )
    if prov.role is not self.role:
        raise BackendConfigurationError(
            f"Backend {self.name!r} runtime provenance role {prov.role.value} does not match "
            f"descriptor role {self.role.value}."
        )
    return backend

BackendStatus dataclass

BackendStatus(descriptor: BackendDescriptor, healthy: bool, reason: str)

Explicit health report for one descriptor in the catalog.

Parameters:

Name Type Description Default
descriptor BackendDescriptor

The described backend.

required
healthy bool

Whether the cheap probe passed.

required
reason str

Human-readable reason when healthy is False.

required

name property

name: str

Registry key of the described backend.

role property

Role of the described backend.

readonly_array

readonly_array(values: object, *, dtype: DTypeLike = float) -> ndarray

Return a contiguous, read-only copy of values.

Parameters:

Name Type Description Default
values object

Anything array-like.

required
dtype DTypeLike

Target dtype (default float).

float

Returns:

Type Description
ndarray

np.ndarray: A read-only defensive copy.

Source code in q2mm/backends/contracts.py
def readonly_array(values: object, *, dtype: npt.DTypeLike = float) -> np.ndarray:
    """Return a contiguous, read-only copy of *values*.

    Args:
        values: Anything array-like.
        dtype: Target dtype (default ``float``).

    Returns:
        np.ndarray: A read-only defensive copy.

    """
    arr: np.ndarray = np.array(values, dtype=dtype, copy=True)
    arr.setflags(write=False)
    return arr

prepare_hessian_batches

prepare_hessian_batches(backend: Backend, sessions: Sequence[PreparedBackend]) -> list[PreparedHessianBatch]

Capability-first, backend-neutral entry to batched-Hessian preparation.

This is the only surface callers (e.g. the objective function) should use to batch Hessians. It is fully backend-agnostic: it checks the declared capability and the batch-preparer protocol, delegates grouping to the backend, and validates the returned batch objects.

Parameters:

Name Type Description Default
backend Backend

The backend to batch with.

required
sessions Sequence[PreparedBackend]

Prepared sessions to group (must be topology-compatible subsets as the backend defines).

required

Returns:

Type Description
list[PreparedHessianBatch]

list[PreparedHessianBatch]: Validated typed batch objects.

Raises:

Type Description
UnsupportedCapabilityError

If the backend does not declare :attr:Capability.BATCHED_HESSIAN.

BackendConfigurationError

If the backend declares the capability but does not implement :class:HessianBatchPreparer, or returns objects that are not valid :class:PreparedHessianBatch instances.

Source code in q2mm/backends/contracts.py
def prepare_hessian_batches(
    backend: Backend,
    sessions: Sequence[PreparedBackend],
) -> list[PreparedHessianBatch]:
    """Capability-first, backend-neutral entry to batched-Hessian preparation.

    This is the only surface callers (e.g. the objective function) should use
    to batch Hessians.  It is fully backend-agnostic: it checks the declared
    capability and the batch-preparer protocol, delegates grouping to the
    backend, and validates the returned batch objects.

    Args:
        backend: The backend to batch with.
        sessions: Prepared sessions to group (must be topology-compatible
            subsets as the backend defines).

    Returns:
        list[PreparedHessianBatch]: Validated typed batch objects.

    Raises:
        UnsupportedCapabilityError: If the backend does not declare
            :attr:`Capability.BATCHED_HESSIAN`.
        BackendConfigurationError: If the backend declares the capability but
            does not implement :class:`HessianBatchPreparer`, or returns
            objects that are not valid :class:`PreparedHessianBatch` instances.

    """
    if not backend.info.supports(Capability.BATCHED_HESSIAN):
        raise UnsupportedCapabilityError(backend.info.name, Capability.BATCHED_HESSIAN)
    if not isinstance(backend, HessianBatchPreparer):
        raise BackendConfigurationError(
            f"Backend {backend.info.name!r} declares BATCHED_HESSIAN but does not implement "
            "the HessianBatchPreparer protocol (prepare_hessian_batches)."
        )
    batches = backend.prepare_hessian_batches(sessions)
    if not isinstance(batches, list):
        raise BackendConfigurationError(
            f"Backend {backend.info.name!r} prepare_hessian_batches must return a list; got {type(batches).__name__}."
        )
    for batch in batches:
        if not isinstance(batch, PreparedHessianBatch):
            raise BackendConfigurationError(
                f"Backend {backend.info.name!r} prepare_hessian_batches returned "
                f"{type(batch).__name__}, which is not a valid PreparedHessianBatch."
            )
    return batches