コード例 #1
0
def average(a, axis=None, weights=None, returned=False):  # pylint: disable=missing-docstring
    if axis is not None and not isinstance(axis, six.integer_types):
        # TODO(wangpeng): Support tuple of ints as `axis`
        raise ValueError('`axis` must be an integer. Tuple of ints is not '
                         'supported yet. Got type: %s' % type(axis))
    a = array_ops.array(a)
    if weights is None:  # Treat all weights as 1
        if not np.issubdtype(a.dtype, np.inexact):
            a = a.astype(
                utils.result_type(a.dtype, dtypes.default_float_type()))
        avg = tf.reduce_mean(a.data, axis=axis)
        if returned:
            if axis is None:
                weights_sum = tf.size(a.data)
            else:
                weights_sum = tf.shape(a.data)[axis]
            weights_sum = tf.cast(weights_sum, a.data.dtype)
    else:
        if np.issubdtype(a.dtype, np.inexact):
            out_dtype = utils.result_type(a.dtype, weights)
        else:
            out_dtype = utils.result_type(a.dtype, weights,
                                          dtypes.default_float_type())
        a = array_ops.array(a, out_dtype).data
        weights = array_ops.array(weights, out_dtype).data

        def rank_equal_case():
            tf.debugging.Assert(
                tf.reduce_all(tf.shape(a) == tf.shape(weights)),
                [tf.shape(a), tf.shape(weights)])
            weights_sum = tf.reduce_sum(weights, axis=axis)
            avg = tf.reduce_sum(a * weights, axis=axis) / weights_sum
            return avg, weights_sum

        if axis is None:
            avg, weights_sum = rank_equal_case()
        else:

            def rank_not_equal_case():
                tf.debugging.Assert(tf.rank(weights) == 1, [tf.rank(weights)])
                weights_sum = tf.reduce_sum(weights)
                axes = tf.convert_to_tensor([[axis], [0]])
                avg = tf.tensordot(a, weights, axes) / weights_sum
                return avg, weights_sum

            # We condition on rank rather than shape equality, because if we do the
            # latter, when the shapes are partially unknown but the ranks are known
            # and different, utils.cond will run shape checking on the true branch,
            # which will raise a shape-checking error.
            avg, weights_sum = utils.cond(
                tf.rank(a) == tf.rank(weights), rank_equal_case,
                rank_not_equal_case)

    avg = array_ops.array(avg)
    if returned:
        weights_sum = array_ops.broadcast_to(weights_sum, tf.shape(avg.data))
        return avg, weights_sum
    return avg
コード例 #2
0
ファイル: array_ops.py プロジェクト: eudora-jia/trax
def array(val, dtype=None, copy=True, ndmin=0):  # pylint: disable=redefined-outer-name
    """Creates an ndarray with the contents of val.

  Args:
    val: array_like. Could be an ndarray, a Tensor or any object that can be
      converted to a Tensor using `tf.convert_to_tensor`.
    dtype: Optional, defaults to dtype of the `val`. The type of the resulting
      ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`.
    copy: Determines whether to create a copy of the backing buffer. Since
      Tensors are immutable, a copy is made only if val is placed on a different
      device than the current one. Even if `copy` is False, a new Tensor may
      need to be built to satisfy `dtype` and `ndim`. This is used only if `val`
      is an ndarray or a Tensor.
    ndmin: The minimum rank of the returned array.

  Returns:
    An ndarray.
  """
    if dtype:
        dtype = utils.result_type(dtype)
    if isinstance(val, arrays_lib.ndarray):
        result_t = val.data
    else:
        result_t = val

    if copy and isinstance(result_t, tf.Tensor):
        # Note: In eager mode, a copy of `result_t` is made only if it is not on
        # the context device.
        result_t = tf.identity(result_t)

    if not isinstance(result_t, tf.Tensor):
        if not dtype:
            dtype = utils.result_type(result_t)
        # We can't call `convert_to_tensor(result_t, dtype=dtype)` here because
        # convert_to_tensor doesn't allow incompatible arguments such as (5.5, int)
        # while np.array allows them. We need to convert-then-cast.
        def maybe_data(x):
            if isinstance(x, arrays_lib.ndarray):
                return x.data
            return x

        # Handles lists of ndarrays
        result_t = tf.nest.map_structure(maybe_data, result_t)
        result_t = arrays_lib.convert_to_tensor(result_t)
        result_t = tf.cast(result_t, dtype=dtype)
    elif dtype:
        result_t = tf.cast(result_t, dtype)
    ndims = tf.rank(result_t)

    def true_fn():
        old_shape = tf.shape(result_t)
        new_shape = tf.concat([tf.ones(ndmin - ndims, tf.int32), old_shape],
                              axis=0)
        return tf.reshape(result_t, new_shape)

    result_t = utils.cond(utils.greater(ndmin, ndims), true_fn,
                          lambda: result_t)
    return arrays_lib.tensor_to_ndarray(result_t)
