class_docstr: A kernel that takes a number of scalar or vector *arguments* and performs
  an *operation* specified as a snippet of C on these arguments.
  
  :arg arguments: a string formatted as a C argument list.
  :arg operation: a snippet of C that carries out the desired 'map'
      operation.  The current index is available as the variable *i*.
      *operation* may contain the statement ``PYOPENCL_ELWISE_CONTINUE``,
      which will terminate processing for the current element.
  :arg name: the function name as which the kernel is compiled
  :arg options: passed unmodified to :meth:`pyopencl.Program.build`.
  :arg preamble: a piece of C source code that gets inserted outside of the
      function context in the elementwise operation's kernel source code.
  
  .. warning :: Using a ``return`` statement in *operation* will lead to
      incorrect results, as some elements may never get processed. Use
      ``PYOPENCL_ELWISE_CONTINUE`` instead.
  
  .. versionchanged:: 2013.1
  
      Added ``PYOPENCL_ELWISE_CONTINUE``.
  
  .. automethod:: __call__
class_docstr_tok: ["A","kernel","that","takes","a","number","of","scalar","or","vector","*","arguments","*","and","performs","an","*","operation","*","specified","as","a","snippet","of","C","on","these","arguments",".",":","arg","arguments",":","a","string","formatted","as","a","C","argument","list",".",":","arg","operation",":","a","snippet","of","C","that","carries","out","the","desired","'map'","operation",".","The","current","index","is","available","as","the","variable","*","i","*",".","*","operation","*","may","contain","the","statement","``","PYOPENCL_ELWISE_CONTINUE","``",",","which","will","terminate","processing","for","the","current","element",".",":","arg","name",":","the","function","name","as","which","the","kernel","is","compiled",":","arg","options",":","passed","unmodified","to",":","meth",":","`","pyopencl.Program.build","`",".",":","arg","preamble",":","a","piece","of","C","source","code","that","gets","inserted","outside","of","the","function","context","in","the","elementwise","operation","'s","kernel","source","code",".","..","warning",":",":","Using","a","``","return","``","statement","in","*","operation","*","will","lead","to","incorrect","results",",","as","some","elements","may","never","get","processed",".","Use","``","PYOPENCL_ELWISE_CONTINUE","``","instead",".","..","versionchanged",":",":","2013.1","Added","``","PYOPENCL_ELWISE_CONTINUE","``",".","..","automethod",":",":","__call__"]
docstr: Invoke the generated scalar kernel.
  
  The arguments may either be scalars or :class:`pyopencl.array.Array`
  instances.
  
  |std-enqueue-blurb|
code: def __call__(self, *args, **kwargs) -> cl.Event:
      """
      Invoke the generated scalar kernel.
  
      The arguments may either be scalars or :class:`pyopencl.array.Array`
      instances.
  
      |std-enqueue-blurb|
      """
      range_ = kwargs.pop("range", None)
      slice_ = kwargs.pop("slice", None)
      capture_as = kwargs.pop("capture_as", None)
      queue = kwargs.pop("queue", None)
      wait_for = kwargs.pop("wait_for", None)
  
      if kwargs:
          raise TypeError(
              f"unknown keyword arguments: '{', '.join(kwargs)}'"
          )
  
      use_range = range_ is not None or slice_ is not None
      kernel, arg_descrs = self.get_kernel(use_range)
  
      if wait_for is None:
          wait_for = []
      else:
          # We'll be modifying it below.
          wait_for = list(wait_for)
  
      # {{{ assemble arg array
  
      repr_vec = None
      invocation_args = []
      for arg, arg_descr in zip(args, arg_descrs):
          if isinstance(arg_descr, VectorArg):
              if repr_vec is None:
                  repr_vec = arg
  
              invocation_args.append(arg)
          else:
              invocation_args.append(arg)
  
      assert repr_vec is not None
  
      # }}}
  
      if queue is None:
          queue = repr_vec.queue
  
      if slice_ is not None:
          if range_ is not None:
              raise TypeError(
                  "may not specify both range and slice keyword arguments"
              )
  
          range_ = slice(*slice_.indices(repr_vec.size))
  
      max_wg_size = kernel.get_work_group_info(
          cl.kernel_work_group_info.WORK_GROUP_SIZE, queue.device
      )
  
      if range_ is not None:
          start = range_.start
          if start is None:
              start = 0
          invocation_args.append(start)
          invocation_args.append(range_.stop)
          if range_.step is None:
              step = 1
          else:
              step = range_.step
  
          invocation_args.append(step)
  
          from pyopencl.array import _splay
  
          gs, ls = _splay(
              queue.device,
              abs(range_.stop - start) // step,
              max_wg_size,
          )
      else:
          invocation_args.append(repr_vec.size)
          gs, ls = repr_vec._get_sizes(queue, max_wg_size)
  
      if capture_as is not None:
          kernel.set_args(*invocation_args)
          kernel.capture_call(
              capture_as,
              queue,
              gs,
              ls,
              *invocation_args,
              wait_for=wait_for,
          )
  
      return kernel(queue, gs, ls, *invocation_args, wait_for=wait_for)
  
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 3 for calling the ElementwiseKernel obj's underlying member method code with example usage: obj.__call__() and returns: kernel