Skip to content

Commit

Permalink
[ONNX] Extend ONNX Frontend with BlackmanWindow, HammingWindow and Ha…
Browse files Browse the repository at this point in the history
…nnWindow operators (openvinotoolkit#19428)

* ONNX BlackManWindow enabled

* added a test periodic

* Add the license statement

* ONNX HammingWindow, HannWindow enabled

also added basic tests for each

* minor tests added

* made reviewed changes

* made reviewed changes

used output_datatype directly, returned y_values directly

* fixed clang-format

* add OPENVINO_SUPPRESS_DEPRECATED_START

* include math.h

* float fix

* fix

* fix namespace to set_1

* test fixes

* fix cast to output_datatype

* fix, replace cast with ov::convert

* fix, use element::f32

* major fixes

* fixes

* Update onnx_import.in.cpp

* Update onnx_import.in.cpp

---------

Co-authored-by: Przemyslaw Wysocki <przemyslaw.wysocki@intel.com>
  • Loading branch information
2 people authored and alvoron committed Nov 6, 2023
1 parent 6f5b002 commit 81b3322
Show file tree
Hide file tree
Showing 15 changed files with 745 additions and 6 deletions.
86 changes: 86 additions & 0 deletions src/frontends/onnx/frontend/src/op/blackmanwindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "op/blackmanwindow.hpp"

#include <memory>

#include "default_opset.hpp"
#include "utils/common.hpp"
#define _USE_MATH_DEFINES
#include <math.h>

OPENVINO_SUPPRESS_DEPRECATED_START
namespace ngraph {
namespace onnx_import {
namespace op {
namespace set_1 {
OutputVector blackmanwindow(const Node& node) {
const auto size = node.get_ng_inputs().at(0);
const auto output_datatype =
common::get_ngraph_element_type(node.get_attribute_value<int64_t>("output_datatype", 1));
const bool periodic = node.get_attribute_value<int64_t>("periodic", 1) == 1;

const ov::PartialShape shape = size.get_partial_shape();
const std::vector<size_t> axis_lengths = shape.to_shape();

// Weights as described in ONNX BlackmanWindow docs
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#blackmanwindow
const auto float_size = std::make_shared<default_opset::Convert>(size, ov::element::f32);
const auto a_0 =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{0.42f});
const auto a_1 =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{-0.50f});
const auto a_2 =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{0.08f});

const auto start =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{0.0f});
const auto one_const =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{1.0f});
const auto two_const =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{2.0f});
const auto four_const =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{4.0f});
const auto range = std::make_shared<default_opset::Range>(start, size, one_const, ov::element::f32);
const auto pi =
default_opset::Constant::create(ov::element::f32, ov::Shape(), std::vector<float>{static_cast<float>(M_PI)});
std::shared_ptr<ov::Node> factor_1, factor_2;
if (periodic) {
factor_1 = std::make_shared<default_opset::Multiply>(
range,
std::make_shared<default_opset::Divide>(std::make_shared<default_opset::Multiply>(pi, two_const),
float_size));
factor_2 = std::make_shared<default_opset::Multiply>(
range,
std::make_shared<default_opset::Divide>(std::make_shared<default_opset::Multiply>(pi, four_const),
float_size));
} else {
factor_1 = std::make_shared<default_opset::Multiply>(
range,
std::make_shared<default_opset::Divide>(std::make_shared<default_opset::Multiply>(pi, two_const),
std::make_shared<default_opset::Subtract>(float_size, one_const)));
factor_2 = std::make_shared<default_opset::Multiply>(
range,
std::make_shared<default_opset::Divide>(std::make_shared<default_opset::Multiply>(pi, four_const),
std::make_shared<default_opset::Subtract>(float_size, one_const)));
}

const auto cos_1 = std::make_shared<default_opset::Cos>(factor_1);
const auto cos_2 = std::make_shared<default_opset::Cos>(factor_2);
const auto scaled_cos_1 = std::make_shared<default_opset::Multiply>(cos_1, a_1);
const auto scaled_cos_2 = std::make_shared<default_opset::Multiply>(cos_2, a_2);
const auto y_values =
std::make_shared<default_opset::Add>(std::make_shared<default_opset::Add>(a_0, scaled_cos_1), scaled_cos_2);

if (output_datatype == element::f32) {
return {y_values};
} else {
return {std::make_shared<default_opset::Convert>(y_values, output_datatype)};
}
}
} // namespace set_1
} // namespace op
} // namespace onnx_import
} // namespace ngraph
OPENVINO_SUPPRESS_DEPRECATED_END
23 changes: 23 additions & 0 deletions src/frontends/onnx/frontend/src/op/blackmanwindow.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "openvino/core/deprecated.hpp"
OPENVINO_SUPPRESS_DEPRECATED_START

#include "ngraph/node.hpp"
#include "onnx_import/core/node.hpp"