コード例 #3
0
ファイル: array_ops.py プロジェクト: rouniuyizu/trax
def eye(N, M=None, k=0, dtype=float):  # pylint: disable=invalid-name,missing-docstring
  if dtype:
    dtype = utils.result_type(dtype)
  if not M:
    M = N
  # Making sure N, M and k are `int`
  N = int(N)
  M = int(M)
  k = int(k)
  if k >= M or -k >= N:
    # tf.linalg.diag will raise an error in this case
    return zeros([N, M], dtype=dtype)
  if k == 0:
    return arrays_lib.tensor_to_ndarray(tf.eye(N, M, dtype=dtype))
  # We need the precise length, otherwise tf.linalg.diag will raise an error
  diag_len = min(N, M)
  if k > 0:
    if N >= M:
      diag_len -= k
    elif N + k > M:
      diag_len = M - k
  elif k <= 0:
    if M >= N:
      diag_len += k
    elif M - k > N:
      diag_len = N + k
  diagonal = tf.ones([diag_len], dtype=dtype)
  return arrays_lib.tensor_to_ndarray(
      tf.linalg.diag(diagonal=diagonal, num_rows=N, num_cols=M, k=k))
コード例 #4
0
def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=float):
    if dtype:
        dtype = utils.result_type(dtype)
    start = array_creation.asarray(start, dtype=dtype)
    stop = array_creation.asarray(stop, dtype=dtype)
    if num == 0:
        return empty(dtype)
    if num < 0:
        raise ValueError(
            'Number of samples {} must be non-negative.'.format(num))
    step = np.nan
    if endpoint:
        result = tf.linspace(start.data, stop.data, num)
        if num > 1:
            step = (stop - start) / (num - 1)
    else:
        # tf.linspace does not support endpoint=False so we manually handle it
        # here.
        if num > 1:
            step = (stop - start) / num
            result = tf.linspace(start.data, (stop - step).data, num)
        else:
            result = tf.linspace(start.data, stop.data, num)
    if dtype:
        result = tf.cast(result, dtype)
    if retstep:
        return arrays.tensor_to_ndarray(result), step
    else:
        return arrays.tensor_to_ndarray(result)
コード例 #5
0
ファイル: array_creation.py プロジェクト: zsunpku/trax
def array(val, dtype=None, copy=True, ndmin=0):
    """Creates an ndarray with the contents of val.

  Args:
    val: array_like. Could be an ndarray, a Tensor or any object that can
      be converted to a Tensor using `tf.convert_to_tensor`.
    dtype: Optional, defaults to dtype of the `val`. The type of the
      resulting ndarray. Could be a python type, a NumPy type or a TensorFlow
      `DType`.
    copy: Determines whether to create a copy of the backing buffer. Since
      Tensors are immutable, a copy is made only if val is placed on a different
      device than the current one. Even if `copy` is False, a new Tensor may
      need to be built to satisfy `dtype` and `ndim`. This is used only if `val`
      is an ndarray or a Tensor.
    ndmin: The minimum rank of the returned array.

  Returns:
    An ndarray.
  """
    if dtype:
        dtype = utils.result_type(dtype)
    if isinstance(val, arrays.ndarray):
        result_t = val.data
    else:
        result_t = val

    if copy and isinstance(result_t, tf.Tensor):
        # Note: In eager mode, a copy of `result_t` is made only if it is not on
        # the context device.
        result_t = tf.identity(result_t)

    if not isinstance(result_t, tf.Tensor):
        if not dtype:
            dtype = utils.result_type(result_t)
        # We can't call `convert_to_tensor(result_t, dtype=dtype)` here because
        # convert_to_tensor doesn't allow incompatible arguments such as (5.5, int)
        # while np.array allows them. We need to convert-then-cast.
        result_t = arrays.convert_to_tensor(result_t)
        result_t = tf.cast(result_t, dtype=dtype)
    elif dtype:
        result_t = tf.cast(result_t, dtype)
    ndims = len(result_t.shape)
    if ndmin > ndims:
        old_shape = list(result_t.shape)
        new_shape = [1 for _ in range(ndmin - ndims)] + old_shape
        result_t = tf.reshape(result_t, new_shape)
    return arrays.tensor_to_ndarray(result_t)
