Skip to content

Reworked dpnp.copyto() implementation through existing calls #1516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/conda-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ env:
test_fft.py
test_linalg.py
test_logic.py
test_manipulation.py
test_mathematical.py
test_random_state.py
test_sort.py
Expand All @@ -26,6 +27,7 @@ env:
test_usm_type.py
third_party/cupy/linalg_tests/test_product.py
third_party/cupy/logic_tests/test_truth.py
third_party/cupy/manipulation_tests/test_basic.py
third_party/cupy/manipulation_tests/test_join.py
third_party/cupy/math_tests/test_explog.py
third_party/cupy/math_tests/test_misc.py
Expand Down
53 changes: 10 additions & 43 deletions dpnp/backend/kernels/dpnp_krnl_elemwise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,59 +414,26 @@ static void func_map_init_elemwise_1arg_2type(func_map_t &fmap)
(void *)
dpnp_copyto_c_default<std::complex<double>, std::complex<double>>};

fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_BLN] = {
eft_BLN, (void *)dpnp_copyto_c_ext<bool, bool>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_INT] = {
eft_INT, (void *)dpnp_copyto_c_ext<bool, int32_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_LNG] = {
eft_LNG, (void *)dpnp_copyto_c_ext<bool, int64_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<bool, float>};
// dpnp_copyto_c is required by dpnp_fft_fft_c and dpnp_fft_rfft_c
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_DBL] = {
eft_DBL, (void *)dpnp_copyto_c_ext<bool, double>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_BLN] = {
eft_BLN, (void *)dpnp_copyto_c_ext<int32_t, bool>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_INT] = {
eft_INT, (void *)dpnp_copyto_c_ext<int32_t, int32_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_LNG] = {
eft_LNG, (void *)dpnp_copyto_c_ext<int32_t, int64_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<int32_t, float>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_DBL] = {
eft_DBL, (void *)dpnp_copyto_c_ext<int32_t, double>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_BLN] = {
eft_BLN, (void *)dpnp_copyto_c_ext<int64_t, bool>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_INT] = {
eft_INT, (void *)dpnp_copyto_c_ext<int64_t, int32_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_LNG] = {
eft_LNG, (void *)dpnp_copyto_c_ext<int64_t, int64_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<int64_t, float>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_DBL] = {
eft_DBL, (void *)dpnp_copyto_c_ext<int64_t, double>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_BLN] = {
eft_BLN, (void *)dpnp_copyto_c_ext<float, bool>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_INT] = {
eft_INT, (void *)dpnp_copyto_c_ext<float, int32_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_LNG] = {
eft_LNG, (void *)dpnp_copyto_c_ext<float, int64_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<float, float>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_DBL] = {
eft_DBL, (void *)dpnp_copyto_c_ext<float, double>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_BLN] = {
eft_BLN, (void *)dpnp_copyto_c_ext<double, bool>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_INT] = {
eft_INT, (void *)dpnp_copyto_c_ext<double, int32_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_LNG] = {
eft_LNG, (void *)dpnp_copyto_c_ext<double, int64_t>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<double, float>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_DBL] = {
eft_DBL, (void *)dpnp_copyto_c_ext<double, double>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_C128][eft_C128] = {
eft_C128,
(void *)dpnp_copyto_c_ext<std::complex<double>, std::complex<double>>};

fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<bool, float>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<int32_t, float>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<int64_t, float>};
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_FLT] = {
eft_FLT, (void *)dpnp_copyto_c_ext<float, float>};

