ARRAY CONTRACT

Bring familiar arrays.

Hyperfold accepts NumPy arrays in host memory and CUDA arrays from CuPy and PyTorch. Results preserve the input framework and device. Multi-array operations require one framework, one dtype and one device across all inputs.

FrameworkLocationReturn conventionInterchange
NumPyCPU host memoryNumPy arrays and NumPy scalarsDirect buffer borrowing
CuPyCUDA deviceCuPy arrays, including 0-D reductionsDLPack
PyTorchCUDA devicePyTorch tensors, including 0-D reductionsDLPack

CPU PyTorch tensors, CUDA NumPy arrays, generic DLPack producers, and implicit host/device transfers are rejected. Inputs are rank-one vectors or rank-two matrices; batching and broadcasting are not part of the v1 interface.

NUMERICAL TYPES

Storage and computation are explicit.

All 32 built-in operations accept the seven production storage dtypes. Ordinary array results retain storage precision, while reductions and solvers may retain the wider compute precision.

Input storageCompute / reductions / solveOrdinary arraysGeneral eig / LU logdet
float16, bfloat16float32input dtypecomplex64
float32float32float32complex64
float64float64float64complex128
complex32complex64complex32complex64
complex64complex64complex64complex64
complex128complex128complex128complex128
Real results

norm, Hermitian eigenvalues and positive-definite log-determinants use the real component of compute precision.

Predicates

vector_equal and is_unitary return booleans.

Structured solvers

eigh, eigvalsh, slogdet and Cholesky logdet return compute-precision results.

No mixed promotion

Inputs to one operation must have identical storage dtypes; convert them explicitly first.

PACKED COMPLEX

Use four-byte complex storage.

complex32 stores real and imaginary IEEE float16 components and computes in complex64. Input rounding is permanent even though later arithmetic is wider.

PythonNumPy
import hyperfold as hf

packed = hf.pack_complex32([[3, 1j], [-1j, 3]])
assert packed.dtype == hf.complex32
product = hf.matmul(packed, packed)
ordinary = hf.unpack_complex32(product)  # NumPy complex64
values, vectors = hf.eigh(packed)        # float32, complex64
FrameworkRepresentationConversion behaviour
NumPyhyperfold.complex32, a structured dtype with float16 real and imag fieldsThe helpers copy between packed storage and complex64; NumPy provides no arithmetic for the structured dtype.
PyTorch CUDAtorch.complex32 / torch.chalfThe helpers preserve the CUDA device and return contiguous tensors.
CuPyUnavailableCuPy has no corresponding dtype; use complex64 or PyTorch complex32.

hyperfold.pack_complex32

pack_complex32(values: Any) -> Any

Copies real or complex numeric values into complex32 storage. Passing complex32 still returns a fresh contiguous copy. Unsupported objects and CuPy inputs raise TypeError.

hyperfold.unpack_complex32

unpack_complex32(values: Any) -> Any

Copies complex32 storage to complex64 without changing the NumPy or PyTorch framework or the PyTorch device. Other input dtypes raise TypeError.

COPY AND OUTPUT

Control boundary ownership.

ArgumentContract
copy=NoneBorrow aligned, native-endian, C-contiguous compatible storage; otherwise create a fresh same-device contiguous input.
copy=FalseRequire borrowing. A layout, alignment, endianness or writability incompatibility that needs normalisation raises an error.
copy=TrueAlways normalise through fresh input storage.
out=Require exact framework, dtype, device and shape. The destination must be writable, aligned, native-endian, C-contiguous and non-overlapping with every input.

The copy policy applies at the Python boundary. Internal scratch storage, solver workspaces and complex layout adaptation remain possible in every mode. Supplying out returns that same object.

DLPACK

Order CUDA work on the selected stream.

Hyperfold passes its execution stream to each producer’s __dlpack__ method, waits for input readiness on that stream, executes into framework-owned output memory, and synchronises before returning. An external stream remains caller-owned and must outlive every call that uses its context.

Arrays from different frameworks, dtypes or devices are rejected before dispatch. Hyperfold never falls back to a NumPy implementation when a backend signature is unavailable.