[ONNX] don't hardcode broadcast shape in Mul, Add, Sub, Div (opset <= 6) operators (#3679)

This commit is contained in:
Mateusz Tabaka authored and GitHub committed 2021-01-14 11:24:37 +01:00
1 parent 3c90a8e421
commit 20b9d390e1
28 files changed
+1476 -71

No files matched your search

@@ -9,7 +9,14 @@
NGRAPH_RTTI_DEFINITION(ngraph::pass::BroadcastElementwiseFusion, "BroadcastElementwiseFusion", 0);
bool is_eliminate_broadcast(const ngraph::PartialShape & input_shape, const ngraph::PartialShape & broadcast_shape) {
bool can_eliminate_broadcast(const ngraph::Output<ngraph::Node>& eltwise,
const ngraph::PartialShape & input_shape,
const ngraph::PartialShape & broadcast_shape) {
auto b = std::dynamic_pointer_cast<ngraph::op::util::BinaryElementwiseArithmetic>(eltwise.get_node_shared_ptr());
if (!b || b->get_autob() == ngraph::op::AutoBroadcastSpec::NONE) {
return false;
}
if (input_shape.rank().is_dynamic() || broadcast_shape.rank().is_dynamic()) {
return false;
}
@@ -53,13 +60,13 @@ ngraph::pass::BroadcastElementwiseFusion::BroadcastElementwiseFusion() {
auto & pattern_value = m.get_pattern_value_map();
const auto & m_eltwise_input = pattern_value.at(eltwise_input);
const auto & m_eltwise = pattern_value.at(eltwise_input);
const auto & m_eltwise = pattern_value.at(eltwise);
const auto & m_broadcast_input = pattern_value.at(broadcast_input);
auto & m_broadcast = pattern_value.at(broadcast);
if (!is_eliminate_broadcast(m_eltwise_input.get_partial_shape(),
m_broadcast.get_partial_shape())) {
if (!can_eliminate_broadcast(m_eltwise, m_eltwise_input.get_partial_shape(),
m_broadcast.get_partial_shape())) {
return false;
}
+30 -12
View File
@@ -130,6 +130,14 @@ void op::util::BroadcastBase::validate_target_shape_none(const Shape& arg_shape,
axes_mapping_val,
" not in sorted order");
if (arg_shape.size() == 0 && axes_mapping_val.size() > 0)
{
NODE_VALIDATION_CHECK(this,
target_shape[axes_mapping_val[0]] == 1,
"Broadcast target[axes_mapping[0]]. Expected 1. Got ",
target_shape[axes_mapping_val[0]]);
}
for (size_t i = 0; i < axes_mapping_val.size(); i++)
{
NODE_VALIDATION_CHECK(this,
@@ -141,15 +149,18 @@ void op::util::BroadcastBase::validate_target_shape_none(const Shape& arg_shape,
" exceeds target rank ",
target_shape.size());
NODE_VALIDATION_CHECK(this,
target_shape[axes_mapping_val[i]] == arg_shape[i],
"Broadcast target[axes_mapping[",
i,
"]]",
" Expected ",
arg_shape[i],
". Got ",
target_shape[axes_mapping_val[i]]);
if (arg_shape.size() > 0)
{
NODE_VALIDATION_CHECK(this,
target_shape[axes_mapping_val[i]] == arg_shape[i],
"Broadcast target[axes_mapping[",
i,
"]]",
" Expected ",
arg_shape[i],
". Got ",
target_shape[axes_mapping_val[i]]);
}
}
}
@@ -246,14 +257,16 @@ void op::util::BroadcastBase::validate_and_infer_types()
{
auto arg_shape = get_input_shape(0);
auto axes_shape = get_input_shape(2);
auto input_rank =
(arg_shape.size() == 0 && shape_size(axes_shape) > 0) ? 1 : arg_shape.size();
// Rank(arg_shape) == shape_size(axes_mapping)
NODE_VALIDATION_CHECK(this,
shape_size(axes_shape) == arg_shape.size(),
shape_size(axes_shape) == input_rank,
"Broadcast axes_mapping shape ",
axes_shape,
" doesn't match rank of input tensor ",
arg_shape.size());
input_rank);
if (shape_constant && op::is_constant(input_value(2).get_node()))
{
@@ -363,9 +376,14 @@ bool op::util::BroadcastBase::evaluate(const HostTensorPtr& arg0,
const AxisSet& broadcast_axes) const
{
NGRAPH_OP_SCOPE(util_BroadcastBase_evaluate_axes);
auto arg0_shape = arg0->get_shape();
if (arg0_shape.size() == 0)
{
arg0_shape = Shape{1};
}
runtime::reference::broadcast(arg0->get_data_ptr<const char>(),
out->get_data_ptr<char>(),
arg0->get_shape(),
arg0_shape,
out->get_shape(),
broadcast_axes,
arg0->get_element_type().size());
@@ -18,7 +18,6 @@
#include <memory>
#include "ngraph/builder/autobroadcast.hpp"
#include "ngraph/node.hpp"
#include "ngraph/shape.hpp"
#include "onnx_import/core/node.hpp"
@@ -36,14 +35,27 @@ namespace ngraph
{
const Output<ngraph::Node> lhs_node = node.get_ng_inputs().at(0);
Output<ngraph::Node> rhs_node = node.get_ng_inputs().at(1);
auto lhs_rank = lhs_node.get_shape().size();
auto rhs_rank = rhs_node.get_shape().size();
auto axis = node.get_attribute_value<std::int64_t>("axis", lhs_rank - rhs_rank);
// Unidirectional broadcast right node to left shape.
rhs_node = ngraph::builder::opset1::legacy_broadcast_for_binary_operation(
lhs_node, rhs_node, axis);
return {std::make_shared<default_opset::Divide>(
lhs_node, rhs_node, ngraph::op::AutoBroadcastSpec::NONE)};
bool broadcast = node.get_attribute_value<std::int64_t>("broadcast", 0);
if (broadcast)
{
if (node.has_attribute("axis"))
{
// Unidirectional broadcast right node to left shape.
auto axis = node.get_attribute_value<std::int64_t>("axis");
rhs_node = std::make_shared<default_opset::Broadcast>(
rhs_node,
std::make_shared<default_opset::ShapeOf>(lhs_node),
default_opset::Constant::create(element::i64, Shape{1}, {axis}));
}
else
{
rhs_node = std::make_shared<default_opset::Broadcast>(
rhs_node, std::make_shared<default_opset::ShapeOf>(lhs_node));
}
return {std::make_shared<default_opset::Divide>(
lhs_node, rhs_node, ngraph::op::AutoBroadcastSpec::NONE)};
}
return {std::make_shared<default_opset::Divide>(lhs_node, rhs_node)};
}
} // namespace set_1
@@ -18,7 +18,6 @@
#include <memory>
#include "ngraph/builder/autobroadcast.hpp"
#include "ngraph/node.hpp"
#include "ngraph/op/broadcast.hpp"
#include "ngraph/op/multiply.hpp"
@@ -37,14 +36,27 @@ namespace ngraph
{
const Output<ngraph::Node> lhs_node = node.get_ng_inputs().at(0);
Output<ngraph::Node> rhs_node = node.get_ng_inputs().at(1);
auto lhs_rank = lhs_node.get_shape().size();
auto rhs_rank = rhs_node.get_shape().size();
auto axis = node.get_attribute_value<std::int64_t>("axis", lhs_rank - rhs_rank);
// Unidirectional broadcast right node to left shape.
rhs_node = ngraph::builder::opset1::legacy_broadcast_for_binary_operation(
lhs_node, rhs_node, axis);
return {std::make_shared<default_opset::Multiply>(
lhs_node, rhs_node, ngraph::op::AutoBroadcastSpec::NONE)};
bool broadcast = node.get_attribute_value<std::int64_t>("broadcast", 0);
if (broadcast)
{
if (node.has_attribute("axis"))
{
// Unidirectional broadcast right node to left shape.
auto axis = node.get_attribute_value<std::int64_t>("axis");
rhs_node = std::make_shared<default_opset::Broadcast>(
rhs_node,
std::make_shared<default_opset::ShapeOf>(lhs_node),
default_opset::Constant::create(element::i64, Shape{1}, {axis}));
}
else
{
rhs_node = std::make_shared<default_opset::Broadcast>(
rhs_node, std::make_shared<default_opset::ShapeOf>(lhs_node));
}
return {std::make_shared<default_opset::Multiply>(
lhs_node, rhs_node, ngraph::op::AutoBroadcastSpec::NONE)};
}
return {std::make_shared<default_opset::Multiply>(lhs_node, rhs_node)};
}
} // namespace set_1
@@ -16,7 +16,6 @@
#pragma once
#include "ngraph/builder/autobroadcast.hpp"
#include "ngraph/node.hpp"
#include "onnx_import/core/node.hpp"
#include "onnx_import/default_opset.hpp"
@@ -33,14 +32,27 @@ namespace ngraph
{
const Output<ngraph::Node> lhs_node = node.get_ng_inputs().at(0);
Output<ngraph::Node> rhs_node = node.get_ng_inputs().at(1);
auto lhs_rank = lhs_node.get_shape().size();
auto rhs_rank = rhs_node.get_shape().size();
auto axis = node.get_attribute_value<std::int64_t>("axis", lhs_rank - rhs_rank);
// Unidirectional broadcast right node to left shape.
rhs_node = ngraph::builder::opset1::legacy_broadcast_for_binary_operation(
lhs_node, rhs_node, axis);
return {std::make_shared<default_opset::Subtract>(
lhs_node, rhs_node, ngraph::op::AutoBroadcastSpec::NONE)};
bool broadcast = node.get_attribute_value<std::int64_t>("broadcast", 0);
if (broadcast)
{
if (node.has_attribute("axis"))
{
// Unidirectional broadcast right node to left shape.
auto axis = node.get_attribute_value<std::int64_t>("axis");
rhs_node = std::make_shared<default_opset::Broadcast>(
rhs_node,
std::make_shared<default_opset::ShapeOf>(lhs_node),
default_opset::Constant::create(element::i64, Shape{1}, {axis}));
}
else
{
rhs_node = std::make_shared<default_opset::Broadcast>(
rhs_node, std::make_shared<default_opset::ShapeOf>(lhs_node));
}
return {std::make_shared<default_opset::Subtract>(
lhs_node, rhs_node, ngraph::op::AutoBroadcastSpec::NONE)};
}
return {std::make_shared<default_opset::Subtract>(lhs_node, rhs_node)};
}
} // namespace set_1
+21 -9
View File
@@ -15,7 +15,6 @@
//*****************************************************************************
#include "onnx_import/op/add.hpp"
#include "ngraph/builder/autobroadcast.hpp"
#include "ngraph/shape.hpp"
#include "onnx_import/default_opset.hpp"
@@ -31,14 +30,27 @@ namespace ngraph
{
const Output<ngraph::Node> lhs_node = node.get_ng_inputs().at(0);
Output<ngraph::Node> rhs_node = node.get_ng_inputs().at(1);
auto lhs_rank = lhs_node.get_shape().size();
auto rhs_rank = rhs_node.get_shape().size();
auto axis = node.get_attribute_value<std::int64_t>("axis", lhs_rank - rhs_rank);
// Unidirectional broadcast right node to left shape.
rhs_node = ngraph::builder::opset1::legacy_broadcast_for_binary_operation(
lhs_node, rhs_node, axis);
return {std::make_shared<default_opset::Add>(
lhs_node, rhs_node, ngraph::op::AutoBroadcastSpec::NONE)};
bool broadcast = node.get_attribute_value<std::int64_t>("broadcast", 0);
if (broadcast)
{
if (node.has_attribute("axis"))
{
// Unidirectional broadcast right node to left shape.
auto axis = node.get_attribute_value<std::int64_t>("axis");
rhs_node = std::make_shared<default_opset::Broadcast>(
rhs_node,
std::make_shared<default_opset::ShapeOf>(lhs_node),
default_opset::Constant::create(element::i64, Shape{1}, {axis}));
}
else
{
rhs_node = std::make_shared<default_opset::Broadcast>(
rhs_node, std::make_shared<default_opset::ShapeOf>(lhs_node));
}
return {std::make_shared<default_opset::Add>(
lhs_node, rhs_node, ngraph::op::AutoBroadcastSpec::NONE)};
}
return {std::make_shared<default_opset::Add>(lhs_node, rhs_node)};
}
} // namespace set_1
@@ -2,7 +2,7 @@
set -e
# provide ONNX Model Zoo commit hash ID to update:
ONNX_SHA=00d95ba9e5758fd0bc5e6978033fabc4f2a95e61
ONNX_SHA=7d9ae32726d872fe9143b7aede149508bdf0b30f
MODELS_DIR="$HOME/.onnx/model_zoo"
ENABLE_MSFT=false
+25
View File
@@ -63,6 +63,31 @@ NGRAPH_TEST(${BACKEND_NAME}, broadcast_scalar_vector)
(vector<float>{6, 6, 6, 6}), read_vector<float>(result), MIN_FLOAT_TOLERANCE_BITS));
}
NGRAPH_TEST(${BACKEND_NAME}, broadcast_scalar_vector_explicit_axis_0)
{
Shape shape_a{};
auto A = make_shared<op::Parameter>(element::f32, shape_a);
Shape shape_r{1, 2};
auto f = make_shared<Function>(
make_shared<op::v1::Broadcast>(
A,
op::Constant::create(element::u64, Shape{shape_r.size()}, shape_r),
op::Constant::create(element::i64, Shape{1}, {0})),
ParameterVector{A});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
// Create some tensors for input/output
auto a = backend->create_tensor(element::f32, shape_a);
copy_data(a, vector<float>{6});
auto result = backend->create_tensor(element::f32, shape_r);
auto handle = backend->compile(f);
handle->call_with_validate({result}, {a});
EXPECT_TRUE(test::all_close_f(
(vector<float>{6, 6}), read_vector<float>(result), MIN_FLOAT_TOLERANCE_BITS));
}
NGRAPH_TEST(${BACKEND_NAME}, broadcast_scalar_matrix)
{
Shape shape_a{};
@@ -0,0 +1,82 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "add"
op_type: "Add"
attribute {
name: "broadcast"
i: 1
type: INT
}
attribute {
name: "axis"
i: 1
type: INT
}
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 3
}
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 3
}
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
}
opset_import {
version: 6
}
@@ -0,0 +1,65 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "add"
op_type: "Add"
attribute {
name: "broadcast"
i: 1
type: INT
}
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
}
opset_import {
version: 6
}
+54
View File
@@ -0,0 +1,54 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "add"
op_type: "Add"
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
}
opset_import {
version: 7
}
@@ -0,0 +1,86 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
model_version: 1
graph {
node {
input: "A"
input: "B"
output: "X"
name: "div"
op_type: "Div"
attribute {
name: "axis"
i: 1
type: INT
}
attribute {
name: "broadcast"
i: 1
type: INT
}
doc_string: ""
domain: ""
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 3
}
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 3
}
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
}
opset_import {
domain: ""
version: 6
}
@@ -0,0 +1,65 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "div"
op_type: "Div"
attribute {
name: "broadcast"
i: 1
type: INT
}
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
}
opset_import {
version: 6
}
+56
View File
@@ -0,0 +1,56 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
model_version: 1
graph {
node {
input: "A"
input: "B"
output: "X"
name: "div"
op_type: "Div"
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
}
opset_import {
domain: ""
version: 7
}
@@ -0,0 +1,68 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
model_version: 1
graph {
node {
input: "A"
input: "B"
output: "X"
name: "div"
op_type: "Div"
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 2
}
dim {
dim_value: 3
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 2
}
dim {
dim_value: 3
}
}
}
}
}
}
opset_import {
domain: ""
version: 7
}
@@ -3,11 +3,15 @@ producer_name: "nGraph ONNX Importer"
graph {
node {
input: "x"
input: "y"
output: "sum"
op_type: "Add"
output: "y"
op_type: "EyeLike"
attribute {
name: "k"
i: -1
type: INT
}
}
name: "test_add_dyn_shapes"
name: "test_graph"
input {
name: "x"
type {
@@ -16,16 +20,8 @@ graph {
}
}
}
input {
name: "y"
type {
tensor_type {
elem_type: 1
}
}
}
output {
name: "sum"
name: "y"
type {
tensor_type {
elem_type: 1
@@ -34,5 +30,5 @@ graph {
}
}
opset_import {
version: 1
version: 9
}
@@ -18,6 +18,16 @@ graph {
output: "current_a"
name: "loop_body_mul"
op_type: "Mul"
attribute {
name: "broadcast"
i: 1
type: INT
}
attribute {
name: "axis"
i: 0
type: INT
}
}
node {
input: "cond_in"
@@ -34,10 +44,8 @@ graph {
name: "simple add"
initializer {
dims: 1
dims: 2
data_type: 1
float_data: 1
float_data: 1
name: "b"
}
input {
+54
View File
@@ -0,0 +1,54 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "mul"
op_type: "Mul"
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
}
opset_import {
version: 6
}
@@ -0,0 +1,82 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "mul"
op_type: "Mul"
attribute {
name: "broadcast"
i: 1
type: INT
}
attribute {
name: "axis"
i: 1
type: INT
}
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 3
}
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 3
}
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
}
opset_import {
version: 6
}
@@ -0,0 +1,65 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "mul"
op_type: "Mul"
attribute {
name: "broadcast"
i: 1
type: INT
}
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
}
opset_import {
version: 6
}
+54
View File
@@ -0,0 +1,54 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "mul"
op_type: "Mul"
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
}
opset_import {
version: 7
}
@@ -0,0 +1,66 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "mul"
op_type: "Mul"
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 2
}
dim {
dim_value: 3
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 2
}
dim {
dim_value: 3
}
}
}
}
}
}
opset_import {
version: 7
}
@@ -0,0 +1,86 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
model_version: 1
graph {
node {
input: "A"
input: "B"
output: "X"
name: "sub"
op_type: "Sub"
attribute {
name: "axis"
i: 1
type: INT
}
attribute {
name: "broadcast"
i: 1
type: INT
}
doc_string: ""
domain: ""
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 3
}
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 3
}
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
}
opset_import {
domain: ""
version: 6
}
@@ -0,0 +1,65 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "A"
input: "B"
output: "X"
name: "sub"
op_type: "Sub"
attribute {
name: "broadcast"
i: 1
type: INT
}
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 2
}
}
}
}
}
}
opset_import {
version: 6
}
+56
View File
@@ -0,0 +1,56 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
model_version: 1
graph {
node {
input: "A"
input: "B"
output: "X"
name: "sub"
op_type: "Sub"
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
}
opset_import {
domain: ""
version: 7
}
@@ -0,0 +1,68 @@
ir_version: 3
producer_name: "nGraph ONNX Importer"
model_version: 1
graph {
node {
input: "A"
input: "B"
output: "X"
name: "sub"
op_type: "Sub"
}
name: "test_graph"
input {
name: "A"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 2
}
dim {
dim_value: 3
}
}
}
}
}
input {
name: "B"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 3
}
}
}
}
}
output {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 1
}
dim {
dim_value: 2
}
dim {
dim_value: 3
}
}
}
}
}
}
opset_import {
domain: ""
version: 7
}
+230
View File
@@ -3286,6 +3286,236 @@ NGRAPH_TEST(${BACKEND_NAME}, onnx_model_hard_sigmoid)
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_mul_v6)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/mul_v6.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
test_case.add_input<float>({1.0f, 2.0f, 3.0f});
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(Shape{3}, {3.0f, 8.0f, 15.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_mul_v6_broadcast_axis_1)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/mul_v6_broadcast_axis_1.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{1, 3, 2, 2};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(
shape, {3.0f, 6.0f, 9.0f, 12.0f, 20.0f, 24.0f, 28.0f, 32.0f, 45.0f, 50.0f, 55.0f, 60.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_mul_v6_broadcast_no_axis)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/mul_v6_broadcast_no_axis.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{2, 2};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f});
test_case.add_expected_output<float>(shape, {3.0f, 6.0f, 9.0f, 12.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_mul_v7)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/mul_v7.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
test_case.add_input<float>({1.0f, 2.0f, 3.0f});
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(Shape{3}, {3.0f, 8.0f, 15.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_mul_v7_broadcast)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/mul_v7_broadcast.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{1, 2, 3};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(shape, {3.0f, 8.0f, 15.0f, 12.0f, 20.0f, 30.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_add_v6_broadcast_axis_1)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/add_v6_broadcast_axis_1.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{1, 3, 2, 2};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(
shape, {4.0f, 5.0f, 6.0f, 7.0f, 9.0f, 10.0f, 11.0f, 12.0f, 14.0f, 15.0f, 16.0f, 17.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_add_v6_broadcast_no_axis)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/add_v6_broadcast_no_axis.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{2, 2};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f});
test_case.add_expected_output<float>(shape, {4.0f, 5.0f, 6.0f, 7.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_add_v7)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/add_v7.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
test_case.add_input<float>({1.0f, 2.0f, 3.0f});
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(Shape{3}, {4.0f, 6.0f, 8.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_sub_v6_broadcast_axis_1)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/sub_v6_broadcast_axis_1.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{1, 3, 2, 2};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(
shape, {-2.0f, -1.0f, 0.0f, 1.0f, 1.0f, 2.0f, 3.0f, 4.0f, 4.0f, 5.0f, 6.0f, 7.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_sub_v6_broadcast_no_axis)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/sub_v6_broadcast_no_axis.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{2, 2};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f});
test_case.add_expected_output<float>(shape, {-2.0f, -1.0f, 0.0f, 1.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_sub_v7)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/sub_v7.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
test_case.add_input<float>({1.0f, 2.0f, 3.0f});
test_case.add_input<float>({3.0f, 8.0f, 7.0f});
test_case.add_expected_output<float>(Shape{3}, {-2.0f, -6.0f, -4.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_sub_v7_broadcast)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/sub_v7_broadcast.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{1, 2, 3};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(shape, {-2.0f, -2.0f, -2.0f, 1.0f, 1.0f, 1.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_div_v6_broadcast_axis_1)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/div_v6_broadcast_axis_1.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{1, 3, 2, 2};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(
shape,
{0.3333333f, 0.6666666f, 1.0f, 1.333333f, 1.25f, 1.5f, 1.75f, 2.0f, 1.8f, 2.0, 2.2f, 2.4f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_div_v6_broadcast_no_axis)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/div_v6_broadcast_no_axis.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{2, 2};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({2.0f});
test_case.add_expected_output<float>(shape, {0.5f, 1.0f, 1.5f, 2.0f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_div_v7)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/div_v7.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
test_case.add_input<float>({1.0f, 2.0f, 3.0f});
test_case.add_input<float>({3.0f, 8.0f, 7.0f});
test_case.add_expected_output<float>(Shape{3}, {0.3333333f, 0.25f, 0.4285714f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_div_v7_broadcast)
{
const auto function = onnx_import::import_onnx_model(
file_util::path_join(SERIALIZED_ZOO, "onnx/div_v7_broadcast.prototxt"));
auto test_case = test::TestCase<TestEngine>(function);
Shape shape{1, 2, 3};
std::vector<float> A(shape_size(shape));
std::iota(A.begin(), A.end(), 1);
test_case.add_input<float>(A);
test_case.add_input<float>({3.0f, 4.0f, 5.0f});
test_case.add_expected_output<float>(shape, {0.3333333f, 0.5f, 0.6f, 1.3333333f, 1.25f, 1.2f});
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, onnx_model_dangling_parameter)
{
auto function = onnx_import::import_onnx_model(
+3 -2
View File
@@ -87,13 +87,14 @@ TEST(onnx_importer, exception_msg_std_err_wrapped)
try
{
onnx_import::import_onnx_model(file_util::path_join(
SERIALIZED_ZOO, "onnx/dynamic_shapes/add_opset6_dyn_shape.prototxt"));
SERIALIZED_ZOO, "onnx/dynamic_shapes/eye_link_dyn_shape.prototxt"));
// Should have thrown, so fail if it didn't
FAIL() << "ONNX Importer did not detected incorrect model!";
}
catch (const std::exception& e)
{
EXPECT_HAS_SUBSTRING(e.what(), std::string("While validating ONNX node '<Node(Add)"));
EXPECT_HAS_SUBSTRING(e.what(),
std::string("While validating ONNX node '<Node(EyeLike): y"));
}
catch (...)
{