Example #1
0
    def test_as_strided(self):
        a = cp.array([1, 2, 3, 4])
        a_view = as_strided(a, shape=(2, ), strides=(2 * a.itemsize, ))
        expected = cp.array([1, 3])
        assert_array_equal(a_view, expected)

        a = cp.array([1, 2, 3, 4])
        a_view = as_strided(a, shape=(3, 4), strides=(0, 1 * a.itemsize))
        expected = cp.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])
        assert_array_equal(a_view, expected)
Example #2
0
def _dot_convolve(a1, a2, mode):

    offset = 0
    if a1.size < a2.size:
        a1, a2 = a2, a1
        offset = 1 - a2.size % 2

    dtype = cupy.result_type(a1, a2)
    n1, n2 = a1.size, a2.size
    a1 = a1.astype(dtype, copy=False)
    a2 = a2.astype(dtype, copy=False)

    if mode == 'full':
        out_size = n1 + n2 - 1
        a1 = cupy.pad(a1, n2 - 1)
    elif mode == 'same':
        out_size = n1
        pad_size = (n2 - 1) // 2 + offset
        a1 = cupy.pad(a1, (n2 - 1 - pad_size, pad_size))
    elif mode == 'valid':
        out_size = n1 - n2 + 1

    stride = a1.strides[0]
    a1 = stride_tricks.as_strided(a1, (out_size, n2), (stride, stride))
    output = _dot_kernel(a1, a2[::-1], axis=1)
    return output
Example #3
0
def _dot_convolve(a1, a2, mode):
    if a1.size == 0 or a2.size == 0:
        raise ValueError('Array arguments cannot be empty')

    is_inverted = False
    if a1.size < a2.size:
        a1, a2 = a2, a1
        is_inverted = True

    dtype = cupy.result_type(a1, a2)
    n1, n2 = a1.size, a2.size
    a1 = a1.astype(dtype, copy=False)
    a2 = a2.astype(dtype, copy=False)

    if mode == 'full':
        out_size = n1 + n2 - 1
        a1 = cupy.pad(a1, n2 - 1)
    elif mode == 'same':
        out_size = n1
        pad_size = (n2 - 1) // 2
        a1 = cupy.pad(a1, (n2 - 1 - pad_size, pad_size))
    elif mode == 'valid':
        out_size = n1 - n2 + 1

    stride = a1.strides[0]
    a1 = stride_tricks.as_strided(a1, (out_size, n2), (stride, stride))
    output = _dot_kernel(a1, a2[::-1], axis=1)
    return is_inverted, output
Example #4
0
def toeplitz(c, r=None):
    """
    Construct a Toeplitz matrix.
    The Toeplitz matrix has constant diagonals, with c as its first column
    and r as its first row.  If r is not given, ``r == conjugate(c)`` is
    assumed.
    Parameters
    ----------
    c : array_like
        First column of the matrix.  Whatever the actual shape of `c`, it
        will be converted to a 1-D array.
    r : array_like, optional
        First row of the matrix. If None, ``r = conjugate(c)`` is assumed;
        in this case, if c[0] is real, the result is a Hermitian matrix.
        r[0] is ignored; the first row of the returned matrix is
        ``[c[0], r[1:]]``.  Whatever the actual shape of `r`, it will be
        converted to a 1-D array.
    Returns
    -------
    A : (len(c), len(r)) ndarray
        The Toeplitz matrix. Dtype is the same as ``(c[0] + r[0]).dtype``.
    See Also
    --------
    circulant : circulant matrix
    hankel : Hankel matrix
    solve_toeplitz : Solve a Toeplitz system.
    Notes
    -----
    The behavior when `c` or `r` is a scalar, or when `c` is complex and
    `r` is None, was changed in version 0.8.0.  The behavior in previous
    versions was undocumented and is no longer supported.
    Examples
    --------
    >>> from scipy.linalg import toeplitz
    >>> toeplitz([1,2,3], [1,4,5,6])
    array([[1, 4, 5, 6],
           [2, 1, 4, 5],
           [3, 2, 1, 4]])
    >>> toeplitz([1.0, 2+3j, 4-1j])
    array([[ 1.+0.j,  2.-3.j,  4.+1.j],
           [ 2.+3.j,  1.+0.j,  2.-3.j],
           [ 4.-1.j,  2.+3.j,  1.+0.j]])
    """
    c = cp.asarray(c).ravel()
    if r is None:
        r = cp.conjugate()
    else:
        r = cp.asarray(r).ravel()
    # Form a 1D array containing a reversed c followed by r[1:] that could be
    # strided to give us toeplitz matrix.
    vals = cp.concatenate((c[::-1], r[1:]))
    out_shp = len(c), len(r)
    n = vals.strides[0]
    return as_strided(vals[len(c) - 1:], shape=out_shp, strides=(-n, n)).copy()
