Backends¶
Backend implementations for different hardware.
- holovec.backends.get_backend(name: str | Backend | None = None, **kwargs) Backend[source]¶
Get a backend instance by name.
- Parameters:
name – Backend name (‘numpy’, ‘torch’, ‘jax’), a Backend instance, or None. If a Backend instance is passed, it is returned as-is. If None, returns default backend.
**kwargs – Backend-specific arguments (e.g., device=’cuda’ for torch)
- Returns:
Backend instance
- Raises:
BackendNotAvailableError – If requested backend is not available
ValueError – If backend name is not recognized
Examples
>>> backend = get_backend('numpy') >>> backend = get_backend('torch', device='cuda') >>> backend = get_backend() # Returns default >>> backend = get_backend(existing_backend) # Returns existing_backend
- class holovec.backends.Backend[source]¶
Bases:
ABCAbstract base class for computational backends.
All backends must implement these operations to support VSA computations across different frameworks (NumPy, PyTorch, JAX).
- abstractmethod is_available() bool[source]¶
Check if the backend is available in the current environment.
- supports_complex() bool[source]¶
Check if backend supports complex number operations.
Complex operations are required for FHRR (Fourier HRR) and other frequency-domain VSA models.
- Returns:
True if backend can handle complex dtypes (complex64, complex128)
- supports_sparse() bool[source]¶
Check if backend supports sparse array operations.
Sparse operations are beneficial for BSC (Binary Spatter Codes) and BSDC (Binary Sparse Distributed Codes) which have high sparsity.
- Returns:
True if backend has native sparse array support
- supports_gpu() bool[source]¶
Check if backend has GPU acceleration support.
GPU support enables significant speedups for large-scale operations and is critical for production deployments.
- Returns:
True if backend can utilize GPU hardware
- supports_jit() bool[source]¶
Check if backend supports Just-In-Time (JIT) compilation.
JIT compilation can provide 10-100x speedups for certain operations by compiling Python code to optimized machine code.
- Returns:
True if backend has JIT compilation (e.g., JAX, Numba)
- supports_device(device: str) bool[source]¶
Check if backend supports a specific device.
- Parameters:
device – Device identifier (e.g., ‘cpu’, ‘cuda’, ‘cuda:0’, ‘mps’)
- Returns:
True if the specified device is available
Examples
>>> backend.supports_device('cpu') # Always True >>> backend.supports_device('cuda') # True if CUDA GPU available >>> backend.supports_device('mps') # True if Apple Metal available
- abstractmethod zeros(shape: int | Tuple[int, ...], dtype: str = 'float32') Any[source]¶
Create an array of zeros with the given shape and dtype.
- abstractmethod ones(shape: int | Tuple[int, ...], dtype: str = 'float32') Any[source]¶
Create an array of ones with the given shape and dtype.
- abstractmethod random_normal(shape: int | Tuple[int, ...], mean: float = 0.0, std: float = 1.0, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create an array of random values from a normal distribution.
- abstractmethod random_uniform(shape: int | Tuple[int, ...], low: float = 0.0, high: float = 1.0, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create an array of random values from a uniform distribution.
- abstractmethod random_binary(shape: int | Tuple[int, ...], p: float = 0.5, dtype: str = 'int32', seed: int | None = None) Any[source]¶
Create a binary array with probability p of being 1.
- abstractmethod random_bipolar(shape: int | Tuple[int, ...], p: float = 0.5, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create a bipolar array {-1, +1} with probability p of being +1.
- abstractmethod random_phasor(shape: int | Tuple[int, ...], dtype: str = 'complex64', seed: int | None = None) Any[source]¶
Create an array of random unit phasors (complex numbers with magnitude 1).
- abstractmethod array(data: Any, dtype: str | None = None) Any[source]¶
Create an array from Python data (list, tuple, etc.).
- abstractmethod exp(a: Any) Any[source]¶
Element-wise exponential: e^a.
- Parameters:
a – Input array
- Returns:
Array with exp applied element-wise
- abstractmethod log(a: Any) Any[source]¶
Element-wise natural logarithm: ln(a).
- Parameters:
a – Input array (must be positive)
- Returns:
Array with log applied element-wise
- abstractmethod multiply_scalar(a: Any, scalar: float) Any[source]¶
Multiply array by a Python scalar.
- abstractmethod linspace(start: float, stop: float, num: int) Any[source]¶
Create linearly spaced array of length num in [start, stop].
- abstractmethod sum(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Sum along an axis.
- abstractmethod mean(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Mean along an axis.
- abstractmethod norm(a: Any, ord: int | str = 2, axis: int | None = None) Any[source]¶
Compute the norm of an array.
- abstractmethod max(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Maximum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to compute max (None for global max)
keepdims – Whether to keep dimensions
- Returns:
Maximum value(s)
- abstractmethod min(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Minimum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to compute min (None for global min)
keepdims – Whether to keep dimensions
- Returns:
Minimum value(s)
- abstractmethod argmax(a: Any, axis: int | None = None) Any[source]¶
Index of maximum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to find argmax (None for global argmax)
- Returns:
Index/indices of maximum value(s)
- abstractmethod argmin(a: Any, axis: int | None = None) Any[source]¶
Index of minimum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to find argmin (None for global argmin)
- Returns:
Index/indices of minimum value(s)
- abstractmethod normalize(a: Any, ord: int | str = 2, axis: int | None = None, eps: float = 1e-12) Any[source]¶
Normalize an array to unit norm.
- abstractmethod softmax(a: Any, axis: int = -1) Any[source]¶
Softmax function with numerical stability.
Computes: softmax(x_i) = exp(x_i - max(x)) / Σ exp(x_j - max(x))
The max subtraction provides numerical stability by preventing overflow in the exponential function.
- Parameters:
a – Input array
axis – Axis along which to compute softmax
- Returns:
Array with softmax applied along specified axis
References
Bricken & Pehlevan (2022): “Attention Approximates Sparse Distributed Memory”
Furlong & Eliasmith (2023): “Fractional binding in VSAs”
- abstractmethod permute(a: Any, indices: Any) Any[source]¶
Permute array elements according to indices.
- abstractmethod roll(a: Any, shift: int, axis: int | None = None) Any[source]¶
Roll array elements along an axis.
- abstractmethod cosine_similarity(a: Any, b: Any) float[source]¶
Compute cosine similarity between two vectors.
- abstractmethod hamming_distance(a: Any, b: Any) float[source]¶
Compute Hamming distance between two binary/bipolar vectors.
- abstractmethod euclidean_distance(a: Any, b: Any) float[source]¶
Compute Euclidean distance between two vectors.
- abstractmethod clip(a: Any, min_val: float, max_val: float) Any[source]¶
Clip array values to [min_val, max_val].
- abstractmethod threshold(a: Any, threshold: float, above: float = 1.0, below: float = 0.0) Any[source]¶
Threshold array values.
- abstractmethod where(condition: Any, x: Any, y: Any) Any[source]¶
Select elements from x or y depending on boolean condition.
- abstractmethod stack(arrays: Sequence[Any], axis: int = 0) Any[source]¶
Stack arrays along a new axis.
- abstractmethod concatenate(arrays: Sequence[Any], axis: int = 0) Any[source]¶
Concatenate arrays along an existing axis.
- abstractmethod matmul(a: Any, b: Any) Any[source]¶
Matrix multiplication (or batched matrix multiplication).
- Parameters:
a – Matrix or batch of matrices
b – Matrix or batch of matrices
- Returns:
Matrix product
- abstractmethod matrix_transpose(a: Any) Any[source]¶
Transpose last two dimensions of array.
For 2D: standard transpose For 3D+: transpose last two dimensions (batch transpose)
- Parameters:
a – Array with at least 2 dimensions
- Returns:
Transposed array
- abstractmethod matrix_trace(a: Any) Any[source]¶
Compute trace of matrix or batch of matrices.
For 2D array: returns scalar For 3D+ array: returns trace of each matrix in batch
- Parameters:
a – Matrix or batch of matrices (last 2 dims are matrix)
- Returns:
Scalar or array of traces
- abstractmethod svd(a: Any, full_matrices: bool = True) Tuple[Any, Any, Any][source]¶
Compute Singular Value Decomposition (SVD).
Decomposes matrix A as A = U @ diag(S) @ Vh, where: - U: left singular vectors (unitary) - S: singular values (non-negative, sorted descending) - Vh: conjugate transpose of right singular vectors (unitary)
For batched matrices (3D+), computes SVD for each matrix in batch.
- Parameters:
a – Matrix or batch of matrices (shape […, m, n])
full_matrices – If True, U and Vh have shapes […, m, m] and […, n, n]. If False, shapes are […, m, k] and […, k, n] where k=min(m,n).
- Returns:
Tuple of (U, S, Vh) arrays
Examples
>>> A = backend.random_normal((3, 3)) >>> U, S, Vh = backend.svd(A) >>> # Verify: A ≈ U @ diag(S) @ Vh
- class holovec.backends.NumPyBackend(seed: int | None = None)[source]¶
Bases:
BackendNumPy-based backend for VSA operations.
This backend uses pure NumPy for all operations and serves as the default backend with minimal dependencies.
Initialize NumPy backend with optional random seed.
- Parameters:
seed – Random seed for reproducibility
- __init__(seed: int | None = None)[source]¶
Initialize NumPy backend with optional random seed.
- Parameters:
seed – Random seed for reproducibility
- supports_sparse() bool[source]¶
NumPy does not have native sparse array support.
Note: scipy.sparse provides sparse arrays but is not part of core NumPy.
- supports_jit() bool[source]¶
NumPy does not have JIT compilation.
Note: Numba can JIT-compile NumPy code but is a separate library.
- zeros(shape: int | Tuple[int, ...], dtype: str = 'float32') Any[source]¶
Create an array of zeros with the given shape and dtype.
- ones(shape: int | Tuple[int, ...], dtype: str = 'float32') Any[source]¶
Create an array of ones with the given shape and dtype.
- random_normal(shape: int | Tuple[int, ...], mean: float = 0.0, std: float = 1.0, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create an array of random values from a normal distribution.
- random_uniform(shape: int | Tuple[int, ...], low: float = 0.0, high: float = 1.0, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create an array of random values from a uniform distribution.
- random_binary(shape: int | Tuple[int, ...], p: float = 0.5, dtype: str = 'int32', seed: int | None = None) Any[source]¶
Create a binary array with probability p of being 1.
- random_bipolar(shape: int | Tuple[int, ...], p: float = 0.5, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create a bipolar array {-1, +1} with probability p of being +1.
- random_phasor(shape: int | Tuple[int, ...], dtype: str = 'complex64', seed: int | None = None) Any[source]¶
Create an array of random unit phasors (complex numbers with magnitude 1).
- array(data, dtype: str | None = None) Any[source]¶
Create an array from Python data (list, tuple, etc.).
- norm(a: Any, ord: int | str = 2, axis: int | None = None) Any[source]¶
Compute the norm of an array.
- max(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Maximum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to compute max (None for global max)
keepdims – Whether to keep dimensions
- Returns:
Maximum value(s)
- min(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Minimum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to compute min (None for global min)
keepdims – Whether to keep dimensions
- Returns:
Minimum value(s)
- argmax(a: Any, axis: int | None = None) Any[source]¶
Index of maximum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to find argmax (None for global argmax)
- Returns:
Index/indices of maximum value(s)
- argmin(a: Any, axis: int | None = None) Any[source]¶
Index of minimum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to find argmin (None for global argmin)
- Returns:
Index/indices of minimum value(s)
- normalize(a: Any, ord: int | str = 2, axis: int | None = None, eps: float = 1e-12) Any[source]¶
Normalize an array to unit norm.
- circular_convolve(a: Any, b: Any) Any[source]¶
Circular convolution using real FFT for numerical stability.
- circular_correlate(a: Any, b: Any) Any[source]¶
Circular correlation using real FFT for numerical stability.
- threshold(a: Any, threshold: float, above: float = 1.0, below: float = 0.0) Any[source]¶
Threshold array values.
- where(condition: Any, x: Any, y: Any) Any[source]¶
Select elements from x or y depending on boolean condition.
- concatenate(arrays: Sequence[Any], axis: int = 0) Any[source]¶
Concatenate arrays along an existing axis.
- class holovec.backends.TorchBackend(device: str = 'cpu', seed: int | None = None)[source]¶
Bases:
BackendPyTorch-based backend for VSA operations.
This backend leverages PyTorch for GPU acceleration and neural network integration. Requires PyTorch to be installed.
Initialize PyTorch backend.
- Parameters:
device – Device to use (‘cpu’, ‘cuda’, ‘cuda:0’, etc.)
seed – Random seed for reproducibility
- __init__(device: str = 'cpu', seed: int | None = None)[source]¶
Initialize PyTorch backend.
- Parameters:
device – Device to use (‘cpu’, ‘cuda’, ‘cuda:0’, etc.)
seed – Random seed for reproducibility
- supports_sparse() bool[source]¶
PyTorch has sparse tensor support (COO and CSR formats).
Note: Sparse support is partial - not all operations work with sparse tensors.
- supports_jit() bool[source]¶
PyTorch has TorchScript JIT compilation but not as advanced as JAX.
Note: TorchScript is mainly for deployment, not general computation like JAX.
- property device: torch.device¶
Return the current device.
- zeros(shape: int | Tuple[int, ...], dtype: str = 'float32') Any[source]¶
Create an array of zeros with the given shape and dtype.
- ones(shape: int | Tuple[int, ...], dtype: str = 'float32') Any[source]¶
Create an array of ones with the given shape and dtype.
- random_normal(shape: int | Tuple[int, ...], mean: float = 0.0, std: float = 1.0, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create an array of random values from a normal distribution.
- random_uniform(shape: int | Tuple[int, ...], low: float = 0.0, high: float = 1.0, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create an array of random values from a uniform distribution.
- random_binary(shape: int | Tuple[int, ...], p: float = 0.5, dtype: str = 'int32', seed: int | None = None) Any[source]¶
Create a binary array with probability p of being 1.
- random_bipolar(shape: int | Tuple[int, ...], p: float = 0.5, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create a bipolar array {-1, +1} with probability p of being +1.
- random_phasor(shape: int | Tuple[int, ...], dtype: str = 'complex64', seed: int | None = None) Any[source]¶
Create an array of random unit phasors (complex numbers with magnitude 1).
- array(data, dtype: str | None = None) Any[source]¶
Create an array from Python data (list, tuple, etc.).
- norm(a: Any, ord: int | str = 2, axis: int | None = None) Any[source]¶
Compute the norm of an array.
- max(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Maximum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to compute max (None for global max)
keepdims – Whether to keep dimensions
- Returns:
Maximum value(s)
- min(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Minimum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to compute min (None for global min)
keepdims – Whether to keep dimensions
- Returns:
Minimum value(s)
- argmax(a: Any, axis: int | None = None) Any[source]¶
Index of maximum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to find argmax (None for global argmax)
- Returns:
Index/indices of maximum value(s)
- argmin(a: Any, axis: int | None = None) Any[source]¶
Index of minimum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to find argmin (None for global argmin)
- Returns:
Index/indices of minimum value(s)
- normalize(a: Any, ord: int | str = 2, axis: int | None = None, eps: float = 1e-12) Any[source]¶
Normalize an array to unit norm.
- threshold(a: Any, threshold: float, above: float = 1.0, below: float = 0.0) Any[source]¶
Threshold array values.
- where(condition: Any, x: Any, y: Any) Any[source]¶
Select elements from x or y depending on boolean condition.
- concatenate(arrays: Sequence[Any], axis: int = 0) Any[source]¶
Concatenate arrays along an existing axis.
- class holovec.backends.JAXBackend(seed: int | None = None)[source]¶
Bases:
BackendJAX-based backend for VSA operations.
This backend leverages JAX for JIT compilation, automatic differentiation, and functional programming patterns. Requires JAX to be installed.
Initialize JAX backend.
- Parameters:
seed – Random seed for reproducibility
- __init__(seed: int | None = None)[source]¶
Initialize JAX backend.
- Parameters:
seed – Random seed for reproducibility
- supports_sparse() bool[source]¶
JAX has experimental sparse array support (BCOO format).
Note: jax.experimental.sparse exists but is not feature-complete.
- zeros(shape: int | Tuple[int, ...], dtype: str = 'float32') Any[source]¶
Create an array of zeros with the given shape and dtype.
- ones(shape: int | Tuple[int, ...], dtype: str = 'float32') Any[source]¶
Create an array of ones with the given shape and dtype.
- random_normal(shape: int | Tuple[int, ...], mean: float = 0.0, std: float = 1.0, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create an array of random values from a normal distribution.
- random_uniform(shape: int | Tuple[int, ...], low: float = 0.0, high: float = 1.0, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create an array of random values from a uniform distribution.
- random_binary(shape: int | Tuple[int, ...], p: float = 0.5, dtype: str = 'int32', seed: int | None = None) Any[source]¶
Create a binary array with probability p of being 1.
- random_bipolar(shape: int | Tuple[int, ...], p: float = 0.5, dtype: str = 'float32', seed: int | None = None) Any[source]¶
Create a bipolar array {-1, +1} with probability p of being +1.
- random_phasor(shape: int | Tuple[int, ...], dtype: str = 'complex64', seed: int | None = None) Any[source]¶
Create an array of random unit phasors (complex numbers with magnitude 1).
- array(data, dtype: str | None = None) Any[source]¶
Create an array from Python data (list, tuple, etc.).
- norm(a: Any, ord: int | str = 2, axis: int | None = None) Any[source]¶
Compute the norm of an array.
- max(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Maximum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to compute max (None for global max)
keepdims – Whether to keep dimensions
- Returns:
Maximum value(s)
- min(a: Any, axis: int | None = None, keepdims: bool = False) Any[source]¶
Minimum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to compute min (None for global min)
keepdims – Whether to keep dimensions
- Returns:
Minimum value(s)
- argmax(a: Any, axis: int | None = None) Any[source]¶
Index of maximum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to find argmax (None for global argmax)
- Returns:
Index/indices of maximum value(s)
- argmin(a: Any, axis: int | None = None) Any[source]¶
Index of minimum value along an axis.
- Parameters:
a – Input array
axis – Axis along which to find argmin (None for global argmin)
- Returns:
Index/indices of minimum value(s)
- normalize(a: Any, ord: int | str = 2, axis: int | None = None, eps: float = 1e-12) Any[source]¶
Normalize an array to unit norm.
- threshold(a: Any, threshold: float, above: float = 1.0, below: float = 0.0) Any[source]¶
Threshold array values.
- concatenate(arrays: Sequence[Any], axis: int = 0) Any[source]¶
Concatenate arrays along an existing axis.
- svd(a: Any, full_matrices: bool = True) Tuple[Any, Any, Any][source]¶
Compute Singular Value Decomposition.
JAX’s SVD natively supports batched operations.
See Also¶
Backends and Performance - Backend selection guide