Metadata-Version: 2.5
Name: anytensor
Version: 1.0.0
Summary: Portable tensor ops across NumPy, JAX, PyTorch, and TensorFlow, with segment/GNN primitives.
Project-URL: Repository, https://github.com/swamidass/anytensor
Project-URL: Issues, https://github.com/swamidass/anytensor/issues
Project-URL: Documentation, https://swamidass.github.io/anytensor/
Author-email: "S. Joshua Swamidass" <swamidass@gmail.com>
License-Expression: MIT
License-File: LICENSE
License-File: NOTICE
Requires-Python: >=3.10
Requires-Dist: array-api-compat>=1.15
Requires-Dist: einops>=0.8.1
Requires-Dist: jaxtyping>=0.2.34
Requires-Dist: numpy>=1.24
Provides-Extra: all
Requires-Dist: beartype>=0.18; extra == 'all'
Requires-Dist: jax>=0.4.32; extra == 'all'
Requires-Dist: tensorflow>=2.13; extra == 'all'
Requires-Dist: torch>=2.1; extra == 'all'
Provides-Extra: jax
Requires-Dist: jax>=0.4.32; extra == 'jax'
Provides-Extra: tensorflow
Requires-Dist: tensorflow>=2.13; extra == 'tensorflow'
Provides-Extra: torch
Requires-Dist: torch>=2.1; extra == 'torch'
Provides-Extra: typecheck
Requires-Dist: beartype>=0.18; extra == 'typecheck'
Description-Content-Type: text/markdown

# AnyTensor

Portable tensor ops across **NumPy**, **JAX**, **PyTorch**, and **TensorFlow**, with a focus on **segment / GNN** primitives.

Write a helper once; run it on whatever tensor the caller already has. Ordinary math uses the [Python Array API](https://data-apis.org/array-api/latest/) via [`array-api-compat`](https://github.com/data-apis/array-api-compat). Segment reductions stay on thin input-adaptive backends.

**Docs** (motivation, GAT-style case study, design, API): <https://swamidass.github.io/anytensor/> — or `uv run --group docs mkdocs serve` from a checkout ([`docs/`](docs/index.md)).

We follow [Semantic Versioning](https://semver.org/): breaking changes require a **major** bump. Portability is backed by cross-backend / symbolic fuzz, a coverage gate, and pytest-run docs examples ([Design](docs/design.md#how-we-keep-the-contract-honest)).

## Install

```bash
pip install "anytensor @ git+https://github.com/swamidass/anytensor.git"
# optional backends (NumPy is a core dependency)
pip install "anytensor[jax]" "anytensor[torch]" "anytensor[tensorflow]"
# or
pip install "anytensor[all]"
```

Requires Python ≥3.10. Backend floors: NumPy ≥1.24, JAX ≥0.4.32, PyTorch ≥2.1, TensorFlow ≥2.13.

## Quick start

```python
import anytensor as at
import numpy as np

x = np.arange(12.0).reshape(3, 4)
seg_ids = np.array([0, 0, 1])
y = at.segment_sum(x, seg_ids, num_segments=2)
```

The same call works on JAX / Torch / TF tensors. `num_segments` is **required** (JAX convention).

Read next:

- [Home / motivation](docs/index.md) — why AnyTensor, GAT neighbor-softmax case study across four backends
- [Design](docs/design.md) — principles, edge cases, **testing as contract**, SemVer
- [Usage](docs/usage.md) — promotion, segment helpers, `torch.compile`, typing
- [Surprising differences](docs/semantics.md) — NaN / ±inf / graph / GPU gotchas from fuzz
- [API reference](docs/api/index.md) — generated from docstrings
- [Contributing](docs/contributing.md) — tests, fuzz, docs build

## Docs / tests (checkout)

```bash
uv sync --extra all --group dev --group docs
uv run mkdocs serve
uv run pytest -m "not fuzz" --cov=anytensor --cov-report=term-missing
```

## License

MIT. Backend dispatch patterns adapted from [einops](https://github.com/arogozhnikov/einops); see `NOTICE`.