Example #5
0
def allocate_gpu_unmanaged(default_origin, shape, layout_map, dtype,
                           alignment_bytes):
    dtype = np.dtype(dtype)
    assert (alignment_bytes % dtype.itemsize
            ) == 0, "Alignment must be a multiple of byte-width of dtype."
    itemsize = dtype.itemsize
    items_per_alignment = int(alignment_bytes / itemsize)

    order_idx = idx_from_order([i for i in layout_map if i is not None])
    padded_shape = compute_padded_shape(shape, items_per_alignment, order_idx)

    strides = strides_from_padded_shape(padded_shape, order_idx, itemsize)
    if len(order_idx) > 0:
        halo_offset = (
            int(math.ceil(default_origin[order_idx[-1]] / items_per_alignment))
            * items_per_alignment - default_origin[order_idx[-1]])
    else:
        halo_offset = 0

    padded_size = int(np.prod(padded_shape))
    buffer_size = padded_size + items_per_alignment - 1

    ptr = cp.cuda.alloc_pinned_memory(buffer_size * itemsize)
    raw_buffer = np.frombuffer(ptr, dtype, buffer_size)
    device_raw_buffer = cp.empty((buffer_size, ), dtype=dtype)

    allocation_mismatch = int(
        (raw_buffer.ctypes.data % alignment_bytes) / itemsize)
    alignment_offset = (halo_offset -
                        allocation_mismatch) % items_per_alignment
    field = np.reshape(
        raw_buffer[alignment_offset:alignment_offset + padded_size],
        padded_shape)
    if field.ndim > 0:
        field.strides = strides
        field = field[tuple(slice(0, s, None) for s in shape)]

    allocation_mismatch = int(
        (device_raw_buffer.data.ptr % alignment_bytes) / itemsize)
    alignment_offset = (halo_offset -
                        allocation_mismatch) % items_per_alignment

    device_field = as_strided(
        device_raw_buffer[alignment_offset:alignment_offset + padded_size],
        shape=padded_shape,
        strides=strides,
    )
    if device_field.ndim > 0:
        device_field = device_field[tuple(slice(0, s, None) for s in shape)]

    return raw_buffer, field, device_raw_buffer, device_field
Example #6
0
def hankel(c, r=None):
    """
    Construct a Hankel matrix.
    The Hankel matrix has constant anti-diagonals, with `c` as its
    first column and `r` as its last row.  If `r` is not given, then
    `r = zeros_like(c)` is assumed.
    Parameters
    ----------
    c : array_like
        First column of the matrix.  Whatever the actual shape of `c`, it
        will be converted to a 1-D array.
    r : array_like, optional
        Last row of the matrix. If None, ``r = zeros_like(c)`` is assumed.
        r[0] is ignored; the last row of the returned matrix is
        ``[c[-1], r[1:]]``.  Whatever the actual shape of `r`, it will be
        converted to a 1-D array.
    Returns
    -------
    A : (len(c), len(r)) ndarray
        The Hankel matrix. Dtype is the same as ``(c[0] + r[0]).dtype``.
    See Also
    --------
    toeplitz : Toeplitz matrix
    circulant : circulant matrix
    Examples
    --------
    >>> from scipy.linalg import hankel
    >>> hankel([1, 17, 99])
    array([[ 1, 17, 99],
           [17, 99,  0],
           [99,  0,  0]])
    >>> hankel([1,2,3,4], [4,7,7,8,9])
    array([[1, 2, 3, 4, 7],
           [2, 3, 4, 7, 7],
           [3, 4, 7, 7, 8],
           [4, 7, 7, 8, 9]])
    """
    c = cp.asarray(c).ravel()
    if r is None:
        r = cp.zeros_like(c)
    else:
        r = cp.asarray(r).ravel()
    # Form a 1D array of values to be used in the matrix, containing `c`
    # followed by r[1:].
    vals = cp.concatenate((c, r[1:]))
    # Stride on concatenated array to get hankel matrix
    out_shp = len(c), len(r)
    n = vals.strides[0]
    return as_strided(vals, shape=out_shp, strides=(n, n)).copy()
Example #7
0
def rolling_window(a, window, axis=-1):
    """
    Make an ndarray with a rolling window along axis.
    This function is taken from https://github.com/numpy/numpy/pull/31
    but slightly modified to accept axis option.
    """
    a = numpy.swapaxes(a, axis, -1)
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1], )
    if isinstance(a, numpy.ndarray):
        rolling = numpy.lib.stride_tricks.as_strided(a,
                                                     shape=shape,
                                                     strides=strides)
    elif isinstance(a, cupy.ndarray):
        rolling = stride_tricks.as_strided(a, shape=shape, strides=strides)
    return rolling.swapaxes(-2, axis)