fmap[DPNPFuncName::DPNP_FN_COS][eft_INT][eft_INT] = {
eft_DBL, (void *)dpnp_cos_c_default<int32_t, double>};
Expand Down
2 changes: 0 additions & 2 deletions dpnp/dpnp_algo/dpnp_algo.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na
DPNP_FN_COPY_EXT
DPNP_FN_COPYSIGN
DPNP_FN_COPYSIGN_EXT
DPNP_FN_COPYTO
DPNP_FN_COPYTO_EXT
DPNP_FN_CORRELATE
DPNP_FN_CORRELATE_EXT
DPNP_FN_COSH
Expand Down
40 changes: 0 additions & 40 deletions dpnp/dpnp_algo/dpnp_algo_manipulation.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ and the rest of the library
__all__ += [
"dpnp_atleast_2d",
"dpnp_atleast_3d",
"dpnp_copyto",
"dpnp_expand_dims",
"dpnp_repeat",
"dpnp_reshape",
Expand Down Expand Up @@ -105,45 +104,6 @@ cpdef utils.dpnp_descriptor dpnp_atleast_3d(utils.dpnp_descriptor arr):
return arr


cpdef dpnp_copyto(utils.dpnp_descriptor dst, utils.dpnp_descriptor src, where=True):
# Convert string type names (array.dtype) to C enum DPNPFuncType
cdef DPNPFuncType dst_type = dpnp_dtype_to_DPNPFuncType(dst.dtype)
cdef DPNPFuncType src_type = dpnp_dtype_to_DPNPFuncType(src.dtype)

cdef shape_type_c dst_shape = dst.shape
cdef shape_type_c dst_strides = utils.strides_to_vector(dst.strides, dst_shape)

cdef shape_type_c src_shape = src.shape
cdef shape_type_c src_strides = utils.strides_to_vector(src.strides, src_shape)

# get the FPTR data structure
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_COPYTO_EXT, src_type, dst_type)

_, _, result_sycl_queue = utils.get_common_usm_allocation(dst, src)

cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_sycl_queue
cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()

# Call FPTR function
cdef fptr_1in_1out_strides_t func = <fptr_1in_1out_strides_t > kernel_data.ptr
cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref,
dst.get_data(),
dst.size,
dst.ndim,
dst_shape.data(),
dst_strides.data(),
src.get_data(),
src.size,
src.ndim,
src_shape.data(),
src_strides.data(),
NULL,
NULL) # dep_events_ref

with nogil: c_dpctl.DPCTLEvent_WaitAndThrow(event_ref)
c_dpctl.DPCTLEvent_Delete(event_ref)


