code: def local_elemwise_alloc(fgraph, node):
      r"""Remove unnecessary `Alloc`\s that occur as inputs of `Elemwise` `Op`\s.
  
      The rewrite essentially performs the following replacement:
      ``Elemwise{op}(..., Alloc(x, s), ..., y, ...) -> Elemwise{op}(..., x, ..., y, ...)``
  
      In its current form, it also explicitly accounts for `DimShuffle`\s of
      `Alloc`\s.  This is largely due to `local_alloc_sink_dimshuffle`, which
      introduces them as a canonicalization of `Alloc`'s with leading
      broadcastable dimensions.
      """
      # This is handled by local_alloc_unary
      if len(node.inputs) == 1:
          return None
  
      def dimshuffled_alloc(i):
          return (
              isinstance(i.owner.op, DimShuffle)
              and i.owner.inputs[0].owner
              and isinstance(i.owner.inputs[0].owner.op, Alloc)
          )
  
      # At least one input must have an owner that is either a `Alloc` or a
      # `DimShuffle` with an owner that is a `Alloc` -- otherwise there is
      # nothing to optimize.
      alloc_idxs = [
          idx
          for idx, i in enumerate(node.inputs)
          if i.owner
          and (isinstance(i.owner.op, Alloc) or dimshuffled_alloc(i))
      ]
      if len(alloc_idxs) == 0:
          return False
  
      new_inputs = list(node.inputs)
      for idx in alloc_idxs:
          i = node.inputs[idx]
  
          # Remove simple `Alloc`
          if isinstance(i.owner.op, Alloc):
              new_inp = i.owner.inputs[0]
  
          # Remove `Dimshuffle(Alloc)`
          elif isinstance(i.owner.op, DimShuffle):
              old_alloc = i.owner.inputs[0]
              old_alloc_inp = old_alloc.owner.inputs[0]
              missing_ndims = (
                  old_alloc.type.ndim - old_alloc_inp.type.ndim
              )
              if missing_ndims > 0:
                  # The `Alloc` added new dimensions to the left.
                  # We replace those cases with a `DimShuffle` here.
                  # Nested dimshuffles will be merged later by other rewrites.
                  old_alloc_inp = shape_padleft(
                      old_alloc_inp, missing_ndims
                  )
              # We need to keep the old `DimShuffle`. It could swap axes or
              # add dimensions anywhere.
              new_inp = i.owner.op(old_alloc_inp)
  
          copy_stack_trace(i, new_inp)
          new_inputs[idx] = new_inp
  
      new_outs = node.op(*new_inputs, return_list=True)
  
      if (
          new_outs[0].type.broadcastable
          != node.outputs[0].type.broadcastable
      ):
          new_outs = [
              alloc_like(new_out, node.outputs[0], fgraph)
              for new_out in new_outs
          ]
  
      copy_stack_trace(node.outputs, new_outs)
      return new_outs
  
imports: import logging
  from typing import Union
  import numpy
  import pytensor.scalar.basic
  from pytensor import compile
  from pytensor.compile.ops import ViewOp
  from pytensor.graph import FunctionGraph
  from pytensor.graph.basic import Constant, Variable
  from pytensor.graph.rewriting.basic import NodeRewriter, RemovalNodeRewriter, Rewriter, copy_stack_trace, in2out, node_rewriter
  from pytensor.graph.rewriting.db import RewriteDatabase
  from pytensor.raise_op import Assert, CheckAndRaise, assert_op
  from pytensor.tensor.basic import Alloc, AllocEmpty, Join, MakeVector, ScalarFromTensor, Split, TensorFromScalar, alloc, as_tensor_variable, cast, extract_constant, fill, get_underlying_scalar_constant_value, join, ones_like, register_infer_shape, switch, tensor_copy, zeros, zeros_like
  from pytensor.tensor.elemwise import DimShuffle, Elemwise
  from pytensor.tensor.exceptions import NotScalarConstantError
  from pytensor.tensor.extra_ops import broadcast_arrays
  from pytensor.tensor.math import Sum, add, eq
  from pytensor.tensor.shape import Shape_i, shape_padleft
  from pytensor.tensor.sort import TopKOp
  from pytensor.tensor.type import DenseTensorType, TensorType
  from pytensor.tensor.variable import TensorConstant, TensorVariable
  from pytensor.utils import NoDuplicateOptWarningFilter
label_desc: Use image node_id 11 for calling a global function with example usage: local_elemwise_alloc(fgraph, node) and returns: new_outs, None, unknown, False