Skip to content

Commit e58f38f

Browse files
[ONNX] Added QLinearAveragePool from com.microsoft domain (#28799)
Details: Microsoft Contrib Operator "QLinearAveragePool" for ONNX RT Tickets: N/A --------- Co-authored-by: Georgy Krivoruchko <georgy.krivoruchko@intel.com>
1 parent 68ecdfb commit e58f38f

File tree

3 files changed

+172
-12
lines changed

3 files changed

+172
-12
lines changed

src/frontends/onnx/frontend/src/op/com.microsoft/qlinear_activation.cpp

+38-12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "exceptions.hpp"
77
#include "openvino/frontend/exception.hpp"
88
#include "openvino/op/add.hpp"
9+
#include "openvino/op/avg_pool.hpp"
910
#include "openvino/op/constant.hpp"
1011
#include "openvino/op/convert.hpp"
1112
#include "openvino/op/divide.hpp"
@@ -57,21 +58,12 @@ ov::OutputVector qlinear_activation(const ov::frontend::onnx::Node& node, const
5758
}
5859

5960
ov::OutputVector qlinear_sigmoid(const ov::frontend::onnx::Node& node) {
60-
// Original documentation:
61-
// https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md#commicrosoftqlinearsigmoid
62-
// f(x) = quantize(Sigmoid(dequantize(x)))
63-
6461
return qlinear_activation(node, [](const std::shared_ptr<ov::Node>& input_dequantized) {
6562
return std::make_shared<v0::Sigmoid>(input_dequantized);
6663
});
6764
}
6865

6966
ov::OutputVector qlinear_leaky_relu(const ov::frontend::onnx::Node& node) {
70-
// Original documentation:
71-
// https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md#commicrosoftqlinearleakyrelu
72-
// f(x) = quantize(alpha * dequantize(x)) for x < 0,
73-
// quantize(dequantize(x)) for x >= 0
74-
7567
return qlinear_activation(node, [&](const std::shared_ptr<ov::Node>& input_dequantized) {
7668
auto alpha =
7769
v0::Constant::create(input_dequantized->get_element_type(), {}, {node.get_attribute_value<float>("alpha")});
@@ -80,10 +72,44 @@ ov::OutputVector qlinear_leaky_relu(const ov::frontend::onnx::Node& node) {
8072
});
8173
}
8274

83-
namespace {
84-
ONNX_OP("QLinearSigmoid", OPSET_SINCE(1), com_microsoft::opset_1::qlinear_sigmoid, MICROSOFT_DOMAIN);
75+
ov::OutputVector qlinear_avg_pool(const ov::frontend::onnx::Node& node) {
76+
return qlinear_activation(node, [&](const std::shared_ptr<ov::Node>& input_dequantized) {
77+
const auto kernel_shape = node.get_attribute_value<std::vector<int64_t>>("kernel_shape");
78+
auto strides = node.get_attribute_value<std::vector<int64_t>>("strides", std::vector<int64_t>{1});
79+
auto pads = node.get_attribute_value<std::vector<int64_t>>("pads", std::vector<int64_t>{0});
80+
const auto ceil_mode = node.get_attribute_value<int64_t>("ceil_mode", 0);
81+
const auto count_include_pad = node.get_attribute_value<int64_t>("count_include_pad", 0);
82+
const auto auto_pad = node.get_attribute_value<std::string>("auto_pad", "NOTSET");
83+
84+
const auto input_rank = input_dequantized->get_shape().size();
85+
const size_t num_spatial_dims = input_rank - 2;
86+
87+
pads.resize(num_spatial_dims * 2, pads.size() == 1 ? pads[0] : 0);
88+
strides.resize(num_spatial_dims, strides.size() == 1 ? strides[0] : 1);
89+
90+
auto avg_pool = std::make_shared<v1::AvgPool>(input_dequantized,
91+
Strides(strides.begin(), strides.end()),
92+
Shape(pads.begin(), pads.begin() + num_spatial_dims),
93+
Shape(pads.begin() + num_spatial_dims, pads.end()),
94+
Shape(kernel_shape.begin(), kernel_shape.end()),
95+
count_include_pad == 0,
96+
ceil_mode != 0 ? RoundingType::CEIL : RoundingType::FLOOR,
97+
auto_pad == "SAME_UPPER" ? PadType::SAME_UPPER
98+
: auto_pad == "SAME_LOWER" ? PadType::SAME_LOWER
99+
: PadType::EXPLICIT);
100+
101+
return avg_pool;
102+
});
85103
}
86-
ONNX_OP("QLinearLeakyRelu", OPSET_SINCE(1), com_microsoft::opset_1::qlinear_leaky_relu, MICROSOFT_DOMAIN);
104+
105+
bool register_multiple_operators(void) {
106+
ONNX_OP_M("QLinearSigmoid", OPSET_SINCE(1), com_microsoft::opset_1::qlinear_sigmoid, MICROSOFT_DOMAIN);
107+
ONNX_OP_M("QLinearLeakyRelu", OPSET_SINCE(1), com_microsoft::opset_1::qlinear_leaky_relu, MICROSOFT_DOMAIN);
108+
ONNX_OP_M("QLinearAveragePool", OPSET_SINCE(1), com_microsoft::opset_1::qlinear_avg_pool, MICROSOFT_DOMAIN);
109+
return true;
110+
}
111+
112+
static bool registered = register_multiple_operators();
87113

88114
} // namespace opset_1
89115
} // namespace com_microsoft
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
ir_version: 3
2+
producer_name: "OpenVINO ONNX Frontend"
3+
graph {
4+
node {
5+
input: "A"
6+
input: "A_scale"
7+
input: "A_zero"
8+
input: "B_scale"
9+
input: "B_zero"
10+
output: "R"
11+
name: "test_Qlinear_avg_pool"
12+
domain: "com.microsoft"
13+
op_type: "QLinearAveragePool"
14+
attribute {
15+
name: "auto_pad"
16+
s: "NOTSET"
17+
type: STRING
18+
}
19+
attribute {
20+
name: "ceil_mode"
21+
i: 0
22+
type: INT
23+
}
24+
attribute {
25+
name: "count_include_pad"
26+
i: 0
27+
type: INT
28+
}
29+
attribute {
30+
name: "kernel_shape"
31+
ints: 7
32+
ints: 7
33+
type: INTS
34+
}
35+
attribute {
36+
name: "strides"
37+
ints: 1
38+
ints: 1
39+
type: INTS
40+
}
41+
}
42+
43+
initializer {
44+
data_type: 1
45+
float_data: 0.023529412
46+
name: "A_scale"
47+
}
48+
49+
initializer {
50+
data_type: 2
51+
int32_data: 0
52+
name: "A_zero"
53+
}
54+
55+
initializer {
56+
data_type: 1
57+
float_data: 0.01812745
58+
name: "B_scale"
59+
}
60+
61+
initializer {
62+
data_type: 2
63+
int32_data: 0
64+
name: "B_zero"
65+
}
66+
67+
68+
input {
69+
name: "A"
70+
type {
71+
tensor_type {
72+
elem_type: 2
73+
shape {
74+
dim {
75+
dim_value: 1
76+
}
77+
dim {
78+
dim_value: 1
79+
}
80+
dim {
81+
dim_value: 7
82+
}
83+
dim {
84+
dim_value: 7
85+
}
86+
}
87+
}
88+
}
89+
}
90+
91+
output {
92+
name: "R"
93+
type {
94+
tensor_type {
95+
elem_type: 2
96+
shape {
97+
dim {
98+
dim_value: 1
99+
}
100+
dim {
101+
dim_value: 1
102+
}
103+
dim {
104+
dim_value: 1
105+
}
106+
dim {
107+
dim_value: 1
108+
}
109+
}
110+
}
111+
}
112+
}
113+
}
114+
opset_import {
115+
domain: "com.microsoft"
116+
version: 1
117+
}

src/frontends/onnx/tests/onnx_import_com_microsoft.in.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -1577,6 +1577,23 @@ OPENVINO_TEST(${BACKEND_NAME}, onnx_com_microsoft_matmul_integer_to_float) {
15771577
test_case.run();
15781578
}
15791579

1580+
OPENVINO_TEST(${BACKEND_NAME}, onnx_com_microsoft_qlinear_avg_pool) {
1581+
const auto model = convert_model("com.microsoft/qlinear_avg_pool.onnx");
1582+
auto test_case = ov::test::TestCase(model, s_device);
1583+
1584+
const std::vector<uint8_t> data_A = {140, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128, 127,
1585+
126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114,
1586+
113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101,
1587+
100, 99, 98, 97, 96, 95, 94, 93, 92, 91};
1588+
1589+
const std::vector<uint8_t> expected_output = {149};
1590+
1591+
test_case.add_input<uint8_t>(Shape{1, 1, 7, 7}, data_A);
1592+
1593+
test_case.add_expected_output<uint8_t>(Shape{1, 1, 1, 1}, expected_output);
1594+
test_case.run();
1595+
}
1596+
15801597
OPENVINO_TEST(${BACKEND_NAME}, onnx_com_microsoft_qlinearsigmoid) {
15811598
const auto model = convert_model("com.microsoft/q_linear_sigmoid.onnx");
15821599
auto test_case = ov::test::TestCase(model, s_device);

0 commit comments

Comments
 (0)