[Opset13][FP8] Introduce FakeConvert op core (#20930)
* FakeConvert op init * Update dest types names * Update op hpp * Update opset ops number * Init type_prop tests * Add attributes tests * Add op check test * Update namespace in fc cpp * Update getters * Refactor static member * Make destination_type lower case * Update type in test * Move get_valid_types out of class * Update ops number in opset * Remove apply_scale attribute * Additional constructor to make `shift` input optional
This commit is contained in:
41
src/core/include/openvino/op/fake_convert.hpp
Normal file
41
src/core/include/openvino/op/fake_convert.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/op/op.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace op {
|
||||
namespace v13 {
|
||||
/// \ingroup ov_ops_cpp_api
|
||||
class OPENVINO_API FakeConvert : public Op {
|
||||
public:
|
||||
OPENVINO_OP("FakeConvert", "opset13");
|
||||
|
||||
FakeConvert() = default;
|
||||
FakeConvert(const ov::Output<ov::Node>& arg,
|
||||
const ov::Output<ov::Node>& scale,
|
||||
std::string destination_type = "f8e4m3");
|
||||
|
||||
FakeConvert(const ov::Output<ov::Node>& arg,
|
||||
const ov::Output<ov::Node>& scale,
|
||||
const ov::Output<ov::Node>& shift,
|
||||
std::string destination_type = "f8e4m3");
|
||||
|
||||
void validate_and_infer_types() override;
|
||||
std::shared_ptr<ov::Node> clone_with_new_inputs(const ov::OutputVector& new_args) const override;
|
||||
bool visit_attributes(ov::AttributeVisitor& visitor) override;
|
||||
bool has_evaluate() const override;
|
||||
|
||||
const std::string& get_destination_type() const;
|
||||
|
||||
private:
|
||||
void validate_type() const;
|
||||
|
||||
std::string m_destination_type = "f8e4m3";
|
||||
};
|
||||
} // namespace v13
|
||||
} // namespace op
|
||||
} // namespace ov
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "openvino/op/experimental_detectron_topkrois.hpp"
|
||||
#include "openvino/op/extractimagepatches.hpp"
|
||||
#include "openvino/op/eye.hpp"
|
||||
#include "openvino/op/fake_convert.hpp"
|
||||
#include "openvino/op/fake_quantize.hpp"
|
||||
#include "openvino/op/floor.hpp"
|
||||
#include "openvino/op/floor_mod.hpp"
|
||||
|
||||
@@ -216,3 +216,4 @@ _OPENVINO_OP_REG(BitwiseXor, ov::op::v13)
|
||||
_OPENVINO_OP_REG(NMSRotated, ov::op::v13)
|
||||
_OPENVINO_OP_REG(Multinomial, ov::op::v13)
|
||||
_OPENVINO_OP_REG(ScaledDotProductAttention, ov::op::v13)
|
||||
_OPENVINO_OP_REG(FakeConvert, ov::op::v13)
|
||||
|
||||
75
src/core/src/op/fake_convert.cpp
Normal file
75
src/core/src/op/fake_convert.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/fake_convert.hpp"
|
||||
|
||||
#include "itt.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace op {
|
||||
namespace v13 {
|
||||
namespace fake_convert {
|
||||
static const std::vector<std::string>& get_valid_types() {
|
||||
static const std::vector<std::string> valid_types{"f8e4m3", "f8e5m2"};
|
||||
return valid_types;
|
||||
}
|
||||
} // namespace fake_convert
|
||||
|
||||
FakeConvert::FakeConvert(const ov::Output<ov::Node>& arg,
|
||||
const ov::Output<ov::Node>& scale,
|
||||
std::string destination_type)
|
||||
: Op({arg, scale}),
|
||||
m_destination_type(std::move(destination_type)) {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
FakeConvert::FakeConvert(const ov::Output<ov::Node>& arg,
|
||||
const ov::Output<ov::Node>& scale,
|
||||
const ov::Output<ov::Node>& shift,
|
||||
std::string destination_type)
|
||||
: Op({arg, scale, shift}),
|
||||
m_destination_type(std::move(destination_type)) {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
const std::string& FakeConvert::get_destination_type() const {
|
||||
return m_destination_type;
|
||||
}
|
||||
|
||||
void FakeConvert::validate_and_infer_types() {
|
||||
OV_OP_SCOPE(v13_FakeConvert_validate_and_infer_types);
|
||||
validate_type();
|
||||
set_output_type(0, get_input_element_type(0), get_input_partial_shape(0));
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Node> FakeConvert::clone_with_new_inputs(const ov::OutputVector& new_args) const {
|
||||
OV_OP_SCOPE(v13_FakeConvert_clone_with_new_inputs);
|
||||
if (new_args.size() == 2) {
|
||||
return std::make_shared<FakeConvert>(new_args.at(0), new_args.at(1), m_destination_type);
|
||||
} else if (new_args.size() == 3) {
|
||||
return std::make_shared<FakeConvert>(new_args.at(0), new_args.at(1), new_args.at(2), m_destination_type);
|
||||
} else {
|
||||
OPENVINO_THROW("Incorrect number of FakeConvert new arguments.");
|
||||
}
|
||||
}
|
||||
|
||||
bool FakeConvert::visit_attributes(ov::AttributeVisitor& visitor) {
|
||||
OV_OP_SCOPE(v13_FakeConvert_visit_attributes);
|
||||
visitor.on_attribute("destination_type", m_destination_type);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeConvert::validate_type() const {
|
||||
const auto& valid_types = fake_convert::get_valid_types();
|
||||
OPENVINO_ASSERT(std::find(valid_types.begin(), valid_types.end(), m_destination_type) != valid_types.end(),
|
||||
"Bad format for f8 conversion type: " + m_destination_type);
|
||||
}
|
||||
|
||||
bool FakeConvert::has_evaluate() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace v13
|
||||
} // namespace op
|
||||
} // namespace ov
|
||||
@@ -71,7 +71,7 @@ INSTANTIATE_TEST_SUITE_P(opset,
|
||||
OpsetTestParams{ov::get_opset10, 177},
|
||||
OpsetTestParams{ov::get_opset11, 177},
|
||||
OpsetTestParams{ov::get_opset12, 178},
|
||||
OpsetTestParams{ov::get_opset13, 185}),
|
||||
OpsetTestParams{ov::get_opset13, 186}),
|
||||
OpsetTestNameGenerator{});
|
||||
|
||||
class MyOpOld : public ov::op::Op {
|
||||
|
||||
51
src/core/tests/type_prop/fake_convert.cpp
Normal file
51
src/core/tests/type_prop/fake_convert.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/fake_convert.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "common_test_utils/type_prop.hpp"
|
||||
|
||||
using namespace ov;
|
||||
using ov::op::v0::Parameter;
|
||||
|
||||
TEST(type_prop, fake_convert_no_shift) {
|
||||
const auto data = std::make_shared<Parameter>(element::f32, PartialShape{2, 3, 8, 6});
|
||||
const auto scale = std::make_shared<Parameter>(element::f32, PartialShape{});
|
||||
|
||||
const auto op = std::make_shared<op::v13::FakeConvert>(data, scale);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{2, 3, 8, 6}));
|
||||
}
|
||||
|
||||
TEST(type_prop, fake_convert_basic_f32) {
|
||||
const auto data = std::make_shared<Parameter>(element::f32, PartialShape{2, 3, 8, 6});
|
||||
const auto scale = std::make_shared<Parameter>(element::f32, PartialShape{});
|
||||
const auto shift = std::make_shared<Parameter>(element::f32, PartialShape{});
|
||||
|
||||
const auto op = std::make_shared<op::v13::FakeConvert>(data, scale, shift);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{2, 3, 8, 6}));
|
||||
}
|
||||
|
||||
TEST(type_prop, fake_convert_basic_f16) {
|
||||
const auto data = std::make_shared<Parameter>(element::f16, PartialShape{2, 3, 8, 6});
|
||||
const auto scale = std::make_shared<Parameter>(element::f16, PartialShape{});
|
||||
const auto shift = std::make_shared<Parameter>(element::f16, PartialShape{});
|
||||
|
||||
const auto op = std::make_shared<op::v13::FakeConvert>(data, scale, shift);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f16);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{2, 3, 8, 6}));
|
||||
}
|
||||
|
||||
TEST(type_prop, fake_convert_dynamic_shape) {
|
||||
const auto data = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
const auto scale = std::make_shared<Parameter>(element::f32, PartialShape{});
|
||||
const auto shift = std::make_shared<Parameter>(element::f32, PartialShape{});
|
||||
|
||||
const auto op = std::make_shared<op::v13::FakeConvert>(data, scale, shift);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape::dynamic()));
|
||||
}
|
||||
47
src/core/tests/visitors/op/fake_convert.cpp
Normal file
47
src/core/tests/visitors/op/fake_convert.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/fake_convert.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "visitors/visitors.hpp"
|
||||
|
||||
using ov::Shape;
|
||||
using ov::op::v0::Parameter;
|
||||
using ov::test::NodeBuilder;
|
||||
|
||||
TEST(attributes, fake_convert_v13_attributes_default) {
|
||||
using ov::op::v13::FakeConvert;
|
||||
NodeBuilder::get_ops().register_factory<FakeConvert>();
|
||||
const auto data = std::make_shared<Parameter>(ov::element::f32, ov::PartialShape{2, 3, 8, 6});
|
||||
const auto scale = std::make_shared<Parameter>(ov::element::f32, ov::PartialShape{});
|
||||
const auto shift = std::make_shared<Parameter>(ov::element::f32, ov::PartialShape{});
|
||||
|
||||
const auto op = std::make_shared<FakeConvert>(data, scale, shift);
|
||||
|
||||
NodeBuilder builder(op, {data, scale, shift});
|
||||
auto g_op = ov::as_type_ptr<FakeConvert>(builder.create());
|
||||
|
||||
EXPECT_EQ(g_op->get_destination_type(), op->get_destination_type());
|
||||
EXPECT_EQ(g_op->get_output_element_type(0), op->get_output_element_type(0));
|
||||
EXPECT_EQ(g_op->get_output_partial_shape(0), op->get_output_partial_shape(0));
|
||||
}
|
||||
|
||||
TEST(attributes, fake_convert_v13_attributes_custom) {
|
||||
using ov::op::v13::FakeConvert;
|
||||
NodeBuilder::get_ops().register_factory<FakeConvert>();
|
||||
const auto data = std::make_shared<Parameter>(ov::element::f32, ov::PartialShape{2, 3, 8, 6});
|
||||
const auto scale = std::make_shared<Parameter>(ov::element::f32, ov::PartialShape{});
|
||||
const auto shift = std::make_shared<Parameter>(ov::element::f32, ov::PartialShape{});
|
||||
|
||||
const auto op = std::make_shared<FakeConvert>(data, scale, shift, "f8e5m2");
|
||||
|
||||
NodeBuilder builder(op, {data, scale, shift});
|
||||
auto g_op = ov::as_type_ptr<FakeConvert>(builder.create());
|
||||
|
||||
EXPECT_EQ(g_op->get_destination_type(), op->get_destination_type());
|
||||
EXPECT_EQ(g_op->get_output_element_type(0), op->get_output_element_type(0));
|
||||
EXPECT_EQ(g_op->get_output_partial_shape(0), op->get_output_partial_shape(0));
|
||||
}
|
||||
@@ -1291,6 +1291,15 @@ std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v13::BitwiseNo
|
||||
return std::make_shared<ov::Model>(results, ov::ParameterVector{param}, "BitwiseNotGraph");
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v13::FakeConvert>& node) {
|
||||
const auto data = std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::PartialShape{2, 3, 8, 6});
|
||||
const auto scale = std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::PartialShape{});
|
||||
const auto shift = std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::PartialShape{});
|
||||
const auto op = std::make_shared<ov::op::v13::FakeConvert>(data, scale, shift, "f8e4m3");
|
||||
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(op)};
|
||||
return std::make_shared<ov::Model>(results, ov::ParameterVector{data, scale, shift}, "FakeConvert");
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Model> generateArithmeticReductionKeepDims(const std::shared_ptr<ov::op::Op> &node) {
|
||||
const auto data = std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::PartialShape{3, 3});
|
||||
const auto axes = ov::op::v0::Constant::create(ov::element::i32, {1}, {1});
|
||||
|
||||
Reference in New Issue
Block a user