def add_pooling(
        self,
        name,
        height,
        width,
        stride_height,
        stride_width,
        layer_type,
        padding_type,
        input_name,
        output_name,
        exclude_pad_area=True,
        is_global=False,
        padding_top=0,
        padding_bottom=0,
        padding_left=0,
        padding_right=0,
        same_padding_asymmetry_mode="BOTTOM_RIGHT_HEAVY",
    ):
        """
        Add a pooling layer to the model that performs spatial pooling.
        Refer to the ``PoolingLayerParams`` message in the specification
        (NeuralNetwork.proto) for more details.

        Parameters
        ----------

        name: str
            The name of this layer.

        height: int
            Height of pooling region.

        width: int
            Width of pooling region.

        stride_height: int
            Stride along the height direction.

        stride_width: int
            Stride along the width direction.

        layer_type: str
            Type of pooling performed. Can either be ``'MAX'``, ``'AVERAGE'``, or ``'L2'``.

        padding_type: str
            Option for the type of padding and output blob shape. Can be either
            ``'VALID'``, ``'SAME'``, or ``'INCLUDE_LAST_PIXEL'``.

        input_name: str
            The input blob name of this layer.

        output_name: str
            The output blob name of this layer.

        exclude_pad_area: boolean
            Whether to exclude padded area in the ``'AVERAGE'`` pooling operation,
            default: true. This flag is only used with average pooling.

            - If True, the value of the padded area will be excluded.
            - If False, the padded area will be included.

        is_global: boolean
            Whether the pooling operation is global. Defaults to False.

            - If True, the pooling operation is global. The pooling region
              is of the same size of the input blob.
              Parameters ``height``, ``width``, ``stride_height``, and ``stride_width`` will be ignored.
            - If False, the pooling operation is not global.

        padding_top, padding_bottom, padding_left, padding_right: int
            Values of height (top, bottom) and width (left, right) padding
            to be used if padding type is ``"VALID"`` or ``"INCLUDE_LAST_PIXEL"``.

        same_padding_asymmetry_mode: str.
            Type of asymmetric padding to be used when ``padding_type = 'SAME'``.
            Can be either ``'BOTTOM_RIGHT_HEAVY'`` or ``'TOP_LEFT_HEAVY'``.

        See Also
        --------
        add_pooling3d, add_convolution, add_activation
        """

        # Create spec layer
        spec_layer = self._add_generic_layer(name, [input_name], [output_name])
        spec_layer_params = spec_layer.pooling

        # Set the parameters
        spec_layer_params.type = _proto.NeuralNetwork_pb2.PoolingLayerParams.PoolingType.Value(
            layer_type.upper()
        )

        padding_type = (
            padding_type.upper()
            if isinstance(padding_type, str)
            else padding_type
        )
        same_padding_asymmetry_mode = (
            same_padding_asymmetry_mode.upper()
            if isinstance(same_padding_asymmetry_mode, str)
            else same_padding_asymmetry_mode
        )

        if padding_type == "VALID":
            height_border = spec_layer_params.valid.paddingAmounts.borderAmounts.add()
            height_border.startEdgeSize = padding_top
            height_border.endEdgeSize = padding_bottom
            width_border = spec_layer_params.valid.paddingAmounts.borderAmounts.add()
            width_border.startEdgeSize = padding_left
            width_border.endEdgeSize = padding_right
        elif padding_type == "SAME":
            if not (
                same_padding_asymmetry_mode == "BOTTOM_RIGHT_HEAVY"
                or same_padding_asymmetry_mode == "TOP_LEFT_HEAVY"
            ):
                raise ValueError(
                    "Invalid value %d of same_padding_asymmetry_mode parameter"
                    % same_padding_asymmetry_mode
                )
            spec_layer_params.same.asymmetryMode = (
                _proto.NeuralNetwork_pb2.SamePadding.SamePaddingMode.Value(
                    same_padding_asymmetry_mode
                )
            )
        elif padding_type == "INCLUDE_LAST_PIXEL":
            if padding_top != padding_bottom or padding_left != padding_right:
                raise ValueError(
                    "Only symmetric padding is supported with the INCLUDE_LAST_PIXEL padding type"
                )
            spec_layer_params.includeLastPixel.paddingAmounts.append(padding_top)
            spec_layer_params.includeLastPixel.paddingAmounts.append(padding_left)
        else:
            raise ValueError("Unknown padding_type %s in pooling" % padding_type)

        spec_layer_params.kernelSize.append(height)
        spec_layer_params.kernelSize.append(width)
        spec_layer_params.stride.append(stride_height)
        spec_layer_params.stride.append(stride_width)
        spec_layer_params.avgPoolExcludePadding = exclude_pad_area
        spec_layer_params.globalPooling = is_global
        return spec_layer

        Add a pooling layer to the model that performs spatial pooling.
        Refer to the ``PoolingLayerParams`` message in the specification
        (NeuralNetwork.proto) for more details.

        Parameters
        ----------

        name: str
            The name of this layer.

        height: int
            Height of pooling region.

        width: int
            Width of pooling region.

        stride_height: int
            Stride along the height direction.

        stride_width: int
            Stride along the width direction.

        layer_type: str
            Type of pooling performed. Can either be ``'MAX'``, ``'AVERAGE'``, or ``'L2'``.

        padding_type: str
            Option for the type of padding and output blob shape. Can be either
            ``'VALID'``, ``'SAME'``, or ``'INCLUDE_LAST_PIXEL'``.

        input_name: str
            The input blob name of this layer.

        output_name: str
            The output blob name of this layer.

        exclude_pad_area: boolean
            Whether to exclude padded area in the ``'AVERAGE'`` pooling operation,
            default: true. This flag is only used with average pooling.

            - If True, the value of the padded area will be excluded.
            - If False, the padded area will be included.

        is_global: boolean
            Whether the pooling operation is global. Defaults to False.

            - If True, the pooling operation is global. The pooling region
              is of the same size of the input blob.
              Parameters ``height``, ``width``, ``stride_height``, and ``stride_width`` will be ignored.
            - If False, the pooling operation is not global.

        padding_top, padding_bottom, padding_left, padding_right: int
            Values of height (top, bottom) and width (left, right) padding
            to be used if padding type is ``"VALID"`` or ``"INCLUDE_LAST_PIXEL"``.

        same_padding_asymmetry_mode: str.
            Type of asymmetric padding to be used when ``padding_type = 'SAME'``.
            Can be either ``'BOTTOM_RIGHT_HEAVY'`` or ``'TOP_LEFT_HEAVY'``.

        See Also
        --------
        add_pooling3d, add_convolution, add_activation
        
coremltools/models/neural_network/builder.py