code: def enqueue_copy(queue, dest, src, **kwargs):
      """Copy from :class:`Image`, :class:`Buffer` or the host to
      :class:`Image`, :class:`Buffer` or the host. (Note: host-to-host
      copies are unsupported.)
  
      The following keyword arguments are available:
  
      :arg wait_for: (optional, default empty)
      :arg is_blocking: Wait for completion. Defaults to *True*.
        (Available on any copy involving host memory)
      :return: A :class:`NannyEvent` if the transfer involved a
          host-side buffer, otherwise an :class:`Event`.
  
      .. note::
  
          Be aware that the deletion of the :class:`NannyEvent` that is
          returned by the function if the transfer involved a host-side buffer
          will block until the transfer is complete, so be sure to keep a
          reference to this :class:`Event` until the
          transfer has completed.
  
      .. note::
  
          Two types of 'buffer' occur in the arguments to this function,
          :class:`Buffer` and 'host-side buffers'. The latter are
          defined by Python and commonly called `buffer objects
          <https://docs.python.org/3/c-api/buffer.html>`__. :mod:`numpy`
          arrays are a very common example.
          Make sure to always be clear on whether a :class:`Buffer` or a
          Python buffer object is needed.
  
      .. ------------------------------------------------------------------------
      .. rubric :: Transfer :class:`Buffer` ↔ host
      .. ------------------------------------------------------------------------
  
      :arg src_offset: offset in bytes (optional)
  
          May only be nonzero if applied on the device side.
  
      :arg dst_offset: offset in bytes (optional)
  
          May only be nonzero if applied on the device side.
  
      .. note::
  
          The size of the transfer is controlled by the size of the
          of the host-side buffer. If the host-side buffer
          is a :class:`numpy.ndarray`, you can control the transfer size by
          transferring into a smaller 'view' of the target array, like this::
  
              cl.enqueue_copy(queue, large_dest_numpy_array[:15], src_buffer)
  
      .. ------------------------------------------------------------------------
      .. rubric :: Transfer :class:`Buffer` ↔ :class:`Buffer`
      .. ------------------------------------------------------------------------
  
      :arg byte_count: (optional) If not specified, defaults to the
          size of the source in versions 2012.x and earlier,
          and to the minimum of the size of the source and target
          from 2013.1 on.
      :arg src_offset: (optional)
      :arg dst_offset: (optional)
  
      .. ------------------------------------------------------------------------
      .. rubric :: Rectangular :class:`Buffer` ↔  host transfers (CL 1.1 and newer)
      .. ------------------------------------------------------------------------
  
      :arg buffer_origin: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg host_origin: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg region: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg buffer_pitches: :class:`tuple` of :class:`int` of length
          two or shorter. (optional, "tightly-packed" if unspecified)
      :arg host_pitches: :class:`tuple` of :class:`int` of length
          two or shorter. (optional, "tightly-packed" if unspecified)
  
      .. ------------------------------------------------------------------------
      .. rubric :: Rectangular :class:`Buffer` ↔  :class:`Buffer`
          transfers (CL 1.1 and newer)
      .. ------------------------------------------------------------------------
  
      :arg src_origin: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg dst_origin: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg region: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg src_pitches: :class:`tuple` of :class:`int` of length
          two or shorter. (optional, "tightly-packed" if unspecified)
      :arg dst_pitches: :class:`tuple` of :class:`int` of length
          two or shorter. (optional, "tightly-packed" if unspecified)
  
      .. ------------------------------------------------------------------------
      .. rubric :: Transfer :class:`Image` ↔ host
      .. ------------------------------------------------------------------------
  
      :arg origin: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg region: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg pitches: :class:`tuple` of :class:`int` of length
          two or shorter. (optional)
  
      .. ------------------------------------------------------------------------
      .. rubric :: Transfer :class:`Buffer` ↔ :class:`Image`
      .. ------------------------------------------------------------------------
  
      :arg offset: offset in buffer (mandatory)
      :arg origin: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg region: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
  
      .. ------------------------------------------------------------------------
      .. rubric :: Transfer :class:`Image` ↔ :class:`Image`
      .. ------------------------------------------------------------------------
  
      :arg src_origin: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg dest_origin: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
      :arg region: :class:`tuple` of :class:`int` of length
          three or shorter. (mandatory)
  
      .. ------------------------------------------------------------------------
      .. rubric :: Transfer :class:`SVMPointer`/host ↔ :class:`SVMPointer`/host
      .. ------------------------------------------------------------------------
  
      :arg byte_count: (optional) If not specified, defaults to the
          size of the source in versions 2012.x and earlier,
          and to the minimum of the size of the source and target
          from 2013.1 on.
  
      |std-enqueue-blurb|
  
      .. versionadded:: 2011.1
      """
  
      if isinstance(dest, MemoryObjectHolder):
          if dest.type == mem_object_type.BUFFER:
              if isinstance(src, MemoryObjectHolder):
                  if src.type == mem_object_type.BUFFER:
                      # {{{ buffer -> buffer
  
                      if "src_origin" in kwargs:
                          # rectangular
                          return _cl._enqueue_copy_buffer_rect(
                              queue, src, dest, **kwargs
                          )
                      else:
                          # linear
                          dest_offset = kwargs.pop("dest_offset", None)
                          if dest_offset is not None:
                              if "dst_offset" in kwargs:
                                  raise TypeError(
                                      "may not specify both 'dst_offset' "
                                      "and 'dest_offset'"
                                  )
  
                              warn(
                                  "The 'dest_offset' argument of enqueue_copy "
                                  "is deprecated. Use 'dst_offset' instead. "
                                  "'dest_offset' will stop working in 2023.x.",
                                  DeprecationWarning,
                                  stacklevel=2,
                              )
  
                              kwargs["dst_offset"] = dest_offset
  
                          return _cl._enqueue_copy_buffer(
                              queue, src, dest, **kwargs
                          )
  
                      # }}}
                  elif src.type in _IMAGE_MEM_OBJ_TYPES:
                      return _cl._enqueue_copy_image_to_buffer(
                          queue, src, dest, **kwargs
                      )
                  else:
                      raise ValueError("invalid src mem object type")
              else:
                  # {{{ host -> buffer
  
                  if "buffer_origin" in kwargs:
                      return _cl._enqueue_write_buffer_rect(
                          queue, dest, src, **kwargs
                      )
                  else:
                      device_offset = kwargs.pop("device_offset", None)
                      if device_offset is not None:
                          if "dst_offset" in kwargs:
                              raise TypeError(
                                  "may not specify both 'device_offset' "
                                  "and 'dst_offset'"
                              )
  
                          warn(
                              "The 'device_offset' argument of enqueue_copy "
                              "is deprecated. Use 'dst_offset' instead. "
                              "'dst_offset' will stop working in 2023.x.",
                              DeprecationWarning,
                              stacklevel=2,
                          )
  
                          kwargs["dst_offset"] = device_offset
  
                      return _cl._enqueue_write_buffer(
                          queue, dest, src, **kwargs
                      )
  
                  # }}}
  
          elif dest.type in _IMAGE_MEM_OBJ_TYPES:
              # {{{ ... -> image
  
              if isinstance(src, MemoryObjectHolder):
                  if src.type == mem_object_type.BUFFER:
                      return _cl._enqueue_copy_buffer_to_image(
                          queue, src, dest, **kwargs
                      )
                  elif src.type in _IMAGE_MEM_OBJ_TYPES:
                      return _cl._enqueue_copy_image(
                          queue, src, dest, **kwargs
                      )
                  else:
                      raise ValueError("invalid src mem object type")
              else:
                  # assume from-host
                  origin = kwargs.pop("origin")
                  region = kwargs.pop("region")
  
                  pitches = kwargs.pop("pitches", (0, 0))
                  if len(pitches) == 1:
                      (kwargs["row_pitch"],) = pitches
                  else:
                      (
                          kwargs["row_pitch"],
                          kwargs["slice_pitch"],
                      ) = pitches
  
                  return _cl._enqueue_write_image(
                      queue, dest, origin, region, src, **kwargs
                  )
  
              # }}}
          else:
              raise ValueError("invalid dest mem object type")
  
      elif get_cl_header_version() >= (2, 0) and isinstance(
          dest, SVMPointer
      ):
          # {{{ ... ->  SVM
  
          if not isinstance(src, SVMPointer):
              src = SVM(src)
  
          is_blocking = kwargs.pop("is_blocking", True)
  
          # These are NOT documented. They only support consistency with the
          # Buffer-based API for the sake of the Array.
          if kwargs.pop("src_offset", 0) != 0:
              raise ValueError("src_offset must be 0")
          if kwargs.pop("dst_offset", 0) != 0:
              raise ValueError("dst_offset must be 0")
  
          return _cl._enqueue_svm_memcpy(
              queue, is_blocking, dest, src, **kwargs
          )
  
          # }}}
  
      else:
          # assume to-host
  
          if isinstance(src, MemoryObjectHolder):
              if src.type == mem_object_type.BUFFER:
                  if "buffer_origin" in kwargs:
                      return _cl._enqueue_read_buffer_rect(
                          queue, src, dest, **kwargs
                      )
                  else:
                      device_offset = kwargs.pop("device_offset", None)
                      if device_offset is not None:
                          if "src_offset" in kwargs:
                              raise TypeError(
                                  "may not specify both 'device_offset' "
                                  "and 'src_offset'"
                              )
  
                          warn(
                              "The 'device_offset' argument of enqueue_copy "
                              "is deprecated. Use 'src_offset' instead. "
                              "'dst_offset' will stop working in 2023.x.",
                              DeprecationWarning,
                              stacklevel=2,
                          )
  
                          kwargs["src_offset"] = device_offset
  
                      return _cl._enqueue_read_buffer(
                          queue, src, dest, **kwargs
                      )
  
              elif src.type in _IMAGE_MEM_OBJ_TYPES:
                  origin = kwargs.pop("origin")
                  region = kwargs.pop("region")
  
                  pitches = kwargs.pop("pitches", (0, 0))
                  if len(pitches) == 1:
                      (kwargs["row_pitch"],) = pitches
                  else:
                      (
                          kwargs["row_pitch"],
                          kwargs["slice_pitch"],
                      ) = pitches
  
                  return _cl._enqueue_read_image(
                      queue, src, origin, region, dest, **kwargs
                  )
              else:
                  raise ValueError("invalid src mem object type")
          elif isinstance(src, SVMPointer):
              # {{{ svm -> host
  
              # dest is not a SVM instance, otherwise we'd be in the branch above
  
              # This is NOT documented. They only support consistency with the
              # Buffer-based API for the sake of the Array.
              if kwargs.pop("src_offset", 0) != 0:
                  raise ValueError("src_offset must be 0")
  
              is_blocking = kwargs.pop("is_blocking", True)
              return _cl._enqueue_svm_memcpy(
                  queue, is_blocking, SVM(dest), src, **kwargs
              )
  
              # }}}
          else:
              # assume from-host
              raise TypeError(
                  "enqueue_copy cannot perform host-to-host transfers"
              )
  