コード例 #6
0
def concatenate(arys, axis=0):
    if not isinstance(arys, (list, tuple)):
        arys = [arys]
    if not arys:
        raise ValueError('Need at least one array to concatenate.')
    dtype = utils.result_type(*arys)
    arys = [array_ops.array(array, dtype=dtype).data for array in arys]
    return arrays.tensor_to_ndarray(tf.concat(arys, axis))
コード例 #7
0
def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):
    if dtype:
        dtype = utils.result_type(dtype)
    result = linspace(start, stop, num=num, endpoint=endpoint)
    result = tf.pow(base, result.data)
    if dtype:
        result = tf.cast(result, dtype)
    return arrays.tensor_to_ndarray(result)
コード例 #8
0
ファイル: array_methods.py プロジェクト: 3Dsamples/trax
def _reduce(tf_fn, a, axis=None, dtype=None, keepdims=None,
            promote_int=_TO_INT64, tf_bool_fn=None, preserve_bool=False):
  """A general reduction function.

  Args:
    tf_fn: the TF reduction function.
    a: the array to be reduced.
    axis: (optional) the axis along which to do the reduction. If None, all
      dimensions are reduced.
    dtype: (optional) the dtype of the result.
    keepdims: (optional) whether to keep the reduced dimension(s).
    promote_int: how to promote integer and bool inputs. There are three
      choices: (1) _TO_INT64: always promote them to int64 or uint64; (2)
      _TO_FLOAT: always promote them to a float type (determined by
      dtypes.default_float_type); (3) None: don't promote.
    tf_bool_fn: (optional) the TF reduction function for bool inputs. It
      will only be used if `dtype` is explicitly set to `np.bool_` or if `a`'s
      dtype is `np.bool_` and `preserve_bool` is True.
    preserve_bool: a flag to control whether to use `tf_bool_fn` if `a`'s dtype
      is `np.bool_` (some reductions such as np.sum convert bools to
      integers, while others such as np.max preserve bools.

  Returns:
    An ndarray.
  """
  if dtype:
    dtype = utils.result_type(dtype)
  if keepdims is None:
    keepdims = False
  a = array_creation.asarray(a, dtype=dtype)
  if ((dtype == np.bool_ or preserve_bool and a.dtype == np.bool_)
      and tf_bool_fn is not None):
    return utils.tensor_to_ndarray(
        tf_bool_fn(input_tensor=a.data, axis=axis, keepdims=keepdims))
  if dtype is None:
    dtype = a.dtype
    if np.issubdtype(dtype, np.integer) or dtype == np.bool_:
      if promote_int == _TO_INT64:
        # If a is an integer/bool type and whose bit width is less than 64,
        # numpy up-casts it to 64-bit.
        if dtype == np.bool_:
          is_signed = True
          width = 8  # We can use any number here that is less than 64
        else:
          is_signed = np.issubdtype(dtype, np.signedinteger)
          width = np.iinfo(dtype).bits
        if width < 64:
          if is_signed:
            dtype = np.int64
          else:
            dtype = np.uint64
          a = a.astype(dtype)
      elif promote_int == _TO_FLOAT:
        a = a.astype(dtypes.default_float_type())

  return utils.tensor_to_ndarray(
      tf_fn(input_tensor=a.data, axis=axis, keepdims=keepdims))
コード例 #9
0
ファイル: array_creation.py プロジェクト: koz4k2/trax
def promote_args_types(a, b):
    a = asarray(a)
    b = asarray(b)
    output_type = utils.result_type(a.dtype, b.dtype)
    if output_type != a.dtype:
        a = a.astype(output_type)
    if output_type != b.dtype:
        b = b.astype(output_type)
    return (a, b)
