[CPU] Disable convert to BF16 in convert-range pattern (#18971)

This commit is contained in:
Xiuchuan Zhai 2023-08-25 13:00:24 +08:00 committed by GitHub
parent bcad953f5f
commit 350c4d2363
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 154 additions and 0 deletions

View File

@ -1806,6 +1806,12 @@ void Graph::EnforceInferencePrecision() {
if (node->getOriginalOutputPrecisionAtPort(i) != Precision::FP32)
continue;
// exclude Convert before Range since it may cause precision loss when integter type to LP.
// TODO: Incorrect subgraph is generated by ONNX FE + ticket 117861.
const auto &child = node->getChildEdgesAtPort(i)[0]->getChild();
if (child->getType() == Type::Range && node->getType() == Type::Convert)
continue;
node->setOriginalOutputPrecisionAtPort(i, inferPrec);
}
}

View File

@ -0,0 +1,148 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "shared_test_classes/base/ov_subgraph.hpp"
#include "ngraph_functions/utils/ngraph_helpers.hpp"
#include "ngraph_functions/builders.hpp"
#include "test_utils/cpu_test_utils.hpp"
#include <openvino/core/graph_util.hpp>
using namespace CPUTestUtils;
using namespace InferenceEngine;
using namespace ov::test;
namespace SubgraphTestsDefinitions {
/*
This test runs the following subgraph:
param1 param2
| |
(INT) |
| |
Convert |
| |
(FP32) |
| |
(No reorder to LP) |
| |
const | const |
\ | / |
\ | / /
Range /
| /
\ /
\ /
\ /
MatMul
|
Result
This test is needed to cover logic that allows to avoid computational error for subgraph: "[I32] -> Convert -> [F32] -> Range" due to precision lowering for floating point path inside "EnforceInferencePrecision" pass".
TODO: Incorrect subgraph is generated by ONNX FE + ticket 117861.
*/
using ConvertRangeSubgraphCPUTestParams = std::tuple<
std::map<std::string, ov::element::Type>,
std::vector<InputShape>,
std::vector<ov::Shape>
>;
class ConvertRangeSubgraphCPUTest: public testing::WithParamInterface<ConvertRangeSubgraphCPUTestParams>,
virtual public SubgraphBaseTest {
public:
static std::string getTestCaseName(testing::TestParamInfo<ConvertRangeSubgraphCPUTestParams> obj) {
std::map<std::string, ov::element::Type> additionalConfig;
std::vector<InputShape> inputShapes;
std::vector<ov::Shape> targetShapes;
std::tie(additionalConfig, inputShapes, targetShapes) = obj.param;
std::ostringstream result;
result << "IS=";
for (const auto& shape : inputShapes) {
result << ov::test::utils::partialShape2str({shape.first}) << "_";
}
result << "TS=";
for (const auto& shape : inputShapes) {
result << "(";
if (!shape.second.empty()) {
for (const auto& itr : shape.second) {
result << ov::test::utils::vec2str(itr);
}
}
result << ")";
}
result << "Prc=" << additionalConfig[ov::hint::inference_precision.name()];
return result.str();
}
void SetUp() override {
targetDevice = ov::test::utils::DEVICE_CPU;
std::vector<InputShape> inputShapes;
std::vector<ov::Shape> targetShapes;
std::map<std::string, ov::element::Type> additionalConfig;
std::tie(additionalConfig, inputShapes, targetShapes) = this->GetParam();
configuration.insert(additionalConfig.begin(), additionalConfig.end());
init_input_shapes(inputShapes);
auto input_params = ngraph::builder::makeDynamicParams(ov::element::f32, inputDynamicShapes);
auto zero = ov::op::v0::Constant::create(ov::element::i32, ov::Shape{}, {0});
auto one = ov::op::v0::Constant::create(ov::element::i32, ov::Shape{}, {1});
auto shapeof = std::make_shared<ov::op::v3::ShapeOf>(input_params[0], ov::element::i32);
auto gather = std::make_shared<ov::op::v8::Gather>(shapeof, one, zero);
auto convert = std::make_shared<ov::op::v0::Convert>(gather, ov::element::f32);
auto start = std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{}, 0);
auto step = std::make_shared<ov::op::v0::Constant>(ov::element::f32, ov::Shape{}, 1);
auto range = std::make_shared<ov::op::v4::Range>(start, convert, step, ov::element::f32);
range->set_friendly_name("float32_range");
auto matmul = std::make_shared<ov::op::v0::MatMul>(range, input_params[1], false, true);
auto result = std::make_shared<ov::op::v0::Result>(matmul);
result->set_friendly_name("output");
ov::ResultVector output_results = {result};
function = std::make_shared<ov::Model>(output_results, input_params, "convert_range");
};
void checkResults() {
for (const auto& n : compiledModel.get_runtime_model()->get_ordered_ops()) {
if (n->get_friendly_name() == "float32_range") {
ASSERT_EQ(n->get_input_element_type(1), ElementType::f32);
}
}
}
};
namespace {
TEST_P(ConvertRangeSubgraphCPUTest, CompareWithRefs) {
SKIP_IF_CURRENT_TEST_IS_DISABLED();
run();
checkResults();
}
const std::vector<std::map<std::string, ov::element::Type>> additionalConfig = {
{{ov::hint::inference_precision.name(), ov::element::bf16}},
{{ov::hint::inference_precision.name(), ov::element::f16}}
};
const std::vector<std::vector<InputShape>> input_shapes = {
{
{{1, -1}, {{1, 291}}}, // input 1
{{1, -1}, {{1, 291}}}, // input 2
}
};
const std::vector<std::vector<ov::Shape>> target_shapes = {
{
{1},
}
};
INSTANTIATE_TEST_SUITE_P(smoke_ConvertRangeSubgraphCPUTest,
ConvertRangeSubgraphCPUTest,
::testing::Combine(::testing::Values(additionalConfig[0], additionalConfig[1]),
::testing::ValuesIn(input_shapes),
::testing::ValuesIn(target_shapes)),
ConvertRangeSubgraphCPUTest::getTestCaseName);
} // namespace
} // namespace SubgraphTestsDefinitions