Skip to content

dpnp.subtract() doesn't work properly with a scalar #1292

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 9 commits into from
Feb 16, 2023
Merged
14 changes: 7 additions & 7 deletions dpnp/backend/include/dpnp_gen_2arg_3type_tbl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@

MACRO_2ARG_3TYPES_OP(dpnp_add_c,
input1_elem + input2_elem,
sycl::add_sat(x1, x2),
MACRO_UNPACK_TYPES(int, long),
x1 + x2,
MACRO_UNPACK_TYPES(bool, std::int32_t, std::int64_t),
oneapi::mkl::vm::add,
MACRO_UNPACK_TYPES(float, double, std::complex<float>, std::complex<double>))

Expand Down Expand Up @@ -170,8 +170,8 @@ MACRO_2ARG_3TYPES_OP(dpnp_minimum_c,
// requires multiplication shape1[10] with shape2[10,1] and result expected as shape[10,10]
MACRO_2ARG_3TYPES_OP(dpnp_multiply_c,
input1_elem* input2_elem,
nullptr,
std::false_type,
x1 * x2,
MACRO_UNPACK_TYPES(bool, std::int32_t, std::int64_t),
oneapi::mkl::vm::mul,
MACRO_UNPACK_TYPES(float, double, std::complex<float>, std::complex<double>))

Expand All @@ -184,9 +184,9 @@ MACRO_2ARG_3TYPES_OP(dpnp_power_c,

MACRO_2ARG_3TYPES_OP(dpnp_subtract_c,
input1_elem - input2_elem,
nullptr,
std::false_type,
x1 - x2,
MACRO_UNPACK_TYPES(bool, std::int32_t, std::int64_t),
oneapi::mkl::vm::sub,
MACRO_UNPACK_TYPES(float, double))
MACRO_UNPACK_TYPES(float, double, std::complex<float>, std::complex<double>))

#undef MACRO_2ARG_3TYPES_OP
142 changes: 55 additions & 87 deletions dpnp/backend/kernels/dpnp_krnl_elemwise.cpp

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion dpnp/dpnp_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ def __rmul__(self, other):
# '__rpow__',
# '__rrshift__',
# '__rshift__',
# '__rsub__',

def __rsub__(self, other):
return dpnp.subtract(other, self)

def __rtruediv__(self, other):
return dpnp.true_divide(other, self)
Expand Down
85 changes: 47 additions & 38 deletions dpnp/dpnp_iface_mathematical.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def add(x1,
if x1_desc and x2_desc:
return dpnp_add(x1_desc, x2_desc, dtype=dtype, out=out, where=where).get_pyobj()

return call_origin(numpy.add, x1, x2, dtype=dtype, out=out, where=where, **kwargs)
return call_origin(numpy.add, x1, x2, out=out, where=where, dtype=dtype, subok=subok, **kwargs)


def around(x1, decimals=0, out=None):
Expand Down Expand Up @@ -1145,7 +1145,7 @@ def multiply(x1,
if x1_desc and x2_desc:
return dpnp_multiply(x1_desc, x2_desc, dtype=dtype, out=out, where=where).get_pyobj()

return call_origin(numpy.multiply, x1, x2, dtype=dtype, out=out, where=where, **kwargs)
return call_origin(numpy.multiply, x1, x2, out=out, where=where, dtype=dtype, subok=subok, **kwargs)


def nancumprod(x1, **kwargs):
Expand Down Expand Up @@ -1520,60 +1520,69 @@ def sign(x1, **kwargs):
return call_origin(numpy.sign, x1, **kwargs)


def subtract(x1, x2, dtype=None, out=None, where=True, **kwargs):
def subtract(x1,
x2,
/,
out=None,
*,
where=True,
dtype=None,
subok=True,
**kwargs):
"""
Subtract arguments, element-wise.

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

Returns
-------
y : dpnp.ndarray
The difference of `x1` and `x2`, element-wise.

Limitations
-----------
Parameters ``x1`` and ``x2`` are supported as either :obj:`dpnp.ndarray` or scalar.
Parameters ``dtype``, ``out`` and ``where`` are supported with their default values.
Parameters `x1` and `x2` are supported as either :class:`dpnp.ndarray` or scalar,
but not both (at least either `x1` or `x2` should be as :class:`dpnp.ndarray`).
Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
Keyword arguments ``kwargs`` are currently unsupported.
Otherwise the functions will be executed sequentially on CPU.
Otherwise the function will be executed sequentially on CPU.
Input array data types are limited by supported DPNP :ref:`Data types`.

Example
-------
>>> import dpnp as np
>>> result = np.subtract(np.array([4, 3]), np.array([2, 7]))
>>> [x for x in result]
>>> import dpnp as dp
>>> result = dp.subtract(dp.array([4, 3]), dp.array([2, 7]))
>>> print(result)
[2, -4]

"""

x1_is_scalar = dpnp.isscalar(x1)
x2_is_scalar = dpnp.isscalar(x2)
x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_strides=False, copy_when_nondefault_queue=False)
x2_desc = dpnp.get_dpnp_descriptor(x2, copy_when_strides=False, copy_when_nondefault_queue=False)
if out is not None:
pass
elif where is not True:
pass
elif dtype is not None:
pass
elif subok is not True:
pass
elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
# at least either x1 or x2 has to be an array
pass
else:
# get USM type and queue to copy scalar from the host memory into a USM allocation
usm_type, queue = get_usm_allocations([x1, x2]) if dpnp.isscalar(x1) or dpnp.isscalar(x2) else (None, None)

if x1_desc and x2_desc and not kwargs:
if not x1_desc and not x1_is_scalar:
pass
elif not x2_desc and not x2_is_scalar:
pass
elif x1_is_scalar and x2_is_scalar:
pass
elif x1_desc and x1_desc.ndim == 0:
pass
elif x1_desc and x1_desc.dtype == dpnp.bool:
pass
elif x2_desc and x2_desc.ndim == 0:
pass
elif x2_desc and x2_desc.dtype == dpnp.bool:
pass
elif dtype is not None:
pass
elif out is not None:
pass
elif not where:
pass
else:
out_desc = dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False) if out is not None else None
return dpnp_subtract(x1_desc, x2_desc, dtype=dtype, out=out_desc, where=where).get_pyobj()
x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_strides=False, copy_when_nondefault_queue=False,
alloc_usm_type=usm_type, alloc_queue=queue)
x2_desc = dpnp.get_dpnp_descriptor(x2, copy_when_strides=False, copy_when_nondefault_queue=False,
alloc_usm_type=usm_type, alloc_queue=queue)
if x1_desc and x2_desc:
if x1_desc.dtype == x2_desc.dtype == dpnp.bool:
raise TypeError("DPNP boolean subtract, the `-` operator, is not supported, "
"use the bitwise_xor, the `^` operator, or the logical_xor function instead.")
return dpnp_subtract(x1_desc, x2_desc, dtype=dtype, out=out, where=where).get_pyobj()

