# Source code for tensorplay._einsum Source: https://www.tensorplay.cn/docs/_modules/tensorplay/_einsum.html ``` # checking, contraction-order planning and the algorithm itself -- lives in # dependency is needed: with more than two operands the kernel plans the # contraction order itself (exact search for small counts, greedy beyond). def _parse_subscript(n): if n is Ellipsis: return "..." if isinstance(n, int) and 0 <= n < 52: return chr(ord("A") + n) if n < 26 else chr(ord("a") + n - 26) raise ValueError( "einsum(): subscript in subscript list is not within the valid range [0, 52)" ) def parse_equation(args): import tensorplay if isinstance(args[0], tensorplay.Tensor): # Convert the subscript list format (an interleaving of operand and # its subscripts list with an optional output subscripts list at the # end) to the equation string format. equation = ",".join( "".join(_parse_subscript(s) for s in lst) for lst in args[1::2] ) if len(args) % 2 == 1: equation += "->" + "".join(_parse_subscript(s) for s in args[-1]) operands = args[:-1:2] else: operands = args[::2] else: equation = args[0] operands = args[1:] if len(operands) == 1 and isinstance(operands[0], (list, tuple)): # The old interface of passing the operands as one list argument. operands = tuple(operands[0]) return equation, operands [docs] def einsum(*args): """einsum(equation, *operands) -> Tensor Sums the product of the elements of the input ``operands`` along dimensions specified using a notation based on the Einstein summation convention, e.g. ``tp.einsum("ij,jk->ik", A, B)`` computes a matrix multiplication. ``tp.einsum(A, [..., 0, 1], B, [..., 1, 2], [..., 0, 2])``. """ import tensorplay if len(args) < 2: raise ValueError( "einsum(): must specify the equation string and at least one operand, " "or at least one operand and its subscripts list" ) equation, operands = parse_equation(args) from tensorplay.graph import capture_call, capturing if capturing(): # Recorded in this function's own spelling: a graph replays the # call through it. captured = capture_call(einsum, (equation, *operands), {}) if captured is not None: return captured # With more than two operands the kernel plans the contraction order # itself; pass path=[...] to pin a specific order. return tensorplay._C.einsum(equation=equation, operands=list(operands), path=[]) ```