[CPU][FP16] Migrate from EnfornceInferencePrecision to ConvertPrecision (#23950)

### Details:
- *Migrate FP16 operations mark-up from `EnforceInferencePrecision`
utility to `ConvertPrecision` pass*


### Tickets:
 - *128875*

---------

Co-authored-by: Egor Duplensky <egor.duplensky@gmail.com>
This commit is contained in:
Bo Liu 2024-05-31 09:27:45 +08:00 committed by GitHub
parent 2d0e0366f7
commit cf08511954
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 144 additions and 43 deletions

View File

@ -229,8 +229,11 @@ auto get_num_result_children(const std::shared_ptr<const Node> &node) -> size_t
} // namespace
const std::set<ov::element::Type>& ov::snippets::pass::TokenizeSnippets::get_supported_element_types() {
static const std::set<ov::element::Type> supported_element_types =
{ ov::element::f32, ov::element::bf16, ov::element::i8, ov::element::u8 };
static const std::set<ov::element::Type> supported_element_types = {ov::element::f32,
ov::element::bf16,
ov::element::f16,
ov::element::i8,
ov::element::u8};
return supported_element_types;
}

View File

@ -70,7 +70,8 @@ ov::snippets::pass::FakeQuantizeDecomposition::FakeQuantizeDecomposition() {
return val == 0.f;
})) ||
out_scales.size() != 0));
const bool do_rounding = do_dequantize || fake_quantize_node->get_output_element_type(0) == ov::element::f32;
const bool do_rounding = do_dequantize || fake_quantize_node->get_output_element_type(0) == ov::element::f32 ||
fake_quantize_node->get_output_element_type(0) == ov::element::f16;
ov::NodeVector decomp_ops;
if (input_type != input_low.get_element_type()) {
@ -92,16 +93,18 @@ ov::snippets::pass::FakeQuantizeDecomposition::FakeQuantizeDecomposition() {
ov::PartialShape::broadcast_merge_into(scale_shape,
input_high.get_partial_shape(),
broadcast_type);
const auto scales =
std::make_shared<ov::op::v0::Constant>(ov::element::f32, scale_shape.get_shape(), out_scales);
const auto scales = std::make_shared<ov::op::v0::Constant>(input_low.get_element_type(),
scale_shape.get_shape(),
out_scales);
decomp_ops.push_back(scales);
result = std::make_shared<ov::op::v1::Multiply>(min, scales);
decomp_ops.push_back(result);
} else {
// (levels-1)
const auto levels_minus_one =
std::make_shared<ov::op::v0::Constant>(input_type, Shape{}, fake_quantize_node->get_levels() - 1);
const auto levels_minus_one = std::make_shared<ov::op::v0::Constant>(input_low.get_element_type(),
Shape{},
fake_quantize_node->get_levels() - 1);
decomp_ops.push_back(levels_minus_one);
// (input_high - input_low)
const auto subInHighLow = std::make_shared<ov::op::v1::Subtract>(input_high, input_low);
@ -129,8 +132,9 @@ ov::snippets::pass::FakeQuantizeDecomposition::FakeQuantizeDecomposition() {
if (do_dequantize) {
// (levels-1)
const auto levels_minus_one =
std::make_shared<ov::op::v0::Constant>(input_type, Shape{}, fake_quantize_node->get_levels() - 1);
const auto levels_minus_one = std::make_shared<ov::op::v0::Constant>(output_high.get_element_type(),
Shape{},
fake_quantize_node->get_levels() - 1);
// (output_high - output_low)
const auto sub_out_high_low = std::make_shared<ov::op::v1::Subtract>(output_high, output_low);
// (output_high - output_low) / (levels-1)

View File

@ -85,6 +85,9 @@ void jit_convert_truncation_emitter::emit_isa(const std::vector<size_t> &in_vec_
Vmm vmm_src = Vmm(in_vec_idxs[0]);
Vmm vmm_dst = Vmm(out_vec_idxs[0]);
Xmm xmm_dst = Xmm(out_vec_idxs[0]);
Ymm ymm_dst = Ymm(out_vec_idxs[0]);
// For Truncation behavior we can just move data from src to dst if we want convert i8 -> u8 or u8 -> i8
if ((input_type == output_type) || is_i8_and_u8_case()) {
if (vmm_src != vmm_dst) {
@ -99,7 +102,7 @@ void jit_convert_truncation_emitter::emit_isa(const std::vector<size_t> &in_vec_
h->uni_vcvttps2dq(vmm_dst, vmm_src);
break;
case ov::element::i32:
if (one_of(output_type, ov::element::f32, ov::element::bf16))
if (one_of(output_type, ov::element::f32, ov::element::bf16, ov::element::f16))
h->uni_vcvtdq2ps(vmm_dst, vmm_src);
break;
case ov::element::bf16:
@ -109,7 +112,11 @@ void jit_convert_truncation_emitter::emit_isa(const std::vector<size_t> &in_vec_
h->uni_vcvttps2dq(vmm_dst, vmm_dst);
break;
case ov::element::f16:
h->vcvtph2ps(vmm_dst, Ymm(vmm_src.getIdx()));
if (isa == dnnl::impl::cpu::x64::avx512_core)
h->vcvtph2ps(vmm_dst, Ymm(vmm_src.getIdx()));
else
h->vcvtph2ps(vmm_dst,
Xmm(vmm_src.getIdx())); // for avx2_vnni_2?
if (one_of(output_type, ov::element::i32, ov::element::i8, ov::element::u8))
h->uni_vcvttps2dq(vmm_dst, vmm_dst);
break;
@ -125,7 +132,7 @@ void jit_convert_truncation_emitter::emit_isa(const std::vector<size_t> &in_vec_
switch (output_type) {
case ov::element::f32:
if (!one_of(input_type, ov::element::i32, ov::element::bf16)) {
if (!one_of(input_type, ov::element::i32, ov::element::bf16, ov::element::f16)) {
h->uni_vcvtdq2ps(vmm_dst, vmm_dst);
}
break;
@ -143,13 +150,20 @@ void jit_convert_truncation_emitter::emit_isa(const std::vector<size_t> &in_vec_
break;
case ov::element::f16:
if (input_type == ov::element::f32) {
h->vcvtps2ph(vmm_dst, vmm_src, 0x4);
if (isa == dnnl::impl::cpu::x64::avx512_core)
h->vcvtps2ph(ymm_dst, vmm_src, 0x4);
else
h->vcvtps2ph(xmm_dst, vmm_src, 0x4);
} else {
if (one_of(input_type, ov::element::i8, ov::element::u8)) {
h->uni_vcvtdq2ps(vmm_dst, vmm_dst);
}
h->vcvtps2ph(vmm_dst, vmm_dst, 0x4);
if (isa == dnnl::impl::cpu::x64::avx512_core)
h->vcvtps2ph(ymm_dst, vmm_dst, 0x4);
else
h->vcvtps2ph(xmm_dst, vmm_dst, 0x4);
}
break;
case ov::element::i8:
case ov::element::u8:
if (input_type == ov::element::i32) {
@ -214,6 +228,9 @@ void jit_convert_saturation_emitter::emit_isa(const std::vector<size_t> &in_vec_
Vmm vmm_src = Vmm(in_vec_idxs[0]);
Vmm vmm_dst = Vmm(out_vec_idxs[0]);
Xmm xmm_dst = Xmm(out_vec_idxs[0]);
Ymm ymm_dst = Ymm(out_vec_idxs[0]);
if (input_type == output_type) {
h->uni_vmovups(vmm_dst, vmm_src);
return;
@ -225,7 +242,7 @@ void jit_convert_saturation_emitter::emit_isa(const std::vector<size_t> &in_vec_
h->uni_vcvtps2dq(vmm_dst, vmm_src);
break;
case ov::element::i32:
if (one_of(output_type, ov::element::f32, ov::element::bf16))
if (one_of(output_type, ov::element::f32, ov::element::bf16, ov::element::f16))
h->uni_vcvtdq2ps(vmm_dst, vmm_src);
break;
case ov::element::bf16:
@ -235,7 +252,11 @@ void jit_convert_saturation_emitter::emit_isa(const std::vector<size_t> &in_vec_
h->uni_vcvttps2dq(vmm_dst, vmm_dst);
break;
case ov::element::f16:
h->vcvtph2ps(vmm_dst, Ymm(vmm_src.getIdx()));
if (isa == dnnl::impl::cpu::x64::avx512_core)
h->vcvtph2ps(vmm_dst, Ymm(vmm_src.getIdx()));
else
h->vcvtph2ps(vmm_dst,
Xmm(vmm_src.getIdx())); // for avx2_vnni_2?
if (one_of(output_type, ov::element::i32, ov::element::i8, ov::element::u8))
h->uni_vcvttps2dq(vmm_dst, vmm_dst);
break;
@ -269,12 +290,18 @@ void jit_convert_saturation_emitter::emit_isa(const std::vector<size_t> &in_vec_
break;
case ov::element::f16:
if (input_type == ov::element::f32) {
h->vcvtps2ph(vmm_dst, vmm_src, 0x4);
if (isa == dnnl::impl::cpu::x64::avx512_core)
h->vcvtps2ph(ymm_dst, vmm_src, 0x4);
else
h->vcvtps2ph(xmm_dst, vmm_src, 0x4);
} else {
if (one_of(input_type, ov::element::i8, ov::element::u8)) {
h->uni_vcvtdq2ps(vmm_dst, vmm_dst);
}
h->vcvtps2ph(vmm_dst, vmm_dst, 0x4);
if (isa == dnnl::impl::cpu::x64::avx512_core)
h->vcvtps2ph(ymm_dst, vmm_dst, 0x4);
else
h->vcvtps2ph(xmm_dst, vmm_dst, 0x4);
}
break;
case ov::element::i8:

View File

@ -32,6 +32,7 @@
#include "openvino/core/except.hpp"
#include "openvino/core/model.hpp"
#include "openvino/core/node.hpp"
#include "openvino/core/type/element_type.hpp"
#include "utils/debug_capabilities.h"
#include "utils/general_utils.h"
#include "utils/ngraph_utils.hpp"
@ -1759,7 +1760,7 @@ void Graph::EnforceInferencePrecision() {
const auto inferPrec = getConfig().inferencePrecision;
if (one_of(inferPrec, element::f32, element::undefined))
if (one_of(inferPrec, element::f32, element::undefined, ov::element::f16))
return; // nothing to do, only precision reduction is currently allowed
#if defined(OPENVINO_ARCH_ARM) || defined(OPENVINO_ARCH_ARM64)
if (inferPrec == ov::element::f16)

View File

@ -512,13 +512,14 @@ void Convolution::getSupportedDescriptors() {
if (canBeExecutedInInt8()) {
DEBUG_LOG(getName(), "Creating I8 descriptor");
SetPostOpsAndZeroPoints(attrs);
// so far oneDNN INT8 convolution only support s8,u8,s32,f32,bf16 output types
if (outputDataType == memory::data_type::f16) {
outputDataType = memory::data_type::f32;
eltwisePrecision = ov::element::f32;
}
SetPostOpsAndZeroPoints(attrs);
in_candidate = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(0), inputDataType, nspc);
out_candidate = std::make_shared<DnnlBlockedMemoryDesc>(getOutputShapeAtPort(0), outputDataType, nspc);
createDescriptor({ in_candidate }, { out_candidate });

View File

@ -58,8 +58,8 @@ static const TypeMapping dnnlFCTypeMapping {
{{_f16, _bf16, _any, _any | _any}, pt(bypass(), bypass(), use<0>(), use<0>())},
// quantization configuration
// int8 inner_product does not support f16 output and bias
{{_u8 | _i8, _i8, _any, _f16}, pt(bypass(), bypass(), just<f32>(), just<f32>())},
{{_u8 | _i8, _i8, _any & ~_f16, _u8 | _i8 | _i32 | _bf16 | _f32}, pt(bypass(), bypass(), bypass(), use<3>())},
{{_u8 | _i8, _i8, _u8 | _i8 | _i32 | _bf16 | _f32 | _undefined, _u8 | _i8 | _i32 | _bf16 | _f32}, pt(bypass(), bypass(), bypass(), bypass())},
{{_u8 | _i8, _i8, _any, _any}, pt(bypass(), bypass(), just<f32>(), just<f32>())},
// compresses int weights (@todo more strict requrements for output precision?)
{{_bf16, _u8 | _i8 | _nf4 | _u4 | _i4, _any, _any}, pt(bypass(), bypass(), use<0>(), use<0>()),
Require<dnnl::impl::cpu::x64::avx512_core_bf16>()}, // Ticket 122347

View File

@ -190,6 +190,7 @@ private:
Xbyak::Reg64 reg_params = abi_param1;
Xbyak::Reg8 reg_tmp_8 = r15b;
Xbyak::Reg16 reg_tmp_16 = r15w;
Xbyak::Reg32 reg_tmp_32 = r15d;
Xbyak::Reg64 reg_tmp_64 = r15;
@ -1012,7 +1013,9 @@ private:
uni_vpextrw(op, xmm_dst, 0x0);
break;
case memory::data_type::f16:
vcvtps2ph(op, xmm_dst, 0x4);
vcvtps2ph(xmm_dst, xmm_dst, 0x4);
movq(reg_tmp_64, xmm_dst);
mov(op, reg_tmp_16);
break;
case memory::data_type::s8:
uni_vpackssdw(xmm_dst, xmm_dst, xmm_dst);
@ -1241,6 +1244,7 @@ private:
Xbyak::Reg64 reg_params = abi_param1;
Xbyak::Reg8 reg_tmp_8 = r14b;
Xbyak::Reg16 reg_tmp_16 = r14w;
Xbyak::Reg32 reg_tmp_32 = r14d;
Xbyak::Reg64 reg_tmp_64 = r14;
@ -1676,7 +1680,9 @@ private:
uni_vpextrw(op, xmm_dst, 0x0);
break;
case memory::data_type::f16:
vcvtps2ph(op, xmm_dst, 0x4);
vcvtps2ph(xmm_dst, xmm_dst, 0x4);
movq(reg_tmp_64, xmm_dst);
mov(op, reg_tmp_16);
break;
case memory::data_type::s8:
uni_vpackssdw(xmm_dst, xmm_dst, xmm_dst);

View File

@ -349,38 +349,31 @@ void Transformations::PreLpt(const std::vector<ov::element::Type>& defaultPrecis
// @todo should we always convert to f32 regardless of hardware support, as it is done for f16?
if (!hasHardwareSupport(ov::element::bf16))
map.insert({ov::element::bf16, ov::element::f32});
#if defined(OPENVINO_ARCH_ARM) || defined(OPENVINO_ARCH_ARM64)
if (!one_of(inferencePrecision, element::f16, element::undefined)) {
map.insert({element::f16, element::f32});
map.insert({ov::element::f16, ov::element::f32});
}
#else
if (inferencePrecision != element::undefined) {
map.insert({element::f16, element::f32});
}
#endif
return map;
};
type_to_fuse_map type_to_fuse = {{ov::opset10::Convert::get_type_info_static(), fuse_type_to_convert}};
#if defined(OPENVINO_ARCH_ARM) || defined(OPENVINO_ARCH_ARM64)
// It cannot be static data, because it may be difference for different inferencePrecision
const auto precisions = get_convert_precisions();
if (inferencePrecision == ov::element::f16) {
precisions_map fp_convert_precision_map = {{ov::element::f32, ov::element::f16}};
//keep fq nodes in f32 prec to avoid performance degradation
type_to_fuse_map f16_fuse_map = {{ov::opset1::FakeQuantize::get_type_info_static(), fuse_type_to_fq}};
#if defined(OPENVINO_ARCH_ARM) || defined(OPENVINO_ARCH_ARM64)
type_to_fuse_map fuse_map = {{ov::opset1::FakeQuantize::get_type_info_static(), fuse_type_to_fq}};
#else
type_to_fuse_map fuse_map = {};
#endif
const bool keep_precision_sensitive_in_fp32 = true;
CPU_REGISTER_PASS_COMMON(manager,
ov::pass::ConvertPrecision,
fp_convert_precision_map,
f16_fuse_map,
fuse_map,
keep_precision_sensitive_in_fp32,
false);
}
#else
const auto precisions = get_convert_precisions();
#endif
CPU_REGISTER_PASS_COMMON(manager, ov::pass::KeepConstAndDecompression);
CPU_SET_CALLBACK_COMMON(manager,
[](const_node_ptr &node) -> bool {
@ -878,6 +871,8 @@ void Transformations::MainSnippets(void) {
return false;
const auto in_type0 = matmul->get_input_element_type(0);
const auto in_type1 = matmul->get_input_element_type(1);
if (in_type0 == ov::element::f16 || in_type1 == ov::element::f16)
return false;
if (in_type0 == ov::element::f32 && in_type1 == ov::element::f32 && one_of(inferencePrecision, element::f32, element::undefined))
return true;
// [114487] brgemm kernel in oneDNN requires brgemm_copy_b kernel if MatMul node has transposed_b=True
@ -949,7 +944,7 @@ void Transformations::MainSnippets(void) {
#if defined(OPENVINO_ARCH_ARM64)
{ ov::element::f32 };
#else
{ ov::element::f32, ov::element::bf16, ov::element::i8, ov::element::u8 };
{ov::element::f32, ov::element::bf16, ov::element::f16, ov::element::i8, ov::element::u8};
#endif
if (!ignoreCallback) {

View File

@ -53,7 +53,15 @@ void TransposeLayerCPUTest::SetUp() {
std::tie(inFmts, outFmts, priority, selectedType) = cpuParams;
updateSelectedType("unknown", inType, configuration);
// ov::pass::TransposeSinking will moves Transposes through Convert, which will change Expected primType for the
// following cases, currently change selectedType to pass primType check
const auto it = configuration.find(ov::hint::inference_precision.name());
if (it != configuration.end() && it->second.as<ov::element::Type>() == ov::element::f16 &&
netPrecision == ov::element::f32) {
selectedType = "unknown_f32";
} else {
updateSelectedType("unknown", inType, configuration);
}
init_input_shapes({inputShapes});

View File

@ -197,6 +197,8 @@ std::vector<std::string> disabledTestPatterns() {
R"(.*smoke_LPT/InterpolateTransformation.*)",
// Issue: 129931
R"(smoke_LPT/ConvolutionTransformation.CompareWithRefImpl/f32_\[.*,3,16,16\]_CPU_f32_rank=4D_fq_on_data=\{level=256_shape=\[1\]_input_low=\{ 0 \}_input_high=\{ 255 \}_output_low=\{ .*18.7 \}_output_high\{ 18.8 \}_precision=\}_fq_on_weights=\{_255_\[6,1,1,1\]_\{ .*1.52806e.*39, .*0.2, .*0.3, .*0.3, .*0.2, .*0.1 \}_\{ 1.52806e.*39, 0.2, 0.3, 0.3, 0.2, 0.1 \}\})",
// TODO: 141068
R"(smoke_Snippets_FQDecomposition.*netPRC=f16_D=CPU.*)",
// Issue: 133173
R"(.*smoke_ScaledAttn_CPU/ScaledAttnLayerCPUTest.CompareWithRefs/netPRC=bf16.*has_scale=0.*)",
R"(.*smoke_LPT_4D/ConvolutionBackpropDataTransformation.CompareWithRefImpl/f32_\[1,8,16,16\]_CPU_f32_\[16,16\]_level=256_shape=\[.*\]_input_low=\{ 0 \}_input_high=\{ 25.5 \}_output_low=\{ 0 \}_output_high\{ 25.5 \}_precision=__255_\[.*\]_\{ -12.7 \}_\{ 12.7 \}_\{\}.*)",
@ -416,6 +418,8 @@ std::vector<std::string> disabledTestPatterns() {
retVector.emplace_back(R"(smoke_Snippets_Eltwise/TwoInputsAndOutputs.*)");
// arm jit_eltwise_emitters doesn't support jit_power_dynamic_emitter yet
retVector.emplace_back(R"(smoke_Snippets_Eltwise/MaxNumParamsEltwise.*)");
// TODO: 141292
retVector.emplace_back(R"(smoke_Snippets_Eltwise_FP16.*)");
#endif
#if defined(_WIN32)
retVector.emplace_back(R"(.*smoke_QuantizedConvolutionBatchNormTransposeOnWeights/QuantizedConvolutionBatchNorm.CompareWithRefs/conv_type=convolution_quantize_type=fake_quantize_intervals_type=per_(tensor|channel)_transpose_on_weights=true_device=CPU.*)");
@ -528,6 +532,9 @@ std::vector<std::string> disabledTestPatterns() {
retVector.emplace_back(R"(smoke_CompareWithRefs_4D.*/EltwiseLayerCPUTest.*Sub_secondary.*INFERENCE_PRECISION_HINT=f16.*FakeQuantize.*enforceSnippets=1.*)");
retVector.emplace_back(R"(smoke_Reduce.*/ReduceCPULayerTest.*axes=\((0.1|1)\).*Prod_KeepDims.*INFERENCE_PRECISION_HINT=f16.*)");
retVector.emplace_back(R"(smoke_ConvertRangeSubgraphCPUTest/ConvertRangeSubgraphCPUTest\.CompareWithRefs.*Prc=f16.*)");
// Issue: 142465
retVector.emplace_back(R"(smoke_Reduce_MultiAxis_4D_fusing_CPU/ReduceCPULayerTest.CompareWithRefs.*INFERENCE_PRECISION_HINT=f16.*)");
retVector.emplace_back(R"(smoke_Reduce_MultiAxis_5D_fusing_CPU/ReduceCPULayerTest.CompareWithRefs.*INFERENCE_PRECISION_HINT=f16.*)");
}
return retVector;

View File

@ -109,6 +109,15 @@ INSTANTIATE_TEST_SUITE_P(smoke_Snippets_Eltwise, AddConst,
::testing::Values(ov::test::utils::DEVICE_CPU)),
AddConst::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Snippets_Eltwise_FP16, AddConst,
::testing::Combine(
::testing::ValuesIn(inShapesAddConst),
::testing::ValuesIn(inShapesConstAddConst),
::testing::Values(ov::element::f16),
::testing::Values(1), // Add
::testing::Values(1), // Subgraph is created, since the inputs are followed by converts
::testing::Values(ov::test::utils::DEVICE_CPU)),
AddConst::getTestCaseName);
// ===================================AddRollConst=========================================================//
INSTANTIATE_TEST_SUITE_P(smoke_Snippets_Eltwise, AddRollConst,
::testing::Combine(

View File

@ -16,18 +16,27 @@ const std::vector<std::pair<std::vector<ov::element::Type>, std::vector<ov::elem
{ { ov::element::f32 }, { ov::element::bf16 } },
{ { ov::element::f32 }, { ov::element::u8 } },
{ { ov::element::f32 }, { ov::element::i8 } },
{ { ov::element::f32 }, { ov::element::f16 } },
{ { ov::element::f16 }, { ov::element::f32 } },
{ { ov::element::f16 }, { ov::element::bf16 } },
{ { ov::element::f16 }, { ov::element::i8 } },
{ { ov::element::f16 }, { ov::element::u8 } },
{ { ov::element::bf16 }, { ov::element::f32 } },
{ { ov::element::bf16 }, { ov::element::i8 } },
{ { ov::element::bf16 }, { ov::element::u8 } },
{ { ov::element::bf16 }, { ov::element::f16 } },
{ { ov::element::i8 }, { ov::element::f32 } },
{ { ov::element::i8 }, { ov::element::bf16 } },
{ { ov::element::i8 }, { ov::element::u8 } },
{ { ov::element::i8 }, { ov::element::f16 } },
{ { ov::element::u8 }, { ov::element::f32 } },
{ { ov::element::u8 }, { ov::element::bf16 } },
{ { ov::element::u8 }, { ov::element::i8 } },
{ { ov::element::u8 }, { ov::element::f16 } },
};
const std::vector<std::vector<ov::test::InputShape>> inputShapes_Convert = {
@ -56,9 +65,11 @@ const std::vector<std::pair<std::vector<ov::element::Type>, std::vector<ov::elem
{ { ov::element::i8 }, { ov::element::f32 } },
{ { ov::element::i8 }, { ov::element::bf16 } },
{ { ov::element::i8 }, { ov::element::f16 } },
{ { ov::element::u8 }, { ov::element::f32 } },
{ { ov::element::u8 }, { ov::element::bf16 } },
{ { ov::element::u8 }, { ov::element::f16 } },
};
const std::vector<std::vector<ov::test::InputShape>> inputShapes_ConvertInput = {

View File

@ -20,6 +20,13 @@ const std::vector<TestValues> testValuesDecompositionScalars = {
1.f,
{{}, {}, {}, {}},
},
{
ov::element::f16,
ov::Shape{1, 3, 16, 16},
ov::element::f16,
1.f,
{{}, {}, {}, {}},
},
};
const std::vector<TestValues> testValuesDecompositionPerChannel = {
{
@ -29,6 +36,16 @@ const std::vector<TestValues> testValuesDecompositionPerChannel = {
1.f,
{{1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}},
},
{
ov::element::f16,
ov::Shape{1, 3, 16, 16},
ov::element::f16,
1.f,
{{1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}},
},
};
const std::vector<TestValues> testValuesDecompositionPerChannelInput = {
{
ov::element::f32,
ov::Shape{1, 3, 16, 16},
@ -36,6 +53,13 @@ const std::vector<TestValues> testValuesDecompositionPerChannel = {
1.f,
{{1, 3, 1, 1}, {1, 3, 1, 1}, {}, {}},
},
{
ov::element::f16,
ov::Shape{1, 3, 16, 16},
ov::element::f16,
1.f,
{{1, 3, 1, 1}, {1, 3, 1, 1}, {}, {}},
},
};
std::vector<std::pair<std::shared_ptr<ov::Node>, std::pair<std::string, std::string> >> operations = {
@ -58,7 +82,7 @@ INSTANTIATE_TEST_SUITE_P(
smoke_Snippets_FQDecomposition_PerChannel,
FakeQuantizeDecompositionTest,
::testing::Combine(
::testing::Values(testValuesDecompositionPerChannel[0]),
::testing::ValuesIn(testValuesDecompositionPerChannel),
::testing::ValuesIn(operations),
// reorder (nChw[16|8]c) + MaxPool + reorder(nChw[16|8]c) x6 + Subgraph + reorder(nchw)
::testing::Values(std::pair<size_t, size_t>{10, 1}),
@ -69,7 +93,7 @@ INSTANTIATE_TEST_SUITE_P(
smoke_Snippets_FQDecomposition_PerChannel_Input,
FakeQuantizeDecompositionTest,
::testing::Combine(
::testing::Values(testValuesDecompositionPerChannel[1]),
::testing::ValuesIn(testValuesDecompositionPerChannelInput),
::testing::ValuesIn(operations),
// reorder (nChw[16|8]c) + MaxPool + reorder(nChw[16|8]c) x4 + Subgraph + reorder(nchw)
::testing::Values(std::pair<size_t, size_t>{8, 1}),

View File

@ -83,6 +83,9 @@ void AddConst::SetUp() {
if (!configuration.count("SNIPPETS_MODE")) {
configuration.insert({"SNIPPETS_MODE", "IGNORE_CALLBACK"});
}
if (type == ov::element::f16) {
abs_threshold = 3e-2;
}
}
void AddRollConst::SetUp() {

View File

@ -53,6 +53,7 @@ parameters Convert::generate_params_random() const {
case ov::element::f32:
case ov::element::i32:
case ov::element::bf16:
case ov::element::f16:
startFrom = -10;
range = 20;
break;
@ -115,6 +116,7 @@ parameters ConvertInput::generate_params_random() const {
switch (funcInputs[i].get_element_type()) {
case ov::element::f32:
case ov::element::bf16:
case ov::element::f16:
startFrom = -10;
range = 20;
resolution = 7;