Backend conformance#

This page is the normative conformance matrix for BackendOps. Every public method on spacecore.backend.BackendOps appears as a row. Columns record which backends implement it within tolerance, which dtypes each backend honors, optional-argument coverage, sparse support, JIT compatibility, native vmap, and conversion behavior. Each row links to the test(s) that pin it.

Tests live under tests/backend/. The shared harness (tests/backend/_conformance.py) defines per-op tolerances, the backend_ops fixture, and the assert_matches_reference helper. The matrix is the contract; tests instantiate it.

Scope and policy#

  • In scope. NumPy is the reference. JAX, Torch, and CuPy are compared against NumPy through the harness. Sparse paths exist where the backend exposes a sparse array type.

  • Out of scope. Performance, device placement, JAX sharding, autograd, and downstream library compatibility.

  • Tolerance. Per-op + per-dtype, set in tests/backend/_conformance.py:TOLERANCE_TABLE. The default is rtol=1e-6, atol=1e-8. Spectral and complex sqrt entries are looser.

  • Skip vs deviation. A backend that genuinely lacks an op is skipped with a justification. A backend that returns a different result inside tolerance is a deviation and appears in Backend deviations.

  • Adding a backend. Implement BackendOps, register the family, add a fixture branch in tests/backend/conftest.py, and update the Backends column of every row this implementation supports.

How to read a row#

  • MethodBackendOps method name.

  • NumPy reference — the numpy or numpy.linalg callable used as ground truth. means no direct NumPy spelling; the row is compared against another invariant (identity, round-trip, etc.).

  • BackendsN J T C columns; y = covered, s = covered with a skip on absent platforms, d = deviation (see Backend deviations), = not implemented for this backend.

  • dtypesr32 r64 c64 c128; y covered, not covered by the backend natively.

  • Tests — link(s) to the test file(s) that pin this row.

Matrix#

Metadata and predicates#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

family

identity

y y y y

n/a

test_backend_registry.py

allow_sparse

identity

y y y y

n/a

test_backend_registry.py

has_native_vmap

constant

y y y y

n/a

test_backend_vmap.py

dense_array

identity

y y y y

n/a

test_backend_registry.py

sparse_array

identity

y y y s

n/a

test_backend_registry.py, test_backend_optional_args.py

is_dense / is_sparse / is_array

direct

y y y y

n/a

test_conformance_numpy.py

get_dtype

x.dtype

y y y y

y y y y

test_conformance_numpy.py

shape / ndim / size

x.shape / x.ndim / x.size

y y y y

y y y y

test_conformance_numpy.py

is_complex_dtype / real_dtype / sanitize_dtype

dtype kind

y y y y

y y y y

test_conformance_numpy.py

Construction and dtype#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

asarray

np.asarray

y y y y

y y y y

test_conformance_numpy.py, test_backend_conversion.py

astype

x.astype

y y y y

y y y y

test_conformance_numpy.py, test_backend_dtype_promotion.py

empty / zeros / ones / full

np.empty / …

y y y y

y y y y

test_conformance_numpy.py

zeros_like / ones_like / full_like

direct

y y y y

y y y y

test_conformance_numpy.py

arange

np.arange

y y y y

y y y y

test_conformance_numpy.py

eye

np.eye

y y y y

y y y y

test_conformance_numpy.py

assparse

SciPy sparse

y s s s

y y y y

test_backend_conversion.py

sparse_matmul

SciPy sparse dot

y s s s

y y y y

test_backend_conversion.py

Shape and layout#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

ravel / reshape

direct

y y y y

y y y y

test_conformance_numpy.py, test_backend_consistency.py

transpose / swapaxes / moveaxis

direct

y y y y

y y y y

test_backend_consistency.py

broadcast_to / expand_dims / squeeze

direct

y y y y

y y y y

test_backend_consistency.py

stack / concatenate

direct

y y y y

y y y y

test_conformance_numpy.py

Elementwise and reductions#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

conj / real / imag / abs / sign

direct

y y y y

y y y y

test_conformance_numpy.py, test_backend_field_consistency.py

sqrt / exp / log

direct

y y y y

y y y y

test_conformance_numpy.py

sum / mean / min / max / prod

direct

y y y y

y y y y

test_conformance_numpy.py, test_backend_optional_args.py

argmin / argmax / argsort / sort

direct

y y y y

y y y y

test_conformance_numpy.py

maximum / minimum / where / clip

direct

y y y y

y y y y

test_conformance_numpy.py

isfinite / isnan

direct

y y y y

y y y y

test_conformance_numpy.py

logsumexp

scipy.special.logsumexp

y y y y

y y y y

test_conformance_numpy.py

Linear algebra#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

vdot

np.vdot

y y y y

y y y y

test_conformance_numpy.py, test_backend_field_consistency.py

matmul

np.matmul

y y y y

y y y y

test_conformance_numpy.py, test_backend_consistency.py

kron / einsum

direct

y y y y

y y y y

test_conformance_numpy.py

norm

np.linalg.norm

y y y y

y y y y

test_backend_consistency.py

solve

np.linalg.solve

y y y y

y y y y

test_backend_consistency.py

eigh

A v = λ v identity

y y y s

y y y y

test_conformance_numpy.py, test_backend_consistency.py

eigvalsh

np.linalg.eigvalsh

y y y y

y y y y

test_backend_consistency.py

svd

np.linalg.svd

y y y y

y y y y

test_backend_consistency.py

cholesky

np.linalg.cholesky

y y y y

y y y y

test_backend_consistency.py

trace / diag / diagonal / tril / triu

direct

y y y y

y y y y

test_conformance_numpy.py

Indexing and updates#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

take

np.take

y y y y

y y y y

test_conformance_numpy.py

index_set / index_add

functional indexing

y y y y

y y y y

test_backend_optional_args.py

ix_

np.ix_

y y y y

n/a

test_conformance_numpy.py

Control flow#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

fori_loop / while_loop / scan / cond

sequential Python

y y y y

n/a

test_backend_loops.py

vmap

sequential stacked loop

y y y y

y y y y

test_backend_vmap.py

Conversion and inspection#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

Context.asarray (cross-backend)

round-trip equality

y y y y

y y y y

test_backend_conversion.py

Context.to_numpy

identity

y y y y

y y y y

test_backend_conversion.py

allclose / allclose_sparse

np.allclose

y y y y

y y y y

test_conformance_numpy.py

Sparse paths#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

sparse_matmul

SciPy

y — — s

y y y y

test_backend_conversion.py

assparse round-trip

SciPy

y — — s

y y y y

test_backend_conversion.py

Constants#

Method

NumPy reference

Backends (N J T C)

dtypes (r32 r64 c64 c128)

Tests

inf / nan / pi / e

np.inf / …

y y y y

y y y y

test_conformance_numpy.py

eps

np.finfo(dtype).eps

y y y y

y y y y

test_conformance_numpy.py

Reading the result columns#

  • s — skipped at runtime because the backend is not installed in the current environment, or because the underlying library does not expose the operation on this platform (e.g. CuPy sparse without a GPU).

  • d — the backend returns a numerically valid result that differs from NumPy within the per-op tolerance; the deviation is documented in Backend deviations. Tests still pass.

  • — not implemented for this backend. BackendOps raises NotImplementedError (not a soft skip) and the test asserts that behavior in test_backend_optional_args.py.

Cross-references#