extended-einsum 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. extended_einsum-0.1.0/LICENSE +21 -0
  2. extended_einsum-0.1.0/PKG-INFO +139 -0
  3. extended_einsum-0.1.0/README.md +104 -0
  4. extended_einsum-0.1.0/pyproject.toml +85 -0
  5. extended_einsum-0.1.0/src/extended_einsum/__init__.py +43 -0
  6. extended_einsum-0.1.0/src/extended_einsum/backend_translation/__init__.py +7 -0
  7. extended_einsum-0.1.0/src/extended_einsum/backend_translation/backend.py +110 -0
  8. extended_einsum-0.1.0/src/extended_einsum/backend_translation/runtime.py +21 -0
  9. extended_einsum-0.1.0/src/extended_einsum/backend_translation/translate.py +760 -0
  10. extended_einsum-0.1.0/src/extended_einsum/backends/__init__.py +1 -0
  11. extended_einsum-0.1.0/src/extended_einsum/backends/jax.py +128 -0
  12. extended_einsum-0.1.0/src/extended_einsum/backends/numpy.py +130 -0
  13. extended_einsum-0.1.0/src/extended_einsum/backends/registry.py +41 -0
  14. extended_einsum-0.1.0/src/extended_einsum/backends/torch.py +158 -0
  15. extended_einsum-0.1.0/src/extended_einsum/interface/__init__.py +35 -0
  16. extended_einsum-0.1.0/src/extended_einsum/interface/functions.py +173 -0
  17. extended_einsum-0.1.0/src/extended_einsum/interface/operator.py +63 -0
  18. extended_einsum-0.1.0/src/extended_einsum/interface/tensor_expression.py +333 -0
  19. extended_einsum-0.1.0/src/extended_einsum/language/__init__.py +1 -0
  20. extended_einsum-0.1.0/src/extended_einsum/language/core.py +28 -0
  21. extended_einsum-0.1.0/src/extended_einsum/language/rich_instruction.py +18 -0
  22. extended_einsum-0.1.0/src/extended_einsum/language/rich_operators.py +437 -0
  23. extended_einsum-0.1.0/src/extended_einsum/language/rich_program.py +62 -0
  24. extended_einsum-0.1.0/src/extended_einsum/language/types.py +30 -0
  25. extended_einsum-0.1.0/src/extended_einsum/preprocess.py +2382 -0
  26. extended_einsum-0.1.0/src/extended_einsum/py.typed +0 -0
  27. extended_einsum-0.1.0/src/extended_einsum/shapes.py +89 -0
  28. extended_einsum-0.1.0/src/extended_einsum/utils.py +73 -0
  29. extended_einsum-0.1.0/src/extended_einsum/visualization.py +648 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FSU Theoretical Computer Science II
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: extended-einsum
3
+ Version: 0.1.0
4
+ Summary: Build, optimize, and execute numerically stable extended Einstein summation expressions with PyTorch, NumPy, and optional JAX.
5
+ Keywords: einsum,machine-learning,probabilistic circuits,tensor
6
+ Author: Christoph Staudt, Maurice Wenig
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: numpy>=2.1.6
20
+ Requires-Dist: sesum>=0.4.0
21
+ Requires-Dist: torch>=2.12.0
22
+ Requires-Dist: jax>=0.10.1 ; extra == 'jax'
23
+ Requires-Dist: jax[cuda13]>=0.10.1 ; extra == 'jax-cuda'
24
+ Requires-Dist: matplotlib>=3.10.9 ; extra == 'visualization'
25
+ Requires-Dist: networkx>=3.6.1 ; extra == 'visualization'
26
+ Requires-Python: >=3.12
27
+ Project-URL: Homepage, https://github.com/ti2-group/extended_einsum
28
+ Project-URL: Repository, https://github.com/ti2-group/extended_einsum
29
+ Project-URL: Issues, https://github.com/ti2-group/extended_einsum/issues
30
+ Project-URL: Changelog, https://github.com/ti2-group/extended_einsum/blob/main/CHANGELOG.md
31
+ Provides-Extra: jax
32
+ Provides-Extra: jax-cuda
33
+ Provides-Extra: visualization
34
+ Description-Content-Type: text/markdown
35
+
36
+ # extended-einsum
37
+
38
+ [![CI](https://github.com/ti2-group/extended_einsum/actions/workflows/ci.yml/badge.svg)](https://github.com/ti2-group/extended_einsum/actions/workflows/ci.yml)
39
+ [![PyPI](https://img.shields.io/pypi/v/extended-einsum.svg)](https://pypi.org/project/extended-einsum/)
40
+ [![Python](https://img.shields.io/pypi/pyversions/extended-einsum.svg)](https://pypi.org/project/extended-einsum/)
41
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ti2-group/extended_einsum/blob/main/LICENSE)
42
+
43
+ `extended-einsum` builds tensor-expression graphs, rewrites contraction programs, and executes them with numerically stable evaluation strategies. PyTorch is the primary backend; NumPy is included in the base installation and JAX is optional.
44
+
45
+ The package is an expression engine, not a drop-in replacement for `torch.einsum` or `numpy.einsum`. Wrap backend arrays with `xe.array`, compose operations lazily, then call `materialize`.
46
+
47
+ > **Status:** `0.1.0` is an alpha release. The public expression API is usable, but indexing and some operators or stability-mode combinations are not implemented yet.
48
+
49
+ ## Installation
50
+
51
+ Python 3.12, 3.13, and 3.14 are supported.
52
+
53
+ ```bash
54
+ pip install extended-einsum
55
+ ```
56
+
57
+ Optional features are installed explicitly:
58
+
59
+ ```bash
60
+ pip install "extended-einsum[jax]"
61
+ pip install "extended-einsum[jax-cuda]"
62
+ pip install "extended-einsum[visualization]"
63
+ ```
64
+
65
+ The CUDA extra follows JAX's CUDA 13 installation. PyTorch device support is determined by the PyTorch build available from your configured package index.
66
+
67
+ ## Quickstart
68
+
69
+ ```python
70
+ import torch
71
+ import extended_einsum as xe
72
+
73
+ left_torch = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
74
+ right_torch = torch.tensor([[2.0, 0.0], [1.0, 2.0]])
75
+
76
+ left = xe.array(left_torch)
77
+ right = xe.array(right_torch)
78
+ expression = xe.einsum("ik,kj->ij", xe.exp(left), right)
79
+ result = expression.materialize(stability_mode="unstable")
80
+
81
+ assert torch.allclose(
82
+ result.backend_array,
83
+ torch.einsum("ik,kj->ij", torch.exp(left_torch), right_torch),
84
+ )
85
+ ```
86
+
87
+ The same interface accepts NumPy arrays. With the `jax` extra installed it also accepts JAX arrays:
88
+
89
+ ```python
90
+ import numpy as np
91
+ import extended_einsum as xe
92
+
93
+ source = xe.array(np.arange(6.0).reshape(2, 3))
94
+ result = xe.softmax(source, axis=1).materialize()
95
+ print(result.backend_array)
96
+ ```
97
+
98
+ ## Expressions and stability
99
+
100
+ The public interface currently includes:
101
+
102
+ - `array`, `einsum`, `stack`, `take`, `slice`, and `select`
103
+ - `exp`, `log`, `sin`, `cos`, `tan`, `sqrt`, `inverse`, and `softmax`
104
+ - `TensorExpression.materialize` and `extract_program`
105
+
106
+ Supported execution backends are PyTorch, NumPy, and optional JAX. Rich programs can be evaluated in `unstable`, `scaled_min`, `scaled_sum`, `logspace_min`, or `logspace_max` mode. Support is operator-dependent; unsupported combinations raise `NotImplementedError` instead of silently changing semantics.
107
+
108
+ The preprocessing API also provides expression folding and contraction-path optimization. DAG plotting is available from `extended_einsum.visualization` when the visualization extra is installed.
109
+
110
+ ## Examples
111
+
112
+ All introductory scripts in [`examples/`](https://github.com/ti2-group/extended_einsum/tree/main/examples) are standalone: copy one into another project with `extended-einsum` installed and run it from any working directory.
113
+
114
+ ```bash
115
+ python examples/torch_quickstart.py
116
+ python examples/numpy_backend.py
117
+ python examples/stable_materialization.py
118
+ python examples/jax_backend.py # requires [jax]
119
+ python examples/visualize_expression.py graph.png # requires [visualization]
120
+ ```
121
+
122
+ The advanced [`demo/cirkit.py`](https://github.com/ti2-group/extended_einsum/blob/main/demo/cirkit.py) integration is also standalone, but requires the repository demo dependencies and currently Python 3.12 or 3.13 because of Cirkit's SciPy constraint. Its defaults use a small synthetic circuit; training and benchmark sweeps are opt-in. Generated benchmark data and plots are repository artifacts and are never included in distributions.
123
+
124
+ ## Development
125
+
126
+ This project uses [uv](https://docs.astral.sh/uv/):
127
+
128
+ ```bash
129
+ uv sync --group dev --group demo --extra jax --extra visualization
130
+ uv run ruff check .
131
+ uv run pytest
132
+ uv build
133
+ ```
134
+
135
+ See [CONTRIBUTING.md](https://github.com/ti2-group/extended_einsum/blob/main/CONTRIBUTING.md) for development details and [PUBLISHING.md](https://github.com/ti2-group/extended_einsum/blob/main/PUBLISHING.md) for the release process.
136
+
137
+ ## License
138
+
139
+ Copyright © 2026 FSU Theoretical Computer Science II. Distributed under the [MIT License](https://github.com/ti2-group/extended_einsum/blob/main/LICENSE).
@@ -0,0 +1,104 @@
1
+ # extended-einsum
2
+
3
+ [![CI](https://github.com/ti2-group/extended_einsum/actions/workflows/ci.yml/badge.svg)](https://github.com/ti2-group/extended_einsum/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/extended-einsum.svg)](https://pypi.org/project/extended-einsum/)
5
+ [![Python](https://img.shields.io/pypi/pyversions/extended-einsum.svg)](https://pypi.org/project/extended-einsum/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ti2-group/extended_einsum/blob/main/LICENSE)
7
+
8
+ `extended-einsum` builds tensor-expression graphs, rewrites contraction programs, and executes them with numerically stable evaluation strategies. PyTorch is the primary backend; NumPy is included in the base installation and JAX is optional.
9
+
10
+ The package is an expression engine, not a drop-in replacement for `torch.einsum` or `numpy.einsum`. Wrap backend arrays with `xe.array`, compose operations lazily, then call `materialize`.
11
+
12
+ > **Status:** `0.1.0` is an alpha release. The public expression API is usable, but indexing and some operators or stability-mode combinations are not implemented yet.
13
+
14
+ ## Installation
15
+
16
+ Python 3.12, 3.13, and 3.14 are supported.
17
+
18
+ ```bash
19
+ pip install extended-einsum
20
+ ```
21
+
22
+ Optional features are installed explicitly:
23
+
24
+ ```bash
25
+ pip install "extended-einsum[jax]"
26
+ pip install "extended-einsum[jax-cuda]"
27
+ pip install "extended-einsum[visualization]"
28
+ ```
29
+
30
+ The CUDA extra follows JAX's CUDA 13 installation. PyTorch device support is determined by the PyTorch build available from your configured package index.
31
+
32
+ ## Quickstart
33
+
34
+ ```python
35
+ import torch
36
+ import extended_einsum as xe
37
+
38
+ left_torch = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
39
+ right_torch = torch.tensor([[2.0, 0.0], [1.0, 2.0]])
40
+
41
+ left = xe.array(left_torch)
42
+ right = xe.array(right_torch)
43
+ expression = xe.einsum("ik,kj->ij", xe.exp(left), right)
44
+ result = expression.materialize(stability_mode="unstable")
45
+
46
+ assert torch.allclose(
47
+ result.backend_array,
48
+ torch.einsum("ik,kj->ij", torch.exp(left_torch), right_torch),
49
+ )
50
+ ```
51
+
52
+ The same interface accepts NumPy arrays. With the `jax` extra installed it also accepts JAX arrays:
53
+
54
+ ```python
55
+ import numpy as np
56
+ import extended_einsum as xe
57
+
58
+ source = xe.array(np.arange(6.0).reshape(2, 3))
59
+ result = xe.softmax(source, axis=1).materialize()
60
+ print(result.backend_array)
61
+ ```
62
+
63
+ ## Expressions and stability
64
+
65
+ The public interface currently includes:
66
+
67
+ - `array`, `einsum`, `stack`, `take`, `slice`, and `select`
68
+ - `exp`, `log`, `sin`, `cos`, `tan`, `sqrt`, `inverse`, and `softmax`
69
+ - `TensorExpression.materialize` and `extract_program`
70
+
71
+ Supported execution backends are PyTorch, NumPy, and optional JAX. Rich programs can be evaluated in `unstable`, `scaled_min`, `scaled_sum`, `logspace_min`, or `logspace_max` mode. Support is operator-dependent; unsupported combinations raise `NotImplementedError` instead of silently changing semantics.
72
+
73
+ The preprocessing API also provides expression folding and contraction-path optimization. DAG plotting is available from `extended_einsum.visualization` when the visualization extra is installed.
74
+
75
+ ## Examples
76
+
77
+ All introductory scripts in [`examples/`](https://github.com/ti2-group/extended_einsum/tree/main/examples) are standalone: copy one into another project with `extended-einsum` installed and run it from any working directory.
78
+
79
+ ```bash
80
+ python examples/torch_quickstart.py
81
+ python examples/numpy_backend.py
82
+ python examples/stable_materialization.py
83
+ python examples/jax_backend.py # requires [jax]
84
+ python examples/visualize_expression.py graph.png # requires [visualization]
85
+ ```
86
+
87
+ The advanced [`demo/cirkit.py`](https://github.com/ti2-group/extended_einsum/blob/main/demo/cirkit.py) integration is also standalone, but requires the repository demo dependencies and currently Python 3.12 or 3.13 because of Cirkit's SciPy constraint. Its defaults use a small synthetic circuit; training and benchmark sweeps are opt-in. Generated benchmark data and plots are repository artifacts and are never included in distributions.
88
+
89
+ ## Development
90
+
91
+ This project uses [uv](https://docs.astral.sh/uv/):
92
+
93
+ ```bash
94
+ uv sync --group dev --group demo --extra jax --extra visualization
95
+ uv run ruff check .
96
+ uv run pytest
97
+ uv build
98
+ ```
99
+
100
+ See [CONTRIBUTING.md](https://github.com/ti2-group/extended_einsum/blob/main/CONTRIBUTING.md) for development details and [PUBLISHING.md](https://github.com/ti2-group/extended_einsum/blob/main/PUBLISHING.md) for the release process.
101
+
102
+ ## License
103
+
104
+ Copyright © 2026 FSU Theoretical Computer Science II. Distributed under the [MIT License](https://github.com/ti2-group/extended_einsum/blob/main/LICENSE).
@@ -0,0 +1,85 @@
1
+ [project]
2
+ name = "extended-einsum"
3
+ version = "0.1.0"
4
+ description = "Build, optimize, and execute numerically stable extended Einstein summation expressions with PyTorch, NumPy, and optional JAX."
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ authors = [
10
+ { name = "Christoph Staudt" },
11
+ { name = "Maurice Wenig" },
12
+ ]
13
+ keywords = [
14
+ "einsum",
15
+ "machine-learning",
16
+ "probabilistic circuits",
17
+ "tensor",
18
+ ]
19
+ classifiers = [
20
+ "Intended Audience :: Developers",
21
+ "Intended Audience :: Science/Research",
22
+ "Operating System :: OS Independent",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Programming Language :: Python :: 3.14",
27
+ "Topic :: Scientific/Engineering",
28
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
29
+ "Typing :: Typed",
30
+ ]
31
+ dependencies = [
32
+ "numpy>=2.1.6",
33
+ "sesum>=0.4.0",
34
+ "torch>=2.12.0",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ jax = ["jax>=0.10.1"]
39
+ jax-cuda = ["jax[cuda13]>=0.10.1"]
40
+ visualization = [
41
+ "matplotlib>=3.10.9",
42
+ "networkx>=3.6.1",
43
+ ]
44
+
45
+ [project.urls]
46
+ Homepage = "https://github.com/ti2-group/extended_einsum"
47
+ Repository = "https://github.com/ti2-group/extended_einsum"
48
+ Issues = "https://github.com/ti2-group/extended_einsum/issues"
49
+ Changelog = "https://github.com/ti2-group/extended_einsum/blob/main/CHANGELOG.md"
50
+
51
+ [build-system]
52
+ requires = ["uv_build>=0.11.19,<0.12.0"]
53
+ build-backend = "uv_build"
54
+
55
+ [tool.uv]
56
+ constraint-dependencies = [
57
+ "numpy>=2.3.0; python_version >= '3.14'",
58
+ "scipy>=1.17.0; python_version >= '3.14'",
59
+ ]
60
+
61
+ [dependency-groups]
62
+ demo = [
63
+ "libcirkit>=0.2.1; python_version < '3.14'",
64
+ "matplotlib>=3.10.9",
65
+ "networkx>=3.6.1",
66
+ "pandas>=2.3.3",
67
+ "seaborn>=0.13.2",
68
+ "torchvision>=0.27.0",
69
+ ]
70
+ dev = [
71
+ "pytest>=9.1.1",
72
+ "ruff>=0.6.0",
73
+ ]
74
+
75
+ [tool.ruff]
76
+ line-length = 200
77
+ target-version = "py312"
78
+
79
+ [tool.ruff.lint]
80
+ select = ["E", "F", "I"]
81
+
82
+ [tool.ruff.format]
83
+ quote-style = "double"
84
+ indent-style = "space"
85
+ line-ending = "lf"
@@ -0,0 +1,43 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ from extended_einsum.interface import TensorExpression as TensorExpression
4
+ from extended_einsum.interface import array as array
5
+ from extended_einsum.interface import cos as cos
6
+ from extended_einsum.interface import einsum as einsum
7
+ from extended_einsum.interface import exp as exp
8
+ from extended_einsum.interface import extract_program as extract_program
9
+ from extended_einsum.interface import inverse as inverse
10
+ from extended_einsum.interface import log as log
11
+ from extended_einsum.interface import select as select
12
+ from extended_einsum.interface import sin as sin
13
+ from extended_einsum.interface import slice as slice
14
+ from extended_einsum.interface import softmax as softmax
15
+ from extended_einsum.interface import sqrt as sqrt
16
+ from extended_einsum.interface import stack as stack
17
+ from extended_einsum.interface import take as take
18
+ from extended_einsum.interface import tan as tan
19
+
20
+ try:
21
+ __version__ = version("extended-einsum")
22
+ except PackageNotFoundError:
23
+ __version__ = "0.1.0.dev0"
24
+
25
+ __all__ = [
26
+ "TensorExpression",
27
+ "__version__",
28
+ "array",
29
+ "cos",
30
+ "einsum",
31
+ "exp",
32
+ "extract_program",
33
+ "inverse",
34
+ "log",
35
+ "select",
36
+ "sin",
37
+ "slice",
38
+ "softmax",
39
+ "sqrt",
40
+ "stack",
41
+ "take",
42
+ "tan",
43
+ ]
@@ -0,0 +1,7 @@
1
+ from .backend import BackendArray as BackendArray
2
+ from .backend import BackendCompiler as BackendCompiler
3
+ from .backend import BackendFunctions as BackendFunctions
4
+ from .backend import BackendProgram as BackendProgram
5
+ from .backend import get_backend_of_array as get_backend_of_array
6
+ from .runtime import run_program as run_program
7
+ from .translate import translate_to_backend_program as translate_to_backend_program
@@ -0,0 +1,110 @@
1
+ from collections.abc import Sequence
2
+ from dataclasses import dataclass
3
+ from typing import Callable, Generic, Protocol, TypeVar
4
+
5
+ import numpy as np
6
+ import torch
7
+
8
+ from extended_einsum.language.types import Backend, HasShape
9
+
10
+
11
+ class BackendArray(Protocol):
12
+ @property
13
+ def shape(self) -> tuple[int, ...] | torch.Size: ...
14
+
15
+
16
+ TBackendArray = TypeVar("TBackendArray", bound=BackendArray)
17
+
18
+
19
+ class BackendFunctions(Protocol[TBackendArray]):
20
+ @staticmethod
21
+ def stop_gradient(array: TBackendArray) -> TBackendArray: ...
22
+
23
+ @staticmethod
24
+ def exp(array: TBackendArray) -> TBackendArray: ...
25
+
26
+ @staticmethod
27
+ def log(array: TBackendArray) -> TBackendArray: ...
28
+
29
+ @staticmethod
30
+ def sum(array: TBackendArray, axis: int | tuple[int, ...] | None = None, keepdims: bool = False) -> TBackendArray: ...
31
+
32
+ @staticmethod
33
+ def max(array: TBackendArray, axis: int | tuple[int, ...] | None = None, keepdims: bool = False) -> TBackendArray: ...
34
+
35
+ @staticmethod
36
+ def min(array: TBackendArray, axis: int | tuple[int, ...] | None = None, keepdims: bool = False) -> TBackendArray: ...
37
+
38
+ @staticmethod
39
+ def maximum(array_1: TBackendArray, array_2: TBackendArray) -> TBackendArray: ...
40
+
41
+ @staticmethod
42
+ def reshape(array: TBackendArray, shape: tuple[int, ...]) -> TBackendArray: ...
43
+
44
+ @staticmethod
45
+ def broadcast_to(array: TBackendArray, shape: tuple[int, ...]) -> TBackendArray: ...
46
+
47
+ @staticmethod
48
+ def stack(arrays: Sequence[TBackendArray], axis: int) -> TBackendArray: ...
49
+
50
+ @staticmethod
51
+ def concat(arrays: Sequence[TBackendArray], axis: int) -> TBackendArray: ...
52
+
53
+ @staticmethod
54
+ def take(array: TBackendArray, indices: TBackendArray, axis: int) -> TBackendArray: ...
55
+
56
+ @staticmethod
57
+ def select(array: TBackendArray, axis: int, index: int) -> TBackendArray: ...
58
+
59
+ @staticmethod
60
+ def slice(array: TBackendArray, start: int, stop: int, axis: int) -> TBackendArray: ...
61
+
62
+ @staticmethod
63
+ def softmax(array: TBackendArray, axis: int | tuple[int, ...]) -> TBackendArray: ...
64
+
65
+ @staticmethod
66
+ def einsum(format_string: str, *operands: TBackendArray) -> TBackendArray: ...
67
+
68
+ @staticmethod
69
+ def add(summand_array_1: TBackendArray, summand_array_2: TBackendArray) -> TBackendArray: ...
70
+
71
+ @staticmethod
72
+ def subtract(minuend_array: TBackendArray, subtrahend_array: TBackendArray) -> TBackendArray: ...
73
+
74
+ @staticmethod
75
+ def multiply(factor_array_1: TBackendArray, factor_array_2: TBackendArray) -> TBackendArray: ...
76
+
77
+ @staticmethod
78
+ def divide(dividend_array: TBackendArray, divisor_array: TBackendArray) -> TBackendArray: ...
79
+
80
+
81
+ @dataclass(frozen=True)
82
+ class BackendProgram(Generic[TBackendArray]):
83
+ backend_calls: list[Callable[[Sequence[TBackendArray]], TBackendArray]]
84
+ call_arguments: list[tuple[int, ...]]
85
+ n_inputs: int
86
+
87
+
88
+ class BackendCompiler(Protocol[TBackendArray]):
89
+ @staticmethod
90
+ def compile(
91
+ program: BackendProgram[TBackendArray],
92
+ inputs: Sequence[TBackendArray],
93
+ ) -> Callable[[Sequence[TBackendArray]], TBackendArray]: ...
94
+
95
+
96
+ def get_backend_of_array(array: HasShape) -> Backend:
97
+ if isinstance(array, torch.Tensor):
98
+ return "torch"
99
+ elif isinstance(array, np.ndarray):
100
+ return "numpy"
101
+
102
+ try:
103
+ import jax
104
+ except ModuleNotFoundError:
105
+ jax = None # type: ignore[assignment]
106
+
107
+ if jax is not None and isinstance(array, jax.Array):
108
+ return "jax"
109
+
110
+ raise ValueError(f"Unsupported array type: {type(array)}")
@@ -0,0 +1,21 @@
1
+ from collections.abc import Sequence
2
+ from typing import TypeVar
3
+
4
+ from extended_einsum.backend_translation.backend import BackendArray, BackendProgram
5
+
6
+ TBackendArray = TypeVar("TBackendArray", bound=BackendArray)
7
+
8
+
9
+ def run_program(
10
+ program: BackendProgram[TBackendArray],
11
+ inputs: Sequence[TBackendArray],
12
+ ) -> TBackendArray:
13
+ if len(inputs) != program.n_inputs:
14
+ raise ValueError(f"The number of inputs ({len(inputs)}) does not match the number of inputs ({program.n_inputs}) in the program.")
15
+
16
+ tensors: list[TBackendArray] = list(inputs)
17
+ for backend_call, argument_ids in zip(program.backend_calls, program.call_arguments):
18
+ argument_tensors = [tensors[argument] for argument in argument_ids]
19
+ result = backend_call(argument_tensors)
20
+ tensors.append(result)
21
+ return tensors[-1]