code: def output_merge(cls, alpha_in, beta_in, out_in):
      """
      Decorator to merge addition by a value on the output.
  
      This will find a pattern of `val * <yourop>(some, params, alpha,
      beta, out_like)` and update it so that the addtition happens as
      part of your op.
  
      The op needs to accept an alpha and a beta scalar which act this way::
  
         out = Op() * alpha + out_like * beta
  
      Where out_like is a buffer that has the same size as the output
      and gets added to the "real" output of the operation.  An example
      of an operation that respects this pattern is GEMM from blas.
  
      The decorated function must have this signature::
  
          maker(node, *inputs)
  
      The `node` argument you receive is the original apply node that
      contains your op.  You should use it to grab relevant properties
      for your op so that the new version performs the same computation.
      The `*inputs` parameters contains the new inputs for your op.  You
      MUST use those inputs instead of the ones on `node`.  Note that
      this function can be as simple as::
  
          def maker(node, *inputs):
              return node.op(*inputs)
  
      Parameters
      ----------
      cls : op class
          The class of the op you want to merge
      alpha_in : int
          The input index for the alpha scalar for your op (in node.inputs).
      beta_in : int
          The input index for the beta scalar for your op (in node.inputs).
      out_in : int
          The input index for the out_like input for your op (in node.inputs).
  
      Returns
      -------
      local optimizer
          an unregistered local optimizer that has the same name as the
          decorated function.
  
      Notes
      -----
      This was factored out since the code to deal with intervening
      transfers and correctness in the presence of different values of
      alpha and beta scaling factors is not trivial.
  
      This also correctly handles the case where the added value is
      broadcasted (by not performing the replacement).
  
      """
  
      def wrapper(maker):
          @local_optimizer([GpuElemwise])
          @wraps(maker)
          def opt(node):
              if (
                  isinstance(node.op, GpuElemwise)
                  and node.op.scalar_op == scal.add
                  and node.nin == 2
              ):
                  targ = find_node(node.inputs[0], cls)
                  W = node.inputs[1]
                  if targ is None:
                      targ = find_node(node.inputs[1], cls)
                      W = node.inputs[0]
                  if targ is None:
                      return None
                  if W.dtype != targ.outputs[0].dtype:
                      return None
                  if not is_equal(targ.inputs[beta_in], 0.0):
                      # other cases are too complex for now
                      return None
                  if (
                      W.broadcastable
                      != targ.inputs[out_in].broadcastable
                  ):
                      # Would need to explicitly tile the output to fill
                      # the full shape here.  Disable for now.
                      return None
                  inputs = list(targ.inputs)
                  inputs[out_in] = W
                  dtype = inputs[beta_in].dtype
                  one = scal.constant(np.asarray(1.0, dtype=dtype))
                  inputs[beta_in] = one
                  with inherit_stack_trace(node.outputs):
                      return maker(targ, *inputs)
  
          return opt
  
      return wrapper
  
file_path: Theano/theano/gpuarray/opt_util.py
imports: from __future__ import absolute_import, print_function, division
  from functools import wraps
  import numpy
  from theano import tensor, scalar, Constant
  from theano.gof import local_optimizer
  from theano.gof.opt import inherit_stack_trace
  from theano.tensor import DimShuffle, get_scalar_constant_value, NotScalarConstantError
  from .basic_ops import GpuFromHost, HostFromGpu, GpuAllocEmpty, GpuReshape
  from .elemwise import GpuDimShuffle, GpuElemwise
label_desc: Use image node_id 5 for calling a global function with example usage: output_merge(cls, alpha_in, beta_in, out_in) and returns: wrapper, opt, None, None, None, None, maker