code: def solve_binary_generic_einsum(
      parsed_vectors, a_var, b_var, name
  ) -> Var:
      def _concat_dims(dims, none_if_empty=False):
          if len(dims) == 0:
              if none_if_empty:
                  return None
              else:
                  return 1
          return mb.concat(values=dims, axis=0)
  
      a_axes, b_axes, out_axes = parsed_vectors
  
      a_dims = mb.shape(x=a_var)
      b_dims = mb.shape(x=b_var)
  
      batched_axes = []
      reduced_axes = []
      a_unique_axes = []
      b_unique_axes = []
  
      batch_dims = []
      reduce_dims = []
      a_unique_dims = []
      b_unique_dims = []
  
      for i, a_axis in enumerate(a_axes):
          a_dim = value_at(a_dims, i)
          if a_axis in b_axes:
              if a_axis in out_axes:
                  batched_axes.append(a_axis)
                  batch_dims.append(a_dim)
              else:
                  reduced_axes.append(a_axis)
                  reduce_dims.append(a_dim)
          else:
              a_unique_axes.append(a_axis)
              a_unique_dims.append(a_dim)
      concat_batch_dims = _concat_dims(batch_dims, True)
      # if there is no dim to reduce, then add a dummy dim,
      # so mb.matmul will reduce the dummy dim to achieve outer product
      concat_reduce_dims = _concat_dims(reduce_dims)
      # if there is no dim of `a` remains, then add a dummy dim for `a` as a matrix dim,
      # otherwise mb.matmul may mistake the batch dim of `a` as the matrix dim
      concat_a_unique_dims = _concat_dims(a_unique_dims)
  
      for i, b_axis in enumerate(b_axes):
          b_dim = value_at(b_dims, i)
          if b_axis not in a_axes:
              b_unique_axes.append(b_axis)
              b_unique_dims.append(b_dim)
      # if there is no dim of `b` remains, then add a dummy dim for `b`,
      # otherwise mb.matmul may mistake the batch dim of `b` as a matrix dim
      concat_b_unique_dims = _concat_dims(b_unique_dims)
  
      a_transpose_axes = batched_axes + a_unique_axes + reduced_axes
      a = mb.transpose(
          x=a_var,
          perm=get_perm_transpose_einsum(a_axes, a_transpose_axes),
      )
      a_reshape_dims = _concat_dims(
          [
              mb.reduce_prod(x=x)
              for x in [
                  concat_batch_dims,
                  concat_a_unique_dims,
                  concat_reduce_dims,
              ]
              if x is not None
          ]
      )
      a = mb.reshape(x=a, shape=a_reshape_dims)
  
      b_transpose_axes = batched_axes + reduced_axes + b_unique_axes
      b = mb.transpose(
          x=b_var,
          perm=get_perm_transpose_einsum(b_axes, b_transpose_axes),
      )
      b_reshape_dims = _concat_dims(
          [
              mb.reduce_prod(x=x)
              for x in [
                  concat_batch_dims,
                  concat_reduce_dims,
                  concat_b_unique_dims,
              ]
              if x is not None
          ]
      )
      b = mb.reshape(x=b, shape=b_reshape_dims)
  
      ab = mb.matmul(x=a, y=b)
      concat_batch_dims = _concat_dims(batch_dims, True)
      concat_a_unique_dims = _concat_dims(a_unique_dims, True)
      concat_b_unique_dims = _concat_dims(b_unique_dims, True)
      ab_reshaped_dims = _concat_dims(
          [
              x
              for x in [
                  concat_batch_dims,
                  concat_a_unique_dims,
                  concat_b_unique_dims,
              ]
              if x is not None
          ],
          True,
      )
      # Removes excessive dimensions for scalar output
      if ab_reshaped_dims is None:
          if name is None:
              return mb.squeeze(x=ab)
          else:
              return mb.squeeze(x=ab, name=name)
      # Reshape tensor output to specified output shape
      else:
          ab = mb.reshape(x=ab, shape=ab_reshaped_dims)
          ab_reshaped_axes = (
              batched_axes + a_unique_axes + b_unique_axes
          )
          if name is None:
              ab = mb.transpose(
                  x=ab,
                  perm=get_perm_transpose_einsum(
                      ab_reshaped_axes, out_axes
                  ),
              )
          else:
              ab = mb.transpose(
                  x=ab,
                  perm=get_perm_transpose_einsum(
                      ab_reshaped_axes, out_axes
                  ),
                  name=name,
              )
          return ab
  
file_path: coremltools/coremltools/converters/mil/frontend/_utils.py
imports: import itertools
  from typing import List, Optional
  from coremltools.converters.mil.input_types import InputType
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import Var, types
  from coremltools.converters.mil.mil.ops.defs._utils import parse_einsum_equation
  from coremltools.converters.mil.mil.types.symbolic import any_symbolic, is_symbolic
label_desc: Use image node_id 11 for calling a global function with example usage: solve_binary_generic_einsum(parsed_vectors, a_var, b_var, name) and returns: mb, ab, mb, mb, None, int