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.
@@ -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]