Skip to content

Commit

Permalink
QuickGelu Operator Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
virajwad authored and gkrivor committed Oct 29, 2024
1 parent e07546d commit 03ba0ef
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/frontends/onnx/frontend/src/op/com.microsoft/quick_gelu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "core/operator_set.hpp"
#include "exceptions.hpp"
#include "openvino/frontend/exception.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/multiply.hpp"
#include "openvino/op/sigmoid.hpp"


using namespace ov::op;

namespace ov {
namespace frontend {
namespace onnx {
namespace com_microsoft {
namespace opset_1 {
ov::OutputVector quickgelu(const ov::frontend::onnx::Node& node) {
// Original Documentation:
// https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md#com.microsoft.QuickGelu
// Goal: Compute x * Sigmoid(alpha * x)

const auto inputs = node.get_ov_inputs();

// Only one input (x) so give a check
auto num_inputs = inputs.size();
FRONT_END_GENERAL_CHECK(num_inputs == 1,
"QuickGelu takes only 1 input but was provided " + std::to_string(num_inputs));
const auto& x = inputs[0];

// Constrain input type to float16, float, double (f64), bfloat16
auto element_type = x.get_element_type();
CHECK_VALID_NODE(node,
element_type == ov::element::f16 || element_type == ov::element::f32 ||
element_type == ov::element::f64 || element_type == ov::element::bf16,
"Unsupported input x type, accepted FP16, FP32, FP64, BFP16 but got: ",
element_type);

// Get attribute from node
const float alpha = node.get_attribute_value<float>("alpha");

// Numpy broadcasting rule is automatically applied with mismatched shapes according to:
// https://docs.openvino.ai/2022.3/openvino_docs_ops_arithmetic_Multiply_1.html "Tensor with dimension of size 1
// will be implicitly broadcasted to match the size of the second tensor." Convert alpha to tensor with size 1
const auto alpha_tensor = std::make_shared<v0::Constant>(ov::element::f32, Shape{1}, alpha);

auto alpha_x = std::make_shared<v1::Multiply>(alpha_tensor, x);
auto sig_alpha_x = std::make_shared<v0::Sigmoid>(alpha_x);
auto result = std::make_shared<v1::Multiply>(x, sig_alpha_x);

return {result};
} // func end

ONNX_OP("QuickGelu", OPSET_SINCE(1), com_microsoft::opset_1::quickgelu, MICROSOFT_DOMAIN);

} // namespace opset_1
} // namespace com_microsoft
} // namespace onnx
} // namespace frontend
} // namespace ov
52 changes: 52 additions & 0 deletions src/frontends/onnx/tests/models/com.microsoft/quick_gelu.prototxt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
ir_version: 3
producer_name: "OpenVINO ONNX Frontend"
graph {
name: "test_quick_gelu"
node {
input: "X"
output: "Y"
op_type: "QuickGelu"
attribute {
name: "alpha"
f: 0.9974269270896912
type: FLOAT
}
domain: "com.microsoft"
}
input {
name: "X"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 5
}
}
}
}
}
output {
name: "Y"
type {
tensor_type {
elem_type: 1
shape {
dim {
dim_value: 2
}
dim {
dim_value: 5
}
}
}
}
}
}
opset_import {
domain: "com.microsoft"
version: 1
}
26 changes: 26 additions & 0 deletions src/frontends/onnx/tests/onnx_import_com_microsoft.in.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1330,3 +1330,29 @@ OPENVINO_TEST(${BACKEND_NAME}, onnx_com_microsoft_matmulnbits_3x17) {
}
test_case.run();
}

OPENVINO_TEST(${BACKEND_NAME}, onnx_com_microsoft_quickgelu) {
const auto model = convert_model("com.microsoft/quick_gelu.onnx");
auto test_case = ov::test::TestCase(model, s_device);

const std::vector<float> input_X{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const std::vector<float> output{0.7305524f,
1.7605114f,
2.8566725f,
3.9273243f,
4.9661055f,
5.984934f,
6.9935064f,
7.997261f,
8.998864f,
9.999535f};

test_case.add_input<float>(Shape{2, 5}, input_X);
test_case.add_expected_output<float>(Shape{2, 5}, output);

if (std::string("${BACKEND_NAME}") == std::string("IE_GPU")) {
test_case.run_with_tolerance_as_fp(1e-4);
} else {
test_case.run();
}
}

0 comments on commit 03ba0ef

Please sign in to comment.