Abstract your array operations (autoray)

0.8.10 · active · verified Sun Apr 12

Autoray is a lightweight Python library designed to abstract array and tensor operations, enabling users to write backend-agnostic numeric code. It provides an automatic dispatch mechanism that works across various array libraries such as NumPy, PyTorch, JAX, TensorFlow, CuPy, Dask, and more, as long as they provide a NumPy-ish API. This allows for swapping custom functions, lazy computation tracing, and unified compilation interfaces. The library is actively maintained, with its current version being 0.8.10, and sees a continuous release cadence.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates the core functionalities of `autoray`: automatic backend dispatch using `ar.do()`, explicit backend selection with the `like` argument, and obtaining a backend-specific API using `ar.get_namespace()`. It also shows how to define a function that works generically across different array backends.

import autoray as ar
import numpy as np

# Basic usage with automatic dispatch (inferred from array type)
x_np = np.random.uniform(size=)
y_np = ar.do('sqrt', x_np)
print(f"Numpy sqrt: {y_np}, type: {type(y_np)}")

# Using 'like' argument for explicit backend or inference
# If torch is not installed, this will silently fall back to numpy behavior
# For full torch functionality, ensure 'torch' is installed.
x_torch_like = ar.do('random.uniform', size=(10, 10), like="torch")
print(f"Array generated with 'like="torch"': {type(x_torch_like)}")

# Using get_namespace for a backend-specific API (Python Array API style)
try:
    # Attempt to get a torch namespace
    xp = ar.get_namespace(like="torch") # Requires 'torch' to be installed for actual torch arrays
    z = xp.ones((3, 4), dtype=xp.float32)
    result = xp.exp(z)
    print(f"Torch-like exp result shape: {result.shape}, type: {type(result)}")
except (ImportError, TypeError):
    # Fallback if torch is not installed, get numpy namespace
    xp = ar.get_namespace(like="numpy")
    z = xp.ones((3, 4), dtype=xp.float32)
    result = xp.exp(z)
    print(f"Numpy-like exp result shape (fallback): {result.shape}, type: {type(result)}")

# Example of a more complex operation with automatic dispatch
def noised_svd(x):
    U, s, VH = ar.do('linalg.svd', x)
    sn = s + 0.1 * ar.do('random.normal', size=ar.shape(s), like=s)
    return ar.do('einsum', 'ij,j,jk->ik', U, sn, VH)

# Use a numpy array for demonstration
x_complex_op = np.random.rand(10, 10)
y_complex_op = noised_svd(x_complex_op)
print(f"Complex operation result shape: {y_complex_op.shape}")

view raw JSON →