Skip to content

Commit b22041c

Browse files
karljanghouseroad
authored andcommitted
Add dilation attribute to MaxPool (onnx#1864)
* add dialation attribute to MaxPool * add shape inference test for dilated MaxPool * regen docs * fix wrong formatting * update test coverage * fix dilation parameter for maxpool * add dilation case for MaxPool op * fix formatting * regen docs
1 parent b29e78a commit b22041c

File tree

9 files changed

+149
-15
lines changed

9 files changed

+149
-15
lines changed

docs/Changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -9574,6 +9574,8 @@ This version of the operator has been available since version 10 of the default
95749574
<dd>auto_pad must be either NOTSET, SAME_UPPER, SAME_LOWER or VALID. Where default value is NOTSET, which means explicit padding is used. SAME_UPPER or SAME_LOWER mean pad the input so that the output size match the input.In case of odd number add the extra padding at the end for SAME_UPPER and at the beginning for SAME_LOWER. VALID mean no padding. DEPRECATION NOTE: auto_pad is only intended to support legacy uses, and for framework authors, one is explicitly encouraged to use explicit padding specified in the pads attribute.</dd>
95759575
<dt><tt>ceil_mode</tt> : int (default is 0)</dt>
95769576
<dd>Wether to use ceil or floor (default) to compute the output shape.</dd>
9577+
<dt><tt>dilations</tt> : list of ints</dt>
9578+
<dd>Dilation value along each axis of filter.</dd>
95779579
<dt><tt>kernel_shape</tt> : list of ints (required)</dt>
95789580
<dd>The size of the kernel along each axis.</dd>
95799581
<dt><tt>pads</tt> : list of ints</dt>

docs/Operators.md

+34
Original file line numberDiff line numberDiff line change
@@ -6199,6 +6199,8 @@ Other versions of this operator: <a href="Changelog.md#MaxPool-1">MaxPool-1</a>,
61996199
<dd>auto_pad must be either NOTSET, SAME_UPPER, SAME_LOWER or VALID. Where default value is NOTSET, which means explicit padding is used. SAME_UPPER or SAME_LOWER mean pad the input so that the output size match the input.In case of odd number add the extra padding at the end for SAME_UPPER and at the beginning for SAME_LOWER. VALID mean no padding. DEPRECATION NOTE: auto_pad is only intended to support legacy uses, and for framework authors, one is explicitly encouraged to use explicit padding specified in the pads attribute.</dd>
62006200
<dt><tt>ceil_mode</tt> : int (default is 0)</dt>
62016201
<dd>Wether to use ceil or floor (default) to compute the output shape.</dd>
6202+
<dt><tt>dilations</tt> : list of ints</dt>
6203+
<dd>Dilation value along each axis of filter.</dd>
62026204
<dt><tt>kernel_shape</tt> : list of ints (required)</dt>
62036205
<dd>The size of the kernel along each axis.</dd>
62046206
<dt><tt>pads</tt> : list of ints</dt>
@@ -6325,6 +6327,38 @@ expect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_default')
63256327
</details>
63266328

63276329

6330+
<details>
6331+
<summary>maxpool_2d_dilations</summary>
6332+
6333+
```python
6334+
"""
6335+
input_shape: [1, 1, 4, 4]
6336+
output_shape: [1, 1, 2, 2]
6337+
"""
6338+
node = onnx.helper.make_node(
6339+
'MaxPool',
6340+
inputs=['x'],
6341+
outputs=['y'],
6342+
kernel_shape=[2, 2],
6343+
strides=[1, 1],
6344+
dilations=[2, 2]
6345+
)
6346+
x = np.array([[[
6347+
[1, 2, 3, 4],
6348+
[5, 6, 7, 8],
6349+
[9, 10, 11, 12],
6350+
[13, 14, 15, 16],
6351+
]]]).astype(np.float32)
6352+
y = np.array([[[
6353+
[11, 12],
6354+
[15, 16]]]]).astype(np.float32)
6355+
6356+
expect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_dilations')
6357+
```
6358+
6359+
</details>
6360+
6361+
63286362
<details>
63296363
<summary>maxpool_2d_pads</summary>
63306364

docs/TestCoverage.md

+49-10
Original file line numberDiff line numberDiff line change
@@ -3142,7 +3142,7 @@ expect(node, inputs=[data_0, data_1], outputs=[result],
31423142

31433143

31443144
### MaxPool
3145-
There are 13 test cases, listed as following:
3145+
There are 14 test cases, listed as following:
31463146
<details>
31473147
<summary>maxpool_1d_default</summary>
31483148

@@ -3224,6 +3224,36 @@ y = pool(padded, x_shape, kernel_shape, strides, out_shape, (0, 0), 'MAX')
32243224
expect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_default')
32253225
```
32263226

3227+
</details>
3228+
<details>
3229+
<summary>maxpool_2d_dilations</summary>
3230+
3231+
```python
3232+
"""
3233+
input_shape: [1, 1, 4, 4]
3234+
output_shape: [1, 1, 2, 2]
3235+
"""
3236+
node = onnx.helper.make_node(
3237+
'MaxPool',
3238+
inputs=['x'],
3239+
outputs=['y'],
3240+
kernel_shape=[2, 2],
3241+
strides=[1, 1],
3242+
dilations=[2, 2]
3243+
)
3244+
x = np.array([[[
3245+
[1, 2, 3, 4],
3246+
[5, 6, 7, 8],
3247+
[9, 10, 11, 12],
3248+
[13, 14, 15, 16],
3249+
]]]).astype(np.float32)
3250+
y = np.array([[[
3251+
[11, 12],
3252+
[15, 16]]]]).astype(np.float32)
3253+
3254+
expect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_dilations')
3255+
```
3256+
32273257
</details>
32283258
<details>
32293259
<summary>maxpool_2d_pads</summary>
@@ -7128,10 +7158,11 @@ bias: 1
71287158
size: 1
71297159
</details>
71307160
<details>
7131-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7161+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
71327162

71337163
auto_pad: 0
71347164
ceil_mode: 0
7165+
dilations: 0
71357166
kernel_shape: 1
71367167
pads: 2
71377168
storage_order: 0
@@ -7201,10 +7232,11 @@ bias: 1
72017232
size: 1
72027233
</details>
72037234
<details>
7204-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7235+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
72057236

72067237
auto_pad: 0
72077238
ceil_mode: 0
7239+
dilations: 0
72087240
kernel_shape: 1
72097241
pads: 3
72107242
storage_order: 0
@@ -7279,10 +7311,11 @@ bias: 1
72797311
size: 1
72807312
</details>
72817313
<details>
7282-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7314+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
72837315

72847316
auto_pad: 0
72857317
ceil_mode: 0
7318+
dilations: 0
72867319
kernel_shape: 1
72877320
pads: 3
72887321
storage_order: 0
@@ -7357,10 +7390,11 @@ bias: 1
73577390
size: 1
73587391
</details>
73597392
<details>
7360-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7393+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
73617394

73627395
auto_pad: 0
73637396
ceil_mode: 0
7397+
dilations: 0
73647398
kernel_shape: 1
73657399
pads: 3
73667400
storage_order: 0
@@ -7435,10 +7469,11 @@ bias: 1
74357469
size: 1
74367470
</details>
74377471
<details>
7438-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7472+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
74397473

74407474
auto_pad: 0
74417475
ceil_mode: 0
7476+
dilations: 0
74427477
kernel_shape: 1
74437478
pads: 3
74447479
storage_order: 0
@@ -7513,10 +7548,11 @@ bias: 1
75137548
size: 1
75147549
</details>
75157550
<details>
7516-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7551+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
75177552

75187553
auto_pad: 0
75197554
ceil_mode: 0
7555+
dilations: 0
75207556
kernel_shape: 1
75217557
pads: 3
75227558
storage_order: 0
@@ -7596,10 +7632,11 @@ bias: 1
75967632
size: 1
75977633
</details>
75987634
<details>
7599-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7635+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
76007636

76017637
auto_pad: 0
76027638
ceil_mode: 0
7639+
dilations: 0
76037640
kernel_shape: 1
76047641
pads: 3
76057642
storage_order: 0
@@ -7679,10 +7716,11 @@ bias: 1
76797716
size: 1
76807717
</details>
76817718
<details>
7682-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7719+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
76837720

76847721
auto_pad: 0
76857722
ceil_mode: 0
7723+
dilations: 0
76867724
kernel_shape: 2
76877725
pads: 3
76887726
storage_order: 0
@@ -7762,10 +7800,11 @@ bias: 2
77627800
size: 1
77637801
</details>
77647802
<details>
7765-
<summary>MaxPool: 3 out of 6 attributes covered</summary>
7803+
<summary>MaxPool: 3 out of 7 attributes covered</summary>
77667804

77677805
auto_pad: 0
77687806
ceil_mode: 0
7807+
dilations: 0
77697808
kernel_shape: 2
77707809
pads: 3
77717810
storage_order: 0

onnx/backend/test/case/node/maxpool.py

+26
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,29 @@ def export_maxpool_2d_ceil(): # type: () -> None
362362
[15, 16]]]]).astype(np.float32)
363363

364364
expect(node, inputs=[x], outputs=[y], name='export_maxpool_2d_ceil')
365+
366+
@staticmethod
367+
def export_maxpool_2d_dilations(): # type: () -> None
368+
"""
369+
input_shape: [1, 1, 4, 4]
370+
output_shape: [1, 1, 2, 2]
371+
"""
372+
node = onnx.helper.make_node(
373+
'MaxPool',
374+
inputs=['x'],
375+
outputs=['y'],
376+
kernel_shape=[2, 2],
377+
strides=[1, 1],
378+
dilations=[2, 2]
379+
)
380+
x = np.array([[[
381+
[1, 2, 3, 4],
382+
[5, 6, 7, 8],
383+
[9, 10, 11, 12],
384+
[13, 14, 15, 16],
385+
]]]).astype(np.float32)
386+
y = np.array([[[
387+
[11, 12],
388+
[15, 16]]]]).astype(np.float32)
389+
390+
expect(node, inputs=[x], outputs=[y], name='test_maxpool_2d_dilations')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
 backend-test:�
2+
L
3+
xy"MaxPool*
4+
dilations@@�*
5+
kernel_shape@@�*
6+
strides@@�test_maxpool_2d_dilationsZ
7+
x
8+

9+

10+

11+

12+
b
13+
y
14+

15+

16+

17+

18+
B
Binary file not shown.
Binary file not shown.

onnx/defs/nn/defs.cc

+13-5
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,8 @@ std::function<void(OpSchema&)> PoolOpSchemaGenerator_9(
250250
std::function<void(OpSchema&)> PoolOpSchemaGenerator(
251251
const char* name,
252252
const char* opName,
253-
const char* additionalDescription) {
253+
const char* additionalDescription,
254+
bool use_dilation) {
254255
return [=](OpSchema& schema) {
255256
std::string doc = R"DOC(
256257
{name} consumes an input tensor X and applies {opName} pooling across
@@ -330,8 +331,8 @@ std::function<void(OpSchema&)> PoolOpSchemaGenerator(
330331
"T",
331332
{"tensor(float16)", "tensor(float)", "tensor(double)"},
332333
"Constrain input and output types to float tensors.");
333-
schema.TypeAndShapeInferenceFunction([](InferenceContext& ctx) {
334-
convPoolTypeAndShapeInference(ctx, false, true);
334+
schema.TypeAndShapeInferenceFunction([use_dilation](InferenceContext& ctx) {
335+
convPoolTypeAndShapeInference(ctx, use_dilation, true);
335336
});
336337
};
337338
} // namespace ONNX_NAMESPACE
@@ -365,7 +366,8 @@ ONNX_OPERATOR_SET_SCHEMA(
365366
.FillUsing(PoolOpSchemaGenerator(
366367
"AveragePool",
367368
"average",
368-
"The output of each pooling window is divided by the number of elements (exclude pad when attribute count_include_pad is zero)."))
369+
"The output of each pooling window is divided by the number of elements (exclude pad when attribute count_include_pad is zero).",
370+
false))
369371
.Attr(
370372
"count_include_pad",
371373
"Whether include pad pixels when calculating values for the edges. Default is 0, doesn't count include pad.",
@@ -416,12 +418,18 @@ ONNX_OPERATOR_SET_SCHEMA(
416418
.FillUsing(PoolOpSchemaGenerator(
417419
"MaxPool",
418420
"max",
419-
"The output of each pooling window is maximum number of elements exclude pad."))
421+
"The output of each pooling window is maximum number of elements exclude pad.",
422+
true))
420423
.Attr(
421424
"storage_order",
422425
"The storage order of the tensor. 0 is row major, and 1 is column major.",
423426
AttributeProto::INT,
424427
static_cast<int64_t>(0))
428+
.Attr(
429+
"dilations",
430+
"Dilation value along each axis of filter.",
431+
AttributeProto::INTS,
432+
OPTIONAL)
425433
.Output(
426434
1,
427435
"Indices",

onnx/test/shape_inference_test.py

+7
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,13 @@ def test_maxpool_ceil(self): # type: () -> None
958958
[])
959959
self._assert_inferred(graph, [make_tensor_value_info("Y", TensorProto.FLOAT, (1, 1, 2, 2))])
960960

961+
def test_maxpool_with_dilations(self): # type: () -> None
962+
graph = self._make_graph(
963+
[("X", TensorProto.FLOAT, (5, 3, 4, 4))],
964+
[make_node("MaxPool", ["X"], ["Y"], kernel_shape=[2, 2], dilations=[2, 2])],
965+
[])
966+
self._assert_inferred(graph, [make_tensor_value_info("Y", TensorProto.FLOAT, (5, 3, 2, 2))])
967+
961968
def test_averagepool(self): # type: () -> None
962969
graph = self._make_graph(
963970
[("X", TensorProto.FLOAT, (5, 3, 4, 4))],

0 commit comments

Comments
 (0)