コード例 #10
0
def _comparison(tf_fun, x1, x2, cast_bool_to_int=False):
    dtype = utils.result_type(x1, x2)
    # Cast x1 and x2 to the result_type if needed.
    x1 = array_creation.asarray(x1, dtype=dtype)
    x2 = array_creation.asarray(x2, dtype=dtype)
    x1 = x1.data
    x2 = x2.data
    if cast_bool_to_int and x1.dtype == tf.bool:
        x1 = tf.cast(x1, tf.int32)
        x2 = tf.cast(x2, tf.int32)
    return utils.tensor_to_ndarray(tf_fun(x1, x2))
コード例 #11
0
ファイル: array_ops.py プロジェクト: rouniuyizu/trax
def ones_like(a, dtype=None):
  """Returns an array of ones with the shape and type of the input array.

  Args:
    a: array_like. Could be an ndarray, a Tensor or any object that can be
      converted to a Tensor using `tf.convert_to_tensor`.
    dtype: Optional, defaults to dtype of the input array. The type of the
      resulting ndarray. Could be a python type, a NumPy type or a TensorFlow
      `DType`.

  Returns:
    An ndarray.
  """
  if isinstance(a, arrays_lib.ndarray):
    a = a.data
  if dtype is None:
    dtype = utils.result_type(a)
  else:
    dtype = utils.result_type(dtype)
  return arrays_lib.tensor_to_ndarray(tf.ones_like(a, dtype))
コード例 #12
0
ファイル: array_creation.py プロジェクト: koz4k2/trax
def arange(start, stop=None, step=1, dtype=None):
    """Returns `step`-separated values in the range [start, stop).

  Args:
    start: Start of the interval. Included in the range.
    stop: End of the interval. If not specified, `start` is treated as 0 and
      `start` value is used as `stop`. If specified, it is not included in the
      range if `step` is integer. When `step` is floating point, it may or may
      not be included.
    step: The difference between 2 consecutive values in the output range.
      It is recommended to use `linspace` instead of using non-integer values
      for `step`.
    dtype: Optional. Type of the resulting ndarray. Could be a python type, a
      NumPy type or a TensorFlow `DType`. If not provided, the largest type of
      `start`, `stop`, `step` is used.

  Raises:
    ValueError: If step is zero.
  """
    if not step:
        raise ValueError('step must be non-zero.')
    if dtype:
        dtype = utils.to_tf_type(dtype)
    else:
        dtype = utils.result_type(
            utils.array_dtype(start).as_numpy_dtype,
            utils.array_dtype(step).as_numpy_dtype)
        if stop is not None:
            dtype = utils.result_type(dtype,
                                      utils.array_dtype(stop).as_numpy_dtype)
        dtype = utils.to_tf_type(dtype)
    if step > 0 and ((stop is not None and start > stop) or
                     (stop is None and start < 0)):
        return array([], dtype=dtype)
    if step < 0 and ((stop is not None and start < stop) or
                     (stop is None and start > 0)):
        return array([], dtype=dtype)
    # TODO(srbs): There are some bugs when start or stop is float type and dtype
    # is integer type.
    return utils.tensor_to_ndarray(
        tf.cast(tf.range(start, limit=stop, delta=step), dtype=dtype))
コード例 #13
0
def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None):  # pylint: disable=missing-docstring,redefined-outer-name
  """order, subok and shape arguments mustn't be changed."""
  if order != 'K':
    raise ValueError('Non-standard orders are not supported.')
  if not subok:
    raise ValueError('subok being False is not supported.')
  if shape:
    raise ValueError('Overriding the shape is not supported.')

  a = asarray(a).data
  dtype = dtype or utils.result_type(a)
  fill_value = asarray(fill_value, dtype=dtype)
  return arrays_lib.tensor_to_ndarray(
      tf.broadcast_to(fill_value.data, tf.shape(a)))
