class_docstr: Interface to concatenate data and transfer them to GPU asynchronously.
  
  It enables to transfer next batch of input data to GPU while GPU is
  running kernels for training using current batch of input data.
  
  An instance of this class is mainly intended to be used as a converter
  function of an updater like below.
  
  .. doctest::
  
      from chainer.dataset import convert
      ...
      updater = chainer.training.updaters.StandardUpdater(
                     ...,
                     converter=convert.ConcatWithAsyncTransfer(),
                     ...)
  
  Args:
      stream (cupy.cuda.Stream): CUDA stream. If ``None``, a stream is
          automatically created on the first call. Data transfer operation
          is launched asynchronously using the stream.
      compute_stream(cupy.cuda.Stream): CUDA stream used for compute kernels.
          If not ``None``, CUDA events are created/used to avoid global
          synchronization and overlap execution of compute kernels and data
          transfers as much as possible. If ``None``, global synchronization
          is used instead.
class_docstr_tok: ["Interface","to","concatenate","data","and","transfer","them","to","GPU","asynchronously",".","It","enables","to","transfer","next","batch","of","input","data","to","GPU","while","GPU","is","running","kernels","for","training","using","current","batch","of","input","data",".","An","instance","of","this","class","is","mainly","intended","to","be","used","as","a","converter","function","of","an","updater","like","below",".","..","doctest",":",":","from","chainer.dataset","import","convert","...","updater","=","chainer.training.updaters.StandardUpdater","(","...",",","converter=convert.ConcatWithAsyncTransfer","(",")",",","...",")","Args",":","stream","(","cupy.cuda.Stream",")",":","CUDA","stream",".","If","``","None","``",",","a","stream","is","automatically","created","on","the","first","call",".","Data","transfer","operation","is","launched","asynchronously","using","the","stream",".","compute_stream","(","cupy.cuda.Stream",")",":","CUDA","stream","used","for","compute","kernels",".","If","not","``","None","``",",","CUDA","events","are","created\/used","to","avoid","global","synchronization","and","overlap","execution","of","compute","kernels","and","data","transfers","as","much","as","possible",".","If","``","None","``",",","global","synchronization","is","used","instead","."]
docstr: Concatenate data and transfer them to GPU asynchronously.
  
  See also :func:`chainer.dataset.concat_examples`.
  
  Args:
      batch (list): A list of examples.
      device (int): Device ID to which each array is sent.
      padding: Scalar value for extra elements.
  
  Returns:
      Array, a tuple of arrays, or a dictionary of arrays.
      The type depends on the type of each example in the batch.
docstr_tok: ["Concatenate","data","and","transfer","them","to","GPU","asynchronously",".","See","also",":","func",":","`","chainer.dataset.concat_examples","`",".","Args",":","batch","(","list",")",":","A","list","of","examples",".","device","(","int",")",":","Device","ID","to","which","each","array","is","sent",".","padding",":","Scalar","value","for","extra","elements",".","Returns",":","Array",",","a","tuple","of","arrays",",","or","a","dictionary","of","arrays",".","The","type","depends","on","the","type","of","each","example","in","the","batch","."]
code: def __call__(self, batch, device=None, padding=None):
      """Concatenate data and transfer them to GPU asynchronously.
  
      See also :func:`chainer.dataset.concat_examples`.
  
      Args:
          batch (list): A list of examples.
          device (int): Device ID to which each array is sent.
          padding: Scalar value for extra elements.
  
      Returns:
          Array, a tuple of arrays, or a dictionary of arrays.
          The type depends on the type of each example in the batch.
      """
      if not batch:
          raise ValueError("batch is empty")
      first_elem = batch[0]
  
      if not self._conveyor:
          self._device = device  # device is set at first call
          if (
              device is not None
              and device >= 0
              and self._stream is None
          ):
              with cuda.get_device_from_id(device):
                  self._stream = cuda.Stream(non_blocking=True)
      if device is not self._device:
          raise ValueError("device is different")
  
      if self.compute_stream is not None:
          self._event1.synchronize()
          self._event1.record(stream=self.compute_stream)
  
      with cuda.get_device_from_id(device):
          if isinstance(first_elem, tuple):
              result = []
              if not isinstance(padding, tuple):
                  padding = [padding] * len(first_elem)
  
              for i in six.moves.range(len(first_elem)):
                  self._conveyor[i].put(
                      _concat_arrays(
                          [example[i] for example in batch], padding[i]
                      )
                  )
  
              for i in six.moves.range(len(first_elem)):
                  result.append(
                      self._conveyor[i].get(sync=self._sync_get)
                  )
  
              if self.compute_stream is not None:
                  self._event2.record(stream=self._stream)
                  self.compute_stream.wait_event(self._event2)
  
              return tuple(result)
  
          elif isinstance(first_elem, dict):
              result = {}
              if not isinstance(padding, dict):
                  padding = {key: padding for key in first_elem}
  
              for key in first_elem:
                  self._conveyor[key].put(
                      _concat_arrays(
                          [example[key] for example in batch],
                          padding[key],
                      )
                  )
  
              for key in first_elem:
                  result[key] = self._conveyor[key].get(
                      sync=self._sync_get
                  )
  
              if self.compute_stream is not None:
                  self._event2.record(stream=self._stream)
                  self.compute_stream.wait_event(self._event2)
  
              return result
  
          else:
              return to_device(device, _concat_arrays(batch, padding))
  
imports: import collections
  import numpy
  import six
  import chainer
  from chainer import backend
  from chainer.backends import cuda
label_desc: Use image node_id 3 for calling the ConcatWithAsyncTransfer obj's underlying member method code with example usage: obj.__call__(batch, device, padding) and returns: tuple, result, to_device