diff --git a/docs/api/python/ndarray.md b/docs/api/python/ndarray.md
index 3f2cef24a73a..cc8a32dba9ae 100644
--- a/docs/api/python/ndarray.md
+++ b/docs/api/python/ndarray.md
@@ -110,6 +110,16 @@ We summarize the interface for each class in the following sections.
NDArray.tostype
```
+### Array creation
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ NDArray.zeros_like
+ NDArray.ones_like
+```
+
### Array change shape
```eval_rst
@@ -118,7 +128,75 @@ We summarize the interface for each class in the following sections.
NDArray.T
NDArray.reshape
+ NDArray.flatten
+ NDArray.expand_dims
+ NDArray.split
+```
+
+### Array expand elements
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
NDArray.broadcast_to
+ NDArray.broadcast_axes
+ NDArray.tile
+ NDArray.pad
+```
+
+### Array rearrange elements
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ NDArray.transpose
+ NDArray.swapaxes
+ NDArray.flip
+```
+
+### Array reduction
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ NDArray.sum
+ NDArray.nansum
+ NDArray.prod
+ NDArray.nanprod
+ NDArray.mean
+ NDArray.max
+ NDArray.min
+ NDArray.norm
+```
+
+### Array rounding
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ NDArray.round
+ NDArray.rint
+ NDArray.fix
+ NDArray.floor
+ NDArray.ceil
+ NDArray.trunc
+```
+
+### Array sorting and searching
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ NDArray.sort
+ NDArray.argsort
+ NDArray.topk
+ NDArray.argmax
+ NDArray.argmin
```
### Arithmetic operations
@@ -174,6 +252,11 @@ We summarize the interface for each class in the following sections.
NDArray.__getitem__
NDArray.__setitem__
+ NDArray.slice
+ NDArray.slice_axis
+ NDArray.take
+ NDArray.one_hot
+ NDArray.pick
```
### Lazy evaluation
@@ -185,6 +268,16 @@ We summarize the interface for each class in the following sections.
NDArray.wait_to_read
```
+### Miscellaneous
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ NDArray.clip
+ NDArray.sign
+```
+
## The `sparse.RowSparseNDArray` Class
```eval_rst
@@ -223,7 +316,9 @@ We summarize the interface for each class in the following sections.
array
empty
zeros
+ zeros_like
ones
+ ones_like
full
arange
load
@@ -290,6 +385,7 @@ We summarize the interface for each class in the following sections.
batch_take
one_hot
pick
+ where
```
## Mathematical functions
@@ -323,6 +419,7 @@ We summarize the interface for each class in the following sections.
arcsin
arccos
arctan
+ broadcast_hypot
degrees
radians
```
@@ -424,6 +521,13 @@ We summarize the interface for each class in the following sections.
random_poisson
random_negative_binomial
random_generalized_negative_binomial
+ sample_uniform
+ sample_normal
+ sample_gamma
+ sample_exponential
+ sample_poisson
+ sample_negative_binomial
+ sample_generalized_negative_binomial
mxnet.random.seed
```
@@ -440,6 +544,21 @@ We summarize the interface for each class in the following sections.
argmin
```
+### Linear Algebra
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ linalg_gemm
+ linalg_gemm2
+ linalg_potrf
+ linalg_potri
+ linalg_trmm
+ linalg_trsm
+ linalg_sumlogdiag
+```
+
### Miscellaneous
```eval_rst
diff --git a/docs/api/python/symbol.md b/docs/api/python/symbol.md
index dd455eee587a..55e459798f61 100644
--- a/docs/api/python/symbol.md
+++ b/docs/api/python/symbol.md
@@ -105,8 +105,95 @@ Composite multiple symbols into a new one by an operator.
Symbol.__ne__
```
-### Query information
+### Symbol creation
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ Symbol.zeros_like
+ Symbol.ones_like
+```
+
+### Changing shape and type
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ Symbol.astype
+ Symbol.reshape
+ Symbol.flatten
+ Symbol.expand_dims
+```
+
+### Expanding elements
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ Symbol.broadcast_to
+ Symbol.broadcast_axes
+ Symbol.tile
+ Symbol.pad
+```
+
+### Rearranging elements
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ Symbol.transpose
+ Symbol.swapaxes
+ Symbol.flip
+```
+
+### Reduce functions
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+ Symbol.sum
+ Symbol.nansum
+ Symbol.prod
+ Symbol.nanprod
+ Symbol.mean
+ Symbol.max
+ Symbol.min
+ Symbol.norm
+```
+
+### Rounding
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ Symbol.round
+ Symbol.rint
+ Symbol.fix
+ Symbol.floor
+ Symbol.ceil
+ Symbol.trunc
+```
+
+### Sorting and searching
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ Symbol.sort
+ Symbol.argsort
+ Symbol.topk
+ Symbol.argmax
+ Symbol.argmin
+```
+
+### Query information
```eval_rst
.. autosummary::
@@ -121,6 +208,19 @@ Composite multiple symbols into a new one by an operator.
Symbol.attr_dict
```
+### Indexing
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ Symbol.slice
+ Symbol.slice_axis
+ Symbol.take
+ Symbol.one_hot
+ Symbol.pick
+```
+
### Get internal and output symbol
```eval_rst
@@ -166,6 +266,16 @@ Composite multiple symbols into a new one by an operator.
Symbol.debug_str
```
+### Miscellaneous
+
+```eval_rst
+.. autosummary::
+ :nosignatures:
+
+ Symbol.clip
+ Symbol.sign
+```
+
## Symbol creation routines
```eval_rst
@@ -174,7 +284,9 @@ Composite multiple symbols into a new one by an operator.
var
zeros
+ zeros_like
ones
+ ones_like
arange
```
@@ -237,6 +349,8 @@ Composite multiple symbols into a new one by an operator.
take
batch_take
one_hot
+ pick
+ where
```
## Mathematical functions
@@ -516,8 +630,16 @@ The `contrib.symbol` module contains many useful experimental APIs for new featu
```eval_rst
+
+.. autoclass:: mxnet.symbol.Symbol
+ :members:
+ :special-members:
+
.. automodule:: mxnet.symbol
:members:
+ :imported-members:
+ :special-members:
+ :exclude-members: Symbol
.. automodule:: mxnet.contrib.symbol
:members:
diff --git a/include/mxnet/c_api.h b/include/mxnet/c_api.h
index a43f73fe45ab..bba61909350d 100644
--- a/include/mxnet/c_api.h
+++ b/include/mxnet/c_api.h
@@ -691,7 +691,7 @@ MXNET_DLL int MXImperativeInvokeEx(AtomicSymbolCreator creator,
MXNET_DLL int MXAutogradSetIsRecording(int is_recording, int* prev);
/*!
* \brief set whether to record operator for autograd
- * \param is_train 1 when training, 0 when testing
+ * \param is_training 1 when training, 0 when testing
* \param prev returns the previous status before this set.
* \return 0 when success, -1 when failure happens
*/
diff --git a/python/mxnet/ndarray/ndarray.py b/python/mxnet/ndarray/ndarray.py
index 7322325722d6..a85ccb5b6076 100644
--- a/python/mxnet/ndarray/ndarray.py
+++ b/python/mxnet/ndarray/ndarray.py
@@ -16,7 +16,7 @@
# under the License.
# coding: utf-8
-# pylint: disable= too-many-lines, redefined-builtin, protected-access
+# pylint: disable=too-many-lines, protected-access
# pylint: disable=import-error, no-name-in-module, undefined-variable
"""NDArray API of MXNet."""
from __future__ import absolute_import
@@ -38,10 +38,15 @@
from ..context import Context
from . import _internal
from .op import NDArrayBase, _STORAGE_TYPE_ID_TO_STR
+from . import cast_storage
from . import broadcast_add, broadcast_mul, transpose, broadcast_not_equal, broadcast_power
-from . import broadcast_sub, broadcast_div, broadcast_to, broadcast_equal, cast_storage
+from . import broadcast_sub, broadcast_div, broadcast_to, broadcast_axes, broadcast_equal
from . import broadcast_greater, broadcast_greater_equal, broadcast_lesser, broadcast_lesser_equal
-from . import zeros_like, slice, broadcast_minimum, broadcast_maximum, broadcast_mod
+from . import zeros_like, ones_like, broadcast_minimum, broadcast_maximum, broadcast_mod
+from . import flatten, norm, rint, fix, floor, ceil, split, slice_axis, one_hot, pick, take
+from . import trunc, expand_dims, flip, tile, repeat, pad, clip, sign
+from . import nansum, prod, nanprod, mean, sort, topk, argsort, argmax, argmin
+from . import sum, round, max, min, slice, abs # pylint: disable=redefined-builtin
__all__ = ["NDArray", "concatenate", "_DTYPE_NP_TO_MX", "_DTYPE_MX_TO_NP", "_GRAD_REQ_MAP",
"ones", "add", "arange", "divide", "equal", "full", "greater", "greater_equal",
@@ -673,6 +678,318 @@ def reshape(self, shape):
ctypes.byref(handle)))
return NDArray(handle=handle, writable=self.writable)
+ def zeros_like(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`zeros_like`.
+
+ The arguments are the same as for :py:func:`zeros_like`, with
+ this array as data.
+ """
+ return zeros_like(self, *args, **kwargs)
+
+ def ones_like(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`ones_like`.
+
+ The arguments are the same as for :py:func:`ones_like`, with
+ this array as data.
+ """
+ return ones_like(self, *args, **kwargs)
+
+ def broadcast_axes(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`broadcast_axes`.
+
+ The arguments are the same as for :py:func:`broadcast_axes`, with
+ this array as data.
+ """
+ return broadcast_axes(self, *args, **kwargs)
+
+ def repeat(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`repeat`.
+
+ The arguments are the same as for :py:func:`repeat`, with
+ this array as data.
+ """
+ return repeat(self, *args, **kwargs)
+
+ def pad(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`pad`.
+
+ The arguments are the same as for :py:func:`pad`, with
+ this array as data.
+ """
+ return pad(self, *args, **kwargs)
+
+ def swapaxes(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`swapaxes`.
+
+ The arguments are the same as for :py:func:`swapaxes`, with
+ this array as data.
+ """
+ return swapaxes(self, *args, **kwargs)
+
+ def split(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`split`.
+
+ The arguments are the same as for :py:func:`split`, with
+ this array as data.
+ """
+ return split(self, *args, **kwargs)
+
+ def slice(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`slice`.
+
+ The arguments are the same as for :py:func:`slice`, with
+ this array as data.
+ """
+ return slice(self, *args, **kwargs)
+
+ def slice_axis(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`slice_axis`.
+
+ The arguments are the same as for :py:func:`slice_axis`, with
+ this array as data.
+ """
+ return slice_axis(self, *args, **kwargs)
+
+ def take(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`take`.
+
+ The arguments are the same as for :py:func:`take`, with
+ this array as data.
+ """
+ return take(self, *args, **kwargs)
+
+ def one_hot(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`one_hot`.
+
+ The arguments are the same as for :py:func:`one_hot`, with
+ this array as data.
+ """
+ return one_hot(self, *args, **kwargs)
+
+ def pick(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`pick`.
+
+ The arguments are the same as for :py:func:`pick`, with
+ this array as data.
+ """
+ return pick(self, *args, **kwargs)
+
+ def sort(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sort`.
+
+ The arguments are the same as for :py:func:`sort`, with
+ this array as data.
+ """
+ return sort(self, *args, **kwargs)
+
+ def topk(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`topk`.
+
+ The arguments are the same as for :py:func:`topk`, with
+ this array as data.
+ """
+ return topk(self, *args, **kwargs)
+
+ def argsort(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`argsort`.
+
+ The arguments are the same as for :py:func:`argsort`, with
+ this array as data.
+ """
+ return argsort(self, *args, **kwargs)
+
+ def argmax(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`argmax`.
+
+ The arguments are the same as for :py:func:`argmax`, with
+ this array as data.
+ """
+ return argmax(self, *args, **kwargs)
+
+ def argmin(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`argmin`.
+
+ The arguments are the same as for :py:func:`argmin`, with
+ this array as data.
+ """
+ return argmin(self, *args, **kwargs)
+
+ def clip(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`clip`.
+
+ The arguments are the same as for :py:func:`clip`, with
+ this array as data.
+ """
+ return clip(self, *args, **kwargs)
+
+ def abs(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`abs`.
+
+ The arguments are the same as for :py:func:`abs`, with
+ this array as data.
+ """
+ return abs(self, *args, **kwargs)
+
+ def sign(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sign`.
+
+ The arguments are the same as for :py:func:`sign`, with
+ this array as data.
+ """
+ return sign(self, *args, **kwargs)
+
+ def flatten(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`flatten`.
+
+ The arguments are the same as for :py:func:`flatten`, with
+ this array as data.
+ """
+ return flatten(self, *args, **kwargs)
+
+ def expand_dims(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`expand_dims`.
+
+ The arguments are the same as for :py:func:`expand_dims`, with
+ this array as data.
+ """
+ return expand_dims(self, *args, **kwargs)
+
+ def tile(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`tile`.
+
+ The arguments are the same as for :py:func:`tile`, with
+ this array as data.
+ """
+ return tile(self, *args, **kwargs)
+
+ def transpose(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`transpose`.
+
+ The arguments are the same as for :py:func:`transpose`, with
+ this array as data.
+ """
+ return transpose(self, *args, **kwargs)
+
+ def flip(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`flip`.
+
+ The arguments are the same as for :py:func:`flip`, with
+ this array as data.
+ """
+ return flip(self, *args, **kwargs)
+
+ def sum(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sum`.
+
+ The arguments are the same as for :py:func:`sum`, with
+ this array as data.
+ """
+ return sum(self, *args, **kwargs)
+
+ def nansum(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`nansum`.
+
+ The arguments are the same as for :py:func:`nansum`, with
+ this array as data.
+ """
+ return nansum(self, *args, **kwargs)
+
+ def prod(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`prod`.
+
+ The arguments are the same as for :py:func:`prod`, with
+ this array as data.
+ """
+ return prod(self, *args, **kwargs)
+
+ def nanprod(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`nanprod`.
+
+ The arguments are the same as for :py:func:`nanprod`, with
+ this array as data.
+ """
+ return nanprod(self, *args, **kwargs)
+
+ def mean(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`mean`.
+
+ The arguments are the same as for :py:func:`mean`, with
+ this array as data.
+ """
+ return mean(self, *args, **kwargs)
+
+ def max(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`max`.
+
+ The arguments are the same as for :py:func:`max`, with
+ this array as data.
+ """
+ return max(self, *args, **kwargs)
+
+ def min(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`min`.
+
+ The arguments are the same as for :py:func:`min`, with
+ this array as data.
+ """
+ return min(self, *args, **kwargs)
+
+ def norm(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`norm`.
+
+ The arguments are the same as for :py:func:`norm`, with
+ this array as data.
+ """
+ return norm(self, *args, **kwargs)
+
+ def round(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`round`.
+
+ The arguments are the same as for :py:func:`round`, with
+ this array as data.
+ """
+ return round(self, *args, **kwargs)
+
+ def rint(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`rint`.
+
+ The arguments are the same as for :py:func:`rint`, with
+ this array as data.
+ """
+ return rint(self, *args, **kwargs)
+
+ def fix(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`fix`.
+
+ The arguments are the same as for :py:func:`fix`, with
+ this array as data.
+ """
+ return fix(self, *args, **kwargs)
+
+ def floor(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`floor`.
+
+ The arguments are the same as for :py:func:`floor`, with
+ this array as data.
+ """
+ return floor(self, *args, **kwargs)
+
+ def ceil(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`ceil`.
+
+ The arguments are the same as for :py:func:`ceil`, with
+ this array as data.
+ """
+ return ceil(self, *args, **kwargs)
+
+ def trunc(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`trunc`.
+
+ The arguments are the same as for :py:func:`trunc`, with
+ this array as data.
+ """
+ return trunc(self, *args, **kwargs)
+
# pylint: disable= undefined-variable
def broadcast_to(self, shape):
"""Broadcasts the input array to a new shape.
@@ -1281,7 +1598,7 @@ def moveaxis(tensor, source, destination):
return transpose(tensor, axes)
-# pylint: disable= no-member, protected-access, too-many-arguments
+# pylint: disable= no-member, protected-access, too-many-arguments, redefined-outer-name
def arange(start, stop=None, step=1.0, repeat=1, ctx=None, dtype=mx_real_t):
"""Returns evenly spaced values within a given interval.
@@ -2330,6 +2647,7 @@ def concatenate(arrays, axis=0, always_copy=True):
return ret
+# pylint: disable=redefined-outer-name
def imdecode(str_img, clip_rect=(0, 0, 0, 0), out=None, index=0, channels=3, mean=None):
"""DEPRECATED, use mx.img instead
diff --git a/python/mxnet/symbol/symbol.py b/python/mxnet/symbol/symbol.py
index aa8ca0b8dd53..0038840540c2 100644
--- a/python/mxnet/symbol/symbol.py
+++ b/python/mxnet/symbol/symbol.py
@@ -40,7 +40,11 @@
from ..ndarray.ndarray import _STORAGE_TYPE_STR_TO_ID
from ..ndarray import _ndarray_cls
from ..executor import Executor
-from . import _internal, reshape
+from . import _internal, reshape, transpose, zeros_like, ones_like, broadcast_axes, broadcast_to
+from . import flatten, norm, rint, fix, floor, ceil, split, slice_axis, one_hot, pick, take
+from . import trunc, expand_dims, flip, tile, repeat, pad, clip, sign
+from . import nansum, prod, nanprod, mean, sort, topk, argsort, argmax, argmin
+from . import sum, round, max, min, slice, abs # pylint: disable=redefined-builtin
from .op import SymbolBase, _set_symbol_class, AttrScope, _Null # pylint: disable=unused-import
@@ -64,8 +68,8 @@ def __iter__(self):
One can loop through the returned object list to get outputs.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.Variable('a')
>>> b = mx.sym.Variable('b')
>>> c = a+b
@@ -120,8 +124,8 @@ def __rsub__(self, other):
Only `NDArray` is supported for now.
- Example usage:
- ----------
+ Example
+ -------
>>> x = mx.nd.ones((2,3))*3
>>> y = mx.nd.ones((2,3))
>>> x.__rsub__(y).asnumpy()
@@ -168,8 +172,8 @@ def __rdiv__(self, other):
Only `NDArray` is supported for now.
- Example usage:
- ----------
+ Example
+ -------
>>> x = mx.nd.ones((2,3))*3
>>> y = mx.nd.ones((2,3))
>>> x.__rdiv__(y).asnumpy()
@@ -198,8 +202,8 @@ def __rmod__(self, other):
Only `NDArray` is supported for now.
- Example usage:
- ----------
+ Example
+ -------
>>> x = mx.nd.ones((2,3))*3
>>> y = mx.nd.ones((2,3))
>>> x.__rmod__(y).asnumpy()
@@ -243,8 +247,8 @@ def __neg__(self):
Numerical negative, element-wise.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.Variable('a')
>>> a
@@ -270,8 +274,8 @@ def __deepcopy__(self, _):
Any changes made to the deep copy do not reflect in the original object.
- Example usage:
- ----------
+ Example
+ -------
>>> import copy
>>> data = mx.sym.Variable('data')
>>> data_1 = copy.deepcopy(data)
@@ -383,8 +387,8 @@ def __call__(self, *args, **kwargs):
This function internally calls `_compose` to compose the symbol and
returns the composed symbol.
- Example usage:
- ----------
+ Example
+ -------
>>> data = mx.symbol.Variable('data')
>>> net1 = mx.symbol.FullyConnected(data=data, name='fc1', num_hidden=10)
>>> net2 = mx.symbol.FullyConnected(name='fc3', num_hidden=10)
@@ -418,8 +422,8 @@ def _compose(self, *args, **kwargs):
This function mutates the current symbol.
- Example usage:
- ----------
+ Example
+ -------
>>> data = mx.symbol.Variable('data')
>>> net1 = mx.symbol.FullyConnected(data=data, name='fc1', num_hidden=10)
>>> net2 = mx.symbol.FullyConnected(name='fc3', num_hidden=10)
@@ -471,8 +475,8 @@ def __getitem__(self, index):
Returns a sliced view of the input symbol.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.var('a')
>>> a.__getitem__(0)
@@ -536,8 +540,8 @@ def attr(self, key):
This function only works for non-grouped symbols.
- Example usage:
- ----------
+ Example
+ -------
>>> data = mx.sym.Variable('data', attr={'mood': 'angry'})
>>> data.attr('mood')
'angry'
@@ -564,8 +568,8 @@ def attr(self, key):
def list_attr(self, recursive=False):
"""Gets all attributes from the symbol.
- Example usage:
- ----------
+ Example
+ -------
>>> data = mx.sym.Variable('data', attr={'mood': 'angry'})
>>> data.list_attr()
{'mood': 'angry'}
@@ -587,8 +591,8 @@ def list_attr(self, recursive=False):
def attr_dict(self):
"""Recursively gets all attributes from the symbol and its children.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.Variable('a', attr={'a1':'a2'})
>>> b = mx.sym.Variable('b', attr={'b1':'b2'})
>>> c = a+b
@@ -638,8 +642,8 @@ def get_internals(self):
Consider the following code:
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.var('a')
>>> b = mx.sym.var('b')
>>> c = a + b
@@ -664,8 +668,8 @@ def get_children(self):
"""Gets a new grouped symbol whose output contains
inputs to output nodes of the original symbol.
- Example usage:
- ----------
+ Example
+ -------
>>> x = mx.sym.Variable('x')
>>> y = mx.sym.Variable('y')
>>> z = mx.sym.Variable('z')
@@ -695,8 +699,8 @@ def get_children(self):
def list_arguments(self):
"""Lists all the arguments in the symbol.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.var('a')
>>> b = mx.sym.var('b')
>>> c = a + b
@@ -717,8 +721,8 @@ def list_arguments(self):
def list_outputs(self):
"""Lists all the outputs in the symbol.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.var('a')
>>> b = mx.sym.var('b')
>>> c = a + b
@@ -742,8 +746,8 @@ def list_outputs(self):
def list_auxiliary_states(self):
"""Lists all the auxiliary states in the symbol.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.var('a')
>>> b = mx.sym.var('b')
>>> c = a + b
@@ -811,8 +815,8 @@ def infer_type(self, *args, **kwargs):
Inconsistencies in the known types will cause an error to be raised.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.var('a')
>>> b = mx.sym.var('b')
>>> c = a + b
@@ -906,8 +910,8 @@ def infer_shape(self, *args, **kwargs):
or keyword argument way as input. It returns a tuple of `None` values
if there is not enough information to deduce the missing shapes.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.var('a')
>>> b = mx.sym.var('b')
>>> c = a + b
@@ -989,8 +993,8 @@ def infer_shape_partial(self, *args, **kwargs):
In the following example, information about fc2 is not available. So, `infer_shape`
will return a tuple of `None` values but `infer_shape_partial` will return partial values.
- Example usage:
- ----------
+ Example
+ -------
>>> data = mx.sym.Variable('data')
>>> prev = mx.sym.Variable('prev')
>>> fc1 = mx.sym.FullyConnected(data=data, name='fc1', num_hidden=128)
@@ -1253,8 +1257,8 @@ def simple_bind(self, ctx, grad_req='write', type_dict=None, stype_dict=None,
Before binding the executor, the function allocates arguments and auxiliary states
that were not explicitly specified. Allows specifying data types.
- Example usage:
- ----------
+ Example
+ -------
>>> x = mx.sym.Variable('x')
>>> y = mx.sym.FullyConnected(x, num_hidden=4)
>>> exe = y.simple_bind(mx.cpu(), x=(5,4), grad_req='null')
@@ -1515,8 +1519,8 @@ def bind(self, ctx, args, args_grad=None, grad_req='write',
This function returns an executor which provides method `forward()` method for evaluation
and a `outputs()` method to get all the results.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.Variable('a')
>>> b = mx.sym.Variable('b')
>>> c = a + b
@@ -1702,8 +1706,8 @@ def eval(self, ctx=None, **kwargs):
In that case, you should call `bind` once and then repeatedly call forward.
This function allows simpler syntax for less cumbersome introspection.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.Variable('a')
>>> b = mx.sym.Variable('b')
>>> c = a + b
@@ -1732,24 +1736,341 @@ def eval(self, ctx=None, **kwargs):
ctx = Context.default_ctx
return self.bind(ctx, kwargs).forward()
- def reshape(self, shape):
- """Shorthand for mxnet.sym.reshape.
+ def reshape(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`reshape`.
- Parameters
- ----------
- shape : tuple of int
- The new shape should not change the array size, namely
- ``np.prod(new_shape)`` should be equal to ``np.prod(self.shape)``.
- One shape dimension can be -1. In this case, the value is inferred
- from the length of the array and remaining dimensions.
+ The arguments are the same as for :py:func:`reshape`, with
+ this array as data.
+ """
+ return reshape(self, *args, **kwargs)
+ def astype(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`cast`.
- Returns
- -------
- Symbol
- A reshaped symbol.
+ The arguments are the same as for :py:func:`cast`, with
+ this array as data.
+ """
+ return cast(self, *args, **kwargs)
+
+ def zeros_like(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`zeros_like`.
+
+ The arguments are the same as for :py:func:`zeros_like`, with
+ this array as data.
+ """
+ return zeros_like(self, *args, **kwargs)
+
+ def ones_like(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`ones_like`.
+
+ The arguments are the same as for :py:func:`ones_like`, with
+ this array as data.
+ """
+ return ones_like(self, *args, **kwargs)
+
+ def broadcast_axes(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`broadcast_axes`.
+
+ The arguments are the same as for :py:func:`broadcast_axes`, with
+ this array as data.
+ """
+ return broadcast_axes(self, *args, **kwargs)
+
+ def repeat(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`repeat`.
+
+ The arguments are the same as for :py:func:`repeat`, with
+ this array as data.
+ """
+ return repeat(self, *args, **kwargs)
+
+ def pad(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`pad`.
+
+ The arguments are the same as for :py:func:`pad`, with
+ this array as data.
+ """
+ return pad(self, *args, **kwargs)
+
+ def swapaxes(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`swapaxes`.
+
+ The arguments are the same as for :py:func:`swapaxes`, with
+ this array as data.
+ """
+ return swapaxes(self, *args, **kwargs)
+
+ def split(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`split`.
+
+ The arguments are the same as for :py:func:`split`, with
+ this array as data.
+ """
+ return split(self, *args, **kwargs)
+
+ def slice(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`slice`.
+
+ The arguments are the same as for :py:func:`slice`, with
+ this array as data.
+ """
+ return slice(self, *args, **kwargs)
+
+ def slice_axis(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`slice_axis`.
+
+ The arguments are the same as for :py:func:`slice_axis`, with
+ this array as data.
"""
- return reshape(self, shape=shape)
+ return slice_axis(self, *args, **kwargs)
+
+ def take(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`take`.
+
+ The arguments are the same as for :py:func:`take`, with
+ this array as data.
+ """
+ return take(self, *args, **kwargs)
+
+ def one_hot(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`one_hot`.
+
+ The arguments are the same as for :py:func:`one_hot`, with
+ this array as data.
+ """
+ return one_hot(self, *args, **kwargs)
+
+ def pick(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`pick`.
+
+ The arguments are the same as for :py:func:`pick`, with
+ this array as data.
+ """
+ return pick(self, *args, **kwargs)
+
+ def sort(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sort`.
+
+ The arguments are the same as for :py:func:`sort`, with
+ this array as data.
+ """
+ return sort(self, *args, **kwargs)
+
+ def topk(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`topk`.
+
+ The arguments are the same as for :py:func:`topk`, with
+ this array as data.
+ """
+ return topk(self, *args, **kwargs)
+
+ def argsort(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`argsort`.
+
+ The arguments are the same as for :py:func:`argsort`, with
+ this array as data.
+ """
+ return argsort(self, *args, **kwargs)
+
+ def argmax(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`argmax`.
+
+ The arguments are the same as for :py:func:`argmax`, with
+ this array as data.
+ """
+ return argmax(self, *args, **kwargs)
+
+ def argmin(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`argmin`.
+
+ The arguments are the same as for :py:func:`argmin`, with
+ this array as data.
+ """
+ return argmin(self, *args, **kwargs)
+
+ def clip(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`clip`.
+
+ The arguments are the same as for :py:func:`clip`, with
+ this array as data.
+ """
+ return clip(self, *args, **kwargs)
+
+ def abs(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`abs`.
+
+ The arguments are the same as for :py:func:`abs`, with
+ this array as data.
+ """
+ return abs(self, *args, **kwargs)
+
+ def sign(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sign`.
+
+ The arguments are the same as for :py:func:`sign`, with
+ this array as data.
+ """
+ return sign(self, *args, **kwargs)
+
+ def flatten(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`flatten`.
+
+ The arguments are the same as for :py:func:`flatten`, with
+ this array as data.
+ """
+ return flatten(self, *args, **kwargs)
+
+ def expand_dims(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`expand_dims`.
+
+ The arguments are the same as for :py:func:`expand_dims`, with
+ this array as data.
+ """
+ return expand_dims(self, *args, **kwargs)
+
+ def broadcast_to(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`broadcast_to`.
+
+ The arguments are the same as for :py:func:`broadcast_to`, with
+ this array as data.
+ """
+ return broadcast_to(self, *args, **kwargs)
+
+ def tile(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`tile`.
+
+ The arguments are the same as for :py:func:`tile`, with
+ this array as data.
+ """
+ return tile(self, *args, **kwargs)
+
+ def transpose(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`transpose`.
+
+ The arguments are the same as for :py:func:`transpose`, with
+ this array as data.
+ """
+ return transpose(self, *args, **kwargs)
+
+ def flip(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`flip`.
+
+ The arguments are the same as for :py:func:`flip`, with
+ this array as data.
+ """
+ return flip(self, *args, **kwargs)
+
+ def sum(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sum`.
+
+ The arguments are the same as for :py:func:`sum`, with
+ this array as data.
+ """
+ return sum(self, *args, **kwargs)
+
+ def nansum(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`nansum`.
+
+ The arguments are the same as for :py:func:`nansum`, with
+ this array as data.
+ """
+ return nansum(self, *args, **kwargs)
+
+ def prod(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`prod`.
+
+ The arguments are the same as for :py:func:`prod`, with
+ this array as data.
+ """
+ return prod(self, *args, **kwargs)
+
+ def nanprod(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`nanprod`.
+
+ The arguments are the same as for :py:func:`nanprod`, with
+ this array as data.
+ """
+ return nanprod(self, *args, **kwargs)
+
+ def mean(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`mean`.
+
+ The arguments are the same as for :py:func:`mean`, with
+ this array as data.
+ """
+ return mean(self, *args, **kwargs)
+
+ def max(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`max`.
+
+ The arguments are the same as for :py:func:`max`, with
+ this array as data.
+ """
+ return max(self, *args, **kwargs)
+
+ def min(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`min`.
+
+ The arguments are the same as for :py:func:`min`, with
+ this array as data.
+ """
+ return min(self, *args, **kwargs)
+
+ def norm(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`norm`.
+
+ The arguments are the same as for :py:func:`norm`, with
+ this array as data.
+ """
+ return norm(self, *args, **kwargs)
+
+ def round(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`round`.
+
+ The arguments are the same as for :py:func:`round`, with
+ this array as data.
+ """
+ return round(self, *args, **kwargs)
+
+ def rint(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`rint`.
+
+ The arguments are the same as for :py:func:`rint`, with
+ this array as data.
+ """
+ return rint(self, *args, **kwargs)
+
+ def fix(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`fix`.
+
+ The arguments are the same as for :py:func:`fix`, with
+ this array as data.
+ """
+ return fix(self, *args, **kwargs)
+
+ def floor(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`floor`.
+
+ The arguments are the same as for :py:func:`floor`, with
+ this array as data.
+ """
+ return floor(self, *args, **kwargs)
+
+ def ceil(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`ceil`.
+
+ The arguments are the same as for :py:func:`ceil`, with
+ this array as data.
+ """
+ return ceil(self, *args, **kwargs)
+
+ def trunc(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`trunc`.
+
+ The arguments are the same as for :py:func:`trunc`, with
+ this array as data.
+ """
+ return trunc(self, *args, **kwargs)
def wait_to_read(self):
raise NotImplementedForSymbol(self.wait_to_read, None)
@@ -1760,9 +2081,6 @@ def asnumpy(self):
def asscalar(self):
raise NotImplementedForSymbol(self.asscalar, None)
- def astype(self):
- raise NotImplementedForSymbol(self.astype, None)
-
def copy(self):
raise NotImplementedForSymbol(self.copy, None)
@@ -1779,8 +2097,8 @@ def var(name, attr=None, shape=None, lr_mult=None, wd_mult=None, dtype=None,
init=None, stype=None, **kwargs):
"""Creates a symbolic variable with specified name.
- Example usage:
- ----------
+ Example
+ -------
>>> data = mx.sym.Variable('data', attr={'a': 'b'})
>>> data
@@ -1852,8 +2170,8 @@ def var(name, attr=None, shape=None, lr_mult=None, wd_mult=None, dtype=None,
def Group(symbols):
"""Creates a symbol that contains a collection of other symbols, grouped together.
- Example usage:
- ----------
+ Example
+ -------
>>> a = mx.sym.Variable('a')
>>> b = mx.sym.Variable('b')
>>> mx.sym.Group([a,b])
@@ -2180,7 +2498,7 @@ def full(shape, val, dtype=None, **kwargs):
dtype = _numpy.float32
return _internal._MulScalar(ones(shape=shape, dtype=dtype, **kwargs), scalar=val)
-
+# pylint: disable=redefined-outer-name
def arange(start, stop=None, step=1.0, repeat=1, name=None, dtype=None):
"""Returns evenly spaced values within a given interval.
diff --git a/tests/python/unittest/test_ndarray.py b/tests/python/unittest/test_ndarray.py
index 3e0ac66c168d..f2c6a834cbcd 100644
--- a/tests/python/unittest/test_ndarray.py
+++ b/tests/python/unittest/test_ndarray.py
@@ -697,6 +697,49 @@ def test_output():
mx.nd.full(shape, 2, out=out)
assert_almost_equal(out.asnumpy(), ones.asnumpy() * 2)
+def test_ndarray_fluent():
+ has_grad = set(['flatten', 'expand_dims', 'flip', 'tile', 'transpose', 'sum', 'nansum', 'prod',
+ 'nanprod', 'mean', 'max', 'min', 'reshape', 'broadcast_to', 'split',
+ 'broadcast_axes', 'pad', 'swapaxes', 'slice', 'slice_axis', 'take',
+ 'one_hot', 'pick', 'sort', 'topk', 'argsort', 'argmax', 'argmin',
+ 'clip', 'abs' 'sign'])
+ def check_fluent_regular(func, kwargs, shape=(5, 17, 1)):
+ with mx.name.NameManager():
+ data = mx.nd.random_uniform(shape=shape)
+ regular = getattr(mx.ndarray, func)(data, **kwargs)
+ fluent = getattr(data, func)(**kwargs)
+ if isinstance(regular, list):
+ for r, f in zip(regular, fluent):
+ assert almost_equal(r.asnumpy(), f.asnumpy())
+ else:
+ assert almost_equal(regular.asnumpy(), fluent.asnumpy())
+
+ for func in ['flatten', 'norm', 'round', 'rint', 'fix', 'floor', 'ceil', 'trunc', 'zeros_like',
+ 'ones_like', 'abs', 'sign']:
+ check_fluent_regular(func, {})
+
+ for func in ['expand_dims', 'flip', 'sort', 'topk', 'argsort', 'argmax', 'argmin']:
+ check_fluent_regular(func, {'axis': 1})
+
+ check_fluent_regular('one_hot', {'depth': 15})
+ check_fluent_regular('tile', {'reps': (1,2)})
+ check_fluent_regular('repeat', {'repeats': 3})
+ check_fluent_regular('transpose', {'axes': (1,0,2)})
+ check_fluent_regular('split', {'axis': 2, 'num_outputs': 3}, shape=(5, 17, 6))
+ check_fluent_regular('slice', {'begin': (2, 5, 1), 'end': (4, 7, 6)}, shape=(5, 17, 6))
+ check_fluent_regular('slice_axis', {'axis': 1, 'begin': 5, 'end': 7})
+ check_fluent_regular('take', {'indices': mx.nd.array([2, 3])})
+ check_fluent_regular('pick', {'axis': 1, 'begin': 5, 'end': 7})
+ check_fluent_regular('clip', {'a_min': 0.25, 'a_max': 0.75})
+ check_fluent_regular('broadcast_axes', {'axis': (2,), 'size': (5,)})
+ check_fluent_regular('pad', {'mode': 'constant', 'pad_width': (0,0,0,0,3,0,0,4)}, shape=(5, 17, 2, 3))
+
+ for func in ['sum', 'nansum', 'prod', 'nanprod', 'mean', 'max', 'min']:
+ check_fluent_regular(func, {'axis': (1, 2)})
+
+ check_fluent_regular('reshape', {'shape': (17, 1, 5)})
+ check_fluent_regular('broadcast_to', {'shape': (5, 17, 47)})
+
if __name__ == '__main__':
import nose
diff --git a/tests/python/unittest/test_symbol.py b/tests/python/unittest/test_symbol.py
index c570325a6b66..4d162ecf6e50 100644
--- a/tests/python/unittest/test_symbol.py
+++ b/tests/python/unittest/test_symbol.py
@@ -162,12 +162,52 @@ def test_symbol_infer_shape_var():
assert arg_shapes[1] == overwrite_shape
assert out_shapes[0] == overwrite_shape
-def check_symbol_consistency(sym1, sym2, ctx):
+def test_symbol_fluent():
+ has_grad = set(['flatten', 'expand_dims', 'flip', 'tile', 'transpose', 'sum', 'nansum', 'prod',
+ 'nanprod', 'mean', 'max', 'min', 'reshape', 'broadcast_to', 'split',
+ 'broadcast_axes', 'pad', 'swapaxes', 'slice', 'slice_axis', 'take',
+ 'one_hot', 'pick', 'sort', 'topk', 'argsort', 'argmax', 'argmin',
+ 'clip', 'abs' 'sign'])
+ def check_fluent_regular(func, kwargs, shape=(5, 17, 1)):
+ with mx.name.NameManager():
+ data = mx.symbol.Variable('data')
+ regular = getattr(mx.symbol, func)(data, name=func+'0', **kwargs)
+ fluent = getattr(data, func)(**kwargs)
+ check_symbol_consistency(regular, fluent, {'ctx': mx.context.current_context(),
+ 'data': shape},
+ skip_grad=func not in has_grad)
+
+ for func in ['flatten', 'norm', 'round', 'rint', 'fix', 'floor', 'ceil', 'trunc', 'zeros_like',
+ 'ones_like', 'abs', 'sign']:
+ check_fluent_regular(func, {})
+
+ for func in ['expand_dims', 'flip', 'sort', 'topk', 'argsort', 'argmax', 'argmin']:
+ check_fluent_regular(func, {'axis': 1})
+
+ check_fluent_regular('one_hot', {'depth': 15})
+ check_fluent_regular('tile', {'reps': (1,2)})
+ check_fluent_regular('repeat', {'repeats': 3})
+ check_fluent_regular('transpose', {'axes': (1,0,2)})
+ check_fluent_regular('split', {'axis': 2, 'num_outputs': 3}, shape=(5, 17, 6))
+ check_fluent_regular('slice', {'begin': (2, 5, 1), 'end': (4, 7, 6)}, shape=(5, 17, 6))
+ check_fluent_regular('slice_axis', {'axis': 1, 'begin': 5, 'end': 7})
+ check_fluent_regular('clip', {'a_min': 0.25, 'a_max': 0.75})
+ check_fluent_regular('broadcast_axes', {'axis': (2,), 'size': (5,)})
+ check_fluent_regular('pad', {'mode': 'constant', 'pad_width': (0,0,0,0,3,0,0,4)}, shape=(5, 17, 2, 3))
+
+ for func in ['sum', 'nansum', 'prod', 'nanprod', 'mean', 'max', 'min']:
+ check_fluent_regular(func, {'axis': (1, 2)})
+
+ check_fluent_regular('reshape', {'shape': (17, 1, 5)})
+ check_fluent_regular('broadcast_to', {'shape': (5, 17, 47)})
+
+def check_symbol_consistency(sym1, sym2, ctx, skip_grad=False):
assert sym1.list_arguments() == sym2.list_arguments()
assert sym1.list_auxiliary_states() == sym2.list_auxiliary_states()
assert sym1.list_outputs() == sym2.list_outputs()
- mx.test_utils.check_consistency([sym1, sym2], ctx_list=[ctx, ctx])
+ mx.test_utils.check_consistency([sym1, sym2], ctx_list=[ctx, ctx],
+ grad_req='null' if skip_grad else 'write')
def test_load_000800():
with mx.AttrScope(ctx_group='stage1'):