コード例 #14
0
def trace(a, offset=0, axis1=0, axis2=1, dtype=None):  # pylint: disable=missing-docstring
    if dtype:
        dtype = utils.result_type(dtype)
    a = array_ops.asarray(a, dtype).data

    if offset == 0:
        a_shape = a.shape
        if a_shape.rank is not None:
            rank = len(a_shape)
            if (axis1 == -2 or axis1 == rank - 2) and (axis2 == -1
                                                       or axis2 == rank - 1):
                return utils.tensor_to_ndarray(tf.linalg.trace(a))

    a = array_ops.diagonal(a, offset, axis1, axis2)
    return array_ops.sum(a, -1, dtype)
コード例 #15
0
ファイル: array_ops.py プロジェクト: rouniuyizu/trax
def zeros_like(a, dtype=None):
  """Returns an array of zeros with the shape and type of the input array.

  Args:
    a: array_like. Could be an ndarray, a Tensor or any object that can be
      converted to a Tensor using `tf.convert_to_tensor`.
    dtype: Optional, defaults to dtype of the input array. The type of the
      resulting ndarray. Could be a python type, a NumPy type or a TensorFlow
      `DType`.

  Returns:
    An ndarray.
  """
  if isinstance(a, arrays_lib.ndarray):
    a = a.data
  if dtype is None:
    # We need to let utils.result_type decide the dtype, not tf.zeros_like
    dtype = utils.result_type(a)
  else:
    # TF and numpy has different interpretations of Python types such as
    # `float`, so we let `utils.result_type` decide.
    dtype = utils.result_type(dtype)
  dtype = tf.as_dtype(dtype)  # Work around b/149877262
  return arrays_lib.tensor_to_ndarray(tf.zeros_like(a, dtype))
コード例 #16
0
def logspace(start,
             stop,
             num=50,
             endpoint=True,
             base=10.0,
             dtype=None,
             axis=0):
    dtype = utils.result_type(start, stop, dtype)
    result = linspace(start,
                      stop,
                      num=num,
                      endpoint=endpoint,
                      dtype=dtype,
                      axis=axis).data
    result = tf.pow(tf.cast(base, result.dtype), result)
    if dtype:
        result = tf.cast(result, dtype)
    return arrays.tensor_to_ndarray(result)
コード例 #17
0
ファイル: array_ops.py プロジェクト: rouniuyizu/trax
def zeros(shape, dtype=float):  # pylint: disable=redefined-outer-name
  """Returns an ndarray with the given shape and type filled with zeros.

  Args:
    shape: A fully defined shape. Could be - NumPy array or a python scalar,
      list or tuple of integers, - TensorFlow tensor/ndarray of integer type and
      rank <=1.
    dtype: Optional, defaults to float. The type of the resulting ndarray. Could
      be a python type, a NumPy type or a TensorFlow `DType`.

  Returns:
    An ndarray.
  """
  if dtype:
    dtype = utils.result_type(dtype)
  if isinstance(shape, arrays_lib.ndarray):
    shape = shape.data
  return arrays_lib.tensor_to_ndarray(tf.zeros(shape, dtype=dtype))
コード例 #18
0
ファイル: array_ops.py プロジェクト: rouniuyizu/trax
def geomspace(start, stop, num=50, endpoint=True, dtype=float):  # pylint: disable=missing-docstring
  if dtype:
    dtype = utils.result_type(dtype)
  if num < 0:
    raise ValueError('Number of samples {} must be non-negative.'.format(num))
  if not num:
    return empty([0])
  step = 1.
  if endpoint:
    if num > 1:
      step = tf.pow((stop / start), 1 / (num - 1))
  else:
    step = tf.pow((stop / start), 1 / num)
  result = tf.cast(tf.range(num), step.dtype)
  result = tf.pow(step, result)
  result = tf.multiply(result, start)
  if dtype:
    result = tf.cast(result, dtype=dtype)
  return arrays_lib.tensor_to_ndarray(result)
コード例 #19
0
ファイル: array_ops.py プロジェクト: rouniuyizu/trax
def full_like(a, fill_value, dtype=None):
  """Returns an array with same shape and dtype as `a` filled with `fill_value`.

  Args:
    a: array_like. Could be an ndarray, a Tensor or any object that can be
      converted to a Tensor using `tf.convert_to_tensor`.
    fill_value: array_like. Could be an ndarray, a Tensor or any object that can
      be converted to a Tensor using `tf.convert_to_tensor`.
    dtype: Optional, defaults to dtype of the `a`. The type of the resulting
      ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`.

  Returns:
    An ndarray.

  Raises:
    ValueError: if `fill_value` can not be broadcast to shape `shape`.
  """
  a = asarray(a)
  dtype = dtype or utils.result_type(a)
  return full(a.shape, fill_value, dtype)
