(dst, src, async_=False, stream=None)
Copy the contents of src into dst.

    The two arrays should have the same dtype, shape, and order, but
    not necessarily the same strides. There may be up to _two_
    axes along which either `src` or `dst` is not contiguous.
Copy the contents of src into dst.
Copy the contents of src into dst .
def _memcpy_discontig(dst, src, async_=False, stream=None):
    """Copy the contents of src into dst.

    The two arrays should have the same dtype, shape, and order, but
    not necessarily the same strides. There may be up to _two_
    axes along which either `src` or `dst` is not contiguous.
    """

    if not isinstance(src, (GPUArray, np.ndarray)):
        raise TypeError("src must be GPUArray or ndarray")
    if not isinstance(dst, (GPUArray, np.ndarray)):
        raise TypeError("dst must be GPUArray or ndarray")
    if src.shape != dst.shape:
        raise ValueError("src and dst must be same shape")
    if src.dtype != dst.dtype:
        raise TypeError("src and dst must have same dtype")

    # ndarray -> ndarray
    if isinstance(src, np.ndarray) and isinstance(dst, np.ndarray):
        dst[...] = src
        return

    if src.flags.forc and dst.flags.forc:
        shape = [src.size]
        src_strides = dst_strides = [src.dtype.itemsize]
    else:
        # put src in Fortran order (which should put dst in Fortran order too)
        # and remove singleton axes
        src_info = sorted(
            (src.strides[axis], axis)
            for axis in range(len(src.shape))
            if src.shape[axis] > 1
        )
        axes = [axis for _, axis in src_info]
        shape = [src.shape[axis] for axis in axes]
        src_strides = [src.strides[axis] for axis in axes]
        dst_strides = [dst.strides[axis] for axis in axes]

        # copy functions require contiguity in minor axis, so add new axis if needed
        if (
            len(shape) == 0
            or src_strides[0] != src.dtype.itemsize
            or dst_strides[0] != dst.dtype.itemsize
        ):
            shape[0:0] = [1]
            src_strides[0:0] = [0]
            dst_strides[0:0] = [0]
            axes[0:0] = [np.newaxis]

        # collapse contiguous dimensions
        # and check that dst is in same order as src
        i = 1
        while i < len(shape):
            if dst_strides[i] < dst_strides[i - 1]:
                raise ValueError("src and dst must have same order")
            if (
                src_strides[i - 1] * shape[i - 1] == src_strides[i]
                and dst_strides[i - 1] * shape[i - 1] == dst_strides[i]
            ):
                shape[i - 1:i + 1] = [shape[i - 1] * shape[i]]
                del src_strides[i]
                del dst_strides[i]
                del axes[i]
            else:
                i += 1

    if len(shape) <= 1:
        if isinstance(src, GPUArray):
            if isinstance(dst, GPUArray):
                if async_:
                    drv.memcpy_dtod_async(
                        dst.gpudata, src.gpudata, src.nbytes, stream=stream
                    )
                else:
                    drv.memcpy_dtod(dst.gpudata, src.gpudata, src.nbytes)
            else:
                # The arrays might be contiguous in the sense of
                # having no gaps, but the axes could be transposed
                # so that the order is neither Fortran or C.
                # So, we attempt to get a contiguous view of dst.
                dst = _as_strided(dst, shape=(dst.size,), strides=(dst.dtype.itemsize,))
                if async_:
                    drv.memcpy_dtoh_async(dst, src.gpudata, stream=stream)
                else:
                    drv.memcpy_dtoh(dst, src.gpudata)
        else:
            src = _as_strided(src, shape=(src.size,), strides=(src.dtype.itemsize,))
            if async_:
                drv.memcpy_htod_async(dst.gpudata, src, stream=stream)
            else:
                drv.memcpy_htod(dst.gpudata, src)
        return

    if len(shape) == 2:
        copy = drv.Memcpy2D()
    elif len(shape) == 3:
        copy = drv.Memcpy3D()
    else:
        raise ValueError(
            "more than 2 discontiguous axes not supported {}".format(tuple(sorted(axes)))
        )

    if isinstance(src, GPUArray):
        copy.set_src_device(src.gpudata)
    else:
        copy.set_src_host(src)

    if isinstance(dst, GPUArray):
        copy.set_dst_device(dst.gpudata)
    else:
        copy.set_dst_host(dst)

    copy.width_in_bytes = src.dtype.itemsize * shape[0]

    copy.src_pitch = src_strides[1]
    copy.dst_pitch = dst_strides[1]
    copy.height = shape[1]

    if len(shape) == 2:
        if async_:
            copy(stream)
        else:
            copy(aligned=True)

    else:  # len(shape) == 3
        if src_strides[2] % src_strides[1] != 0:
            raise RuntimeError("src's major stride must be a multiple of middle stride")
        copy.src_height = src_strides[2] // src_strides[1]

        if dst_strides[2] % dst_strides[1] != 0:
            raise RuntimeError("dst's major stride must be a multiple of middle stride")
        copy.dst_height = dst_strides[2] // dst_strides[1]

        copy.depth = shape[2]
        if async_:
            copy(stream)
        else:
            copy()
