code: def get_binary_op_kernel(
      dtype_x,
      dtype_y,
      dtype_z,
      operator,
      x_is_scalar=False,
      y_is_scalar=False,
  ):
      """
      Returns a kernel corresponding to ``z = x (operator) y``.
  
      :arg x_is_scalar: A :class:`bool` which is *True* only if `x` is a scalar :class:`gpuarray`.
      :arg y_is_scalar: A :class:`bool` which is *True* only if `y` is a scalar :class:`gpuarray`.
      """
  
      out_t = dtype_to_ctype(dtype_z)
  
      # {{{ cast real scalars in context of complex scalar arithmetic
  
      if dtype_z.kind == "c" and dtype_x.kind != "c":
          dtype_z_real = _get_real_dtype(dtype_z)
          x_t = dtype_to_ctype(dtype_z_real)
      else:
          x_t = out_t
  
      if dtype_z.kind == "c" and dtype_y.kind != "c":
          dtype_z_real = _get_real_dtype(dtype_z)
          y_t = dtype_to_ctype(dtype_z_real)
      else:
          y_t = out_t
  
      # }}}
  
      x = "x[0]" if x_is_scalar else "x[i]"
      x = f"({x_t}) {x}"
      y = "y[0]" if y_is_scalar else "y[i]"
      y = f"({y_t}) {y}"
      result = f"{x} {operator} {y}"
      return get_elwise_kernel(
          "%(tp_x)s *x, %(tp_y)s *y, %(tp_z)s *z"
          % {
              "tp_x": dtype_to_ctype(dtype_x),
              "tp_y": dtype_to_ctype(dtype_y),
              "tp_z": dtype_to_ctype(dtype_z),
          },
          f"z[i] = ({out_t}) {result}",
          "multiply",
      )
  
imports: from pycuda.tools import context_dependent_memoize
  from typing import Any
  import numpy
  from pycuda.tools import dtype_to_ctype, VectorArg, ScalarArg
  from pytools import memoize_method
label_desc: Use image node_id 13 for calling a global function with example usage: get_binary_op_kernel(dtype_x, dtype_y, dtype_z, operator, x_is_scalar, y_is_scalar) and returns: get_elwise_kernel