• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020-2022 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15"""pooling"""
16from __future__ import absolute_import
17
18from mindspore.ops import operations as P
19from mindspore.ops import functional as F
20import mindspore.ops as ops
21from mindspore._checkparam import _check_3d_int_or_tuple
22from mindspore import _checkparam as validator
23from mindspore.ops.primitive import constexpr, _primexpr
24from mindspore.common.tensor import Tensor
25import mindspore.context as context
26from mindspore.common import dtype as mstype
27from mindspore.ops.operations.nn_ops import AdaptiveMaxPool2D
28from mindspore.ops.operations.nn_ops import AdaptiveMaxPool3D, AdaptiveAvgPool3D
29from mindspore.nn.cell import Cell
30from mindspore._c_expression import MSContext
31
32__all__ = ['AvgPool3d', 'MaxPool3d', 'AvgPool2d', 'MaxPool2d', 'AvgPool1d', 'MaxPool1d', 'FractionalMaxPool2d',
33           'FractionalMaxPool3d', 'AdaptiveAvgPool1d', 'AdaptiveMaxPool1d', 'AdaptiveMaxPool2d', 'AdaptiveMaxPool3d',
34           'AdaptiveAvgPool2d', 'AdaptiveAvgPool3d', 'MaxUnpool1d', 'MaxUnpool2d', 'MaxUnpool3d', 'LPPool1d',
35           'LPPool2d']
36
37
38class _PoolNd(Cell):
39    """N-D  AvgPool"""
40
41    def __init__(self, kernel_size, stride, pad_mode, data_format="NCHW"):
42        """Initialize _PoolNd."""
43        super(_PoolNd, self).__init__()
44        validator.check_value_type('pad_mode', pad_mode, [str], self.cls_name)
45        self.pad_mode = validator.check_string(pad_mode.upper(), ['VALID', 'SAME', 'PAD'], 'pad_mode', self.cls_name)
46        self.format = validator.check_string(data_format, ['NCHW', 'NHWC'], 'format', self.cls_name)
47        if context.get_context("device_target") != "GPU" and self.format == "NHWC":
48            raise ValueError(f"For '{self.cls_name}, the 'NHWC' format only support in GPU target, but got device "
49                             f"target {context.get_context('device_target')}.")
50
51        def _check_int_or_tuple(arg_name, arg_value):
52            validator.check_value_type(arg_name, arg_value, [int, tuple], self.cls_name)
53            error_msg = f"For '{self.cls_name}', the '{arg_name}' must be an positive int number or " \
54                        f"a tuple, but got {arg_value}"
55            if isinstance(arg_value, int):
56                if arg_value <= 0:
57                    raise ValueError(error_msg)
58            else:
59                for item in arg_value:
60                    if isinstance(item, int) and item > 0:
61                        continue
62                    raise ValueError(error_msg)
63                if len(arg_value) == 1:
64                    return arg_value[0]
65            return arg_value
66
67        self.kernel_size = _check_int_or_tuple('kernel_size', kernel_size)
68        self.stride = _check_int_or_tuple('stride', stride)
69
70    def construct(self, *inputs):
71        pass
72
73    def extend_repr(self):
74        return 'kernel_size={kernel_size}, stride={stride}, pad_mode={pad_mode}'.format(**self.__dict__)
75
76
77@_primexpr
78def _shape_check(in_shape, prim_name=None):
79    msg_prefix = f"For '{prim_name}', the" if prim_name else "The"
80
81    def _check():
82        if len(in_shape) != 3:
83            raise ValueError(f"{msg_prefix} input must has 3 dim, but got {len(in_shape)}")
84
85    _check()
86
87
88class LPPool1d(Cell):
89    r"""
90    Applying 1D LPPooling operation on an input Tensor can be regarded as forming a 1D input plane.
91
92    Typically the input is of shape :math:`(N_{in}, C_{in}, L_{in})` or :math:`(C_{in}, L_{in})``, the output is of
93    shape :math:`(N_{out}, C_{out}, L_{out})` or :math:`(C_{out}, L_{out})`, with the same shape as input,
94    the operation is as follows.
95
96    .. math::
97        f(X) = \sqrt[p]{\sum_{x \in X} x^{p}}
98
99    Args:
100        norm_type (Union[int, float]): Type of normalization, represents :math:`p` in the formula, can not be 0.
101
102            - if p = 1, the result is the sum of the elements within the pooling kernel(proportional to average
103              pooling).
104            - if p = :math:`\infty`, the result is the result of maximum pooling.
105
106        kernel_size (int): The size of kernel window.
107        stride (int): The distance of kernel moving, an int number that represents the width of movement is stride,
108            if the value is None, the default value `kernel_size` is used. Default: ``None`` .
109        ceil_mode (bool): If ``True``, use ceil to calculate output shape.
110            If ``False``, use ceil to calculate output shape. Default: ``False`` .
111
112    Inputs:
113        - **x** (Tensor) - Tensor of shape :math:`(N_{in}, C_{in}, L_{in})` or :math:`(C_{in}, L_{in})`.
114
115    Outputs:
116        - **output** (Tensor) - LPPool1d result, with shape :math:`(N_{out}, C_{out}, L_{out})` or
117          :math:`(C_{out}, L_{out})`, it has the same data type as `x`, where
118
119        .. math::
120            L_{out} = \left\lfloor\frac{L_{in} - \text{kernel_size}}{\text{stride}} + 1\right\rfloor
121
122
123    Raises:
124        TypeError: If `x` is not a Tensor.
125        TypeError: If `kernel_size` or `stride` is not an int.
126        TypeError: If `ceil_mode` is not a bool.
127        TypeError: If `norm_type` is neither float nor int.
128        ValueError: If `norm_type` is equal to 0.
129        ValueError: If `kernel_size` or `stride` is less than 1.
130        ValueError: If length of shape of `x` is not equal to 2 or 3.
131
132    Supported Platforms:
133        ``Ascend`` ``GPU`` ``CPU``
134
135    Examples:
136        >>> import mindspore as ms
137        >>> import numpy as np
138        >>> a = ms.Tensor(np.arange(2 * 3 * 4).reshape((2, 3, 4)), dtype=ms.float32)
139        >>> net = ms.nn.LPPool1d(norm_type=1, kernel_size=3, stride=1)
140        >>> out = net(a)
141        >>> print(out)
142        [[[ 3.  6.]
143          [15. 18.]
144          [27. 30.]]
145         [[39. 42.]
146          [51. 54.]
147          [63. 66.]]]
148    """
149
150    def __init__(self, norm_type, kernel_size, stride=None, ceil_mode=False):
151        super(LPPool1d, self).__init__()
152        self.norm_type = norm_type
153        self.kernel_size = kernel_size
154        self.stride = stride
155        self.ceil_mode = ceil_mode
156
157    def construct(self, x):
158        return ops.lp_pool1d(x, self.norm_type, self.kernel_size,
159                             self.stride, self.ceil_mode)
160
161
162class LPPool2d(Cell):
163    r"""
164    Applying 2D LPPooling operation on an input Tensor can be regarded as forming a 1D input plane.
165
166    Typically the input is of shape :math:`(N, C, H_{in}, W_{in})`, the output is of shape
167    :math:`(N, C, H_{in}, W_{in})`, with the same shape as input, the operation is as follows.
168
169    .. math::
170        f(X) = \sqrt[p]{\sum_{x \in X} x^{p}}
171
172    Args:
173        norm_type(Union[int, float]): Type of normalization, represents :math:`p` in the formula, can not be 0.
174
175            - if p = 1, the result is the sum of the elements within the pooling kernel(proportional to average
176              pooling).
177            - if p = :math:`\infty`, the result is the result of maximum pooling.
178
179        kernel_size(Union[int, tuple[int]]): The size of kernel window.
180            The data type of kernel_size must be int and the value represents the height and width,
181            or a tuple of two int numbers that represent height and width respectively.
182        stride(Union[int, tuple[int]]): The distance of kernel moving, an int number that represents
183            the height and width of movement are both stride, or a tuple of two int numbers that
184            represent height and width of movement respectively, if the value is ``None``,
185            the default value `kernel_size` is used. Default: ``None`` .
186        ceil_mode(bool): Whether to use ceil or floor to calculate output shape. Default: ``False`` .
187
188    Inputs:
189        - **x** (Tensor) - Tensor of shape :math:`(N, C, H_{in}, W_{in})`.
190
191    Outputs:
192        - **output** (Tensor) - LPPool2d result, with shape :math:`(N, C, H_{in}, W_{in})`,
193          It has the same data type as `x`, where
194
195        .. math::
196            H_{out} = \left\lfloor\frac{H_{in} - \text{kernel_size}[0]}{\text{stride}[0]} + 1\right\rfloor
197
198        .. math::
199            W_{out} = \left\lfloor\frac{W_{in} - \text{kernel_size}[1]}{\text{stride}[1]} + 1\right\rfloor
200
201    Raises:
202        TypeError: If `x` is not a Tensor.
203        TypeError: If `kernel_size` or `stride` is neither int nor tuple.
204        TypeError: If `ceil_mode` is not a bool.
205        TypeError: If `norm_type` is neither float nor int.
206        ValueError: If `norm_type` is equal to 0.
207        ValueError: If `kernel_size` or `stride` is less than 1.
208        ValueError: If `kernel_size` or `stride` is a tuple whose length is not equal to `2`.
209        ValueError: If length of shape of `x` is not equal to 4.
210
211    Supported Platforms:
212        ``Ascend`` ``GPU`` ``CPU``
213
214    Examples:
215        >>> import mindspore as ms
216        >>> import numpy as np
217        >>> a = ms.Tensor(np.arange(2 * 3 * 4 * 5).reshape((2, 3, 4, 5)), dtype=ms.float32)
218        >>> net = ms.nn.LPPool2d(norm_type=1, kernel_size=3, stride=1)
219        >>> out = net(a)
220        >>> print(out)
221        [[[[  54.   63.   72.]
222           [  99.  108.  117.]]
223          [[ 234.  243.  252.]
224           [ 279.  288.  297.]]
225          [[ 414.  423.  432.]
226           [ 459.  468.  477.]]]
227         [[[ 594.  603.  612.]
228           [ 639.  648.  657.]]
229          [[ 774.  783.  792.]
230           [ 819.  828.  837.]]
231          [[ 954.  963.  972.]
232           [ 999. 1008. 1017.]]]]
233    """
234
235    def __init__(self, norm_type, kernel_size, stride=None, ceil_mode=False):
236        super(LPPool2d, self).__init__()
237        self.norm_type = norm_type
238        self.kernel_size = kernel_size
239        self.stride = stride
240        self.ceil_mode = ceil_mode
241
242    def construct(self, x):
243        return ops.lp_pool2d(x, self.norm_type, self.kernel_size,
244                             self.stride, self.ceil_mode)
245
246
247def _check_maxpool_padding(padding, nd, cls_name):
248    """Calculate maxpool padding before call primitive"""
249    validator.check_value_type('padding', padding, (int, tuple, list), cls_name)
250    if isinstance(padding, int):
251        return (0,) * (3 - nd) + (padding,) * nd
252    if isinstance(padding, (tuple, list)):
253        validator.check_non_negative_int_sequence(padding, "padding", cls_name)
254        if len(padding) == 1:
255            return (0,) * (3 - nd) + tuple(padding * nd)
256        if len(padding) != nd:
257            raise ValueError(f"For {cls_name}, the length of padding must equal to {nd}, but got {len(padding)}.")
258        return (0,) * (3 - nd) + tuple(padding)
259    return padding
260
261
262def _cal_dilation(dilation, nd, cls_name):
263    """check the dilation"""
264    if isinstance(dilation, int):
265        return dilation
266    if isinstance(dilation, tuple):
267        if len(dilation) == 1:
268            return dilation[0]
269        if len(dilation) == nd:
270            return (3 - nd) * (1,) + dilation
271        if nd == 1:
272            raise ValueError(f"For {cls_name}, the length of 'dilation' must be 1, but got {len(dilation)}.")
273        raise ValueError(f"For {cls_name}, the length of 'dilation' must be 1 or {nd}, but got {len(dilation)}.")
274    raise ValueError(f"For {cls_name}, the 'dilation' must be int or tuple, but got {type(dilation)}.")
275
276
277class MaxPool3d(_PoolNd):
278    r"""
279    3D max pooling operation.
280
281    Applies a 3D max pooling over an input Tensor which can be regarded as a composition of 3D planes.
282
283    Typically the input is of shape :math:`(N_{in}, C_{in}, D_{in}, H_{in}, W_{in})`, MaxPool outputs
284    regional maximum in the :math:`(D_{in}, H_{in}, W_{in})`-dimension. Given kernel size is
285    :math:`ks = (d_{ker}, h_{ker}, w_{ker})` and stride is :math:`s = (s_0, s_1, s_2)`, the operation is as follows.
286
287    .. math::
288        \text{output}(N_i, C_j, d, h, w) =
289        \max_{l=0, \ldots, d_{ker}-1} \max_{m=0, \ldots, h_{ker}-1} \max_{n=0, \ldots, w_{ker}-1}
290        \text{input}(N_i, C_j, s_0 \times d + l, s_1 \times h + m, s_2 \times w + n)
291
292    Args:
293        kernel_size (Union[int, tuple[int]]): The size of kernel used to take the maximum value,
294            is an int number or a single element tuple that represents depth, height and width of the kernel, or a tuple
295            of three int numbers that represent depth, height and width respectively.
296            The value must be a positive integer. Default: ``1`` .
297        stride (Union[int, tuple[int]]): The moving stride of pooling operation, an int number or a single element tuple
298            that represents the moving stride of pooling kernel in the directions of depth, height and the width,
299            or a tuple of three int numbers that represent depth, height and width of movement respectively.
300            The value must be a positive integer. If the value is None, the default value `kernel_size` is used.
301            Default: ``1`` .
302        pad_mode (str, optional): Specifies the padding mode with a padding value of 0. It can be set to:
303            ``"same"`` , ``"valid"`` or ``"pad"`` . Default: ``"valid"`` .
304
305            - ``"same"``: Pad the input around its depth/height/width dimension so that the shape of input and output
306              are the same when `stride` is set to ``1``.
307              The amount of padding to is calculated by the operator internally.  If the amount is even,
308              it isuniformly distributed around the input, if it is odd, the excess amount goes
309              to the front/right/bottom side.
310              If this mode is set, `padding` must be 0.
311            - ``"valid"``: No padding is applied to the input, and the output returns the maximum
312              possible depth, height and width. Extra pixels that could not complete a full stride will
313              be discarded. If this mode is set, `padding` must be 0.
314            - ``"pad"``: Pad the input with a specified amount. In this mode, the amount of padding
315              in the depth, height and width dimension is determined by the `padding` parameter.
316              If this mode is set, `padding` must be greater than or equal to 0.
317
318        padding (Union(int, tuple[int], list[int])): Pooling padding value. Default: ``0`` .
319            `padding` can only be an integer or a tuple/list containing one or three integers.
320            If `padding` is an integer or a tuple/list containing one integer, it will be padded in six directions of
321            front, back, top, bottom, left and right of the input. If `padding` is a tuple/list containing three
322            integers, it will be padded in front and back of the input `padding[0]` times, up and down `padding[1]`
323            times, and left and right of the input `padding[2]` times.
324        dilation (Union(int, tuple[int])): The spacing between the elements of the kernel in convolution,
325            used to increase the receptive field of the pooling operation. If it is a tuple, it must contain one or
326            three integers. Default: ``1`` .
327        return_indices (bool): If ``True`` , output is a Tuple of 2 Tensors, representing the maxpool result and where
328            the max values are generated. Otherwise, only the maxpool result is returned. Default: ``False`` .
329        ceil_mode (bool): If ``True``, use ceil to calculate output shape.
330            If ``False``, use ceil to calculate output shape. Default: ``False`` .
331
332    Inputs:
333        - **x** (Tensor) - Tensor of shape :math:`(N_{in}, C_{in}, D_{in}, H_{in}, W_{in})` or
334          :math:`(C_{in}, D_{in}, H_{in}, W_{in})`.
335
336    Outputs:
337        If `return_indices` is False, output is a Tensor, with shape
338        :math:`(N_{out}, C_{out}, D_{out}, H_{out}, W_{out})`  or :math:`(C_{out}, D_{out}, H_{out}, W_{out})`.
339        It has the same data type as `x`.
340
341        If `return_indices` is True, output is a Tuple of 2 Tensors, representing the maxpool result and where
342        the max values are generated.
343
344        - **output** (Tensor) - Maxpooling result, with shape :math:`(N_{out}, C_{out}, D_{out}, H_{out}, W_{out})` or
345          :math:`(C_{out}, D_{out}, H_{out}, W_{out})`. It has the same data type as `x`.
346        - **argmax** (Tensor) - Index corresponding to the maximum value. Data type is int64.
347
348        If `pad_mode` is in ``"pad"`` mode, the output shape calculation formula is as follows:
349
350        .. math::
351            D_{out} = \left\lfloor\frac{D_{in} + 2 \times \text{padding}[0] - \text{dilation}[0] \times
352            (\text{kernel_size}[0] - 1) - 1}{\text{stride}[0]} + 1\right\rfloor
353
354        .. math::
355            H_{out} = \left\lfloor\frac{H_{in} + 2 \times \text{padding}[1] - \text{dilation}[1] \times
356            (\text{kernel_size}[1] - 1) - 1}{\text{stride}[1]} + 1\right\rfloor
357
358        .. math::
359            W_{out} = \left\lfloor\frac{W_{in} + 2 \times \text{padding}[2] - \text{dilation}[2] \times
360            (\text{kernel_size}[2] - 1) - 1}{\text{stride}[2]} + 1\right\rfloor
361
362    Raises:
363        ValueError: If length of shape of `x` is not equal to 4 or 5.
364        TypeError: If `kernel_size` , `stride` , `padding` or `dilation` is neither an int nor a tuple.
365        ValueError: If `kernel_size` or `stride` is less than 1.
366        ValueError: If the `padding` parameter is neither an integer nor a tuple of length 3.
367        ValueError: If `pad_mode` is not set to ``"pad"``, setting return_indices to True or dilation to a value
368            other than 1.
369        ValueError: If `padding` is non-zero when `pad_mode` is not ``"pad"``.
370
371    Supported Platforms:
372        ``Ascend`` ``GPU`` ``CPU``
373
374    Examples:
375        >>> import mindspore as ms
376        >>> import mindspore.nn as nn
377        >>> import numpy as np
378        >>> np_x = np.random.randint(0, 10, [5, 3, 4, 6, 7])
379        >>> x = Tensor(np_x, ms.float32)
380        >>> pool1 = nn.MaxPool3d(kernel_size=2, stride=1, pad_mode="pad", padding=1, dilation=3, return_indices=True)
381        >>> output = pool1(x)
382        >>> print(output[0].shape)
383        (5, 3, 3, 5, 6)
384        >>> print(output[1].shape)
385        (5, 3, 3, 5, 6)
386        >>> pool2 = nn.MaxPool3d(kernel_size=2, stride=1, pad_mode="pad", padding=1, dilation=3, return_indices=False)
387        >>> output2 = pool2(x)
388        >>> print(output2.shape)
389        (5, 3, 3, 5, 6)
390    """
391
392    def __init__(self, kernel_size=1, stride=1, pad_mode="valid", padding=0, dilation=1, return_indices=False,
393                 ceil_mode=False):
394        """Initialize MaxPool3d."""
395        super(MaxPool3d, self).__init__(kernel_size, stride, pad_mode)
396        self.return_indices = return_indices
397        padding = _check_maxpool_padding(padding, 3, self.cls_name)
398        _check_3d_int_or_tuple("padding", padding, self.cls_name, greater_zero=False, ret_five=False)
399        if dilation != 1 or return_indices:
400            self.only_pad = True
401            if pad_mode.upper() != "PAD":
402                raise ValueError(f"For {self.cls_name}, the pad_mode must be 'pad' when dilation is not 1 "
403                                 f"or return_indices is True, but got pad_mode:{pad_mode}.")
404            self.max_pool = P.MaxPool3DWithArgmax(ksize=kernel_size, strides=stride, pads=padding,
405                                                  dilation=dilation, ceil_mode=ceil_mode)
406        else:
407            self.only_pad = False
408            ceil_mode = None if not ceil_mode else True
409            self.max_pool = P.MaxPool3D(kernel_size=kernel_size, strides=stride, pad_mode=pad_mode, pad_list=padding,
410                                        ceil_mode=ceil_mode)
411
412    def construct(self, x):
413        expand_batch = False
414        if x.ndim == 4:
415            x = x.unsqueeze(0)
416            expand_batch = True
417        out = self.max_pool(x)
418        if expand_batch:
419            if isinstance(out, tuple):
420                out = (out[0].squeeze(0), out[1].squeeze(0))
421            else:
422                out = out.squeeze(0)
423        if self.only_pad and not self.return_indices:
424            return out[0]
425        return out
426
427
428class MaxPool2d(_PoolNd):
429    r"""
430    Applies a 2D max pooling over an input Tensor which can be regarded as a composition of 2D planes.
431
432    Typically the input is of shape :math:`(N_{in}, C_{in}, H_{in}, W_{in})`, MaxPool2d outputs
433    regional maximum in the :math:`(H_{in}, W_{in})`-dimension. Given kernel size
434    :math:`(h_{ker}, w_{ker})` and stride :math:`(s_0, s_1)`, the operation is as follows.
435
436    .. math::
437        \text{output}(N_i, C_j, h, w) = \max_{m=0, \ldots, h_{ker}-1} \max_{n=0, \ldots, w_{ker}-1}
438        \text{input}(N_i, C_j, s_0 \times h + m, s_1 \times w + n)
439
440    Args:
441        kernel_size (Union[int, tuple[int]]): The size of kernel used to take the max value,
442            is an int number or a single element tuple that represents height and width are both kernel_size,
443            or a tuple of two int numbers that represent height and width respectively.
444            Default: ``1`` .
445        stride (Union[int, tuple[int]]): The distance of kernel moving, an int number or a single element tuple that
446            represents the height and width of movement are both stride, or a tuple of two int numbers that
447            represent height and width of movement respectively. Default: ``1`` .
448        pad_mode (str, optional): Specifies the padding mode with a padding value of 0. It can be set to:
449            ``"same"`` , ``"valid"`` or ``"pad"`` . Default: ``"valid"`` .
450
451            - ``"same"``: Pad the input around its edges so that the shape of input and output
452              are the same when `stride` is set to ``1``.
453              The amount of padding to is calculated by the operator internally, If the amount is even, it is
454              uniformly distributed around the input, if it is odd, the excess amount goes to the right/bottom side.
455              If this mode is set, `padding` must be 0.
456            - ``"valid"``: No padding is applied to the input, and the output returns the maximum
457              possible height and width. Extra pixels that could not complete a full stride will
458              be discarded. If this mode is set, `padding` must be 0.
459            - ``"pad"``: Pad the input with a specified amount. In this mode, the amount of padding
460              in the height and width directions is determined by the `padding` parameter.
461              If this mode is set, `padding` must be greater than or equal to 0.
462
463        padding (Union(int, tuple[int], list[int])): Specifies the padding value of the pooling operation.
464            Default: ``0`` . `padding` can only be an integer or a tuple/list containing one or two integers. If
465            `padding` is an integer or a tuple/list containing one integer, it will be padded `padding` times in the
466            four directions of the input. If `padding` is a tuple/list containing two integers, it will be padded
467            `padding[0]` times in the up-down direction of the input and `padding[1]` times in the left-right direction
468            of the input.
469        dilation (Union(int, tuple[int])): The spacing between the elements of the kernel in convolution,
470            used to increase the receptive field of the pooling operation. If it is a tuple, it must contain one or two
471            integers. Default: ``1`` .
472        return_indices (bool): If ``True`` , the function will return both the result of max pooling and the indices of
473            the max elements. Default: ``False`` .
474        ceil_mode (bool): If ``True`` , use ceil to compute the output shape instead of floor. Default: ``False`` .
475        data_format (str): The optional value for data format, is ``'NHWC'`` or ``'NCHW'`` .
476            Default: ``'NCHW'`` .
477
478    Inputs:
479        - **x** (Tensor) - Tensor of shape :math:`(N,C_{in},H_{in},W_{in})` or :math:`(C_{in},H_{in},W_{in})`.
480
481    Outputs:
482        If `return_indices` is False, output is a Tensor, with shape :math:`(N, C, H_{out}, W_{out})` or
483        :math:`(C_{out}, H_{out}, W_{out})`. It has the same data type as `x`.
484
485        If `return_indices` is True, output is a Tuple of 2 Tensors, representing the maxpool result and where
486        the max values are generated.
487
488        - **output** (Tensor) - Maxpooling result, with shape :math:`(N_{out}, C_{out}, H_{out}, W_{out})` or
489          :math:`(C_{out}, H_{out}, W_{out})`. It has the same data type as `x`.
490        - **argmax** (Tensor) - Index corresponding to the maximum value. Data type is int64.
491
492        If `pad_mode` is in `pad` mode, the output shape calculation formula is as follows:
493
494        .. math::
495            H_{out} = \left\lfloor\frac{H_{in} + 2 * \text{padding[0]} - \text{dilation[0]}
496                \times (\text{kernel_size[0]} - 1) - 1}{\text{stride[0]}} + 1\right\rfloor
497
498        .. math::
499            W_{out} = \left\lfloor\frac{W_{in} + 2 * \text{padding[1]} - \text{dilation[1]}
500                \times (\text{kernel_size[1]} - 1) - 1}{\text{stride[1]}} + 1\right\rfloor
501
502    Raises:
503        TypeError: If `kernel_size` or `stride` is neither int nor tuple.
504        ValueError: If `pad_mode` is neither ``"valid"`` nor ``"same"`` with not case sensitive.
505        ValueError: If `data_format` is neither ``'NCHW'`` nor ``'NHWC'`` .
506        ValueError: If `kernel_size` or `stride` is less than 1.
507        ValueError: If length of shape of `x` is not equal to 3 or 4.
508        ValueError: If `pad_mode` is not ``"pad"``, `padding`, `dilation`, `return_indices`, `ceil_mode` parameters
509            are not set to their default values.
510        ValueError: If the length of the tuple/list `padding` parameter is not 2.
511        ValueError: If The length of the tuple dilation parameter is not 2.
512        ValueError: If dilation parameter is neither an integer nor a tuple.
513        ValueError: If `pad_mode` is ``"pad"`` and `data_format` is ``'NHWC'``.
514        ValueError: If `padding` is non-zero when `pad_mode` is not ``"pad"``.
515
516    Supported Platforms:
517        ``Ascend`` ``GPU`` ``CPU``
518
519    Examples:
520        >>> import mindspore as ms
521        >>> import numpy as np
522        >>> pool = ms.nn.MaxPool2d(kernel_size=3, stride=1)
523        >>> x = ms.Tensor(np.random.randint(0, 10, [1, 2, 4, 4]), ms.float32)
524        >>> output = pool(x)
525        >>> print(output.shape)
526        (1, 2, 2, 2)
527        >>> np_x = np.random.randint(0, 10, [5, 3, 4, 5])
528        >>> x = ms.Tensor(np_x, ms.float32)
529        >>> pool2 = ms.nn.MaxPool2d(kernel_size=2, stride=1, pad_mode="pad", padding=1, dilation=1, return_indices=True)
530        >>> output = pool2(x)
531        >>> print(output[0].shape)
532        (5, 3, 5, 6)
533        >>> print(output[1].shape)
534        (5, 3, 5, 6)
535    """
536
537    def __init__(self, kernel_size=1, stride=1, pad_mode="valid", padding=0, dilation=1, return_indices=False,
538                 ceil_mode=False, data_format="NCHW"):
539        """Initialize MaxPool2d."""
540        super(MaxPool2d, self).__init__(kernel_size, stride, pad_mode, data_format)
541        self.return_indices = return_indices
542        if pad_mode.upper() == 'PAD':
543            if self.format == "NHWC":
544                raise ValueError(f"For '{self.cls_name}, the 'NHWC' format are not support when 'pad_mode' is 'pad'.")
545            self.use_pad = True
546            if isinstance(self.kernel_size, tuple):
547                _check_tuple_length(self.kernel_size, 'kernel_size', 2, self.cls_name)
548                kernel_size = (1,) + self.kernel_size
549            elif isinstance(self.kernel_size, int):
550                kernel_size = (1, self.kernel_size, self.kernel_size)
551            if isinstance(self.stride, tuple):
552                _check_tuple_length(self.stride, 'stride', 2, self.cls_name)
553                stride = (1,) + self.stride
554            elif isinstance(self.stride, int):
555                stride = (1, self.stride, self.stride)
556            self.padding = _check_maxpool_padding(padding, 2, self.cls_name)
557            dilation = _cal_dilation(dilation, 2, self.cls_name)
558            self.max_pool = P.MaxPool3DWithArgmax(ksize=kernel_size, strides=stride, pads=self.padding,
559                                                  dilation=dilation, ceil_mode=ceil_mode)
560        else:
561            self.use_pad = False
562            if padding != 0 or dilation != 1 or return_indices or ceil_mode:
563                raise ValueError(f"For MaxPool2d, the parameter 'padding', 'dilation', 'return_indices', 'ceil_mode' "
564                                 f"can not be set to non-default value when pad_mode is not 'pad', "
565                                 f"but got pad_mode:{pad_mode}.")
566            self.max_pool = P.MaxPool(kernel_size=self.kernel_size,
567                                      strides=self.stride,
568                                      pad_mode=self.pad_mode,
569                                      data_format=self.format)
570
571    def construct(self, x):
572        expand_batch = False
573        if x.ndim == 3:
574            x = x.unsqueeze(0)
575            expand_batch = True
576        if self.use_pad:
577            x = x.unsqueeze(2)
578            out = self.max_pool(x)
579            if isinstance(out, tuple):
580                out = out[0].squeeze(2), out[1].squeeze(2)
581            else:
582                out = out.squeeze(2)
583        else:
584            out = self.max_pool(x)
585        if expand_batch:
586            if isinstance(out, tuple):
587                out = (out[0].squeeze(0), out[1].squeeze(0))
588            else:
589                out = out.squeeze(0)
590        if self.use_pad and not self.return_indices:
591            return out[0]
592        return out
593
594
595class MaxPool1d(_PoolNd):
596    r"""
597    Applies a 1D max pooling over an input Tensor which can be regarded as a composition of 1D planes.
598
599    Typically the input is of shape :math:`(N_{in}, C_{in}, L_{in})`, MaxPool1d outputs
600    regional maximum in the :math:`(L_{in})`-dimension. Given `kernel size`
601    :math:`ks = (l_{ker})` and `stride` :math:`s = (s_0)`, the operation is as follows:
602
603    .. math::
604        \text{output}(N_i, C_j, l) = \max_{n=0, \ldots, l_{ker}-1}
605        \text{input}(N_i, C_j, s_0 \times l + n)
606
607    Args:
608        kernel_size (int): The size of kernel used to take the max value, Default: ``1`` .
609        stride (int): The distance of kernel moving, an int number that represents
610            the width of movement is stride, Default: ``1`` .
611        pad_mode (str, optional): Specifies the padding mode with a padding value of 0. It can be set to:
612            ``"same"`` , ``"valid"`` or ``"pad"`` . Default: ``"valid"`` .
613
614            - ``"same"``: Pad the input at the begin and end so that the shape of input and output
615              are the same when `stride` is set to ``1``.
616              The amount of padding to is calculated by the operator internally. If the amount is even, it is
617              uniformly distributed around the input, if it is odd, the excess padding is goes to the right side.
618              If this mode is set, `padding` must be 0.
619            - ``"valid"``: No padding is applied to the input, and the output returns the maximum
620              possible length. Extra pixels that could not complete a full stride will
621              be discarded. If this mode is set, `padding` must be 0.
622            - ``"pad"``: Pad the input with a specified amount. In this mode, the amount of padding
623              at the begin and end is determined by the `padding` parameter.
624              If this mode is set, `padding` must be greater than or equal to 0.
625
626        padding (Union(int, tuple[int], list[int])): Padding value for the pooling. Default value is ``0``.
627            padding can only be an integer or a tuple/list containing a single integer, in which case padding times or
628            padding[0] times are padded on both sides of the input.
629        dilation (Union(int, tuple[int])): The spacing between the elements of the kernel in convolution,
630            used to increase the receptive field of the pooling operation. If it is a tuple, its length can only be 1.
631            Default: ``1`` .
632        return_indices (bool): If ``True`` , the function will return both the result of max pooling and the indices of
633            the max elements. Default: ``False`` .
634        ceil_mode (bool): If True, use ceil to compute the output shape instead of floor. Default: ``False`` .
635
636    Inputs:
637        - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, L_{in})` or :math:`(C_{in}, L_{in})`.
638
639    Outputs:
640        If `return_indices` is False, output is a Tensor, with shape :math:`(N, C_{out}, L_{out})` or
641        :math:`(C_{out}, L_{out})`. It has the same data type as `x`.
642
643        If `return_indices` is True, output is a Tuple of 2 Tensors, representing the maxpool result and where
644        the max values are generated.
645
646        - **output** (Tensor) - Maxpooling result, with shape :math:`(N, C_{out}, L_{out})` or
647          :math:`(C_{out}, L_{out})`. It has the same data type as `x`.
648        - **argmax** (Tensor) - Index corresponding to the maximum value. Data type is int64.
649
650        If `pad_mode` is in `pad` mode, the output shape calculation formula is as follows:
651
652        .. math::
653            L_{out} = \left\lfloor \frac{L_{in} + 2 \times \text{padding} - \text{dilation}
654                \times (\text{kernel_size} - 1) - 1}{\text{stride}} + 1\right\rfloor
655
656    Raises:
657        TypeError: If `kernel_size` or `strides` is not an int.
658        ValueError: If `pad_mode` is not ``"valid"``, ``"same"`` or ``"pad"``, case-insensitive.
659        ValueError: If `data_format` is neither ``'NCHW'`` nor ``'NHWC'``.
660        ValueError: If `kernel_size` or `strides` is less than 1.
661        ValueError: If length of shape of `x` is not equal to 2 or 3.
662        ValueError: If `pad_mode` is not ``"pad"``, `padding`, `dilation`, `return_indices`, `ceil_mode` parameters
663            are not set to their default values.
664        ValueError: If the length of the tuple/list `padding` parameter is not 1.
665        ValueError: If The length of the tuple dilation parameter is not 1.
666        ValueError: If dilation parameter is neither an integer nor a tuple.
667        ValueError: If `padding` is non-zero when `pad_mode` is not ``"pad"``.
668
669    Supported Platforms:
670        ``Ascend`` ``GPU`` ``CPU``
671
672    Examples:
673        >>> import mindspore as ms
674        >>> import mindspore.nn as nn
675        >>> import numpy as np
676        >>> mpool1 = nn.MaxPool1d(kernel_size=3, stride=1)
677        >>> x = ms.Tensor(np.random.randint(0, 10, [1, 2, 4]), ms.float32)
678        >>> output = mpool1(x)
679        >>> result = output.shape
680        >>> print(result)
681        (1, 2, 2)
682        >>> np_x = np.random.randint(0, 10, [5, 3, 4])
683        >>> x = ms.Tensor(np_x, ms.float32)
684        >>> mpool2 = nn.MaxPool1d(kernel_size=2, stride=1, pad_mode="pad", padding=1, dilation=1, return_indices=True)
685        >>> output = mpool2(x)
686        >>> print(output[0].shape)
687        (5, 3, 5)
688        >>> print(output[1].shape)
689        (5, 3, 5)
690    """
691
692    def __init__(self, kernel_size=1, stride=1, pad_mode="valid", padding=0, dilation=1, return_indices=False,
693                 ceil_mode=False):
694        """Initialize MaxPool1d."""
695        super(MaxPool1d, self).__init__(kernel_size, stride, pad_mode)
696        validator.check_int(kernel_size, 1, validator.GE, "kernel_size", self.cls_name)
697        validator.check_int(stride, 1, validator.GE, "stride", self.cls_name)
698        self.kernel_size = (1, kernel_size)
699        self.stride = (1, stride)
700        self.return_indices = return_indices
701        if pad_mode.upper() == "PAD":
702            self.use_pad = True
703            self.kernel_size = (1, 1, kernel_size)
704            self.stride = (1, 1, stride)
705            self.padding = _check_maxpool_padding(padding, 1, self.cls_name)
706            dilation = _cal_dilation(dilation, 1, self.cls_name)
707            self.max_pool = P.MaxPool3DWithArgmax(ksize=self.kernel_size, strides=self.stride, pads=self.padding,
708                                                  dilation=dilation, ceil_mode=ceil_mode)
709
710        else:
711            self.use_pad = False
712            if padding != 0 or dilation != 1 or return_indices or ceil_mode:
713                raise ValueError(f"For MaxPool1d, the parameter 'padding', 'dilation', 'return_indices', 'ceil_mode' "
714                                 f"can not be set to non-default value when pad_mode is not 'pad', "
715                                 f"but got pad_mode:{pad_mode}.")
716            self.max_pool = P.MaxPool(kernel_size=self.kernel_size,
717                                      strides=self.stride,
718                                      pad_mode=self.pad_mode)
719            self.shape = F.shape
720            self.reduce_mean = P.ReduceMean(keep_dims=True)
721            self.expand = P.ExpandDims()
722            self.squeeze = P.Squeeze(2)
723
724    def construct(self, x):
725        expand_batch = False
726        if x.ndim == 2:
727            x = x.unsqueeze(0)
728            expand_batch = True
729        if self.use_pad:
730            x = x.unsqueeze(2).unsqueeze(3)
731            output = self.max_pool(x)
732            if isinstance(output, tuple):
733                output = output[0].squeeze(3).squeeze(2), output[1].squeeze(3).squeeze(2)
734            else:
735                output = output.squeeze(3).squeeze(2)
736        else:
737            _shape_check(self.shape(x), self.cls_name)
738            x = self.expand(x, 2)
739            output = self.max_pool(x)
740            output = self.squeeze(output)
741        if expand_batch:
742            if isinstance(output, tuple):
743                output = (output[0].squeeze(0), output[1].squeeze(0))
744            else:
745                output = output.squeeze(0)
746        if self.use_pad and not self.return_indices:
747            return output[0]
748        return output
749
750
751def _cal_padding(padding, cls_name, nd):
752    """Calculate padding before call primitive"""
753    validator.check_value_type('padding', padding, (int, tuple, list), cls_name)
754    if isinstance(padding, int):
755        padding = (0, 0) * (3 - nd) + (padding,) * nd * 2
756    elif isinstance(padding, (tuple, list)):
757        validator.check_non_negative_int_sequence(padding, "padding", cls_name)
758        if len(padding) == nd:
759            padding_start = (0, 0) * (3 - nd)
760            padding_end = tuple(padding[i // 2] for i in range(nd * 2))
761            padding = padding_start + padding_end
762        elif len(padding) == 1:
763            padding = (0, 0) * (3 - nd) + tuple(padding * nd * 2)
764        else:
765            if nd == 1:
766                raise ValueError(f"For {cls_name}, the padding must be a int or tuple/list contains one int, "
767                                 f"but got tuple/list with length:{len(padding)}.")
768            raise ValueError(f"For {cls_name}, the padding must be a int or tuple/list contains 1 or {nd} int, "
769                             f"but got tuple/list with length:{len(padding)}.")
770    return padding
771
772
773def _check_tuple_length(arg_name, prim_name, length, cls_name):
774    """check the tuple length"""
775    if len(arg_name) != length:
776        raise ValueError(f"For {cls_name}, the length of {prim_name} must be equal to {length}, "
777                         f"but got {len(arg_name)}.")
778    return arg_name
779
780
781class AvgPool3d(_PoolNd):
782    r"""
783    Applies a 3D average pooling over an input Tensor which can be regarded as a composition of 3D input planes.
784    Typically, the input is of shape :math:`(N_{in}, C_{in}, D_{in}, H_{in}, W_{in})`, and AvgPool3D outputs
785    regional average in the :math:`(D_{in}, H_{in}, W_{in})`-dimension. Given kernel size
786    is :math:`ks = (d_{ker}, h_{ker}, w_{ker})` and stride :math:`s = (s_0, s_1, s_2)`, the operation is as follows.
787
788    .. warning::
789        `kernel_size` is in the range [1, 255]. `stride` is in the range [1, 63].
790
791    .. math::
792        \text{output}(N_i, C_j, d, h, w) =
793        \frac{1}{d_{ker} * h_{ker} * w_{ker}} \sum_{l=0}^{d_{ker}-1} \sum_{m=0}^{h_{ker}-1} \sum_{n=0}^{w_{ker}-1}
794        \text{input}(N_i, C_j, s_0 \times d + l, s_1 \times h + m, s_2 \times w + n)
795
796    Args:
797        kernel_size (Union[int, tuple[int]], optional): The size of kernel used to take the average value,
798            can be an int number or a single element tuple that represents depth, height and width, or a tuple of three
799            positive integers that represent depth, height and width respectively. Default: ``1`` .
800        stride (Union[int, tuple[int]], optional): The distance of kernel moving, can be a positive int or a single
801            element tuple that represents the depth, height and width of movement, or a tuple of three positive integers
802            that represents depth, height and width of movement respectively. If the value is None, the default value
803            `kernel_size` is used. Default: ``1`` .
804        pad_mode (str, optional): Specifies the padding mode with a padding value of 0. It can be set to:
805            ``"same"`` , ``"valid"`` or ``"pad"`` . Default: ``"valid"`` .
806
807            - ``"same"``: Pad the input around its depth/height/width dimension so that the shape of input and output
808              are the same when `stride` is set to ``1``.
809              The amount of padding to is calculated by the operator internally.  If the amount is even,
810              it isuniformly distributed around the input, if it is odd, the excess amount goes
811              to the front/right/bottom side.
812              If this mode is set, `padding` must be 0.
813            - ``"valid"``: No padding is applied to the input, and the output returns the maximum
814              possible depth, height and width. Extra pixels that could not complete a full stride will
815              be discarded. If this mode is set, `padding` must be 0.
816            - ``"pad"``: Pad the input with a specified amount. In this mode, the amount of padding
817              in the depth, height and width dimension is determined by the `padding` parameter.
818              If this mode is set, `padding` must be greater than or equal to 0.
819
820        padding (Union(int, tuple[int], list[int]), optional): Pooling padding value, only ``"pad"`` mode can be set to
821            non-zero. Default: ``0`` . Only the following paddings are supported:
822
823            - `padding` is an integer or a tuple/list containing one integer, it will be padded in six directions of
824              front, back, top, bottom, left and right of the input.
825
826            - `padding` is a tuple/list containing three integers, it will be padded in front and back of the input
827              `padding[0]` times, up and down `padding[1]` times, and left and right of the input `padding[2]` times.
828
829        ceil_mode (bool, optional): If ``True`` , use ceil to compute the output shape instead of floor.
830            Default: ``False`` .
831        count_include_pad (bool, optional): If ``True`` , averaging calculation will include the zero-padding.
832            Default: ``True`` .
833        divisor_override (int, optional): If it is specified as a non-zero parameter, this parameter will be used as the
834            divisor in the average calculation. Otherwise, `kernel_size` will be used as the divisor.
835            Default: ``None`` .
836
837    Inputs:
838        - **x** (Tensor) - Tensor of shape :math:`(N, C, D_{in}, H_{in}, W_{in})` or
839          :math:`(C, D_{in}, H_{in}, W_{in})`.
840          Currently support float16, float32 and float64 data type.
841
842    Outputs:
843        Tensor, with shape :math:`(N, C, D_{out}, H_{out}, W_{out})` or
844        :math:`(C, D_{out}, H_{out}, W_{out})`, with the same data type as `x`.
845
846        If `pad_mode` is in `pad` mode, the output shape calculation formula is as follows:
847
848        .. math::
849            D_{out} = \left\lfloor\frac{D_{in} + 2 \times \text{padding}[0] -
850                \text{kernel_size}[0]}{\text{stride}[0]} + 1\right\rfloor
851
852        .. math::
853            H_{out} = \left\lfloor\frac{H_{in} + 2 \times \text{padding}[1] -
854                \text{kernel_size}[1]}{\text{stride}[1]} + 1\right\rfloor
855
856        .. math::
857            W_{out} = \left\lfloor\frac{W_{in} + 2 \times \text{padding}[2] -
858                \text{kernel_size}[2]}{\text{stride}[2]} + 1\right\rfloor
859
860    Raises:
861        TypeError: If `kernel_size` is neither an int nor a tuple.
862        TypeError: If `stride` is neither an int nor a tuple.
863        TypeError: If `padding` is neither an int nor a tuple/list.
864        TypeError: If `ceil_mode` or `count_include_pad` is not a bool.
865        TypeError: If `divisor_override` is not an int.
866        ValueError: If numbers in `kernel_size` or `stride` are not positive.
867        ValueError: If `kernel_size` or `stride` is a tuple whose length is not equal to 3.
868        ValueError: If `padding` is a tuple/list whose length is neither 1 nor 3.
869        ValueError: If element of `padding` is less than 0.
870        ValueError: If length of shape of `x` is neither 4 nor 5.
871        ValueError: If `divisor_override` is less than or equal to 0.
872        ValueError: If `padding` is non-zero when `pad_mode` is not ``"pad"``.
873
874    Supported Platforms:
875        ``Ascend`` ``GPU`` ``CPU``
876
877    Examples:
878        >>> import mindspore as ms
879        >>> pool = ms.nn.AvgPool3d(kernel_size=3, stride=1)
880        >>> x = ms.ops.randn(1, 2, 4, 4, 5).astype(ms.float32)
881        >>> output = pool(x)
882        >>> print(output.shape)
883        (1, 2, 2, 2, 3)
884        >>> x1 = ms.ops.randn(6, 5, 7, 7, 5).astype(ms.float32)
885        >>> pool2 = ms.nn.AvgPool3d(4, stride=2, pad_mode="pad", padding=(2, 2, 1), divisor_override=10)
886        >>> output2 = pool2(x1)
887        >>> print(output2.shape)
888        (6, 5, 4, 4, 2)
889    """
890
891    def __init__(self, kernel_size=1, stride=1, pad_mode="valid", padding=0, ceil_mode=False, count_include_pad=True,
892                 divisor_override=None):
893        """Initialize AvgPool3d."""
894        super(AvgPool3d, self).__init__(kernel_size, stride, pad_mode)
895        padding = _cal_padding(padding, self.cls_name, 3)
896        if divisor_override is not None and divisor_override <= 0:
897            raise ValueError(f"For '{self.cls_name}', the 'divisor_override' must be > 0, but got {divisor_override}.")
898        divisor_override = 0 if divisor_override is None else divisor_override
899        self.avg_pool = P.AvgPool3D(self.kernel_size, self.stride, pad_mode, padding, ceil_mode, count_include_pad,
900                                    divisor_override)
901
902    def construct(self, x):
903        expand_batch = False
904        if len(x.shape) == 4:
905            x = x.unsqueeze(0)
906            expand_batch = True
907        out = self.avg_pool(x)
908        if expand_batch:
909            out = out.squeeze(0)
910        return out
911
912
913class AvgPool2d(_PoolNd):
914    r"""
915    Applies a 2D average pooling over an input Tensor which can be regarded as a composition of 2D input planes.
916
917    Typically the input is of shape :math:`(N_{in}, C_{in}, H_{in}, W_{in})`, AvgPool2d outputs
918    regional average in the :math:`(H_{in}, W_{in})`-dimension. Given kernel size
919    :math:`ks = (h_{ker}, w_{ker})` and stride :math:`s = (s_0, s_1)`, the operation is as follows:
920
921    .. math::
922        \text{output}(N_i, C_j, h, w) = \frac{1}{h_{ker} * w_{ker}} \sum_{m=0}^{h_{ker}-1} \sum_{n=0}^{w_{ker}-1}
923        \text{input}(N_i, C_j, s_0 \times h + m, s_1 \times w + n)
924
925    Args:
926        kernel_size (Union[int, tuple[int]]): The size of kernel used to take the average value.
927            The data type of kernel_size must be int or a single element tuple and the value represents the height
928            and width, or a tuple of two int numbers that represent height and width respectively.
929            Default: ``1`` .
930        stride (Union[int, tuple[int]]): The distance of kernel moving, an int number or a single element tuple that
931            represents the height and width of movement are both strides, or a tuple of two int numbers that
932            represent height and width of movement respectively. Default: ``1`` .
933        pad_mode (str, optional): Specifies the padding mode with a padding value of 0. It can be set to:
934            ``"same"`` , ``"valid"`` or ``"pad"`` . Default: ``"valid"`` .
935
936            - ``"same"``: Pad the input around its edges so that the shape of input and output
937              are the same when `stride` is set to ``1``.
938              The amount of padding to is calculated by the operator internally, If the amount is even, it is
939              uniformly distributed around the input, if it is odd, the excess amount goes to the right/bottom side.
940              If this mode is set, `padding` must be 0.
941            - ``"valid"``: No padding is applied to the input, and the output returns the maximum
942              possible height and width. Extra pixels that could not complete a full stride will
943              be discarded. If this mode is set, `padding` must be 0.
944            - ``"pad"``: Pad the input with a specified amount. In this mode, the amount of padding
945              in the height and width directions is determined by the `padding` parameter.
946              If this mode is set, `padding` must be greater than or equal to 0.
947
948        padding (Union(int, tuple[int], list[int])): Pooling padding value, only ``"pad"`` mode can be set to non-zero.
949            Default: ``0`` . `padding` can only be an integer or a tuple/list containing one or two integers.
950            If `padding` is an integer or a tuple/list containing one integer, it will be padded `padding` times in the
951            four directions of the input. If `padding` is a tuple/list containing two integers, it will be padded
952            `padding[0]` times in the up-down direction of the input and `padding[1]` times in the left-right direction
953            of the input.
954        ceil_mode (bool): If ``True`` , use ceil to compute the output shape instead of floor. Default: ``False`` .
955        count_include_pad (bool): If ``True`` , averaging calculation will include the zero-padding. Default: ``True`` .
956        divisor_override (int): If it is specified as a non-zero parameter, this parameter will be used as the divisor
957            in the average calculation. Otherwise, `kernel_size` will be used as the divisor. Default: ``None`` .
958        data_format (str): The optional value for data format, is ``'NHWC'`` or ``'NCHW'`` .
959            Default: ``'NCHW'`` .
960
961    Inputs:
962        - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})` or :math:`(C_{in}, H_{in}, W_{in})`.
963
964    Outputs:
965        Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})` or :math:`(C_{out}, H_{out}, W_{out})`.
966
967        If `pad_mode` is in `pad` mode, the output shape calculation formula is as follows:
968
969        .. math::
970            H_{out} = \left\lfloor\frac{H_{in}  + 2 \times \text{padding}[0] -
971            \text{kernel_size}[0]}{\text{stride}[0]} + 1\right\rfloor
972
973        .. math::
974            W_{out} = \left\lfloor\frac{W_{in}  + 2 \times \text{padding}[1] -
975            \text{kernel_size}[1]}{\text{stride}[1]} + 1\right\rfloor
976
977    Raises:
978        TypeError: If `kernel_size` or `strides` is neither int nor tuple.
979        ValueError: If `pad_mode` is not ``"valid"`` , ``"same"`` or ``"pad"`` with not case sensitive.
980        ValueError: If `data_format` is neither ``'NCHW'`` nor ``'NHWC'``.
981        ValueError: If `padding`, `ceil_mode`, `count_include_pad`, or `divisor_override` is used
982            or `pad_mode` is ``"pad"`` when `data_format` is 'NHWC'.
983        ValueError: If `kernel_size` or `strides` is less than 1.
984        ValueError: If length of `padding` tuple/list is not 1 or 2.
985        ValueError: If length of shape of `x` is not equal to 3 or 4.
986        ValueError: If `divisor_override` is less than or equal to 0.
987        ValueError: If `padding` is non-zero when `pad_mode` is not ``"pad"``.
988
989    Supported Platforms:
990        ``Ascend`` ``GPU`` ``CPU``
991
992    Examples:
993        >>> import mindspore as ms
994        >>> import numpy as np
995        >>> pool = ms.nn.AvgPool2d(kernel_size=3, stride=1)
996        >>> x = ms.Tensor(np.random.randint(0, 10, [1, 2, 4, 4]), ms.float32)
997        >>> output = pool(x)
998        >>> print(output.shape)
999        (1, 2, 2, 2)
1000        >>> x = ms.ops.randn(6, 6, 8, 8)
1001        >>> pool2 = ms.nn.AvgPool2d(4, stride=1, pad_mode="pad", padding=2, divisor_override=5)
1002        >>> output2 = pool2(x)
1003        >>> print(output2.shape)
1004        (6, 6, 9, 9)
1005    """
1006
1007    def __init__(self,
1008                 kernel_size=1,
1009                 stride=1,
1010                 pad_mode="valid",
1011                 padding=0,
1012                 ceil_mode=False,
1013                 count_include_pad=True,
1014                 divisor_override=None,
1015                 data_format="NCHW"):
1016        """Initialize AvgPool2d."""
1017        super(AvgPool2d, self).__init__(kernel_size, stride, pad_mode, data_format)
1018        self.ascend_910bc_target = (MSContext.get_instance().get_ascend_soc_version() in ['ascend910b', 'ascend910c'])
1019        if pad_mode.upper() == 'PAD' or padding != 0 or ceil_mode or not count_include_pad \
1020                or divisor_override is not None:
1021            if self.ascend_910bc_target:
1022                raise ValueError(f"For '{self.cls_name}, the pad_mod 'PAD' is not support in 910B now, "
1023                                 f"it will be supported in the future.")
1024            if self.format == "NHWC":
1025                raise ValueError(f"For '{self.cls_name}, the 'NHWC' format are not support when 'pad_mode' is 'pad' or "
1026                                 f"'padding' is not 0 or 'ceil_mode' is not False or 'count_include_pad' is not True"
1027                                 f"or divisor_override is not None, but got pade_mode:{pad_mode}, padding:{padding}, "
1028                                 f"ceil_mode:{ceil_mode}, count_include_pad:{count_include_pad}, "
1029                                 f"divisor_override:{divisor_override}.")
1030            self.is_expand = True
1031            if divisor_override is not None and divisor_override <= 0:
1032                raise ValueError(
1033                    f"For '{self.cls_name}', the 'divisor_override' must be > 0, but got {divisor_override}.")
1034            divisor_override = 0 if divisor_override is None else divisor_override
1035            padding = _cal_padding(padding, self.cls_name, 2)
1036
1037            if isinstance(self.kernel_size, tuple):
1038                _check_tuple_length(self.kernel_size, 'kernel_size', 2, self.cls_name)
1039                kernel_size = (1,) + self.kernel_size
1040            elif isinstance(self.kernel_size, int):
1041                kernel_size = (1, self.kernel_size, self.kernel_size)
1042
1043            if isinstance(self.stride, tuple):
1044                _check_tuple_length(self.stride, 'stride', 2, self.cls_name)
1045                stride = (1,) + self.stride
1046            elif isinstance(self.stride, int):
1047                stride = (1, self.stride, self.stride)
1048            self.avg_pool = P.AvgPool3D(kernel_size=kernel_size, strides=stride, pad_mode=pad_mode, pad=padding,
1049                                        ceil_mode=ceil_mode,
1050                                        count_include_pad=count_include_pad, divisor_override=divisor_override)
1051        else:
1052            self.is_expand = False
1053            self.avg_pool = P.AvgPool(kernel_size=self.kernel_size,
1054                                      strides=self.stride,
1055                                      pad_mode=self.pad_mode,
1056                                      data_format=self.format)
1057
1058    def construct(self, x):
1059        expand_batch = False
1060        if x.ndim == 3:
1061            x = x.unsqueeze(0)
1062            expand_batch = True
1063        if self.is_expand:
1064            x = x.unsqueeze(2)
1065            out = self.avg_pool(x)
1066            res = out.squeeze(2)
1067        else:
1068            res = self.avg_pool(x)
1069        if expand_batch:
1070            res = res.squeeze(0)
1071        return res
1072
1073
1074class AvgPool1d(_PoolNd):
1075    r"""
1076    Applies a 1D average pooling over an input Tensor which can be regarded as a composition of 1D input planes.
1077
1078    Typically the input is of shape :math:`(N_{in}, C_{in}, L_{in})`, AvgPool1d outputs
1079    regional average in the :math:`(L_{in})`-dimension. Given `kernel_size`
1080    :math:`l_{ker}` and `stride` :math:`s_0`, the operation is as follows:
1081
1082    .. math::
1083        \text{output}(N_i, C_j, l) = \frac{1}{l_{ker}} \sum_{n=0}^{l_{ker}-1}
1084        \text{input}(N_i, C_j, s_0 \times l + n)
1085
1086    Args:
1087        kernel_size (int): The size of kernel window used to take the average value, Default: ``1`` .
1088        stride (int): The distance of kernel moving, an int number that represents
1089            the width of movement is strides, Default: ``1`` .
1090        pad_mode (str, optional): Specifies the padding mode with a padding value of 0. It can be set to:
1091            ``"same"`` , ``"valid"`` or ``"pad"`` . Default: ``"valid"`` .
1092
1093            - ``"same"``: Pad the input at the begin and end so that the shape of input and output
1094              are the same when `stride` is set to ``1``.
1095              The amount of padding to is calculated by the operator internally. If the amount is even, it is
1096              uniformly distributed around the input, if it is odd, the excess padding is goes to the right side.
1097              If this mode is set, `padding` must be 0.
1098            - ``"valid"``: No padding is applied to the input, and the output returns the maximum
1099              possible length. Extra pixels that could not complete a full stride will
1100              be discarded. If this mode is set, `padding` must be 0.
1101            - ``"pad"``: Pad the input with a specified amount. In this mode, the amount of padding
1102              at the begin and end is determined by the `padding` parameter.
1103              If this mode is set, `padding` must be greater than or equal to 0.
1104
1105        padding (Union(int, tuple[int], list[int])): Pooling padding value, only ``"pad"`` mode can be set to non-zero.
1106            Default: ``0`` . padding can only be an integer or a tuple/list containing a single integer, in which case
1107            padding times or padding[0] times are padded on both sides of the input.
1108        ceil_mode (bool): If ``True`` , use ceil to compute the output shape instead of floor. Default: ``False`` .
1109        count_include_pad (bool): If ``True`` , averaging calculation will include the zero-padding. Default: ``True`` .
1110
1111    Inputs:
1112        - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, L_{in})` or :math:`(C_{in}, L_{in})`.
1113
1114    Outputs:
1115        Tensor of shape :math:`(N, C_{out}, L_{out})` or :math:`(C_{out}, L_{out})`.
1116
1117        If `pad_mode` is in `pad` mode, the output shape calculation formula is as follows:
1118
1119        .. math::
1120            L_{out} = \left\lfloor \frac{L_{in} +
1121            2 \times \text{padding} - \text{kernel_size}}{\text{stride}} + 1\right\rfloor
1122
1123    Raises:
1124        TypeError: If `kernel_size` or `stride` is not an int.
1125        ValueError: If `pad_mode` is not ``"valid"`` , ``"same"`` or ``"pad"`` with not case sensitive.
1126        ValueError: If `kernel_size` or `strides` is less than 1.
1127        ValueError: If length of `padding` tuple/list is not 1.
1128        ValueError: If length of shape of `x` is not equal to 2 or 3.
1129        ValueError: If `padding` is non-zero when `pad_mode` is not ``"pad"``.
1130
1131    Supported Platforms:
1132        ``Ascend`` ``GPU`` ``CPU``
1133
1134    Examples:
1135        >>> import mindspore as ms
1136        >>> import numpy as np
1137        >>> pool = ms.nn.AvgPool1d(kernel_size=6, stride=1)
1138        >>> x = ms.Tensor(np.random.randint(0, 10, [1, 3, 6]), ms.float32)
1139        >>> output = pool(x)
1140        >>> result = output.shape
1141        >>> print(result)
1142        (1, 3, 1)
1143        >>> pool2 = ms.nn.AvgPool1d(4, stride=1, ceil_mode=True, pad_mode="pad", padding=2)
1144        >>> x1 = ms.ops.randn(6, 6, 8)
1145        >>> output = pool2(x1)
1146        >>> print(output.shape)
1147        (6, 6, 9)
1148    """
1149
1150    def __init__(self,
1151                 kernel_size=1,
1152                 stride=1,
1153                 pad_mode="valid",
1154                 padding=0,
1155                 ceil_mode=False,
1156                 count_include_pad=True):
1157        """Initialize AvgPool1d."""
1158        super(AvgPool1d, self).__init__(kernel_size, stride, pad_mode)
1159        validator.check_int(self.kernel_size, 1, validator.GE, "kernel_size", self.cls_name)
1160        validator.check_int(self.stride, 1, validator.GE, "stride", self.cls_name)
1161        if pad_mode.upper() == 'PAD' or padding != 0 or ceil_mode or not count_include_pad:
1162            padding = _cal_padding(padding, self.cls_name, 1)
1163            self.is_expand_3d = True
1164            kernel_size = (1, 1, self.kernel_size)
1165            stride = (1, 1, self.stride)
1166            self.avg_pool = P.AvgPool3D(kernel_size=kernel_size, strides=stride, pad_mode=pad_mode, pad=padding,
1167                                        ceil_mode=ceil_mode,
1168                                        count_include_pad=count_include_pad)
1169        else:
1170            self.is_expand_3d = False
1171            self.kernel_size = (1, self.kernel_size)
1172            self.stride = (1, self.stride)
1173            self.avg_pool = P.AvgPool(kernel_size=self.kernel_size,
1174                                      strides=self.stride,
1175                                      pad_mode=self.pad_mode)
1176            self.shape = F.shape
1177            self.reduce_mean = P.ReduceMean(keep_dims=True)
1178            self.slice = P.Slice()
1179            self.expand = P.ExpandDims()
1180            self.squeeze = P.Squeeze(2)
1181
1182    def construct(self, x):
1183        expand_batch = False
1184        if x.ndim == 2:
1185            x = x.unsqueeze(0)
1186            expand_batch = True
1187        if self.is_expand_3d:
1188            x = x.unsqueeze(2).unsqueeze(3)
1189            x = self.avg_pool(x)
1190            x = x.squeeze(3).squeeze(2)
1191        else:
1192            _shape_check(self.shape(x), self.cls_name)
1193            batch, channel, width = self.shape(x)
1194            if width == self.kernel_size[1]:
1195                x = self.reduce_mean(x, 2)
1196            elif width - self.kernel_size[1] < self.stride[1]:
1197                x = self.slice(x, (0, 0, 0), (batch, channel, self.kernel_size[1]))
1198                x = self.reduce_mean(x, 2)
1199            else:
1200                x = self.expand(x, 2)
1201                x = self.avg_pool(x)
1202                x = self.squeeze(x)
1203        if expand_batch:
1204            x = x.squeeze(0)
1205        return x
1206
1207
1208@_primexpr
1209def _adaptive_shape_check(in_shape, output_size, prim_name):
1210    """Check shape."""
1211    msg_prefix = f"For {prim_name}, the"
1212    if len(in_shape) != 3:
1213        raise ValueError(f"{msg_prefix} input must has 3 dim, but got {len(in_shape)}.")
1214    if in_shape[2] < output_size:
1215        raise ValueError(f"{msg_prefix} input's last dimension must be greater or equal to "
1216                         f"output size {output_size}, but got {in_shape[2]}.")
1217    if in_shape[2] % output_size != 0:
1218        raise ValueError(f"{msg_prefix} input's last dimension must be divisible by "
1219                         f"output size {output_size}, but got {in_shape[2]}.")
1220
1221
1222@constexpr
1223def _adaptive_dtype_check(x_dtype, prim_name):
1224    """Check dtype."""
1225    if x_dtype not in [mstype.float16, mstype.float32]:
1226        raise TypeError(f"For {prim_name}, the x_dtype must be float16 or float32, "
1227                        f"but got {x_dtype}.")
1228
1229
1230class AdaptiveAvgPool1d(Cell):
1231    r"""
1232    Applies a 1D adaptive average pooling over an input Tensor which can be regarded as
1233    a composition of 1D input planes.
1234
1235    Typically, the input is of shape :math:`(N_{in}, C_{in}, L_{in})`,
1236    AdaptiveAvgPool1d outputs regional average in the :math:`L_{in}`-dimension.
1237    The output is of shape :math:`(N_{in}, C_{in}, L_{out})`,
1238    where :math:`L_{out}` is defined by `output_size`.
1239
1240    Note:
1241        :math:`L_{in}` must be divisible by `output_size`.
1242
1243    Args:
1244        output_size (int): the target output size :math:`L_{out}`.
1245
1246    Inputs:
1247        - **input** (Tensor) - Tensor of shape :math:`(N, C_{in}, L_{in})`, with float16 or float32 data type.
1248
1249    Outputs:
1250        Tensor of shape :math:`(N, C_{in}, L_{out})`, has the same type as `input`.
1251
1252    Raises:
1253        TypeError: If `output_size` is not an int.
1254        TypeError: If `input` is neither float16 nor float32.
1255        ValueError: If `output_size` is less than 1.
1256        ValueError: If length of shape of `input` is not equal to 3.
1257        ValueError: If the last dimension of `input` is smaller than `output_size`.
1258        ValueError: If the last dimension of `input` is not divisible by `output_size`.
1259
1260
1261    Supported Platforms:
1262        ``Ascend`` ``GPU`` ``CPU``
1263
1264    Examples:
1265        >>> import mindspore as ms
1266        >>> import numpy as np
1267        >>> pool = ms.nn.AdaptiveAvgPool1d(output_size=2)
1268        >>> input = ms.Tensor(np.random.randint(0, 10, [1, 3, 6]), ms.float32)
1269        >>> output = pool(input)
1270        >>> result = output.shape
1271        >>> print(result)
1272        (1, 3, 2)
1273    """
1274
1275    def __init__(self, output_size):
1276        """Initialize AdaptiveAvgPool1d."""
1277        super(AdaptiveAvgPool1d, self).__init__()
1278        validator.check_value_type('output_size', output_size, [int], self.cls_name)
1279        validator.check_int(output_size, 1, validator.GE, "output_size", self.cls_name)
1280        self.shape = F.shape
1281        self.expand = P.ExpandDims()
1282        self.squeeze = P.Squeeze(2)
1283        self.output_size = output_size
1284        self.dtype = P.DType()
1285
1286    def construct(self, input):
1287        _adaptive_shape_check(self.shape(input), self.output_size, self.cls_name)
1288        _adaptive_dtype_check(self.dtype(input), self.cls_name)
1289
1290        _, _, width = self.shape(input)
1291        stride = width // self.output_size
1292        kernel_size = width - (self.output_size - 1) * stride
1293
1294        stride = (1, width // self.output_size)
1295        kernel_size = (1, kernel_size)
1296
1297        input = self.expand(input, 2)
1298        avg_pool = P.AvgPool(kernel_size=kernel_size, strides=stride)
1299        input = avg_pool(input)
1300        input = self.squeeze(input)
1301
1302        return input
1303
1304
1305class AdaptiveAvgPool2d(Cell):
1306    r"""
1307    This operator applies a 2D adaptive average pooling to an input signal composed of multiple input planes.
1308    That is, for any input size, the size of the specified output is H x W.
1309    The number of output features is equal to the number of input features.
1310
1311    The input and output data format can be "NCHW" and "CHW". N is the batch size, C is the number of channels,
1312    H is the feature height, and W is the feature width.
1313
1314    .. math::
1315        \begin{align}
1316        h_{start} &= floor(i * H_{in} / H_{out})\\
1317        h_{end} &= ceil((i + 1) * H_{in} / H_{out})\\
1318        w_{start} &= floor(j * W_{in} / W_{out})\\
1319        w_{end} &= ceil((j + 1) * W_{in} / W_{out})\\
1320        Output(i,j) &= \frac{\sum Input[h_{start}:h_{end}, w_{start}:w_{end}]}{(h_{end}- h_{start})
1321        * (w_{end}- w_{start})}
1322        \end{align}
1323
1324    Args:
1325        output_size (Union[int, tuple]): The target output size is H x W.
1326            `output_size` can be a tuple consisted of int type H and W, or a single H for H x H, or None.
1327            If it is None, it means the output size is the same as the input size.
1328
1329    Inputs:
1330        - **input** (Tensor) - The input of AdaptiveAvgPool2d, which is a 3D or 4D tensor,
1331          with float16, float32 or float64 data type.
1332
1333    Outputs:
1334        Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`.
1335
1336    Raises:
1337        ValueError: If `output_size` is a tuple and the length of `output_size` is not 2.
1338        TypeError: If `input` is not a Tensor.
1339        TypeError: If dtype of `input` is not float16, float32 or float64.
1340        ValueError: If the dimension of `input` is less than or equal to the dimension of `output_size`.
1341
1342    Supported Platforms:
1343        ``Ascend`` ``GPU`` ``CPU``
1344
1345    Examples:
1346        >>> import mindspore as ms
1347        >>> import numpy as np
1348        >>> pool = ms.nn.AdaptiveAvgPool2d(2)
1349        >>> input_x = ms.Tensor(np.array([[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]],
1350        ...                            [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]],
1351        ...                            [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]]), ms.float32)
1352        >>> output = pool(input_x)
1353        >>> result = output.shape
1354        >>> print(result)
1355        (3, 2, 2)
1356    """
1357
1358    def __init__(self, output_size):
1359        """Initialize AdaptiveAvgPool2d."""
1360        super(AdaptiveAvgPool2d, self).__init__()
1361        self.adaptive_avgpool2d = P.AdaptiveAvgPool2D(output_size)
1362
1363    def construct(self, input):
1364        return self.adaptive_avgpool2d(input)
1365
1366
1367class AdaptiveAvgPool3d(Cell):
1368    r"""
1369    This operator applies a 3D adaptive average pooling to an input signal composed of multiple input planes.
1370    That is, for any input size, the size of the specified output is :math:`(D, H, W)`.
1371    The number of output features is equal to the number of input planes.
1372
1373    Suppose the last 3 dimension size of input is :math:`(inD, inH, inW)`, then the last 3 dimension size of output is
1374    :math:`(outD, outH, outW)`.
1375
1376    .. math::
1377        \begin{array}{ll} \\
1378            \forall \quad od \in [0,outD-1], oh \in [0,outH-1], ow \in [0,outW-1]\\
1379            output[od,oh,ow] = \\
1380            \qquad mean(input[istartD:iendD+1,istartH:iendH+1,istartW:iendW+1])\\
1381            where,\\
1382            \qquad istartD= \left\lceil \frac{od * inD}{outD} \right\rceil \\
1383            \qquad iendD=\left\lfloor \frac{(od+1)* inD}{outD} \right\rfloor \\
1384            \qquad istartH=\left\lceil \frac{oh * inH}{outH} \right\rceil \\
1385            \qquad iendH=\left\lfloor \frac{(oh+1) * inH}{outH} \right\rfloor \\
1386            \qquad istartW=\left\lceil \frac{ow * inW}{outW} \right\rceil \\
1387            \qquad iendW=\left\lfloor \frac{(ow+1) * inW}{outW} \right\rfloor
1388        \end{array}
1389
1390    Args:
1391        output_size (Union[int, tuple]): The target output size. `output_size` can be a tuple :math:`(D, H, W)`,
1392            or an int D for :math:`(D, D, D)`. :math:`D`, :math:`H` and :math:`W` can be int or None
1393            which means the output size is the same as that of the input.
1394
1395    Inputs:
1396        - **input** (Tensor) - The input of AdaptiveAvgPool3d, which is a 5D or 4D Tensor,
1397          with float16, float32 or float64 data type.
1398
1399    Outputs:
1400        Tensor, with the same type as the `input`.
1401
1402    Raises:
1403        TypeError: If `input` is not a Tensor.
1404        TypeError: If dtype of `input` is not float16, float32 or float64.
1405        ValueError: If the dimension of `input` is not 4D or 5D.
1406        ValueError: If `output_size` value is not positive.
1407
1408    Supported Platforms:
1409        ``Ascend`` ``GPU`` ``CPU``
1410
1411    Examples:
1412        >>> import mindspore as ms
1413        >>> import numpy as np
1414        >>> # case 1: output_size=(3, 3, 4)
1415        >>> output_size=(3, 3, 4)
1416        >>> input_x_val = np.random.randn(4, 3, 5, 6, 7)
1417        >>> input_x = ms.Tensor(input_x_val, ms.float32)
1418        >>> net = ms.nn.AdaptiveAvgPool3d(output_size)
1419        >>> output = net(input_x)
1420        >>> print(output.shape)
1421        (4, 3, 3, 3, 4)
1422        >>> # case 2: output_size=4
1423        >>> output_size=5
1424        >>> input_x_val = np.random.randn(2, 3, 8, 6, 12)
1425        >>> input_x = ms.Tensor(input_x_val, ms.float32)
1426        >>> net = ms.nn.AdaptiveAvgPool3d(output_size)
1427        >>> output = net(input_x)
1428        >>> print(output.shape)
1429        (2, 3, 5, 5, 5)
1430        >>> # case 3: output_size=(None, 4, 5)
1431        >>> output_size=(None, 4, 5)
1432        >>> input_x_val = np.random.randn(4, 1, 9, 10, 8)
1433        >>> input_x = ms.Tensor(input_x_val, ms.float32)
1434        >>> net = ms.nn.AdaptiveAvgPool3d(output_size)
1435        >>> output = net(input_x)
1436        >>> print(output.shape)
1437        (4, 1, 9, 4, 5)
1438    """
1439
1440    def __init__(self, output_size):
1441        """Initialize AdaptiveAvgPool3d."""
1442        super(AdaptiveAvgPool3d, self).__init__()
1443        self.adaptive_avg_pool3d = AdaptiveAvgPool3D(output_size)
1444
1445    def construct(self, input):
1446        return self.adaptive_avg_pool3d(input)
1447
1448
1449class AdaptiveMaxPool1d(Cell):
1450    r"""
1451    Applies a 1D adaptive maximum pooling over an input Tensor which can be regarded as
1452    a composition of 1D input planes.
1453
1454    Typically, the input is of shape :math:`(N_{in}, C_{in}, L_{in})`,
1455    AdaptiveMaxPool1d outputs regional maximum in the :math:`L_{in}`-dimension. The output is of
1456    shape :math:`(N_{in}, C_{in}, L_{out})`, where :math:`L_{out}` is defined by `output_size`.
1457
1458    Note:
1459        :math:`L_{in}` must be divisible by `output_size`.
1460
1461    Args:
1462        output_size (int): the target output size :math:`L_{out}`.
1463
1464    Inputs:
1465        - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, L_{in})`, with float16 or float32 data type.
1466
1467    Outputs:
1468        Tensor of shape :math:`(N, C_{in}, L_{out})`, has the same type as `x`.
1469
1470    Raises:
1471        TypeError: If `x` is neither float16 nor float32.
1472        TypeError: If `output_size` is not an int.
1473        ValueError: If `output_size` is less than 1.
1474        ValueError: If the last dimension of `x` is smaller than `output_size`.
1475        ValueError: If the last dimension of `x` is not divisible by `output_size`.
1476        ValueError: If length of shape of `x` is not equal to 3.
1477
1478
1479    Supported Platforms:
1480        ``Ascend`` ``GPU`` ``CPU``
1481
1482    Examples:
1483        >>> import mindspore as ms
1484        >>> import numpy as np
1485        >>> pool = ms.nn.AdaptiveMaxPool1d(output_size=3)
1486        >>> x = ms.Tensor(np.random.randint(0, 10, [1, 3, 6]), ms.float32)
1487        >>> output = pool(x)
1488        >>> result = output.shape
1489        >>> print(result)
1490        (1, 3, 3)
1491    """
1492
1493    def __init__(self, output_size):
1494        """Initialize AdaptiveMaxPool1d."""
1495        super(AdaptiveMaxPool1d, self).__init__()
1496        validator.check_int(output_size, 1, validator.GE, "output_size", self.cls_name)
1497        validator.check_value_type('output_size', output_size, [int], self.cls_name)
1498        self.expand = P.ExpandDims()
1499        self.squeeze = P.Squeeze(2)
1500        self.output_size = output_size
1501        self.shape = F.shape
1502        self.dtype = P.DType()
1503
1504    def construct(self, x):
1505        _adaptive_shape_check(self.shape(x), self.output_size, self.cls_name)
1506        _adaptive_dtype_check(self.dtype(x), self.cls_name)
1507
1508        _, _, width = self.shape(x)
1509        stride = width // self.output_size
1510        kernel_size = width - (self.output_size - 1) * stride
1511
1512        stride = (1, width // self.output_size)
1513        kernel_size = (1, kernel_size)
1514
1515        max_pool = P.MaxPool(kernel_size=kernel_size, strides=stride)
1516        x = self.expand(x, 2)
1517        x = max_pool(x)
1518        x = self.squeeze(x)
1519
1520        return x
1521
1522
1523class AdaptiveMaxPool2d(Cell):
1524    r"""
1525    This operator applies a 2D adaptive max pooling to an input signal composed of multiple input planes.
1526    That is, for any input size, the size of the specified output is H x W.
1527    The number of output features is equal to the number of input planes.
1528
1529    The input and output data format can be "NCHW" and "CHW". N is the batch size, C is the number of channels,
1530    H is the feature height, and W is the feature width.
1531
1532    For max adaptive pool2d:
1533
1534    .. math::
1535
1536        \begin{align}
1537        h_{start} &= floor(i * H_{in} / H_{out})\\
1538        h_{end} &= ceil((i + 1) * H_{in} / H_{out})\\
1539        w_{start} &= floor(j * W_{in} / W_{out})\\
1540        w_{end} &= ceil((j + 1) * W_{in} / W_{out})\\
1541        Output(i,j) &= {\max Input[h_{start}:h_{end}, w_{start}:w_{end}]}
1542        \end{align}
1543
1544    Note:
1545        Ascend platform only supports float16 type for input.
1546
1547    Args:
1548        output_size (Union[int, tuple]): The target output size. `output_size` can be a tuple :math:`(H, W)`,
1549            or an int H for :math:`(H, H)`. :math:`H` and :math:`W` can be int or None.
1550            If it is None, it means the output size is the same as the input size.
1551        return_indices (bool): If `return_indices` is ``True`` , the indices of max value would be output.
1552            Default: ``False`` .
1553
1554    Inputs:
1555        - **input** (Tensor) - The input of AdaptiveMaxPool2d, which is a 3D or 4D tensor,
1556          with float16, float32 or float64 data type.
1557
1558    Outputs:
1559        Tensor, with the same type as the `input`.
1560        Shape of the output is :math:`input\_shape[:len(input\_shape) - len(out\_shape)] + out\_shape`.
1561
1562    Raises:
1563        TypeError: If `output_size` is not int or tuple.
1564        TypeError: If `input` is not a tensor.
1565        TypeError: If `return_indices` is not a bool.
1566        TypeError: If dtype of `input` is not float16, float32 or float64.
1567        ValueError: If `output_size` is a tuple and the length of `output_size` is not 2.
1568        ValueError: If the dimension of `input` is not NCHW or CHW.
1569
1570    Supported Platforms:
1571        ``Ascend`` ``GPU`` ``CPU``
1572
1573    Examples:
1574        >>> import mindspore as ms
1575        >>> import numpy as np
1576        >>> # case 1: output_size=(None, 2)
1577        >>> input = ms.Tensor(np.array([[[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]],
1578        ...                             [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]],
1579        ...                             [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]]]), ms.float32)
1580        >>> adaptive_max_pool_2d = ms.nn.AdaptiveMaxPool2d((None, 2))
1581        >>> output = adaptive_max_pool_2d(input)
1582        >>> print(output)
1583        [[[[2. 3.]
1584           [5. 6.]
1585           [8. 9.]]
1586          [[2. 3.]
1587           [5. 6.]
1588           [8. 9.]]
1589          [[2. 3.]
1590           [5. 6.]
1591           [8. 9.]]]]
1592        >>> # case 2: output_size=2
1593        >>> adaptive_max_pool_2d = ms.nn.AdaptiveMaxPool2d(2)
1594        >>> output = adaptive_max_pool_2d(input)
1595        >>> print(output)
1596        [[[[5. 6.]
1597           [8. 9.]]
1598          [[5. 6.]
1599           [8. 9.]]
1600          [[5. 6.]
1601           [8. 9.]]]]
1602        >>> # case 3: output_size=(1, 2)
1603        >>> adaptive_max_pool_2d = ms.nn.AdaptiveMaxPool2d((1, 2))
1604        >>> output = adaptive_max_pool_2d(input)
1605        >>> print(output)
1606        [[[[8. 9.]]
1607          [[8. 9.]]
1608          [[8. 9.]]]]
1609    """
1610
1611    def __init__(self, output_size, return_indices=False):
1612        """Initialize AdaptiveMaxPool2d."""
1613        super(AdaptiveMaxPool2d, self).__init__()
1614        validator.check_value_type('return_indices', return_indices, [bool], self.cls_name)
1615        self.adaptive_max_pool2d = AdaptiveMaxPool2D(output_size)
1616        self.return_indices = return_indices
1617
1618    def construct(self, input):
1619        output = self.adaptive_max_pool2d(input)
1620        if self.return_indices:
1621            return output
1622        return output[0]
1623
1624
1625class AdaptiveMaxPool3d(Cell):
1626    r"""
1627    Calculates the 3D adaptive max pooling for an input Tensor.
1628    That is, for any input size, the size of the specified output is :math:`(D, H, W)`.
1629
1630    Args:
1631        output_size (Union[int, tuple]): The specified output size, which is a positive integer that represents depth,
1632            height and width, or a tuple of three positive integers that represent depth, height and width respectively.
1633            If it is None, the output size and input size of the corresponding dimension are the same.
1634        return_indices (bool, optional): If `return_indices` is ``True`` , the indices of max value would be output.
1635            Otherwise, the indices will not be returned. Default: ``False`` .
1636
1637    Inputs:
1638        - **input** (Tensor) - Tensor, has shape of :math:`(C, D, H, W)` or :math:`(N, C, D, H, W)`.
1639
1640    Outputs:
1641        - **y** (Tensor) - Tensor, has the same number of dims and data type as the `input` .
1642        - **argmax** (Tensor) - Tensor, the indices of the maximum values along with the outputs, has the same shape as
1643          `y` and a dtype of int32. Return this only when `return_indices` is ``True`` .
1644
1645    Raises:
1646        TypeError: If `input` is not a Tensor.
1647        ValueError: If the dimensions number of `input` is not 4 or 5.
1648        TypeError: If dtype of `input` is not int, uint or float.
1649        ValueError: If `output_size` is neither an int nor a tuple with shape :math:`(3,)`.
1650
1651    Supported Platforms:
1652        ``GPU`` ``CPU``
1653
1654    Examples:
1655        >>> import mindspore as ms
1656        >>> import numpy as np
1657        >>> input = ms.Tensor(np.arange(0,36).reshape((1, 3, 3, 4)).astype(np.float32))
1658        >>> output_size = (1, 1, 2)
1659        >>> net = ms.nn.AdaptiveMaxPool3d(output_size, True)
1660        >>> output = net(input)
1661        >>> print(output[0].asnumpy())
1662        [[[[33. 35.]]]]
1663        >>> print(output[1].asnumpy())
1664        [[[[33 35]]]]
1665    """
1666
1667    def __init__(self, output_size, return_indices=False):
1668        """Initialize AdaptiveMaxPool3d."""
1669        super(AdaptiveMaxPool3d, self).__init__()
1670        if isinstance(output_size, int):
1671            output_size = (output_size, output_size, output_size)
1672        self.output_size = Tensor(output_size, dtype=mstype.int32)
1673        self.return_indices = return_indices
1674        self.adaptive_max_pool3d = AdaptiveMaxPool3D()
1675
1676    def construct(self, input):
1677        output = self.adaptive_max_pool3d(input, self.output_size)
1678        if self.return_indices:
1679            return output
1680        return output[0]
1681
1682
1683class FractionalMaxPool2d(Cell):
1684    r"""
1685    Applies the 2D FractionalMaxPool operatin over input. The output Tensor shape can be determined by either
1686    `output_size` or `output_ratio`, and the step size is determined by `_random_samples`. `output_size` will take
1687    effect when `output_size` and `output_ratio` are set at the same time.
1688    And `output_size` and `output_ratio` can not be ``None`` at the same time.
1689
1690    Refer to the paper `Fractional MaxPooling by Ben Graham <https://arxiv.org/abs/1412.6071>`_  for more details.
1691
1692    Args:
1693        kernel_size (Union[int, tuple[int]]): The size of kernel used to take the maximum value,
1694            is an int number that represents height and width of the kernel, or a tuple
1695            of two int numbers that represent height and width respectively.
1696            The value must be a positive integer.
1697        output_size (Union[int, tuple[int]], optional): The Shape of the target `output_size`,
1698            is a positive int that represents height and width, or a tuple of two positive integers that represent
1699            height and width respectively. The value must be a positive integer. If None, the shape of the target will
1700            be determined by `output_ratio`. Default: ``None`` .
1701        output_ratio (Union[float, tuple[float]], optional): The ratio of target output shape to input shape.
1702            Specifying the size of the output tensor by using a ratio of the input size.
1703            Data type : float16, float32, float64, and value is between (0, 1). If None, the shape of the target will be
1704            determined by `output_size`. Default: ``None`` .
1705        return_indices (bool, optional): Whether to return the indices of max value. Default: ``False`` .
1706        _random_samples (Tensor, optional): The random step of FractionalMaxPool2d, which is a 3D tensor.
1707            Tensor of data type: float16, float32, double, and value is between [0, 1).
1708            Supported shape :math:`(N, C, 2)` or :math:`(1, C, 2)`.
1709            Default: ``None``, the values of `_random_samples`
1710            will be randomly distributed using uniform distribution over an interval [0,1).
1711
1712    Inputs:
1713        - **input** (Tensor) - Tensor of shape :math:`(N, C, H_{in}, W_{in})` or :math:`(C, H_{in}, W_{in})`,
1714          with float16, float32, float64, int32, int64 data type.
1715
1716    Outputs:
1717        - **y** (Tensor) - Has the same type as the `input`.
1718          Has the shape :math:`(N, C, H_{out}, W_{out})` or :math:`(C, H_{out}, W_{out})` ,
1719          where :math:`(H_{out}, W_{out})` = `output_size`
1720          or :math:`(H_{out}, W_{out})` = `output_ratio` * :math:`(H_{in}, W_{in})`.
1721        - **argmax** (Tensor) - The indices along with the outputs, which is a Tensor, with the same shape as the
1722          `y` and int64 data type. It will be returned only when `return_indices` is True.
1723
1724    Raises:
1725        TypeError: If data type of `input` is not one of the following: float16, float32, float64, int32, int64.
1726        TypeError: If data type of `_random_samples` is not one of the following: float16, float32, float64.
1727        ValueError: If `kernel_size` is not a number and `kernel_size` is not a tuple of length 2.
1728        ValueError: If `output_size` is not a number and `output_size` is not a tuple of length 2.
1729        ValueError: If the sum of `kernel_size` , `output_size` and -1 is larger than the corresponding
1730                    dimension of `input`.
1731        ValueError: If the dimension of `_random_samples` is not 3.
1732        ValueError: if `output_size` and `output_ratio` are None at the same time.
1733        ValueError: If the first dimension size of `input` and `_random_samples` is not equal.
1734        ValueError: If the second dimension size of `input` and `_random_samples` is not equal.
1735        ValueError: If the third dimension size of `_random_samples` is not 2.
1736
1737    Supported Platforms:
1738        ``CPU``
1739
1740    Examples:
1741        >>> # the kernel_size is an int number and the output_size is a tuple.
1742        >>> import numpy as np
1743        >>> import mindspore as ms
1744        >>> input = ms.Tensor(np.array([0.3220, 0.9545, 0.7879, 0.0975, 0.3698,
1745        ...                            0.5135, 0.5740, 0.3435, 0.1895, 0.8764,
1746        ...                            0.9581, 0.4760, 0.9014, 0.8522, 0.3664,
1747        ...                            0.4980, 0.9673, 0.9879, 0.6988, 0.9022,
1748        ...                            0.9304, 0.1558, 0.0153, 0.1559, 0.9852]).reshape([1, 1, 5, 5]), ms.float32)
1749        >>> _random_samples = ms.Tensor(np.array([[[0.8, 0.8]]]), ms.float32)
1750        >>> net = ms.nn.FractionalMaxPool2d(kernel_size=2, output_size=(2, 2), _random_samples=_random_samples,
1751        ...                              return_indices=True)
1752        >>> y, argmax = net(input)
1753        >>> y
1754        [[[[0.9545 0.8764]
1755           [0.9673 0.9852]]]]
1756        >>> argmax
1757        [[[[ 1  9]
1758           [16 24]]]]
1759        >>> net = ms.nn.FractionalMaxPool2d(kernel_size=2, output_ratio=(0.5, 0.5), _random_samples=_random_samples,
1760        ...                              return_indices=True)
1761        >>> y, argmax = net(input)
1762        >>> print(y)
1763        [[[[0.9545 0.8764]
1764           [0.9673 0.9852]]]]
1765        >>> print(argmax)
1766        [[[[ 1  9]
1767           [16 24]]]]
1768    """
1769
1770    def __init__(self, kernel_size, output_size=None, output_ratio=None, return_indices=False, _random_samples=None):
1771        """Initialize FractionalMaxPool2d."""
1772        super(FractionalMaxPool2d, self).__init__()
1773        self.kernel_size = kernel_size
1774        self.output_size = output_size
1775        self.output_ratio = output_ratio
1776        self.return_indices = return_indices
1777        self._random_samples = _random_samples
1778
1779    def construct(self, input):
1780        return ops.fractional_max_pool2d(input, self.kernel_size, self.output_size, self.output_ratio,
1781                                         self.return_indices, self._random_samples)
1782
1783
1784class FractionalMaxPool3d(Cell):
1785    r"""
1786    Applies the 3D FractionalMaxPool operatin over `input`. The output Tensor shape can be determined by either
1787    `output_size` or `output_ratio`, and the step size is determined by `_random_samples`. `output_size` will take
1788    effect when `output_size` and `output_ratio` are set at the same time.
1789    And `output_size` and `output_ratio` can not be ``None`` at the same time.
1790
1791    Refer to the paper `Fractional MaxPooling by Ben Graham <https://arxiv.org/abs/1412.6071>`_  for more details.
1792
1793    The input and output data format can be "NCDHW". N is the batch size, C is the number of channels,
1794    D the feature depth, H is the feature height, and W is the feature width.
1795
1796    Args:
1797        kernel_size (Union[int, tuple[int]]): The size of kernel used to take the maximum value, is a positive int
1798            that represents depth, height and width of the kernel, or a tuple of three positive integers that represent
1799            depth, height and width respectively.
1800        output_size (Union[int, tuple[int]], optional): The shape of the target `output_size`,
1801            is an int number that represents depth, height and width, or a tuple of three positive integers that
1802            represents depth, height and width respectively. If ``None`` , the shape of the target will be determined
1803            by `output_ratio`. Default: ``None`` .
1804        output_ratio (Union[float, tuple[float]], optional): The ratio of target output shape to input shape.
1805            Specifying the size of the output tensor by using a ratio of the input size.
1806            Data type : float16, float32, float64, and value is between (0, 1). If ``None`` , the shape of the target
1807            will be determined by `output_size`.Default: ``None`` .
1808        return_indices (bool, optional): Whether to return the indices of max value. Default: ``False`` .
1809        _random_samples (Tensor, optional): The random step of FractionalMaxPool3d, which is a 3D tensor.
1810            Tensor of data type: float16, float32, double, and value is between [0, 1).
1811            Supported shape :math:`(N, C, 3)` or :math:`(1, C, 3)` . Default: ``None``, the values of `_random_samples`
1812            will be randomly distributed using uniform distribution over an interval [0,1).
1813
1814    Inputs:
1815        - **input** (Tensor) - The input of FractionalMaxPool3d, which is a 4D or 5D tensor.
1816          Tensor of data type : float16, float32, float64.
1817          Supported shape :math:`(N, C, D_{in}, H_{in}, W_{in})` or :math:`(C, D_{in}, H_{in}, W_{in})`.
1818
1819    Outputs:
1820        - **y** (Tensor) - A tensor, the output of FractionalMaxPool3d.
1821          Has the same data type with `input`.
1822          Has the shape :math:`(N, C, D_{out}, H_{out}, W_{out})` or :math:`(C, D_{out}, H_{out}, W_{out})` ,
1823          where :math:`(D_{out}, H_{out}, W_{out})` = `output_size`
1824          or :math:`(D_{out}, H_{out}, W_{out})` = `output_ratio` * :math:`(D_{in}, H_{in}, W_{in})` .
1825
1826        - **argmax** (Tensor) - The indices along with the outputs, which is a Tensor, with the same shape as the
1827          `y` and int32 data type. It will output only when `return_indices` is True.
1828
1829    Raises:
1830        TypeError: If `input` is not a 4D or 5D tensor.
1831        TypeError: If `_random_samples` is not a 3D tensor.
1832        TypeError: If data type of `imput_x` is not float16, float32, float64.
1833        TypeError: If dtype of `_random_samples` is not float16, float32, float64.
1834        TypeError: If dtype of `argmax` is not int32, int64.
1835        TypeError: if _random_samples to have the different dtypes as input.
1836        ValueError: If `output_size` is a tuple and if `output_size` length is not 3.
1837        ValueError: If `kernel_size` is a tuple and if `kernel_size` length is not 3.
1838        ValueError: If numbers in `output_size` or `kernel_size` is not positive.
1839        ValueError: if `output_size` and `output_ratio` are None at the same time.
1840        ValueError: If the first dimension size of `input` and `_random_samples` is not equal.
1841        ValueError: If the second dimension size of `input` and `_random_samples` is not equal.
1842        ValueError: If the third dimension size of `_random_samples` is not 3.
1843
1844    Supported Platforms:
1845        ``GPU`` ``CPU``
1846
1847    Examples:
1848        >>> import numpy as np
1849        >>> import mindspore as ms
1850        >>> x = ms.Tensor(np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
1851        ...            .reshape([1, 1, 2, 2, 4]), ms.float32)
1852        >>> _random_samples = ms.Tensor(np.array([0.7, 0.7, 0.7]).reshape([1, 1, 3]), ms.float32)
1853        >>> net = ms.nn.FractionalMaxPool3d(kernel_size=(1, 1, 1), output_size=(1, 1, 3),
1854        ...                              _random_samples=_random_samples, return_indices=True)
1855        >>> output, argmax = net(x)
1856        >>> print(output)
1857        [[[[[13. 14. 16.]]]]]
1858        >>> print(argmax)
1859        [[[[[12 13 15]]]]]
1860        >>> net = ms.nn.FractionalMaxPool3d(kernel_size=(1, 1, 1), output_ratio=(0.5, 0.5, 0.5),
1861        ...                              _random_samples=_random_samples, return_indices=True)
1862        >>> output, argmax = net(x)
1863        >>> print(output)
1864        [[[[[13. 16.]]]]]
1865        >>> print(argmax)
1866        [[[[[12 15]]]]]
1867    """
1868
1869    def __init__(self, kernel_size, output_size=None, output_ratio=None, return_indices=False, _random_samples=None):
1870        """Initialize FractionalMaxPool3d."""
1871        super(FractionalMaxPool3d, self).__init__()
1872        self.kernel_size = kernel_size
1873        self.output_size = output_size
1874        self.output_ratio = output_ratio
1875        self.return_indices = return_indices
1876        self._random_samples = _random_samples
1877
1878    def construct(self, input):
1879        return ops.fractional_max_pool3d(input, self.kernel_size, self.output_size, self.output_ratio,
1880                                         self.return_indices, self._random_samples)
1881
1882
1883class MaxUnpool1d(Cell):
1884    r"""
1885    Computes the inverse of :class:`mindspore.nn.MaxPool1d`.
1886
1887    MaxUnpool1d keeps the maximal value and set all position of non-maximal values to zero. Typically the input
1888    is of shape :math:`(N, C, H_{in})` or :math:`(C, H_{in})`, and the output is of shape
1889    :math:`(N, C, H_{out})` or :math:`(C, H_{out})`. The operation is as follows.
1890
1891
1892    .. math::
1893        \begin{array}{ll} \\
1894        H_{out} = (H_{in} - 1) \times stride[0] - 2 \times padding[0] + kernel\_size[0] \\
1895        \end{array}
1896
1897    Args:
1898        kernel_size (Union[int, tuple[int]]): The size of kernel used to take the maximum value.
1899        stride (Union[int, tuple[int]]): The distance of kernel moving,
1900            If stride is None, then stride equal to kernel_size. Default: ``None`` .
1901        padding (Union[int, tuple[int]]): The pad value to be filled. Default: ``0`` .
1902
1903    Inputs:
1904        - **x** (Tensor) - The input Tensor to invert.
1905          Tensor of shape :math:`(N, C, H_{in})` or :math:`(C, H_{in})`.
1906        - **indices** (Tensor) - Max values' index represented by the indices.
1907          Tensor of shape must be same with input 'x'.
1908          Values of indices must belong to :math:`[0, H_{in} - 1]`.
1909          Data type must be in int32 or int64.
1910        - **output_size** (tuple[int], optional) - The output size. Default: ``None`` .
1911          If output_size is ``None``, then the shape of output computed by kernel_size, stride and padding.
1912          If output_size is not ``None``, then output_size must be :math:`(N, C, H)` , :math:`(C, H)` or
1913          :math:`(H)` and output_size must belong to
1914          :math:`[(N, C, H_{out} - stride[0]), (N, C, H_{out} + stride[0])]`.
1915
1916    Outputs:
1917        Tensor, with shape :math:`(N, C, H_{out})` or :math:`(C, H_{out})`,
1918        with the same data type with `x`.
1919
1920    Raises:
1921        TypeError: If data type of `x` or `indices` is not supported.
1922        TypeError: If `kernel_size`, `stride` or `padding` is neither an int nor a tuple.
1923        ValueError: If numbers in `stride`, `padding` (also support 0 and (0)) or `kernel_size` is not positive.
1924        ValueError: If the shapes of `x` and `indices` are not equal.
1925        ValueError: If `x` whose length is not 2 or 3.
1926        ValueError: If type of `output_size` is not tuple.
1927        ValueError: If `output_size` whose length is not 0, 2 or 3.
1928        ValueError: If `output_size` is not close to output size computed by attr `kernel_size`, `stride`, `padding`.
1929
1930    Supported Platforms:
1931        ``GPU`` ``CPU``
1932
1933    Examples:
1934        >>> import mindspore as ms
1935        >>> import numpy as np
1936        >>> x = ms.Tensor(np.array([[2, 4, 6, 8]]).astype(np.float32))
1937        >>> indices = ms.Tensor(np.array([[1, 3, 5, 7]]).astype(np.int64))
1938        >>> maxunpool1d = ms.nn.MaxUnpool1d(kernel_size =2, stride=2, padding=0)
1939        >>> output = maxunpool1d(x, indices)
1940        >>> print(output.asnumpy())
1941        [[0. 2. 0. 4. 0. 6. 0. 8.]]
1942    """
1943
1944    def __init__(self, kernel_size, stride=None, padding=0):
1945        """Initialize MaxUnpool1d."""
1946        super(MaxUnpool1d, self).__init__()
1947        if stride is None:
1948            stride = kernel_size
1949        self.kernel_size = kernel_size
1950        self.stride = stride
1951        self.padding = padding
1952
1953    def construct(self, x, indices, output_size=None):
1954        if output_size is None:
1955            output_size = ()
1956        else:
1957            if not isinstance(output_size, tuple):
1958                raise ValueError(f"For MaxUnpool1d, output_size must be tuple, but type {type(output_size)}.")
1959            if not output_size:
1960                raise ValueError(f"For MaxUnpool1d, the length of output_size must be positive, but got 0.")
1961        out = ops.max_unpool1d(x, indices, self.kernel_size, stride=self.stride, padding=self.padding,
1962                               output_size=output_size)
1963        return out
1964
1965
1966class MaxUnpool2d(Cell):
1967    r"""
1968    Computes the inverse of :class:`mindspore.nn.MaxPool2d`.
1969
1970    MaxUnpool2d keeps the maximal value and set all position of non-maximal values to zero. Typically the input
1971    is of shape :math:`(N, C, H_{in}, W_{in})` or :math:`(C, H_{in}, W_{in})`, and the output is of
1972    shape :math:`(N, C, H_{out}, W_{out})` or :math:`(C, H_{out}, W_{out})`. The operation is as follows.
1973
1974    .. math::
1975        \begin{array}{ll} \\
1976        H_{out} = (H_{in} - 1) \times stride[0] - 2 \times padding[0] + kernel\_size[0] \\
1977        W_{out} = (W_{in} - 1) \times stride[1] - 2 \times padding[1] + kernel\_size[1] \\
1978        \end{array}
1979
1980    Args:
1981        kernel_size (Union[int, tuple[int]]): The size of kernel used to take the maximum value,
1982            an int number that represents height and width of the kernel, or a tuple
1983            of two int numbers that represent height and width respectively.
1984        stride (Union[int, tuple[int]]): The distance of kernel moving, an int number that represents
1985            the height and width of movement are both stride, or a tuple of two int numbers that
1986            represent height and width of movement respectively.
1987            If stride is ``None``, then stride equal to kernel_size. Default: ``None`` .
1988        padding (Union[int, tuple[int]]): The pad value to be filled. Default: ``0`` . If `padding` is an integer,
1989            the paddings of height and width are the same, equal to padding. If `padding` is a tuple of two
1990            integers, the padding of height and width equal to padding[0] and padding[1] correspondingly.
1991
1992    Inputs:
1993        - **x** (Tensor) - The input Tensor to invert.
1994          Tensor of shape :math:`(N, C, H_{in}, W_{in})` or :math:`(C, H_{in}, W_{in})`.
1995        - **indices** (Tensor) - Max values' index represented by the indices.
1996          Tensor of shape must be same with input 'x'.
1997          Values of indices must belong to :math:`[0, H_{in} \times W_{in} - 1]`.
1998          Data type must be in int32 or int64.
1999        - **output_size** (tuple[int], optional) - The output size. Default: ``None`` .
2000          If output_size is ``None``, then the shape of output computed by kernel_size, stride and padding.
2001          If output_size is not ``None``, then output_size must be :math:`(N, C, H, W)`, :math:`(C, H, W)` or
2002          :math:`(H, W)` and output_size must belong to
2003          :math:`[(N, C, H_{out} - stride[0], W_{out} - stride[1]), (N, C, H_{out} + stride[0], W_{out} + stride[1])]`.
2004
2005    Outputs:
2006        Tensor, with shape :math:`(N, C, H_{out}, W_{out})` or :math:`(C, H_{out}, W_{out})`,
2007        with the same data type with `x`.
2008
2009    Raises:
2010        TypeError: If data type of `x` or `indices` is not supported.
2011        TypeError: If `kernel_size`, `stride` or `padding` is neither an int nor a tuple.
2012        ValueError: If numbers in `stride`, `padding` (also support 0 and (0, 0)) or `kernel_size` is not positive.
2013        ValueError: If the shape of `x` and `indices` are not equal.
2014        ValueError: If `kernel_size`, `stride` or `padding` is a tuple whose length is not equal to 2.
2015        ValueError: If `x` whose length is not 3 or 4.
2016        ValueError: If `output_size` whose type is not tuple.
2017        ValueError: If `output_size` whose length is not 0, 3 or 4.
2018        ValueError: If `output_size` is not close to output size computed by attr `kernel_size`, `stride`, `padding`.
2019
2020    Supported Platforms:
2021        ``GPU`` ``CPU``
2022
2023    Examples:
2024        >>> import mindspore as ms
2025        >>> import numpy as np
2026        >>> x = ms.Tensor(np.array([[[[0, 1], [8, 9]]]]).astype(np.float32))
2027        >>> indices = ms.Tensor(np.array([[[[0, 1], [2, 3]]]]).astype(np.int64))
2028        >>> maxunpool2d = ms.nn.MaxUnpool2d(kernel_size=1, stride=1, padding=0)
2029        >>> output = maxunpool2d(x, indices)
2030        >>> print(output.asnumpy())
2031        [[[[0. 1.]
2032           [8. 9.]]]]
2033    """
2034
2035    def __init__(self, kernel_size, stride=None, padding=0):
2036        """Initialize MaxUnpool2d."""
2037        super(MaxUnpool2d, self).__init__()
2038        if stride is None:
2039            stride = kernel_size
2040        self.kernel_size = kernel_size
2041        self.stride = stride
2042        self.padding = padding
2043
2044    def construct(self, x, indices, output_size=None):
2045        if output_size is None:
2046            output_size = ()
2047        else:
2048            if not isinstance(output_size, tuple):
2049                raise ValueError(f"For MaxUnpool2d, output_size must be tuple, but type {type(output_size)}.")
2050            if not output_size:
2051                raise ValueError(f"For MaxUnpool2d, the length of output_size must be positive, but got 0.")
2052        out = ops.max_unpool2d(x, indices, self.kernel_size, stride=self.stride, padding=self.padding,
2053                               output_size=output_size)
2054        return out
2055
2056
2057class MaxUnpool3d(Cell):
2058    r"""
2059    Computes the inverse of :class:`mindspore.nn.MaxPool3d`.
2060
2061    MaxUnpool3d keeps the maximal value and set all position of non-maximal values to zero.
2062    Typically the input is of shape :math:`(N, C, D_{in}, H_{in}, W_{in})` or :math:`(C, D_{in}, H_{in}, W_{in})`,
2063    and the output is of shape :math:`(N, C, D_{out}, H_{out}, W_{out})` or :math:`(C, D_{out}, H_{out}, W_{out})`.
2064    The operation is as follows.
2065
2066    .. math::
2067        \begin{array}{ll} \\
2068        D_{out} = (D_{in} - 1) \times stride[0] - 2 \times padding[0] + kernel\_size[0] \\
2069        H_{out} = (H_{in} - 1) \times stride[1] - 2 \times padding[1] + kernel\_size[1] \\
2070        W_{out} = (W_{in} - 1) \times stride[2] - 2 \times padding[2] + kernel\_size[2] \\
2071        \end{array}
2072
2073    Args:
2074        kernel_size (Union[int, tuple[int]]): The size of kernel used to take the maximum value,
2075            an int number that represents depth, height and width of the kernel, or a tuple
2076            of three int numbers that represent depth, height and width respectively.
2077        stride (Union[int, tuple[int]]): The distance of kernel moving, an int number that represents
2078            the depth, height and width of movement are both stride, or a tuple of three int numbers that
2079            represent depth, height and width of movement respectively.
2080            If stride is ``None``, then stride equal to kernel_size. Default: ``None`` .
2081        padding (Union[int, tuple[int]]): The pad value to be filled. Default: ``0`` . If `padding` is an integer,
2082            the paddings of depth, height and width are the same, equal to padding. If `padding` is a tuple of three
2083            integers, the padding of depth, height and width equal to padding[0], padding[1] and padding[2]
2084            correspondingly.
2085
2086    Inputs:
2087        - **x** (Tensor) - The input Tensor to invert.
2088          Tensor of shape :math:`(N, C, D_{in}, H_{in}, W_{in})` or :math:`(C, D_{in}, H_{in}, W_{in})`.
2089        - **indices** (Tensor) - Max values' index represented by the indices.
2090          Tensor of shape must be same with input 'x'.
2091          Values of indices must belong to :math:`[0, D_{in} \times H_{in} \times W_{in} - 1]`.
2092          Data type must be in int32 or int64.
2093        - **output_size** (tuple[int], optional) - The output size. Default: ``None`` .
2094          If output_size is ``None``, then the shape of output computed by kernel_size, stride and padding.
2095          If output_size is not ``None``, then output_size must be :math:`(N, C, D, H, W)` , :math:`(C, D, H, W)` or
2096          :math:`(D, H, W)` and output_size must belong to
2097          :math:`[(N, C, D_{out} - stride[0], H_{out} - stride[1], W_{out} - stride[2]),
2098          (N, C, D_{out} + stride[0], H_{out} + stride[1], W_{out} + stride[2])]`.
2099
2100    Outputs:
2101        Tensor, with shape :math:`(N, C, D_{out}, H_{out}, W_{out})` or :math:`(C, D_{out}, H_{out}, W_{out})`,
2102        with the same data type with `x`.
2103
2104    Raises:
2105        TypeError: If data type of `x` or `indices` is not supported.
2106        TypeError: If `kernel_size`, `stride` or `padding` is neither an int nor a tuple.
2107        ValueError: If numbers in `stride` or `padding` (also support 0 and (0, 0, 0)) or `kernel_size` is not positive.
2108        ValueError: If the shape of `x` and `indices` are not equal.
2109        ValueError: If `kernel_size`, `stride` or `padding` is a tuple whose length is not equal to 3.
2110        ValueError: If `x` whose length is not 4 or 5.
2111        ValueError: If `output_size` whose length is not 0, 4 or 5.
2112        ValueError: If `output_size` whose type is not tuple.
2113        ValueError: If `output_size` is not close to output size computed by attr `kernel_size`, `stride`, `padding`.
2114
2115    Supported Platforms:
2116        ``GPU`` ``CPU``
2117
2118    Examples:
2119        >>> import mindspore as ms
2120        >>> import numpy as np
2121        >>> x = ms.Tensor(np.array([[[[[0, 1], [8, 9]]]]]).astype(np.float32))
2122        >>> indices= ms.Tensor(np.array([[[[[0, 1], [2, 3]]]]]).astype(np.int64))
2123        >>> maxunpool3d = ms.nn.MaxUnpool3d(kernel_size=1, stride=1, padding=0)
2124        >>> output = maxunpool3d(x, indices)
2125        >>> print(output.asnumpy())
2126        [[[[[0. 1.]
2127            [8. 9.]]]]]
2128    """
2129
2130    def __init__(self, kernel_size, stride=None, padding=0):
2131        super(MaxUnpool3d, self).__init__()
2132        if stride is None:
2133            stride = kernel_size
2134        self.kernel_size = kernel_size
2135        self.stride = stride
2136        self.padding = padding
2137
2138    def construct(self, x, indices, output_size=None):
2139        if output_size is None:
2140            output_size = ()
2141        else:
2142            if not isinstance(output_size, tuple):
2143                raise ValueError(f"For MaxUnpool3d, output_size must be tuple, but type {type(output_size)}.")
2144            if not output_size:
2145                raise ValueError(f"For MaxUnpool3d, the length of output_size must be positive, but got 0.")
2146        out = ops.max_unpool3d(x, indices, self.kernel_size, stride=self.stride, padding=self.padding,
2147                               output_size=output_size)
2148        return out
2149