code: def local_IncSubtensor_serialize(fgraph, node):
      """
      When using Subtensor, gradient graphs can be ugly.
  
      If we ask for grad(f(a[0]), a), we are going to get something like
  
          IncSubtensor(Elemwise{second}(a, 0), g(f(a[0])), [0])
  
      This might be ugly, but at least it's as fast as you could want.
      If we ask for grad(f(a[0], a[1], a[2]), a), it's much worse...
  
          Elemwise{Add}
              IncSubtensor(Elemwise{second}(a, 0), g(f(a[0])), [0])
              IncSubtensor(Elemwise{second}(a, 0), g(f(a[1])), [1])
              IncSubtensor(Elemwise{second}(a, 0), g(f(a[2])), [2])
  
      This is much worse because this time we have to produce 3 matrices
      the size of 'a', just so we can add them together.
  
      This Op rearranges IncSubtensor's that all work on the same
      initial argument (here, Elemwise{second}(a,0)) into a chain.  The
      advantage of the chain structure is that each one can be optimized
      later in the pipeline to operate inplace.
  
      Ideally, the op will do something like this:
  
      #
      #  add(x, incsubtensor(b, c), incsubtensor(b, d))
      #  -> incsubtensor(incsubtensor(add(x,b,b), c), d)
  
      """
  
      def movable(i):
          # Return True iff this is a incsubtensor that we can move
          return (
              i.owner
              and isinstance(
                  i.owner.op,
                  (
                      IncSubtensor,
                      AdvancedIncSubtensor1,
                      AdvancedIncSubtensor,
                  ),
              )
              and i.type.is_super(o_type)
              and len(fgraph.clients[i]) == 1
              and not i.owner.op.set_instead_of_inc
          )
  
      if node.op == add:
          o_type = node.outputs[0].type
  
          movable_inputs = [i for i in node.inputs if movable(i)]
  
          if movable_inputs:
              new_inputs = [
                  i for i in node.inputs if not movable(i)
              ] + [mi.owner.inputs[0] for mi in movable_inputs]
              if len(new_inputs) == 0:
                  new_add = new_inputs[0]
              else:
                  new_add = add(*new_inputs)
  
                  # Copy over stacktrace from original output, as an error
                  # (e.g. an index error) in this add operation should
                  # correspond to an error in the original add operation.
                  copy_stack_trace(node.outputs[0], new_add)
  
              # stack up the new incsubtensors
              tip = new_add
              for mi in movable_inputs:
                  assert o_type.is_super(tip.type)
                  tip = mi.owner.op(tip, *mi.owner.inputs[1:])
                  # Copy over stacktrace from outputs of the original
                  # "movable" operation to the new operation.
                  copy_stack_trace(node.outputs + mi.owner.outputs, tip)
  
              return [tip]
  
imports: import sys
  from collections.abc import Iterable
  import numpy
  import pytensor
  import pytensor.scalar.basic
  from pytensor import compile
  from pytensor.graph.basic import Constant, Variable
  from pytensor.graph.rewriting.basic import WalkingGraphRewriter, copy_stack_trace, in2out, node_rewriter
  from pytensor.raise_op import Assert
  from pytensor.tensor.basic import Alloc, Join, MakeVector, ScalarFromTensor, TensorFromScalar, alloc, as_tensor, cast, concatenate, extract_constant, get_underlying_scalar_constant_value, register_infer_shape, switch
  from pytensor.tensor.blockwise import Blockwise
  from pytensor.tensor.elemwise import Elemwise
  from pytensor.tensor.exceptions import NotScalarConstantError
  from pytensor.tensor.math import Dot, add, and_, ceil_intdiv, dot, eq, ge, gt, le, lt, maximum, minimum, or_
  from pytensor.tensor.math import all
  from pytensor.tensor.rewriting.basic import register_canonicalize, register_specialize, register_stabilize
  from pytensor.tensor.shape import Shape, SpecifyShape, Unbroadcast, shape_padleft, shape_tuple, specify_shape, unbroadcast
  from pytensor.tensor.sharedvar import TensorSharedVariable
  from pytensor.tensor.subtensor import AdvancedIncSubtensor, AdvancedIncSubtensor1, AdvancedSubtensor, AdvancedSubtensor1, IncSubtensor, Subtensor, advanced_inc_subtensor1, advanced_subtensor, advanced_subtensor1, as_index_constant, as_index_literal, get_canonical_form_slice, get_constant_idx, get_idx_list, get_slice_elements, inc_subtensor, indices_from_subtensor
  from pytensor.tensor.type import TensorType
  from pytensor.tensor.type_other import NoneTypeT, SliceConstant, SliceType
  from pytensor.tensor.variable import TensorConstant, TensorVariable
label_desc: Use image node_id 20 for calling a global function with example usage: local_IncSubtensor_serialize(fgraph, node) and returns: unknown, list