@@ -0,0 +1,126 @@
Loading
1 +
# -*- encoding: utf-8 -*-
2 +
# pylint: disable=E0203,E1101,C0111
3 +
"""
4 +
@file
5 +
@brief Runtime operator.
6 +
"""
7 +
import itertools
8 +
import numpy
9 +
from ..shape_object import ShapeObjectFct
10 +
from ._op import OpRun
11 +
from .op_max_pool_ import MaxPoolFloat, MaxPoolDouble  # pylint: disable=E0611
12 +
13 +
14 +
def _pool_get_pad_shape(auto_pad, input_spatial_shape, kernel_spatial_shape,
15 +
                        strides_spatial, output_spatial_shape):
16 +
    pad_shape = [0] * len(input_spatial_shape)
17 +
    if auto_pad in (b'SAME_UPPER', b'SAME_LOWER'):
18 +
        for i in range(len(input_spatial_shape)):  # pylint: disable=C0200
19 +
            pad_shape[i] = (output_spatial_shape[i] - 1) * strides_spatial[i] + \
20 +
                kernel_spatial_shape[i] - input_spatial_shape[i]
21 +
    elif auto_pad == b'VALID':
22 +
        pass
23 +
    return pad_shape
24 +
25 +
26 +
def _pool_get_output_shape(auto_pad, input_spatial_shape, kernel_spatial_shape,
27 +
                           strides_spatial):
28 +
    out_shape = [0] * len(input_spatial_shape)
29 +
    if auto_pad in (b'SAME_UPPER', b'SAME_LOWER'):
30 +
        for i in range(len(input_spatial_shape)):  # pylint: disable=C0200
31 +
            out_shape[i] = int(
32 +
                numpy.ceil(
33 +
                    float(input_spatial_shape[i]) / float(strides_spatial[i])))
34 +
    elif auto_pad == b'VALID':
35 +
        for i in range(len(input_spatial_shape)):  # pylint: disable=C0200
36 +
            out_shape[i] = int(
37 +
                numpy.ceil(float(input_spatial_shape[i] - (kernel_spatial_shape[i] - 1)) /
38 +
                           float(strides_spatial[i])))
39 +
    return out_shape
40 +
41 +
42 +
def _pool_impl(padded, x_shape, kernel_shape, strides_shape,
43 +
               out_shape, pad_shape, pooling_type,
44 +
               count_include_pad=0):
45 +
    spatial_size = len(x_shape) - 2
46 +
    y = numpy.zeros([x_shape[0], x_shape[1]] + list(out_shape))
47 +
48 +
    for shape in itertools.product(
49 +
            range(x_shape[0]), range(x_shape[1]),
50 +
            *[range(int((x_shape[i + 2] + pad_shape[i] - kernel_shape[i]) /
51 +
                        strides_shape[i] + 1))
52 +
              for i in range(spatial_size)]):
53 +
        window = padded[shape[0], shape[1]]
54 +
        window_vals = numpy.array(
55 +
            [window[i] for i in list(
56 +
                itertools.product(
57 +
                    *[range(strides_shape[i] * shape[i + 2],
58 +
                            strides_shape[i] * shape[i + 2] + kernel_shape[i])
59 +
                      for i in range(spatial_size)]))])
60 +
        if pooling_type == b'AVG':
61 +
            f = numpy.average
62 +
        elif pooling_type == b'MAX':
63 +
            f = numpy.max
64 +
        else:
65 +
            raise NotImplementedError(  # pragma: no cover
66 +
                "Pooling type '{}' does not support. Should be AVG, MAX."
67 +
                "".format(pooling_type))
68 +
69 +
        if count_include_pad == 1 and pooling_type == b'AVG':
70 +
            y[shape] = f(window_vals)
71 +
        else:
72 +
            y[shape] = f(window_vals[numpy.where(~numpy.isnan(window_vals))])
73 +
    return y.astype(numpy.float32)
74 +
75 +
76 +
class MaxPool(OpRun):
77 +
78 +
    atts = {'auto_pad': b'NOTSET', 'ceil_mode': 0, 'dilations': [],
79 +
            'kernel_shape': [], 'pads': [], 'storage_order': 0,
80 +
            'strides': []}
81 +
82 +
    def __init__(self, onnx_node, desc=None, **options):
83 +
        OpRun.__init__(self, onnx_node, desc=desc,
84 +
                       expected_attributes=MaxPool.atts,
85 +
                       **options)
86 +
        self.auto_pad_ = self.auto_pad.decode('ascii')
87 +
        self.nb_outputs = len(onnx_node.output)
88 +
        self._init()
89 +
90 +
    def _init(self):
91 +
        self.rt32_ = MaxPoolFloat()
92 +
        self.rt64_ = MaxPoolDouble()
93 +
        for rt in [self.rt32_, self.rt64_]:
94 +
            rt.init(self.auto_pad,
95 +
                    numpy.array(self.dilations, dtype=numpy.int64),
96 +
                    self.ceil_mode,
97 +
                    self.storage_order,
98 +
                    numpy.array(self.kernel_shape, dtype=numpy.int64),
99 +
                    numpy.array(self.pads, dtype=numpy.int64),
100 +
                    numpy.array(self.strides, dtype=numpy.int64))
101 +
102 +
    def _run(self, X):  # pylint: disable=W0221
103 +
        if X.dtype == numpy.float32:
104 +
            res = self.rt32_.compute(X)
105 +
        else:
106 +
            res = self.rt64_.compute(X)
107 +
        if self.nb_outputs == 1:
108 +
            return res[:1]
109 +
        return res
110 +
111 +
    def _infer_shapes(self, X):  # pylint: disable=W0221
112 +
113 +
        def compute_shape1(xshape):
114 +
            xs = numpy.ones(xshape, dtype=numpy.float32)
115 +
            res, _ = self.rt32_.compute(xs)
116 +
            return res.shape
117 +
118 +
        def compute_shape2(xshape):
119 +
            xs = numpy.ones(xshape, dtype=numpy.float32)
120 +
            _, res2 = self.rt32_.compute(xs)
121 +
            return res2.shape
122 +
123 +
        if self.nb_outputs == 1:
124 +
            return (ShapeObjectFct(compute_shape1, X, name="MaxPool", dtype=X.dtype), )
125 +
        return (ShapeObjectFct(compute_shape1, X, name="MaxPool", dtype=X.dtype),
126 +
                ShapeObjectFct(compute_shape2, X, name="MaxPool", dtype=X.dtype))

@@ -56,6 +56,7 @@
Loading
56 56
from .op_lp_normalization import LpNormalization
57 57
from .op_matmul import MatMul
58 58
from .op_max import Max
59 +
from .op_max_pool import MaxPool
59 60
from .op_mean import Mean
60 61
from .op_min import Min
61 62
from .op_mul import Mul

@@ -1018,7 +1018,7 @@
Loading
1018 1018
                print(oinf2)
1019 1019
        """
1020 1020
        def clean_name(name):
1021 -
            return name.replace(":", "_").replace('.', '_')
1021 +
            return name.replace(":", "_").replace('.', '_').replace('/', '_')
1022 1022
1023 1023
        # inits
1024 1024
        inputs = self.input_names

@@ -41,6 +41,6 @@
Loading
41 41
42 42
    def _infer_shapes(self, data, pads, constant_value=None):  # pylint: disable=E0202,W0221
43 43
        """
44 -
        Returns the same shape by default.
44 +
        Returns an empty shape by default.
45 45
        """
46 46
        return (ShapeObject(None, data.dtype), )
Files Coverage
mlprodict 91.44%
Project Totals (227 files) 91.44%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading