Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Port shape op to 1.6.x #16912

Merged
merged 1 commit into from
Nov 26, 2019
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
40 changes: 36 additions & 4 deletions python/mxnet/ndarray/numpy/_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from . import _internal as _npi
from ..ndarray import NDArray

__all__ = ['zeros', 'ones', 'full', 'add', 'subtract', 'multiply', 'divide', 'mod', 'remainder', 'power',
__all__ = ['shape', 'zeros', 'ones', 'full', 'add', 'subtract', 'multiply', 'divide', 'mod', 'remainder', 'power',
'arctan2', 'sin', 'cos', 'tan', 'sinh', 'cosh', 'tanh', 'log10', 'sqrt', 'cbrt', 'abs',
'absolute', 'exp', 'expm1', 'arcsin', 'arccos', 'arctan', 'sign', 'log', 'degrees', 'log2',
'log1p', 'rint', 'radians', 'reciprocal', 'square', 'negative', 'fix', 'ceil', 'floor',
Expand All @@ -41,7 +41,37 @@
'hsplit', 'rot90', 'einsum', 'true_divide', 'nonzero', 'shares_memory', 'may_share_memory', 'diff']

@set_module('mxnet.ndarray.numpy')
def zeros(shape, dtype=_np.float32, order='C', ctx=None):
def shape(a):
"""
Return the shape of an array.
Parameters
----------
a : array_like
Input array.
Returns
-------
shape : tuple of ints
The elements of the shape tuple give the lengths of the
corresponding array dimensions.
See Also
--------
ndarray.shape : Equivalent array method.
Examples
--------
>>> np.shape(np.eye(3))
(3, 3)
>>> np.shape([[1, 2]])
(1, 2)
>>> np.shape([0])
(1,)
>>> np.shape(0)
()
"""
return a.shape


@set_module('mxnet.ndarray.numpy')
def zeros(shape, dtype=_np.float32, order='C', ctx=None): # pylint: disable=redefined-outer-name
"""Return a new array of given shape and type, filled with zeros.
This function currently only supports storing multi-dimensional data
in row-major (C-style).
Expand Down Expand Up @@ -75,7 +105,7 @@ def zeros(shape, dtype=_np.float32, order='C', ctx=None):


@set_module('mxnet.ndarray.numpy')
def ones(shape, dtype=_np.float32, order='C', ctx=None):
def ones(shape, dtype=_np.float32, order='C', ctx=None): # pylint: disable=redefined-outer-name
"""Return a new array of given shape and type, filled with ones.
This function currently only supports storing multi-dimensional data
in row-major (C-style).
Expand Down Expand Up @@ -108,8 +138,9 @@ def ones(shape, dtype=_np.float32, order='C', ctx=None):
return _npi.ones(shape=shape, ctx=ctx, dtype=dtype)


# pylint: disable=too-many-arguments, redefined-outer-name
@set_module('mxnet.ndarray.numpy')
def full(shape, fill_value, dtype=None, order='C', ctx=None, out=None): # pylint: disable=too-many-arguments
def full(shape, fill_value, dtype=None, order='C', ctx=None, out=None):
"""
Return a new array of given shape and type, filled with `fill_value`.
Parameters
Expand Down Expand Up @@ -161,6 +192,7 @@ def full(shape, fill_value, dtype=None, order='C', ctx=None, out=None): # pylin
ctx = current_context()
dtype = _np.float32 if dtype is None else dtype
return _npi.full(shape=shape, value=fill_value, ctx=ctx, dtype=dtype, out=out)
# pylint: enable=too-many-arguments, redefined-outer-name


@set_module('mxnet.ndarray.numpy')
Expand Down
68 changes: 52 additions & 16 deletions python/mxnet/numpy/multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
from ..ndarray import numpy as _mx_nd_np
from ..ndarray.numpy import _internal as _npi

__all__ = ['ndarray', 'empty', 'array', 'zeros', 'ones', 'full', 'add', 'subtract', 'multiply', 'divide',
__all__ = ['ndarray', 'empty', 'array', 'shape', 'zeros', 'ones', 'full', 'add', 'subtract', 'multiply', 'divide',
'mod', 'remainder', 'power', 'arctan2', 'sin', 'cos', 'tan', 'sinh', 'cosh', 'tanh', 'log10',
'sqrt', 'cbrt', 'abs', 'absolute', 'exp', 'expm1', 'arcsin', 'arccos', 'arctan', 'sign', 'log',
'degrees', 'log2', 'log1p', 'rint', 'radians', 'reciprocal', 'square', 'negative',
Expand All @@ -66,7 +66,7 @@

# This function is copied from ndarray.py since pylint
# keeps giving false alarm error of undefined-all-variable
def _new_alloc_handle(shape, ctx, delay_alloc, dtype=mx_real_t):
def _new_alloc_handle(shape, ctx, delay_alloc, dtype=mx_real_t): # pylint: disable=redefined-outer-name
"""Return a new handle with specified shape and context.

Empty handle is only used to hold results.
Expand All @@ -88,7 +88,7 @@ def _new_alloc_handle(shape, ctx, delay_alloc, dtype=mx_real_t):
return hdl


def _reshape_view(a, *shape):
def _reshape_view(a, *shape): # pylint: disable=redefined-outer-name
"""Returns a **view** of this array with a new shape without altering any data.

Parameters
Expand Down Expand Up @@ -459,7 +459,7 @@ def __getitem__(self, key):
"""
# handling possible boolean indexing first
ndim = self.ndim
shape = self.shape
shape = self.shape # pylint: disable=redefined-outer-name

if isinstance(key, list):
try:
Expand Down Expand Up @@ -801,7 +801,7 @@ def __int__(self):

def __len__(self):
"""Number of elements along the first axis."""
shape = self.shape
shape = self.shape # pylint: disable=redefined-outer-name
if len(shape) == 0:
raise TypeError('len() of unsized object')
return self.shape[0]
Expand Down Expand Up @@ -1161,7 +1161,7 @@ def reshape_like(self, *args, **kwargs):
"""
raise AttributeError('mxnet.numpy.ndarray object has no attribute reshape_like')

def reshape_view(self, *shape, **kwargs):
def reshape_view(self, *shape, **kwargs): # pylint: disable=redefined-outer-name
"""Returns a **view** of this array with a new shape without altering any data.
Inheritated from NDArray.reshape.
"""
Expand Down Expand Up @@ -1515,13 +1515,15 @@ def mean(self, axis=None, dtype=None, out=None, keepdims=False): # pylint: disa
"""Returns the average of the array elements along given axis."""
return mean(self, axis=axis, dtype=dtype, out=out, keepdims=keepdims)

def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: disable=arguments-differ
# pylint: disable=too-many-arguments, arguments-differ
def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
"""Returns the standard deviation of the array elements along given axis."""
return std(self, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out)

def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: disable=arguments-differ
def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
"""Returns the variance of the array elements, along given axis."""
return var(self, axis=axis, dtype=dtype, out=out, ddof=ddof, keepdims=keepdims)
# pylint: enable=too-many-arguments, arguments-differ

def cumsum(self, axis=None, dtype=None, out=None):
"""Return the cumulative sum of the elements along the given axis."""
Expand Down Expand Up @@ -1850,7 +1852,7 @@ def squeeze(self, axis=None): # pylint: disable=arguments-differ
"""Remove single-dimensional entries from the shape of a."""
return _mx_np_op.squeeze(self, axis=axis)

def broadcast_to(self, shape):
def broadcast_to(self, shape): # pylint: disable=redefined-outer-name
return _mx_np_op.broadcast_to(self, shape)

def broadcast_like(self, other):
Expand Down Expand Up @@ -1912,7 +1914,7 @@ def tostype(self, stype):


@set_module('mxnet.numpy')
def empty(shape, dtype=_np.float32, order='C', ctx=None):
def empty(shape, dtype=_np.float32, order='C', ctx=None): # pylint: disable=redefined-outer-name
"""Return a new array of given shape and type, without initializing entries.

Parameters
Expand Down Expand Up @@ -2016,7 +2018,37 @@ def array(object, dtype=None, ctx=None):


@set_module('mxnet.numpy')
def zeros(shape, dtype=_np.float32, order='C', ctx=None):
def shape(a):
"""
Return the shape of an array.
Parameters
----------
a : array_like
Input array.
Returns
-------
shape : tuple of ints
The elements of the shape tuple give the lengths of the
corresponding array dimensions.
See Also
--------
ndarray.shape : Equivalent array method.
Examples
--------
>>> np.shape(np.eye(3))
(3, 3)
>>> np.shape([[1, 2]])
(1, 2)
>>> np.shape([0])
(1,)
>>> np.shape(0)
()
"""
return _mx_nd_np.shape(a)


@set_module('mxnet.numpy')
def zeros(shape, dtype=_np.float32, order='C', ctx=None): # pylint: disable=redefined-outer-name
"""Return a new array of given shape and type, filled with zeros.
This function currently only supports storing multi-dimensional data
in row-major (C-style).
Expand Down Expand Up @@ -2057,7 +2089,7 @@ def zeros(shape, dtype=_np.float32, order='C', ctx=None):


@set_module('mxnet.numpy')
def ones(shape, dtype=_np.float32, order='C', ctx=None):
def ones(shape, dtype=_np.float32, order='C', ctx=None): # pylint: disable=redefined-outer-name
"""Return a new array of given shape and type, filled with ones.
This function currently only supports storing multi-dimensional data
in row-major (C-style).
Expand Down Expand Up @@ -2102,8 +2134,9 @@ def ones(shape, dtype=_np.float32, order='C', ctx=None):
return _mx_nd_np.ones(shape, dtype, order, ctx)


# pylint: disable=too-many-arguments, redefined-outer-name
@set_module('mxnet.numpy')
def full(shape, fill_value, dtype=None, order='C', ctx=None, out=None): # pylint: disable=too-many-arguments
def full(shape, fill_value, dtype=None, order='C', ctx=None, out=None):
"""
Return a new array of given shape and type, filled with `fill_value`.

Expand Down Expand Up @@ -2156,6 +2189,7 @@ def full(shape, fill_value, dtype=None, order='C', ctx=None, out=None): # pylin
[2, 2]], dtype=int32)
"""
return _mx_nd_np.full(shape, fill_value, order=order, ctx=ctx, dtype=dtype, out=out)
# pylint: enable=too-many-arguments, redefined-outer-name


@set_module('mxnet.numpy')
Expand Down Expand Up @@ -4220,7 +4254,7 @@ def tensordot(a, b, axes=2):


@set_module('mxnet.numpy')
def histogram(a, bins=10, range=None, normed=None, weights=None, density=None): # pylint-disable=too-many-arguments
def histogram(a, bins=10, range=None, normed=None, weights=None, density=None): # pylint: disable=too-many-arguments
"""
Compute the histogram of a set of data.

Expand Down Expand Up @@ -4379,6 +4413,7 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis
return _mx_nd_np.linspace(start, stop, num, endpoint, retstep, dtype, axis, ctx)


# pylint: disable=too-many-arguments
@set_module('mxnet.numpy')
def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0, ctx=None):
r"""Return numbers spaced evenly on a log scale.
Expand Down Expand Up @@ -4453,6 +4488,7 @@ def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0,
array([ 100. , 215.44347, 464.15887, 1000. ], ctx=gpu(0))
"""
return _mx_nd_np.logspace(start, stop, num, endpoint, base, dtype, axis, ctx=ctx)
# pylint: enable=too-many-arguments


@set_module('mxnet.numpy')
Expand Down Expand Up @@ -5418,7 +5454,7 @@ def mean(a, axis=None, dtype=None, out=None, keepdims=False): # pylint: disable


@set_module('mxnet.numpy')
def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: disable=too-many-arguments
"""
Compute the standard deviation along the specified axis.
Returns the standard deviation, a measure of the spread of a distribution,
Expand Down Expand Up @@ -5485,7 +5521,7 @@ def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):


@set_module('mxnet.numpy')
def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: disable=too-many-arguments
"""
Compute the variance along the specified axis.
Returns the variance of the array elements, a measure of the spread of a
Expand Down
1 change: 1 addition & 0 deletions python/mxnet/numpy_dispatch_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ def _run_with_array_ufunc_proto(*args, **kwargs):
'column_stack',
'zeros_like',
'linalg.norm',
'shape',
'trace',
'tril',
'meshgrid',
Expand Down
15 changes: 11 additions & 4 deletions tests/python/unittest/test_numpy_interoperability.py
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,12 @@ def _add_workload_nonzero():
OpArgMngr.add_workload('nonzero', np.array([True, False, False], dtype=np.bool_))


def _add_workload_shape():
OpArgMngr.add_workload('shape', np.random.uniform(size=()))
OpArgMngr.add_workload('shape', np.random.uniform(size=(0, 1)))
OpArgMngr.add_workload('shape', np.random.uniform(size=(2, 3)))


def _add_workload_diff():
x = np.array([1, 4, 6, 7, 12])
OpArgMngr.add_workload('diff', x)
Expand Down Expand Up @@ -1240,6 +1246,7 @@ def _prepare_workloads():
_add_workload_greater_equal(array_pool)
_add_workload_less(array_pool)
_add_workload_less_equal(array_pool)
_add_workload_shape()
_add_workload_diff()


Expand Down Expand Up @@ -1271,11 +1278,11 @@ def _check_interoperability_helper(op_name, *args, **kwargs):
expected_out = _get_numpy_op_output(onp_op, *args, **kwargs)
if isinstance(out, (tuple, list)):
assert type(out) == type(expected_out)
for arr in out:
assert isinstance(arr, np.ndarray)
for arr, expected_arr in zip(out, expected_out):
assert isinstance(arr, np.ndarray)
assert_almost_equal(arr.asnumpy(), expected_arr, rtol=1e-3, atol=1e-4, use_broadcast=False, equal_nan=True)
if isinstance(arr, np.ndarray):
assert_almost_equal(arr.asnumpy(), expected_arr, rtol=1e-3, atol=1e-4, use_broadcast=False, equal_nan=True)
else:
_np.testing.assert_equal(arr, expected_arr)
else:
assert isinstance(out, np.ndarray)
assert_almost_equal(out.asnumpy(), expected_out, rtol=1e-3, atol=1e-4, use_broadcast=False, equal_nan=True)
Expand Down
19 changes: 19 additions & 0 deletions tests/python/unittest/test_numpy_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,25 @@ def legalize_shape(shape):
np_out = getattr(_np, name)(x.asnumpy(), axis=axis, dtype=acc_type[itype], keepdims=keepdims, ddof=ddof).astype(dtype)
assert_almost_equal(mx_out.asnumpy(), np_out, rtol=rtol, atol=atol, use_broadcast=False, equal_nan=True)

haojin2 marked this conversation as resolved.
Show resolved Hide resolved
@with_seed()
@use_np
def test_np_shape():
shapes = [
(),
(0, 1),
(2, 3),
(2, 3, 4),
]

for shape in shapes:
mx_a = np.random.uniform(size=shape)
np_a = _np.random.uniform(size=shape)

mx_shape = np.shape(mx_a)
np_shape = _np.shape(np_a)

assert mx_shape == np_shape


@with_seed()
@use_np
Expand Down