code: def get_reduction_kernel(
      stage: int,
      ctx: cl.Context,
      dtype_out: Any,
      neutral: str,
      reduce_expr: str,
      map_expr: Optional[str] = None,
      arguments: Optional[List[DtypedArgument]] = None,
      name: str = "reduce_kernel",
      preamble: str = "",
      device: Optional[cl.Device] = None,
      options: Any = None,
      max_group_size: Optional[int] = None,
  ) -> _ReductionInfo:
      if stage not in (1, 2):
          raise ValueError(f"unknown stage index: '{stage}'")
  
      if map_expr is None:
          map_expr = (
              "pyopencl_reduction_inp[i]" if stage == 2 else "in[i]"
          )
  
      from pyopencl.tools import (
          parse_arg_list,
          get_arg_list_scalar_arg_dtypes,
          get_arg_offset_adjuster_code,
          VectorArg,
      )
  
      if arguments is None:
          raise ValueError("arguments must not be None")
  
      arguments = parse_arg_list(arguments, with_offset=True)
      arg_prep = get_arg_offset_adjuster_code(arguments)
  
      if stage == 2 and arguments is not None:
          arguments = [
              VectorArg(dtype_out, "pyopencl_reduction_inp")
          ] + arguments
  
      source, group_size = _get_reduction_source(
          ctx,
          dtype_to_ctype(dtype_out),
          dtype_out.itemsize,
          neutral,
          reduce_expr,
          map_expr,
          arguments,
          name,
          preamble,
          arg_prep,
          device,
          max_group_size,
      )
  
      program = cl.Program(ctx, source)
      program.build(options)
  
      kernel = getattr(program, name)
      kernel.set_scalar_arg_dtypes(
          [None, np.int64]
          + get_arg_list_scalar_arg_dtypes(arguments)
          + [np.int64] * 3
          + [np.uint32, np.int64]
      )
  
      return _ReductionInfo(
          context=ctx,
          source=source,
          group_size=group_size,
          program=program,
          kernel=kernel,
          arg_types=arguments,
      )
  
imports: from dataclasses import dataclass
  from typing import Any, List, Optional, Tuple, Union
  import numpy
  import pyopencl
  from pyopencl.tools import DtypedArgument, KernelTemplateBase, context_dependent_memoize, dtype_to_ctype, _process_code_for_macro
label_desc: Use image node_id 2 for calling a global function with example usage: get_reduction_kernel(stage, ctx, dtype_out, neutral, reduce_expr, map_expr, arguments, name, preamble, device, options, max_group_size) and returns: _ReductionInfo