diff --git a/mindspore/_extends/parse/standard_method.py b/mindspore/_extends/parse/standard_method.py index ae66971b8d..1256a81cba 100644 --- a/mindspore/_extends/parse/standard_method.py +++ b/mindspore/_extends/parse/standard_method.py @@ -38,8 +38,8 @@ shape_ = P.Shape() dtype_ = P.DType() abs_ = P.Abs() ndim_ = P.Rank() -size_ = P.Size() cumsum_ = P.CumSum() +size_op_ = P.Size() _reduce_sum_default = P.ReduceSum() _reduce_sum_keepdims = P.ReduceSum(True) _mean_keepdims = P.ReduceMean(True) @@ -117,6 +117,24 @@ def any_(x, axis=(), keep_dims=False): return reduce_any(x, axis) +def size_(x): + """ + Return the number of elements in tensor `x`. + + Note: + To strictly follow Numpy's behaviour, return 1 for tensor scalar. + + Args: + x (Tensor): Input tensor. + + Returns: + size(int). + """ + if not shape_(x): + return size_op_(x) + 1 + return size_op_(x) + + def itemsize_(x): """ Return length of one tensor element in bytes. diff --git a/mindspore/common/tensor.py b/mindspore/common/tensor.py index fd9ec47579..866c2f71e0 100644 --- a/mindspore/common/tensor.py +++ b/mindspore/common/tensor.py @@ -372,11 +372,11 @@ class Tensor(Tensor_): return output def itemset(self, *args): - """ + r""" Insert scalar into a tensor (scalar is cast to tensor’s dtype, if possible). There must be at least 1 argument, and define the last argument as item. - Then, tensor.itemset(*args) is equivalent to :math:`tensor[args] = item`. + Then, tensor.itemset(\*args) is equivalent to :math:`tensor[args] = item`. Args: args (Union[(Number), (int/tuple(int), Number)]): The arguments that diff --git a/mindspore/numpy/array_creations.py b/mindspore/numpy/array_creations.py index 5422be9ffe..0a8dc73286 100644 --- a/mindspore/numpy/array_creations.py +++ b/mindspore/numpy/array_creations.py @@ -2448,7 +2448,7 @@ def pad(arr, pad_width, mode="constant", stat_length=None, constant_values=0, [0. 0. 0. 1. 2. 3. 4. 5. 0. 0. 0. 0.] >>> print(np.pad(tensor, (3, 4), mode="wrap")) [3. 4. 5. 1. 2. 3. 4. 5. 1. 2. 3. 4.] - >>> >>> print(np.pad(tensor, (3, 4), mode="linear_ramp", end_values=(10, 10))) + >>> print(np.pad(tensor, (3, 4), mode="linear_ramp", end_values=(10, 10))) [10. 7. 4. 1. 2. 3. 4. 5. 6.25 7.5 8.75 10. ] """ arr = _to_tensor(arr) diff --git a/mindspore/numpy/array_ops.py b/mindspore/numpy/array_ops.py index 56e7d70275..c6ca84c56d 100644 --- a/mindspore/numpy/array_ops.py +++ b/mindspore/numpy/array_ops.py @@ -2148,8 +2148,7 @@ def choose(a, choices, mode='clip'): Examples: >>> import mindspore.numpy as np - >>> choices = [[0, 1, 2, 3], [10, 11, 12, 13], - ... [20, 21, 22, 23], [30, 31, 32, 33]] + >>> choices = [[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23], [30, 31, 32, 33]] >>> print(np.choose([2, 3, 1, 0], choices)) [20 31 12 3] >>> print(np.choose([2, 4, 1, 0], choices, mode='clip')) diff --git a/mindspore/numpy/logic_ops.py b/mindspore/numpy/logic_ops.py index b6a4b7ba96..43057b160f 100644 --- a/mindspore/numpy/logic_ops.py +++ b/mindspore/numpy/logic_ops.py @@ -371,9 +371,9 @@ def isposinf(x): Examples: >>> import mindspore.numpy as np - >>> output = np.isposinf(np.array([-np.inf, 0., np.inf], np.float32)) + >>> output = np.isposinf(np.array([-np.inf, 0., np.inf, np.nan], np.float32)) >>> print(output) - [False False True] + [False False True False] """ _check_input_tensor(x) return _is_sign_inf(x, F.tensor_gt) @@ -402,9 +402,9 @@ def isneginf(x): Examples: >>> import mindspore.numpy as np - >>> output = np.isneginf(np.array([-np.inf, 0., np.inf], np.float32)) + >>> output = np.isneginf(np.array([-np.inf, 0., np.inf, np.nan], np.float32)) >>> print(output) - [ True False False] + [ True False False False] """ return _is_sign_inf(x, F.tensor_lt) @@ -750,6 +750,9 @@ def array_equal(a1, a2, equal_nan=False): In mindpsore, a bool tensor is returned instead, since in Graph mode, the value cannot be traced and computed at compile time. + Since on Ascend, :class:`nan` is treated differently, currently the argument + `equal_nan` is not supported on Ascend. + Args: a1/a2 (Union[int, float, bool, list, tuple, Tensor]): Input arrays. equal_nan (bool): Whether to compare NaN’s as equal. @@ -761,7 +764,7 @@ def array_equal(a1, a2, equal_nan=False): TypeError: If inputs have types not specified above. Supported Platforms: - ``GPU`` ``CPU`` + ``GPU`` ``CPU`` ``Ascend`` Examples: >>> import mindspore.numpy as np diff --git a/mindspore/numpy/math_ops.py b/mindspore/numpy/math_ops.py index b6a82d5044..fe27e511cb 100644 --- a/mindspore/numpy/math_ops.py +++ b/mindspore/numpy/math_ops.py @@ -2505,6 +2505,8 @@ def nanmin(a, axis=None, dtype=None, keepdims=False): Note: Numpy arguments `out` is not supported. For all-NaN slices, a very large number is returned instead of NaN. + On Ascend, since checking for NaN is currently not supported, it is not recommended to + use np.nanmin. If the array does not contain NaN, np.min should be used instead. Args: a (Union[int, float, list, tuple, Tensor]): Array containing numbers whose minimum @@ -4038,8 +4040,6 @@ def sum_(a, axis=None, dtype=None, keepdims=False, initial=None): >>> import mindspore.numpy as np >>> print(np.sum([0.5, 1.5])) 2.0 - >>> print(np.sum(np.array([-1, 0, 1], np.int32))) - 0 >>> x = np.arange(10).reshape(2, 5).astype('float32') >>> print(np.sum(x, axis=1)) [10. 35.] @@ -4121,6 +4121,7 @@ def multi_dot(arrays): ``Ascend`` ``GPU`` ``CPU`` Examples: + >>> import mindspore.numpy as np >>> A = np.ones((10000, 100)) >>> B = np.ones((100, 1000)) >>> C = np.ones((1000, 5)) @@ -5093,13 +5094,13 @@ def polyval(p, x): Examples: >>> import mindspore.numpy as np - >>> print(np.polyval([3,0,1], 5)) - 76 + >>> print(np.polyval([3.,0.,1.], 5.)) + 76.0 """ p = _to_poly1d(p) x = _to_tensor(x) shape = F.shape(x) - exp_p = arange(_type_convert(int, p.size) - 1, -1, -1) + exp_p = arange(_type_convert(int, p.size) - 1, -1, -1).astype(mstype.float32) var_p = (x.reshape(shape + (1,)))**exp_p return F.reduce_sum(p*var_p, -1) @@ -5159,7 +5160,7 @@ def polymul(a1, a2): ValueError: if the input array has more than 1 dimensions. Supported Platforms: - ``Ascend`` ``GPU`` ``CPU`` + ``GPU`` Examples: >>> import mindspore.numpy as np @@ -5446,6 +5447,9 @@ def ravel_multi_index(multi_index, dims, mode='clip', order='C'): >>> output = np.ravel_multi_index(arr, (7, 6)) >>> print(output) [22. 41. 37.] + >>> output = np.ravel_multi_index((3, 1, 4, 1), (6, 7, 8, 9)) + >>> print(output) + 1621.0 """ if isinstance(dims, int): dims = (dims,) @@ -5548,7 +5552,7 @@ def norm(x, ord=None, axis=None, keepdims=False): # pylint: disable=redefined-bu Examples: >>> import mindspore.numpy as np - >>> print(np.norm(np.arange(9))) + >>> print(np.norm(np.arange(9).astype(np.float32))) 14.282857 """ if not isinstance(ord, (int, float)) and not _in(ord, (None, 'fro', 'nuc', inf, -inf)): @@ -5787,6 +5791,9 @@ def correlate(a, v, mode='valid'): >>> output = np.correlate([1, 2, 3], [0, 1, 0.5], mode="same") >>> print(output) [2. 3.5 3. ] + >>> output = np.correlate([1, 2, 3, 4, 5], [1, 2], mode="same") + >>> print(output) + [ 2. 5. 8. 11. 14.] """ a, v = _to_tensor(a, v) if a.ndim != 1 or v.ndim != 1: diff --git a/mindspore/ops/composite/multitype_ops/_compile_utils.py b/mindspore/ops/composite/multitype_ops/_compile_utils.py index ffc089995d..de6c45a139 100644 --- a/mindspore/ops/composite/multitype_ops/_compile_utils.py +++ b/mindspore/ops/composite/multitype_ops/_compile_utils.py @@ -922,6 +922,14 @@ def reduce_(a, reduce_fn, cmp_fn=None, axis=None, keepdims=False, initial=None, if initial is None: const_utils.raise_value_error('initial value must be provided for where masks') ndim_orig = F.rank(a) + # broadcasts input tensors + shape_out = const_utils.infer_out_shape(F.shape(where), F.shape(a), F.shape(initial)) + broadcast_to = P.BroadcastTo(shape_out) + where = where.astype(mstype.float32) + where = broadcast_to(where) + where = where.astype(mstype.bool_) + a = broadcast_to(a) + initial = broadcast_to(initial) a = F.select(where, a, initial) axes = const_utils.real_axes(ndim_orig, F.rank(a), axes) diff --git a/mindspore/ops/composite/multitype_ops/_constexpr_utils.py b/mindspore/ops/composite/multitype_ops/_constexpr_utils.py index f42642df3e..ce4c0ae8ef 100644 --- a/mindspore/ops/composite/multitype_ops/_constexpr_utils.py +++ b/mindspore/ops/composite/multitype_ops/_constexpr_utils.py @@ -14,8 +14,9 @@ # ============================================================================ """constexpr util""" -from itertools import compress +from itertools import compress, zip_longest from functools import partial +from collections import deque import operator import numpy as np @@ -810,3 +811,18 @@ def compute_slice_shape(slice_shape, broadcast_shape_len, slice_cnt, fancy_posit shape[slice_cnt] = slice_shape[slice_cnt] shape = shape[:fancy_position] + [1] * broadcast_shape_len + shape[fancy_position:] return shape + + +@constexpr +def infer_out_shape(*shapes): + """ + Returns shape of output after broadcasting. Raises ValueError if shapes cannot be broadcast. + """ + shape_out = deque() + reversed_shapes = map(reversed, shapes) + for items in zip_longest(*reversed_shapes, fillvalue=1): + max_size = 0 if 0 in items else max(items) + if any(item not in (1, max_size) for item in items): + raise ValueError(f'operands could not be broadcast together with shapes {*shapes,}') + shape_out.appendleft(max_size) + return tuple(shape_out)