return call_origin(numpy.subtract, x1, x2, dtype=dtype, out=out, where=where, **kwargs)
return call_origin(numpy.subtract, x1, x2, out=out, where=where, dtype=dtype, subok=subok, **kwargs)


def sum(x1, axis=None, dtype=None, out=None, keepdims=False, initial=None, where=True):
Expand Down
8 changes: 3 additions & 5 deletions tests/skipped_tests.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_asar
tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_ascontiguousarray_on_noncontiguous_array
tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_asfortranarray_cuda_array_zero_dim
tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_asfortranarray_cuda_array_zero_dim_dtype
tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_fromfile

tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid0
tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid1
tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid2
Expand Down Expand Up @@ -765,17 +765,15 @@ tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_para
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_547_{arg1=array([[1, 2, 3], [4, 5, 6]]), arg2=array([[0, 1, 2], [3, 4, 5]]), dtype=float64, name='remainder', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_549_{arg1=array([[1, 2, 3], [4, 5, 6]]), arg2=array([[0, 1, 2], [3, 4, 5]]), dtype=float64, name='mod', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticModf::test_modf
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_0_{name='reciprocal', nargs=1}::test_raises_with_numpy_input

tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_10_{name='remainder', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_11_{name='mod', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_1_{name='angle', nargs=1}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_4_{name='divide', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_5_{name='power', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_6_{name='subtract', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_7_{name='true_divide', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_8_{name='floor_divide', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_9_{name='fmod', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestBoolSubtract_param_3_{shape=(), xp=dpnp}::test_bool_subtract

tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp
tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp2
tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_copysign_float
Expand Down
14 changes: 5 additions & 9 deletions tests/skipped_tests_gpu.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-conjugate-data2]
tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-copy-data3]
tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-cumprod-data4]
tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-cumsum-data5]
tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-diff-data6]
tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-ediff1d-data7]
tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-fabs-data8]
tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-floor-data9]
Expand All @@ -29,11 +28,9 @@ tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-conjugate-data2]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-copy-data3]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-cumprod-data4]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-cumsum-data5]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-diff-data6]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-ediff1d-data7]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-fabs-data8]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-floor-data9]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-gradient-data10]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-nancumprod-data11]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-nancumsum-data12]
tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-nanprod-data13]
Expand Down Expand Up @@ -91,6 +88,7 @@ tests/third_party/cupy/indexing_tests/test_insert.py::TestDiagIndicesInvalidValu
tests/third_party/cupy/indexing_tests/test_insert.py::TestDiagIndicesFrom_param_0_{shape=(3, 3)}::test_diag_indices_from
tests/third_party/cupy/indexing_tests/test_insert.py::TestDiagIndicesFrom_param_1_{shape=(0, 0)}::test_diag_indices_from
tests/third_party/cupy/indexing_tests/test_insert.py::TestDiagIndicesFrom_param_2_{shape=(2, 2, 2)}::test_diag_indices_from

tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_295_{arg1=array([[1., 2., 3.], [4., 5., 6.]], dtype=float32), arg2=array([[0, 1, 2], [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_303_{arg1=array([[1., 2., 3.], [4., 5., 6.]], dtype=float32), arg2=array([[0, 1, 2], [3, 4, 5]], dtype=int64), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_375_{arg1=array([[1., 2., 3.], [4., 5., 6.]]), arg2=array([[0, 1, 2], [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
Expand All @@ -103,6 +101,7 @@ tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_para
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_527_{arg1=array([[1, 2, 3], [4, 5, 6]], dtype=int64), arg2=array([[0., 1., 2.], [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_535_{arg1=array([[1, 2, 3], [4, 5, 6]], dtype=int64), arg2=array([[0, 1, 2], [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_543_{arg1=array([[1, 2, 3], [4, 5, 6]], dtype=int64), arg2=array([[0, 1, 2], [3, 4, 5]], dtype=int64), dtype=float64, name='floor_divide', use_dtype=False}::test_binary

tests/third_party/cupy/math_tests/test_sumprod.py::TestSumprod::test_external_prod_all
tests/third_party/cupy/math_tests/test_sumprod.py::TestSumprod::test_external_prod_axis
tests/third_party/cupy/math_tests/test_sumprod.py::TestSumprod::test_external_sum_all
Expand Down Expand Up @@ -565,7 +564,6 @@ tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_asar
tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_ascontiguousarray_on_noncontiguous_array
tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_asfortranarray_cuda_array_zero_dim
tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_asfortranarray_cuda_array_zero_dim_dtype
tests/third_party/cupy/creation_tests/test_from_data.py::TestFromData::test_fromfile

tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid0
tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid1
Expand Down Expand Up @@ -969,6 +967,7 @@ tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_4_{reps
tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_5_{reps=(2, 3, 4, 5)}::test_array_tile
tests/third_party/cupy/manipulation_tests/test_transpose.py::TestTranspose::test_moveaxis_invalid5_2
tests/third_party/cupy/manipulation_tests/test_transpose.py::TestTranspose::test_moveaxis_invalid5_3

tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_279_{arg1=array([[1., 2., 3.], [4., 5., 6.]], dtype=float32), arg2=array([[0., 1., 2.], [3., 4., 5.]], dtype=float32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_287_{arg1=array([[1., 2., 3.], [4., 5., 6.]], dtype=float32), arg2=array([[0., 1., 2.], [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_295_{arg1=array([[1., 2., 3.], [4., 5., 6.]], dtype=float32), arg2=array([[0, 1, 2], [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
Expand All @@ -985,18 +984,15 @@ tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_para
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_527_{arg1=array([[1, 2, 3], [4, 5, 6]]), arg2=array([[0., 1., 2.], [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_535_{arg1=array([[1, 2, 3], [4, 5, 6]]), arg2=array([[0, 1, 2], [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_543_{arg1=array([[1, 2, 3], [4, 5, 6]]), arg2=array([[0, 1, 2], [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticModf::test_modf
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_0_{name='reciprocal', nargs=1}::test_raises_with_numpy_input

tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_10_{name='remainder', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_11_{name='mod', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_1_{name='angle', nargs=1}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_4_{name='divide', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_5_{name='power', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_6_{name='subtract', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_7_{name='true_divide', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_8_{name='floor_divide', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_9_{name='fmod', nargs=2}::test_raises_with_numpy_input
tests/third_party/cupy/math_tests/test_arithmetic.py::TestBoolSubtract_param_3_{shape=(), xp=dpnp}::test_bool_subtract

tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp
tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp2
tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_copysign_float
Expand Down
Loading