extended-einsum 0.1.0__py3-none-any.whl
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.
- extended_einsum/__init__.py +43 -0
- extended_einsum/backend_translation/__init__.py +7 -0
- extended_einsum/backend_translation/backend.py +110 -0
- extended_einsum/backend_translation/runtime.py +21 -0
- extended_einsum/backend_translation/translate.py +760 -0
- extended_einsum/backends/__init__.py +1 -0
- extended_einsum/backends/jax.py +128 -0
- extended_einsum/backends/numpy.py +130 -0
- extended_einsum/backends/registry.py +41 -0
- extended_einsum/backends/torch.py +158 -0
- extended_einsum/interface/__init__.py +35 -0
- extended_einsum/interface/functions.py +173 -0
- extended_einsum/interface/operator.py +63 -0
- extended_einsum/interface/tensor_expression.py +333 -0
- extended_einsum/language/__init__.py +1 -0
- extended_einsum/language/core.py +28 -0
- extended_einsum/language/rich_instruction.py +18 -0
- extended_einsum/language/rich_operators.py +437 -0
- extended_einsum/language/rich_program.py +62 -0
- extended_einsum/language/types.py +30 -0
- extended_einsum/preprocess.py +2382 -0
- extended_einsum/py.typed +0 -0
- extended_einsum/shapes.py +89 -0
- extended_einsum/utils.py +73 -0
- extended_einsum/visualization.py +648 -0
- extended_einsum-0.1.0.dist-info/METADATA +139 -0
- extended_einsum-0.1.0.dist-info/RECORD +29 -0
- extended_einsum-0.1.0.dist-info/WHEEL +4 -0
- extended_einsum-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -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]
|