code: def get_elwise_kernel_and_types(
      context: cl.Context,
      arguments: Union[str, List[DtypedArgument]],
      operation: str,
      *,
      name: str = "elwise_kernel",
      options: Any = None,
      preamble: str = "",
      use_range: bool = False,
      **kwargs: Any,
  ) -> Tuple[cl.Kernel, List[DtypedArgument]]:
      from pyopencl.tools import (
          parse_arg_list,
          get_arg_offset_adjuster_code,
      )
  
      parsed_args = parse_arg_list(arguments, with_offset=True)
  
      auto_preamble = kwargs.pop("auto_preamble", True)
  
      pragmas = []
      includes = []
      have_double_pragma = False
      have_complex_include = False
  
      if auto_preamble:
          for arg in parsed_args:
              if arg.dtype in [np.float64, np.complex128]:
                  if not have_double_pragma:
                      pragmas.append(
                          """
                          #if __OPENCL_C_VERSION__ < 120
                          #pragma OPENCL EXTENSION cl_khr_fp64: enable
                          #endif
                          #define PYOPENCL_DEFINE_CDOUBLE
                          """
                      )
                      have_double_pragma = True
              if arg.dtype.kind == "c":
                  if not have_complex_include:
                      includes.append("#include <pyopencl-complex.h>\n")
                      have_complex_include = True
  
      if pragmas or includes:
          preamble = "\n".join(pragmas + includes) + "\n" + preamble
  
      if use_range:
          parsed_args.extend(
              [
                  ScalarArg(np.intp, "start"),
                  ScalarArg(np.intp, "stop"),
                  ScalarArg(np.intp, "step"),
              ]
          )
      else:
          parsed_args.append(ScalarArg(np.intp, "n"))
  
      loop_prep = kwargs.pop("loop_prep", "")
      loop_prep = get_arg_offset_adjuster_code(parsed_args) + loop_prep
      prg = get_elwise_program(
          context,
          parsed_args,
          operation,
          name=name,
          options=options,
          preamble=preamble,
          use_range=use_range,
          loop_prep=loop_prep,
          **kwargs,
      )
  
      from pyopencl.tools import get_arg_list_arg_types
  
      kernel = getattr(prg, name)
      kernel.set_scalar_arg_dtypes(get_arg_list_arg_types(parsed_args))
  
      return kernel, parsed_args
  
imports: import enum
  from typing import Any, List, Optional, Tuple, Union
  import numpy
  import pyopencl
  from pyopencl.tools import context_dependent_memoize
  from pyopencl.tools import dtype_to_ctype, DtypedArgument, VectorArg, ScalarArg, KernelTemplateBase, dtype_to_c_struct
  from pytools import memoize_method
label_desc: Use image node_id 2 for calling a global function with example usage: get_elwise_kernel_and_types(context, arguments, operation) and returns: kernel,  parsed_args