Skip to content

Commit 2ba7b24

Browse files
committed
drop einsum parser in favor of opt_einsum
1 parent 71eab2c commit 2ba7b24

1 file changed

Lines changed: 4 additions & 34 deletions

File tree

effectful/handlers/jax/monoid.py

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -786,39 +786,6 @@ def _(self, monoid: Monoid, body, streams: Streams):
786786
return contraction
787787

788788

789-
def _parse_einsum_spec(
790-
subscripts: str, *operands: tuple[int, ...]
791-
) -> tuple[list[str], str]:
792-
"""Parse a numpy/jax-style einsum subscripts string.
793-
794-
Supports explicit ``"ij,jk->ik"`` and implicit ``"ij,jk"`` forms; in the
795-
implicit case the output is each letter appearing exactly once across all
796-
inputs, sorted alphabetically. Does not support ellipsis ``...``.
797-
"""
798-
if "..." in subscripts:
799-
raise NotImplementedError("einsum ellipsis not yet supported")
800-
if "->" in subscripts:
801-
in_part, out_spec = subscripts.split("->")
802-
else:
803-
in_part = subscripts
804-
counts: dict[str, int] = {}
805-
for c in in_part.replace(",", ""):
806-
counts[c] = counts.get(c, 0) + 1
807-
out_spec = "".join(sorted(c for c, n in counts.items() if n == 1))
808-
in_specs = in_part.split(",")
809-
if len(in_specs) != len(operands):
810-
raise ValueError(
811-
f"einsum: {len(in_specs)} input specs but {len(operands)} operands"
812-
)
813-
for spec, shape in zip(in_specs, operands, strict=True):
814-
if len(spec) != len(shape):
815-
raise ValueError(
816-
f"einsum spec {spec!r} has {len(spec)} indices but operand "
817-
f"has shape {shape}"
818-
)
819-
return in_specs, out_spec
820-
821-
822789
def _named_dims(term: Expr[jax.Array]) -> tuple[Operation, ...]:
823790
if not (isinstance(term, Term) and term.op == jax_getitem):
824791
return ()
@@ -921,7 +888,10 @@ def einsum(subscripts: str, /, *operands: jax.Array) -> jax.Array:
921888
if not operands:
922889
raise ValueError("einsum requires at least one operand")
923890

924-
in_specs, out_spec = _parse_einsum_spec(subscripts, *[op.shape for op in operands])
891+
in_spec, out_spec, _ = opt_einsum.parser.parse_einsum_input(
892+
[subscripts, *(op.shape for op in operands)], shapes=True
893+
)
894+
in_specs = in_spec.split(",")
925895

926896
all_letters = set(out_spec) | {c for s in in_specs for c in s}
927897
ops = {c: Operation.define(jax.Array, name=c) for c in all_letters}

0 commit comments

Comments
 (0)