コード例 #20
0
def equal(x1, x2):
    """Compare two arrays for equality element-wise.

  Both arrays must either be of the same shape or one should be broadcastable
  to the other.

  Args:
    x1: array_like. Could be an ndarray, a Tensor or any object that can
      be converted to a Tensor using `tf.convert_to_tensor`.
    x2: array_like. Could be an ndarray, a Tensor or any object that can
      be converted to a Tensor using `tf.convert_to_tensor`.

  Returns:
    An ndarray of type bool and broadcasted shape of x1 and x2.
  """
    dtype = utils.result_type(x1, x2)
    # Cast x1 and x2 to the result_type if needed.
    x1 = array_creation.array(x1, copy=False, dtype=dtype)
    x2 = array_creation.array(x2, copy=False, dtype=dtype)
    return utils.tensor_to_ndarray(tf.equal(x1.data, x2.data))
コード例 #21
0
def tri(N, M=None, k=0, dtype=None):  # pylint: disable=invalid-name,missing-docstring
  M = M if M is not None else N
  if dtype is not None:
    dtype = utils.result_type(dtype)
  else:
    dtype = dtypes.default_float_type()

  if k < 0:
    lower = -k - 1
    if lower > N:
      r = tf.zeros([N, M], dtype)
    else:
      # Keep as tf bool, since we create an upper triangular matrix and invert
      # it.
      o = tf.ones([N, M], dtype=tf.bool)
      r = tf.cast(tf.math.logical_not(tf.linalg.band_part(o, lower, -1)), dtype)
  else:
    o = tf.ones([N, M], dtype)
    if k > M:
      r = o
    else:
      r = tf.linalg.band_part(o, -1, k)
  return utils.tensor_to_ndarray(r)
コード例 #22
0
def linspace(  # pylint: disable=missing-docstring
        start,
        stop,
        num=50,
        endpoint=True,
        retstep=False,
        dtype=float,
        axis=0):
    if dtype:
        dtype = utils.result_type(dtype)
    start = array_ops.array(start, dtype=dtype).data
    stop = array_ops.array(stop, dtype=dtype).data
    if num < 0:
        raise ValueError(
            'Number of samples {} must be non-negative.'.format(num))
    step = tf.convert_to_tensor(np.nan)
    if endpoint:
        result = tf.linspace(start, stop, num, axis=axis)
        if num > 1:
            step = (stop - start) / (num - 1)
    else:
        # tf.linspace does not support endpoint=False so we manually handle it
        # here.
        if num > 1:
            step = ((stop - start) / num)
            new_stop = tf.cast(stop, step.dtype) - step
            start = tf.cast(start, new_stop.dtype)
            result = tf.linspace(start, new_stop, num, axis=axis)
        else:
            result = tf.linspace(start, stop, num, axis=axis)
    if dtype:
        result = tf.cast(result, dtype)
    if retstep:
        return arrays.tensor_to_ndarray(result), arrays.tensor_to_ndarray(step)
    else:
        return arrays.tensor_to_ndarray(result)
コード例 #23
0
ファイル: array_ops.py プロジェクト: rouniuyizu/trax
def asarray(a, dtype=None):
  if dtype:
    dtype = utils.result_type(dtype)
  if isinstance(a, arrays_lib.ndarray) and (not dtype or dtype == a.dtype):
    return a
  return array(a, dtype, copy=False)
コード例 #24
0
def concatenate(arys, axis=0):
    if not arys:
        raise ValueError('Need at least one array to concatenate.')
    dtype = utils.result_type(*arys)
    arys = [array_creation.asarray(array, dtype=dtype).data for array in arys]
    return arrays.tensor_to_ndarray(tf.concat(arys, axis))
コード例 #25
0
ファイル: array_ops.py プロジェクト: rouniuyizu/trax
def _promote_dtype(*arrays):
  dtype = utils.result_type(*arrays)
  return [asarray(a, dtype=dtype) for a in arrays]