imports: from sys import intern
  from warnings import warn
  from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
  from pyopencl.version import VERSION, VERSION_STATUS, VERSION_TEXT
  import pyopencl.cltypes
  import logging
  import os
  import numpy
  import sys
  from pyopencl._cl import get_cl_header_version, program_kind, status_code, platform_info, device_type, device_info, device_topology_type_amd, device_fp_config, device_mem_cache_type, device_local_mem_type, device_exec_capabilities, device_svm_capabilities, command_queue_properties, context_info, gl_context_info, context_properties, command_queue_info, queue_properties, mem_flags, svm_mem_flags, channel_order, channel_type, mem_object_type, mem_info, image_info, pipe_info, pipe_properties, addressing_mode, filter_mode, sampler_info, sampler_properties, map_flags, program_info, program_build_info, program_binary_type, kernel_info, kernel_arg_info, kernel_arg_address_qualifier, kernel_arg_access_qualifier, kernel_arg_type_qualifier, kernel_work_group_info, kernel_sub_group_info, event_info, command_type, command_execution_status, profiling_info, mem_migration_flags, device_partition_property, device_affinity_domain, device_atomic_capabilities, device_device_enqueue_capabilities, version_bits, khronos_vendor_id, Error, MemoryError, LogicError, RuntimeError, Platform, get_platforms, Device, Context, CommandQueue, LocalMemory, MemoryObjectHolder, MemoryObject, MemoryMap, Buffer, _Program, Kernel, Event, wait_for_events, NannyEvent, enqueue_nd_range_kernel, _enqueue_marker, _enqueue_read_buffer, _enqueue_write_buffer, _enqueue_copy_buffer, _enqueue_read_buffer_rect, _enqueue_write_buffer_rect, _enqueue_copy_buffer_rect, _enqueue_read_image, _enqueue_copy_image, _enqueue_write_image, _enqueue_copy_image_to_buffer, _enqueue_copy_buffer_to_image, have_gl, ImageFormat, get_supported_image_formats, Image, Sampler, Pipe
  import inspect
label_desc: Use image node_id 11 for calling a global function with example usage: enqueue_copy(queue, dest, src) and returns: _cl, _cl, _cl, _cl, _cl, _cl, _cl, _cl, _cl, _cl, _cl, _cl, _cl