From f49837803f161a2ecb71d69c2ea5bb3d8918ed87 Mon Sep 17 00:00:00 2001 From: Xingjian Shi Date: Tue, 2 Jun 2020 08:45:16 -0700 Subject: [PATCH] [Numpy] [Operator] Fix __neg__ (#18467) * fix negation * support boolean type * Update elemwise_unary_op.h * Update test_numpy_op.py --- python/mxnet/numpy/multiarray.py | 2 +- python/mxnet/symbol/numpy/_symbol.py | 2 +- tests/python/unittest/test_numpy_op.py | 21 +++++++++++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 9073f3fca093..f6b4c8081645 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -985,7 +985,7 @@ def __mul__(self, other): return multiply(self, other) def __neg__(self): - return self.__mul__(-1.0) + return negative(self) @wrap_mxnp_np_ufunc def __imul__(self, other): diff --git a/python/mxnet/symbol/numpy/_symbol.py b/python/mxnet/symbol/numpy/_symbol.py index b37dd9da0d63..54c155006b04 100644 --- a/python/mxnet/symbol/numpy/_symbol.py +++ b/python/mxnet/symbol/numpy/_symbol.py @@ -280,7 +280,7 @@ def __rpow__(self, other): def __neg__(self): """x.__neg__() <=> - x""" - return self.__mul__(-1.0) + return negative(self) def __deepcopy__(self, _): return super(_Symbol, self).as_np_ndarray() diff --git a/tests/python/unittest/test_numpy_op.py b/tests/python/unittest/test_numpy_op.py index 572dd346ac04..2247700ff4f0 100644 --- a/tests/python/unittest/test_numpy_op.py +++ b/tests/python/unittest/test_numpy_op.py @@ -2373,10 +2373,10 @@ def hybrid_forward(self, F, a, *args, **kwargs): return getattr(F.np, self._func)(a) np_func = getattr(_np, func) - mx_func = TestUnary(func) np_test_data = _np.random.uniform(low, high, shape).astype(_np.float32) mx_test_data = mx.numpy.array(np_test_data) for hybridize in [True, False]: + mx_func = TestUnary(func) if hybridize: mx_func.hybridize() if ref_grad: @@ -2420,13 +2420,30 @@ def hybrid_forward(self, F, a, *args, **kwargs): funcs['rad2deg'] = (lambda x: 180. / _np.pi * _np.ones(x.shape), -1.0, 1.0) funcs['deg2rad'] = (lambda x: _np.pi / 180. * _np.ones(x.shape), -1.0, 1.0) ndim = random.choice([2, 3, 4]) - shape = random.choice([rand_shape_nd(ndim, dim=3), (1, 0, 2)]) for shape in [rand_shape_nd(ndim, dim=3), (1, 0, 2)]: for func, func_data in funcs.items(): ref_grad, low, high = func_data check_unary_func(func, ref_grad, shape, low, high) +@use_np +def test_negation(): + class TestNegation(HybridBlock): + def hybrid_forward(self, F, a): + return -a + mx_func = TestNegation() + for dtype in [_np.int8, _np.int32, _np.float16, _np.float32, _np.float64]: + np_test_data = _np.random.uniform(-1, 1, (5, 5)).astype(dtype) + for hybridize in [True, False]: + mx_test_data = mx.numpy.array(np_test_data, dtype=dtype) + if hybridize: + mx_func.hybridize() + y = mx_func(mx_test_data) + assert y.shape == (5, 5) + assert y.dtype == dtype + assert_almost_equal(y.asnumpy(), -np_test_data) + + @with_seed() @use_np @retry(3)