cpdef utils.dpnp_descriptor dpnp_expand_dims(utils.dpnp_descriptor in_array, axis):
axis_tuple = utils._object_to_tuple(axis)
result_ndim = len(axis_tuple) + in_array.ndim
Expand Down
117 changes: 66 additions & 51 deletions dpnp/dpnp_iface_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def concatenate(arrays, /, *, axis=0, out=None, dtype=None, **kwargs):
Limitations
-----------
Each array in `arrays` is supported as either :class:`dpnp.ndarray`
or :class:`dpctl.tensor.usm_ndarray`. Otherwise ``TypeError`` exeption
or :class:`dpctl.tensor.usm_ndarray`. Otherwise ``TypeError`` exception
will be raised.
Parameters `out` and `dtype are supported with default value.
Keyword argument ``kwargs`` is currently unsupported.
Expand Down Expand Up @@ -313,64 +313,79 @@ def copyto(dst, src, casting="same_kind", where=True):
"""
Copies values from one array to another, broadcasting as necessary.

Raises a ``TypeError`` if the `casting` rule is violated, and if
`where` is provided, it selects which elements to copy.

For full documentation refer to :obj:`numpy.copyto`.

Limitations
-----------
Input arrays are supported as :obj:`dpnp.ndarray`.
Otherwise the function will be executed sequentially on CPU.
Parameter ``casting`` is supported only with default value ``"same_kind"``.
Parameter ``where`` is supported only with default value ``True``.
Shapes of input arrays are supported to be equal.
The `dst` parameter is supported as either :class:`dpnp.ndarray`
or :class:`dpctl.tensor.usm_ndarray`.
The `where` parameter is supported as either :class:`dpnp.ndarray`,
:class:`dpctl.tensor.usm_ndarray` or scalar.
Otherwise ``TypeError`` exception will be raised.
Input array data types are limited by supported DPNP :ref:`Data types`.

Examples
--------
>>> import dpnp as np
>>> A = np.array([4, 5, 6])
>>> B = [1, 2, 3]
>>> np.copyto(A, B)
>>> A
array([1, 2, 3])

>>> A = np.array([[1, 2, 3], [4, 5, 6]])
>>> B = [[4, 5, 6], [7, 8, 9]]
>>> np.copyto(A, B)
>>> A
array([[4, 5, 6],
[7, 8, 9]])

"""

dst_desc = dpnp.get_dpnp_descriptor(
dst, copy_when_strides=False, copy_when_nondefault_queue=False
)
src_desc = dpnp.get_dpnp_descriptor(src, copy_when_nondefault_queue=False)
if dst_desc and src_desc:
if casting != "same_kind":
pass
elif (
dst_desc.dtype == dpnp.bool
and src_desc.dtype # due to 'same_kind' casting
in [
dpnp.int32,
dpnp.int64,
dpnp.float32,
dpnp.float64,
dpnp.complex128,
]
):
pass
elif dst_desc.dtype in [
dpnp.int32,
dpnp.int64,
] and src_desc.dtype in [ # due to 'same_kind' casting
dpnp.float32,
dpnp.float64,
dpnp.complex128,
]:
pass
elif (
dst_desc.dtype in [dpnp.float32, dpnp.float64]
and src_desc.dtype == dpnp.complex128
): # due to 'same_kind' casting
pass
elif where is not True:
pass
elif dst_desc.shape != src_desc.shape:
pass
elif dst_desc.strides != src_desc.strides:
pass
else:
return dpnp_copyto(dst_desc, src_desc, where=where)
if not dpnp.is_supported_array_type(dst):
raise TypeError(
"Destination array must be any of supported type, "
f"but got {type(dst)}"
)
elif not dpnp.is_supported_array_type(src):
src = dpnp.array(src, sycl_queue=dst.sycl_queue)

return call_origin(
numpy.copyto, dst, src, casting, where, dpnp_inplace=True
)
if not dpt.can_cast(src.dtype, dst.dtype, casting=casting):
raise TypeError(
f"Cannot cast from {src.dtype} to {dst.dtype} "
f"according to the rule {casting}."
)

if where is True:
dst[...] = src
elif where is False:
# nothing to copy
pass
else:
if dpnp.isscalar(where):
where = dpnp.array(
where, dtype=dpnp.bool, sycl_queue=dst.sycl_queue
)
elif not dpnp.is_supported_array_type(where):
raise TypeError(
"`where` array must be any of supported type, "
f"but got {type(where)}"
)
elif where.dtype != dpnp.bool:
raise TypeError(
"`where` keyword argument must be of boolean type, "
f"but got {where.dtype}"
)

dst_usm, src_usm, mask_usm = dpt.broadcast_arrays(
dpnp.get_usm_ndarray(dst),
dpnp.get_usm_ndarray(src),
dpnp.get_usm_ndarray(where),
)
dst_usm[mask_usm] = src_usm[mask_usm]


def expand_dims(x1, axis):
Expand Down Expand Up @@ -847,7 +862,7 @@ def stack(arrays, /, *, axis=0, out=None, dtype=None, **kwargs):
Limitations
-----------
Each array in `arrays` is supported as either :class:`dpnp.ndarray`
or :class:`dpctl.tensor.usm_ndarray`. Otherwise ``TypeError`` exeption
or :class:`dpctl.tensor.usm_ndarray`. Otherwise ``TypeError`` exception
will be raised.
Parameters `out` and `dtype are supported with default value.
Keyword argument ``kwargs`` is currently unsupported.
Expand Down
31 changes: 0 additions & 31 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,7 @@
import numpy

import dpnp
from tests import testing
from tests.third_party.cupy import testing as cupy_testing

from .helper import has_support_aspect64

numpy.testing.assert_allclose = testing.assert_allclose
numpy.testing.assert_array_equal = testing.assert_array_equal
numpy.testing.assert_equal = testing.assert_equal

# patch for shaped_arange func to exclude calls of astype and reshape
# necessary because new data container does not support these functions yet

orig_shaped_arange = cupy_testing.shaped_arange
orig_shaped_reverse_arange = cupy_testing.shaped_reverse_arange