namespace ngraph {
namespace onnx_import {
namespace op {
namespace set_1 {

OutputVector blackmanwindow(const Node& node);

} // namespace set_1
} // namespace op
} // namespace onnx_import
} // namespace ngraph
OPENVINO_SUPPRESS_DEPRECATED_END
72 changes: 72 additions & 0 deletions src/frontends/onnx/frontend/src/op/hammingwindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "op/hammingwindow.hpp"

#include <memory>

#include "default_opset.hpp"
#include "utils/common.hpp"
#define _USE_MATH_DEFINES
#include <math.h>

OPENVINO_SUPPRESS_DEPRECATED_START
namespace ngraph {
namespace onnx_import {
namespace op {
namespace set_1 {
OutputVector hammingwindow(const Node& node) {
const auto size = node.get_ng_inputs().at(0);
const auto output_datatype =
common::get_ngraph_element_type(node.get_attribute_value<int64_t>("output_datatype", 1));
const bool periodic = node.get_attribute_value<int64_t>("periodic", 1) == 1;

const ov::PartialShape shape = size.get_partial_shape();
const std::vector<size_t> axis_lengths = shape.to_shape();

// Weights as described in ONNX HammingWindow docs
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#hammingwindow
const auto float_size = std::make_shared<default_opset::Convert>(size, ov::element::f32);
const auto a_0 = std::make_shared<default_opset::Divide>(
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{25.0f}),
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{46.0f}));
const auto a_1 = std::make_shared<default_opset::Subtract>(
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{1.0f}),
a_0);

const auto start =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{0.0f});
const auto one_const =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{1.0f});
const auto two_const =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{2.0f});
const auto range = std::make_shared<default_opset::Range>(start, size, one_const, ov::element::f32);
const auto pi =
default_opset::Constant::create(ov::element::f32, ov::Shape(), std::vector<float>{static_cast<float>(M_PI)});
std::shared_ptr<ov::Node> factor;
if (periodic) {
factor = std::make_shared<default_opset::Multiply>(
range,
std::make_shared<default_opset::Divide>(std::make_shared<default_opset::Multiply>(pi, two_const),
float_size));
} else {
factor = std::make_shared<default_opset::Multiply>(
range,
std::make_shared<default_opset::Divide>(std::make_shared<default_opset::Multiply>(pi, two_const),
std::make_shared<default_opset::Subtract>(float_size, one_const)));
}

const auto cos = std::make_shared<default_opset::Cos>(factor);
const auto scaled_cos = std::make_shared<default_opset::Multiply>(cos, a_1);
const auto y_values = std::make_shared<default_opset::Subtract>(a_0, scaled_cos);
if (output_datatype == element::f32) {
return {y_values};
} else {
return {std::make_shared<default_opset::Convert>(y_values, output_datatype)};
}
}
} // namespace set_1
} // namespace op
} // namespace onnx_import
} // namespace ngraph
OPENVINO_SUPPRESS_DEPRECATED_END
23 changes: 23 additions & 0 deletions src/frontends/onnx/frontend/src/op/hammingwindow.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "openvino/core/deprecated.hpp"
OPENVINO_SUPPRESS_DEPRECATED_START

#include "ngraph/node.hpp"
#include "onnx_import/core/node.hpp"

namespace ngraph {
namespace onnx_import {
namespace op {
namespace set_1 {

OutputVector hammingwindow(const Node& node);

} // namespace set_1
} // namespace op
} // namespace onnx_import
} // namespace ngraph
OPENVINO_SUPPRESS_DEPRECATED_END
68 changes: 68 additions & 0 deletions src/frontends/onnx/frontend/src/op/hannwindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "op/hannwindow.hpp"

#include <memory>

#include "default_opset.hpp"
#include "utils/common.hpp"
#define _USE_MATH_DEFINES
#include <math.h>