Example #8
0
    def split_by_strides(X, kh, kw, s):
        """
         reference 1,一种卷积算法的高效实现 :https://zhuanlan.zhihu.com/p/64933417
         (forward 借鉴了这个,backward是自己推的)

        :param X: 原矩阵
        :param kh: 卷积核h
        :param kw: 卷积核w
        :param s: 步长
        :return:
        """
        N, C, H, W = X.shape
        oh = (H - kh) // s + 1
        ow = (W - kw) // s + 1
        strides = (*X.strides[:-2], X.strides[-2] * s, X.strides[-1] * s,
                   *X.strides[-2:])
        A = as_strided(X, shape=(N, C, oh, ow, kh, kw), strides=strides)
        return A
Example #9
0
 def sliding_window(x, w, s):
     shape = (x.shape[0], ((x.shape[1] - w) // s + 1), w)
     strides = (x.strides[0], x.strides[1]*s, x.strides[1])
     return as_strided(x, shape, strides)
Example #10
0
def view_as_blocks(arr_in, block_shape):
    """Block view of the input n-dimensional array (using re-striding).

    Blocks are non-overlapping views of the input array.

    Parameters
    ----------
    arr_in : ndarray
        N-d input array.
    block_shape : tuple
        The shape of the block. Each dimension must divide evenly into the
        corresponding dimensions of `arr_in`.

    Returns
    -------
    arr_out : ndarray
        Block view of the input array.  If `arr_in` is non-contiguous, a
        copy is made.

    Examples
    --------
    >>> import cupy as cp
    >>> from skimage.util.shape import view_as_blocks
    >>> A = cp.arange(4*4).reshape(4,4)
    >>> A
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15]])
    >>> B = view_as_blocks(A, block_shape=(2, 2))
    >>> B[0, 0]
    array([[0, 1],
           [4, 5]])
    >>> B[0, 1]
    array([[2, 3],
           [6, 7]])
    >>> B[1, 0, 1, 1]
    13

    >>> A = cp.arange(4*4*6).reshape(4,4,6)
    >>> A  # doctest: +NORMALIZE_WHITESPACE
    array([[[ 0,  1,  2,  3,  4,  5],
            [ 6,  7,  8,  9, 10, 11],
            [12, 13, 14, 15, 16, 17],
            [18, 19, 20, 21, 22, 23]],
           [[24, 25, 26, 27, 28, 29],
            [30, 31, 32, 33, 34, 35],
            [36, 37, 38, 39, 40, 41],
            [42, 43, 44, 45, 46, 47]],
           [[48, 49, 50, 51, 52, 53],
            [54, 55, 56, 57, 58, 59],
            [60, 61, 62, 63, 64, 65],
            [66, 67, 68, 69, 70, 71]],
           [[72, 73, 74, 75, 76, 77],
            [78, 79, 80, 81, 82, 83],
            [84, 85, 86, 87, 88, 89],
            [90, 91, 92, 93, 94, 95]]])
    >>> B = view_as_blocks(A, block_shape=(1, 2, 2))
    >>> B.shape
    (4, 2, 3, 1, 2, 2)
    >>> B[2:, 0, 2]  # doctest: +NORMALIZE_WHITESPACE
    array([[[[52, 53],
             [58, 59]]],
           [[[76, 77],
             [82, 83]]]])
    """
    if not isinstance(block_shape, tuple):
        raise TypeError("block needs to be a tuple")

    if any(s <= 0 for s in block_shape):
        raise ValueError("'block_shape' elements must be strictly positive")

    if len(block_shape) != arr_in.ndim:
        raise ValueError(
            "'block_shape' must have the same length as 'arr_in.shape'")

    if any(s % bs for s, bs in zip(arr_in.shape, block_shape)):
        raise ValueError("'block_shape' is not compatible with 'arr_in'")

    # TODO: This C-contiguous check and call to ascontiguousarray is not in
    #       skimage. Remove it?
    if not arr_in.flags.c_contiguous:  # c_contiguous:
        warn(
            RuntimeWarning("Cannot provide views on a non-contiguous "
                           "input array without copying."))
    arr_in = cp.ascontiguousarray(arr_in)

    # -- restride the array to build the block view
    new_shape = tuple([s // bs for s, bs in zip(arr_in.shape, block_shape)
                       ]) + tuple(block_shape)
    new_strides = (tuple(s * bs
                         for s, bs in zip(arr_in.strides, block_shape)) +
                   arr_in.strides)

    arr_out = as_strided(arr_in, shape=new_shape, strides=new_strides)

    return arr_out
Example #11
0
def view_as_windows(arr_in, window_shape, step=1):
    """Rolling window view of the input n-dimensional array.

    Windows are overlapping views of the input array, with adjacent windows
    shifted by a single row or column (or an index of a higher dimension).

    Parameters
    ----------
    arr_in : ndarray
        N-d input array.
    window_shape : integer or tuple of length arr_in.ndim
        Defines the shape of the elementary n-dimensional orthotope
        (better know as hyperrectangle [1]_) of the rolling window view.
        If an integer is given, the shape will be a hypercube of
        sidelength given by its value.
    step : integer or tuple of length arr_in.ndim
        Indicates step size at which extraction shall be performed.
        If integer is given, then the step is uniform in all dimensions.

    Returns
    -------
    arr_out : ndarray
        (rolling) window view of the input array.

    Notes
    -----
    One should be very careful with rolling views when it comes to
    memory usage.  Indeed, although a 'view' has the same memory
    footprint as its base array, the actual array that emerges when this
    'view' is used in a computation is generally a (much) larger array
    than the original, especially for 2-dimensional arrays and above.

    For example, let us consider a 3 dimensional array of size (100,
    100, 100) of ``float64``. This array takes about 8*100**3 Bytes for
    storage which is just 8 MB. If one decides to build a rolling view
    on this array with a window of (3, 3, 3) the hypothetical size of
    the rolling view (if one was to reshape the view for example) would
    be 8*(100-3+1)**3*3**3 which is about 203 MB! The scaling becomes
    even worse as the dimension of the input array becomes larger.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Hyperrectangle

    Examples
    --------
    >>> import cupy as cp
    >>> from skimage.util.shape import view_as_windows
    >>> A = cp.arange(4*4).reshape(4,4)
    >>> A
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15]])
    >>> window_shape = (2, 2)
    >>> B = view_as_windows(A, window_shape)
    >>> B[0, 0]
    array([[0, 1],
           [4, 5]])
    >>> B[0, 1]
    array([[1, 2],
           [5, 6]])

    >>> A = cp.arange(10)
    >>> A
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    >>> window_shape = (3,)
    >>> B = view_as_windows(A, window_shape)
    >>> B.shape
    (8, 3)
    >>> B
    array([[0, 1, 2],
           [1, 2, 3],
           [2, 3, 4],
           [3, 4, 5],
           [4, 5, 6],
           [5, 6, 7],
           [6, 7, 8],
           [7, 8, 9]])

    >>> A = cp.arange(5*4).reshape(5, 4)
    >>> A
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15],
           [16, 17, 18, 19]])
    >>> window_shape = (4, 3)
    >>> B = view_as_windows(A, window_shape)
    >>> B.shape
    (2, 2, 4, 3)
    >>> B  # doctest: +NORMALIZE_WHITESPACE
    array([[[[ 0,  1,  2],
             [ 4,  5,  6],
             [ 8,  9, 10],
             [12, 13, 14]],
            [[ 1,  2,  3],
             [ 5,  6,  7],
             [ 9, 10, 11],
             [13, 14, 15]]],
           [[[ 4,  5,  6],
             [ 8,  9, 10],
             [12, 13, 14],
             [16, 17, 18]],
            [[ 5,  6,  7],
             [ 9, 10, 11],
             [13, 14, 15],
             [17, 18, 19]]]])
    """

    # -- basic checks on arguments
    if not isinstance(arr_in, cp.ndarray):
        raise TypeError("`arr_in` must be a cupy ndarray")

    ndim = arr_in.ndim

    if isinstance(window_shape, numbers.Number):
        window_shape = (window_shape, ) * ndim
    if not (len(window_shape) == ndim):
        raise ValueError("`window_shape` is incompatible with `arr_in.shape`")

    if isinstance(step, numbers.Number):
        if step < 1:
            raise ValueError("`step` must be >= 1")
        step = (step, ) * ndim
    if len(step) != ndim:
        raise ValueError("`step` is incompatible with `arr_in.shape`")

    arr_shape = arr_in.shape
    window_shape = tuple([int(w) for w in window_shape])

    if any(s < ws for s, ws in zip(arr_shape, window_shape)):
        raise ValueError("`window_shape` is too large")

    if any(ws < 0 for ws in window_shape):
        raise ValueError("`window_shape` is too small")

    # -- build rolling window view
    slices = tuple(slice(None, None, st) for st in step)
    win_indices_shape = tuple([
        (s - ws) // st + 1 for s, ws, st in zip(arr_shape, window_shape, step)
    ])
    new_shape = win_indices_shape + window_shape

    window_strides = arr_in.strides
    indexing_strides = arr_in[slices].strides
    strides = indexing_strides + window_strides

    arr_out = as_strided(arr_in, shape=new_shape, strides=strides)
    return arr_out