def _shaped_arange(shape, xp=dpnp, dtype=dpnp.float64, order="C"):
if dtype is dpnp.float64:
dtype = dpnp.float32 if not has_support_aspect64() else dtype
res = xp.array(
orig_shaped_arange(shape, xp=numpy, dtype=dtype, order=order),
dtype=dtype,
)
return res


def _shaped_reverse_arange(shape, xp=dpnp, dtype=dpnp.float32):
res = xp.array(
orig_shaped_reverse_arange(shape, xp=numpy, dtype=dtype), dtype=dtype
)
return res


cupy_testing.shaped_arange = _shaped_arange
cupy_testing.shaped_reverse_arange = _shaped_reverse_arange
2 changes: 2 additions & 0 deletions tests/skipped_tests.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_ones_like_s
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_like_subok
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_strides

tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_copy_order

tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_list
tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_tuple
tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_list
Expand Down
31 changes: 3 additions & 28 deletions tests/skipped_tests_gpu.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -212,34 +212,6 @@ tests/third_party/cupy/linalg_tests/test_einsum.py::TestListArgEinSumError::test
tests/third_party/cupy/linalg_tests/test_einsum.py::TestListArgEinSumError::test_too_many_dims3

tests/third_party/cupy/linalg_tests/test_product.py::TestProduct::test_reversed_vdot
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_7_{dst_shape=(0,), src=3.2}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_8_{dst_shape=(0,), src=0}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_9_{dst_shape=(0,), src=4}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_10_{dst_shape=(0,), src=-4}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_11_{dst_shape=(0,), src=True}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_12_{dst_shape=(0,), src=False}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_13_{dst_shape=(0,), src=(1+1j)}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_14_{dst_shape=(1,), src=3.2}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_15_{dst_shape=(1,), src=0}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_16_{dst_shape=(1,), src=4}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_17_{dst_shape=(1,), src=-4}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_18_{dst_shape=(1,), src=True}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_19_{dst_shape=(1,), src=False}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_20_{dst_shape=(1,), src=(1+1j)}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_21_{dst_shape=(1, 1), src=3.2}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_22_{dst_shape=(1, 1), src=0}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_23_{dst_shape=(1, 1), src=4}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_24_{dst_shape=(1, 1), src=-4}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_25_{dst_shape=(1, 1), src=True}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_26_{dst_shape=(1, 1), src=False}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_27_{dst_shape=(1, 1), src=(1+1j)}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_28_{dst_shape=(2, 2), src=3.2}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_29_{dst_shape=(2, 2), src=0}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_30_{dst_shape=(2, 2), src=4}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_31_{dst_shape=(2, 2), src=-4}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_32_{dst_shape=(2, 2), src=True}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_33_{dst_shape=(2, 2), src=False}::test_copyto_where
tests/third_party/cupy/manipulation_tests/test_basic.py::TestCopytoFromScalar_param_34_{dst_shape=(2, 2), src=(1+1j)}::test_copyto_where

tests/third_party/cupy/math_tests/test_sumprod.py::TestCumprod::test_cumprod_out_noncontiguous
tests/third_party/cupy/math_tests/test_sumprod.py::TestCumsum_param_0_{axis=0}::test_cumsum_axis_out_noncontiguous
Expand Down Expand Up @@ -459,6 +431,9 @@ tests/third_party/cupy/creation_tests/test_ranges.py::TestRanges::test_linspace_
tests/third_party/cupy/creation_tests/test_ranges.py::TestRanges::test_linspace_with_retstep
tests/third_party/cupy/creation_tests/test_ranges.py::TestRanges::test_linspace_zero_num_no_endopoint_with_retstep
tests/third_party/cupy/creation_tests/test_ranges.py::TestRanges::test_logspace_zero_num

tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_copy_order

tests/third_party/cupy/fft_tests/test_fft.py::TestFft2_param_1_{axes=None, norm=None, s=(1, None), shape=(3, 4)}::test_fft2
tests/third_party/cupy/fft_tests/test_fft.py::TestFft2_param_7_{axes=(), norm=None, s=None, shape=(3, 4)}::test_fft2
tests/third_party/cupy/fft_tests/test_fft.py::TestFft2_param_7_{axes=(), norm=None, s=None, shape=(3, 4)}::test_ifft2
Expand Down
Loading