OPENVINO_SUPPRESS_DEPRECATED_START
namespace ngraph {
namespace onnx_import {
namespace op {
namespace set_1 {
OutputVector hannwindow(const Node& node) {
const auto size = node.get_ng_inputs().at(0);
const auto output_datatype =
common::get_ngraph_element_type(node.get_attribute_value<int64_t>("output_datatype", 1));
const bool periodic = node.get_attribute_value<int64_t>("periodic", 1) == 1;

const ov::PartialShape shape = size.get_partial_shape();
const std::vector<size_t> axis_lengths = shape.to_shape();

// Weights as described in ONNX HannWindow docs
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#hannwindow
const auto float_size = std::make_shared<default_opset::Convert>(size, ov::element::f32);
const auto a_0 = std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{0.5f});
const auto a_1 = a_0;

const auto start =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{0.0f});
const auto one_const =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{1.0f});
const auto two_const =
std::make_shared<default_opset::Constant>(ov::element::f32, ov::Shape(), std::vector<float>{2.0f});
const auto range = std::make_shared<default_opset::Range>(start, size, one_const, ov::element::f32);
const auto pi =
default_opset::Constant::create(ov::element::f32, ov::Shape(), std::vector<float>{static_cast<float>(M_PI)});
std::shared_ptr<ov::Node> factor;
if (periodic) {
factor = std::make_shared<default_opset::Multiply>(
range,
std::make_shared<default_opset::Divide>(std::make_shared<default_opset::Multiply>(pi, two_const),
float_size));
} else {
factor = std::make_shared<default_opset::Multiply>(
range,
std::make_shared<default_opset::Divide>(std::make_shared<default_opset::Multiply>(pi, two_const),
std::make_shared<default_opset::Subtract>(float_size, one_const)));
}

const auto cos = std::make_shared<default_opset::Cos>(factor);
const auto scaled_cos = std::make_shared<default_opset::Multiply>(cos, a_1);
const auto y_values = std::make_shared<default_opset::Subtract>(a_0, scaled_cos);
if (output_datatype == element::f32) {
return {y_values};
} else {
return {std::make_shared<default_opset::Convert>(y_values, output_datatype)};
}
}
} // namespace set_1
} // namespace op
} // namespace onnx_import
} // namespace ngraph
OPENVINO_SUPPRESS_DEPRECATED_END
23 changes: 23 additions & 0 deletions src/frontends/onnx/frontend/src/op/hannwindow.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "openvino/core/deprecated.hpp"
OPENVINO_SUPPRESS_DEPRECATED_START

#include "ngraph/node.hpp"
#include "onnx_import/core/node.hpp"

namespace ngraph {
namespace onnx_import {
namespace op {
namespace set_1 {

OutputVector hannwindow(const Node& node);

} // namespace set_1
} // namespace op
} // namespace onnx_import
} // namespace ngraph
OPENVINO_SUPPRESS_DEPRECATED_END
6 changes: 6 additions & 0 deletions src/frontends/onnx/frontend/src/ops_bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "op/average_pool.hpp"
#include "op/batch_norm.hpp"
#include "op/bitshift.hpp"
#include "op/blackmanwindow.hpp"
#include "op/cast.hpp"
#include "op/cast_like.hpp"
#include "op/ceil.hpp"
Expand Down Expand Up @@ -75,6 +76,8 @@
#include "op/greater.hpp"
#include "op/grid_sample.hpp"
#include "op/gru.hpp"
#include "op/hammingwindow.hpp"
#include "op/hannwindow.hpp"
#include "op/hard_sigmoid.hpp"
#include "op/hard_swish.hpp"
#include "op/hardmax.hpp"
Expand Down Expand Up @@ -345,6 +348,7 @@ OperatorsBridge::OperatorsBridge() {
REGISTER_OPERATOR("BatchNormalization", 1, batch_norm);
REGISTER_OPERATOR("BatchNormalization", 7, batch_norm);
REGISTER_OPERATOR("BitShift", 1, bitshift);
REGISTER_OPERATOR("BlackmanWindow", 1, blackmanwindow);
REGISTER_OPERATOR("Cast", 1, cast);
REGISTER_OPERATOR("CastLike", 1, cast_like);
REGISTER_OPERATOR("Ceil", 1, ceil);
Expand Down Expand Up @@ -392,6 +396,8 @@ OperatorsBridge::OperatorsBridge() {
REGISTER_OPERATOR("Greater", 1, greater);
REGISTER_OPERATOR("GridSample", 1, grid_sample);
REGISTER_OPERATOR("GRU", 1, gru);
REGISTER_OPERATOR("HannWindow", 1, hannwindow);
REGISTER_OPERATOR("HammingWindow", 1, hammingwindow);
REGISTER_OPERATOR("Hardmax", 1, hardmax);
REGISTER_OPERATOR("Hardmax", 13, hardmax);
REGISTER_OPERATOR("HardSigmoid", 1, hard_sigmoid);
Expand Down
46 changes: 46 additions & 0 deletions src/frontends/onnx/tests/models/blackmanwindow_periodic.prototxt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
ir_version: 7
producer_name: "nGraph ONNX Importer"
graph {
node {
input: "size"
output: "y"
op_type: "BlackmanWindow"
attribute {
name: "output_datatype"
i: 1 # Use 1 for f32
type: INT
}
attribute {
name: "periodic"
i: 1 # Set to 1 for periodic, 0 for non-periodic
type: INT
}
}
name: "test_blackmanwindow_periodic"
input {
name: "size"
type {
tensor_type {
elem_type: 7 # INT64
shape {
}
}
}
}
output {
name: "y"
type {
tensor_type {
elem_type: 1 # FLOAT
shape {
dim {
dim_value: 10 # Modify this based on your expected output shape
}
}
}
}
}
}
opset_import {
version: 17
}
Loading

0 comments on commit 81b3322

Please sign in to comment.