code: def grad_einsum(argnum, ans, operands_, kwargs):
      result_meta = anp.metadata(operands_[argnum])
  
      def vjp(g):
          operands = operands_
          if isinstance(
              operands[0], string_types
          ):  # using "ijk" convention.
              in_subs, out_subs, _ = anp.parse_einsum_input(*operands)
              string, operands = operands[0], operands[1:]
  
              in_subs_list = in_subs.split(",")
              op_num = argnum - 1
              subs_wrt = in_subs_list[op_num]
              rest_of_ops = operands[:op_num] + operands[op_num + 1 :]
              rest_of_subs = (
                  in_subs_list[:op_num] + in_subs_list[op_num + 1 :]
              )
  
              # subscripts that only appear in subs_wrt (and not in other subscript lists
              # or in the output) are implicitly being summed out, as if contracted
              # against a tensor of ones. we make that tensor of ones explicit to handle
              # the necessary vjp broadcasting inside einsum.
              other_named_subs = set("".join([out_subs] + rest_of_subs))
              naked_summed = [
                  (i, sub)
                  for i, sub in enumerate(subs_wrt)
                  if sub not in other_named_subs
              ]
              if naked_summed:
                  naked_summed_dims, ones_subs = zip(*naked_summed)
                  ones_subs = "".join(ones_subs)
                  ones = onp.ones(
                      onp.array(operands[op_num].shape)[
                          list(naked_summed_dims)
                      ]
                  )
                  new_input_subs = ",".join(
                      [out_subs, ones_subs] + rest_of_subs
                  )
                  new_operands = (g, ones) + rest_of_ops
              else:
                  new_input_subs = ",".join([out_subs] + rest_of_subs)
                  new_operands = (g,) + rest_of_ops
  
              new_subscripts = new_input_subs + "->" + subs_wrt
              return unbroadcast(
                  anp.einsum(new_subscripts, *new_operands), result_meta
              )
          else:  # using (op0, sublist0, op1, sublist1, ..., sublistout) convention
              if len(operands) % 2 == 0:
                  raise NotImplementedError("Need sublistout argument")
              operands = list(operands)
              rest_of_ops = (
                  [operands[-1]]
                  + operands[:argnum]
                  + operands[(argnum + 2) : -1]
                  + [operands[argnum + 1]]
              )
              return unbroadcast_einsum(
                  anp.einsum(g, *rest_of_ops),
                  result_meta,
                  operands[argnum + 1],
              )
  
      return vjp
  
imports: from __future__ import absolute_import
  from six import string_types
  from functools import partial
  import numpy
  from ..util import func
  from .None import numpy_wrapper
  from .numpy_boxes import ArrayBox
  from autograd.extend import primitive, vspace, defvjp, defvjp_argnum, SparseObject, VJPNode, register_notrace
label_desc: Use image node_id 37 for calling a global function with example usage: grad_einsum(argnum, ans, operands_, kwargs) and returns: vjp, unbroadcast, unbroadcast_einsum