def _memcpy_discontig ( dst , src , async_ = False , stream = None ) : if not isinstance ( src , ( GPUArray , np . ndarray ) ) : raise TypeError ( "src must be GPUArray or ndarray" ) if not isinstance ( dst , ( GPUArray , np . ndarray ) ) : raise TypeError ( "dst must be GPUArray or ndarray" ) if src . shape != dst . shape : raise ValueError ( "src and dst must be same shape" ) if src . dtype != dst . dtype : raise TypeError ( "src and dst must have same dtype" ) # ndarray -> ndarray if isinstance ( src , np . ndarray ) and isinstance ( dst , np . ndarray ) : dst [ ... ] = src return if src . flags . forc and dst . flags . forc : shape = [ src . size ] src_strides = dst_strides = [ src . dtype . itemsize ] else : # put src in Fortran order (which should put dst in Fortran order too) # and remove singleton axes src_info = sorted ( ( src . strides [ axis ] , axis ) for axis in range ( len ( src . shape ) ) if src . shape [ axis ] > 1 ) axes = [ axis for _ , axis in src_info ] shape = [ src . shape [ axis ] for axis in axes ] src_strides = [ src . strides [ axis ] for axis in axes ] dst_strides = [ dst . strides [ axis ] for axis in axes ] # copy functions require contiguity in minor axis, so add new axis if needed if ( len ( shape ) == 0 or src_strides [ 0 ] != src . dtype . itemsize or dst_strides [ 0 ] != dst . dtype . itemsize ) : shape [ 0 : 0 ] = [ 1 ] src_strides [ 0 : 0 ] = [ 0 ] dst_strides [ 0 : 0 ] = [ 0 ] axes [ 0 : 0 ] = [ np . newaxis ] # collapse contiguous dimensions # and check that dst is in same order as src i = 1 while i < len ( shape ) : if dst_strides [ i ] < dst_strides [ i - 1 ] : raise ValueError ( "src and dst must have same order" ) if ( src_strides [ i - 1 ] * shape [ i - 1 ] == src_strides [ i ] and dst_strides [ i - 1 ] * shape [ i - 1 ] == dst_strides [ i ] ) : shape [ i - 1 : i + 1 ] = [ shape [ i - 1 ] * shape [ i ] ] del src_strides [ i ] del dst_strides [ i ] del axes [ i ] else : i += 1 if len ( shape ) <= 1 : if isinstance ( src , GPUArray ) : if isinstance ( dst , GPUArray ) : if async_ : drv . memcpy_dtod_async ( dst . gpudata , src . gpudata , src . nbytes , stream = stream ) else : drv . memcpy_dtod ( dst . gpudata , src . gpudata , src . nbytes ) else : # The arrays might be contiguous in the sense of # having no gaps, but the axes could be transposed # so that the order is neither Fortran or C. # So, we attempt to get a contiguous view of dst. dst = _as_strided ( dst , shape = ( dst . size , ) , strides = ( dst . dtype . itemsize , ) ) if async_ : drv . memcpy_dtoh_async ( dst , src . gpudata , stream = stream ) else : drv . memcpy_dtoh ( dst , src . gpudata ) else : src = _as_strided ( src , shape = ( src . size , ) , strides = ( src . dtype . itemsize , ) ) if async_ : drv . memcpy_htod_async ( dst . gpudata , src , stream = stream ) else : drv . memcpy_htod ( dst . gpudata , src ) return if len ( shape ) == 2 : copy = drv . Memcpy2D ( ) elif len ( shape ) == 3 : copy = drv . Memcpy3D ( ) else : raise ValueError ( "more than 2 discontiguous axes not supported {}" . format ( tuple ( sorted ( axes ) ) ) ) if isinstance ( src , GPUArray ) : copy . set_src_device ( src . gpudata ) else : copy . set_src_host ( src ) if isinstance ( dst , GPUArray ) : copy . set_dst_device ( dst . gpudata ) else : copy . set_dst_host ( dst ) copy . width_in_bytes = src . dtype . itemsize * shape [ 0 ] copy . src_pitch = src_strides [ 1 ] copy . dst_pitch = dst_strides [ 1 ] copy . height = shape [ 1 ] if len ( shape ) == 2 : if async_ : copy ( stream ) else : copy ( aligned = True ) else : # len(shape) == 3 if src_strides [ 2 ] % src_strides [ 1 ] != 0 : raise RuntimeError ( "src's major stride must be a multiple of middle stride" ) copy . src_height = src_strides [ 2 ] // src_strides [ 1 ] if dst_strides [ 2 ] % dst_strides [ 1 ] != 0 : raise RuntimeError ( "dst's major stride must be a multiple of middle stride" ) copy . dst_height = dst_strides [ 2 ] // dst_strides [ 1 ] copy . depth = shape [ 2 ] if async_ : copy ( stream ) else : copy ( )