Merge remote-tracking branch 'upstream/master' into layer_test_common

This commit is contained in:
Efode, Irina committed 2021-10-18 18:23:50 +03:00
commit a504be8440
445 files changed
+33687 -509

No files matched your search

+10
View File
@@ -64,3 +64,13 @@
*.gif filter=lfs diff=lfs merge=lfs -text
*.vsdx filter=lfs diff=lfs merge=lfs -text
*.bmp filter=lfs diff=lfs merge=lfs -text
#POT attributes
tools/pot/tests/data/test_cases_refs/* filter=lfs diff=lfs merge=lfs -text
/tools/pot/tests/** -pot_package
/configs/accuracy_checker/** -pot_package
/configs/quantization/** -pot_package
/tools/pot/tools/auxilary/** -pot_package
/tools/pot/tools/run_series_experiments.py -pot_package
/tools/pot/.pylintrc -pot_package
/tools/pot/README_dev.md -pot_package
+3
View File
@@ -56,3 +56,6 @@
[submodule "thirdparty/onednn_gpu"]
path = thirdparty/onednn_gpu
url = https://github.com/oneapi-src/oneDNN.git
[submodule "tools/pot/thirdparty/open_model_zoo"]
path = tools/pot/thirdparty/open_model_zoo
url = https://github.com/openvinotoolkit/open_model_zoo.git
@@ -0,0 +1,98 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/op/bucketize.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
struct BucketizeParams {
template <class IT, class BT, class OT>
BucketizeParams(const element::Type& input_type, const PartialShape& input_pshape, const std::vector<IT>& input,
const element::Type& bucket_type, const PartialShape& bucket_pshape, const std::vector<BT>& buckets, bool with_right_bound,
const element::Type& output_type, const std::vector<OT>& expected_output)
: input_type(input_type),
input_pshape(input_pshape),
input(CreateTensor(input_type, input)),
bucket_type(bucket_type),
bucket_pshape(bucket_pshape),
buckets(CreateTensor(bucket_type, buckets)),
with_right_bound(with_right_bound),
output_type(output_type),
expected_output(CreateTensor(output_type, expected_output)) {}
element::Type input_type;
PartialShape input_pshape;
runtime::Tensor input;
element::Type bucket_type;
PartialShape bucket_pshape;
runtime::Tensor buckets;
bool with_right_bound;
element::Type output_type;
runtime::Tensor expected_output;
};
class ReferenceBucketizeLayerTest : public testing::TestWithParam<BucketizeParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params.input_type, params.input_pshape, params.bucket_type, params.bucket_pshape,
params.with_right_bound, params.output_type);
inputData = {params.input, params.buckets};
refOutData = {params.expected_output};
}
static std::string getTestCaseName(const testing::TestParamInfo<BucketizeParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "input_type=" << param.input_type << "_";
result << "input_pshape=" << param.input_pshape << "_";
result << "bucket_type=" << param.bucket_type << "_";
result << "bucket_pshape=" << param.bucket_pshape << "_";
result << "with_right_bound=" << param.with_right_bound << "_";
result << "output_type=" << param.output_type;
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const element::Type& input_type, const PartialShape& input_pshape,
const element::Type& bucket_type, const PartialShape& bucket_pshape,
const bool with_right_bound, const element::Type& output_type) {
auto data = std::make_shared<op::v0::Parameter>(input_type, input_pshape);
auto buckets = std::make_shared<op::v0::Parameter>(bucket_type, bucket_pshape);
return std::make_shared<Function>(std::make_shared<op::v3::Bucketize>(data, buckets, output_type, with_right_bound),
ParameterVector {data, buckets});
}
};
TEST_P(ReferenceBucketizeLayerTest, CompareWithHardcodedRefs) {
Exec();
}
INSTANTIATE_TEST_SUITE_P(smoke_Bucketize_With_Hardcoded_Refs, ReferenceBucketizeLayerTest,
::testing::Values(
// fp32, int32, with_right_bound
BucketizeParams(element::f32,
PartialShape {10, 1},
std::vector<float> {8.f, 1.f, 2.f, 1.1f, 8.f, 10.f, 1.f, 10.2f, 0.f, 20.f},
element::i32,
PartialShape {4},
std::vector<int32_t> {1, 4, 10, 20},
true,
element::i32,
std::vector<int32_t> {2, 0, 1, 1, 2, 2, 0, 3, 0, 3}),
// fp32, int32, with_right_bound
BucketizeParams(element::i32,
PartialShape {1, 1, 10},
std::vector<int32_t> {8, 1, 2, 1, 8, 5, 1, 5, 0, 20},
element::i32,
PartialShape {4},
std::vector<int32_t> {1, 4, 10, 20},
false,
element::i32,
std::vector<int32_t> {2, 1, 1, 1, 2, 2, 1, 2, 0, 4})),
ReferenceBucketizeLayerTest::getTestCaseName);
@@ -0,0 +1,262 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <random>
#include "openvino/op/non_zero.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
namespace {
struct NonZeroParams {
template <class IT, class OT>
NonZeroParams(const PartialShape& dynamicShape, const PartialShape& inputShape,
const element::Type& inType, const element::Type& refType,
const std::vector<IT>& inputData, const std::vector<OT>& refData,
const std::string& test_name = "")
: dynamicShape(dynamicShape),
inputShape(inputShape),
inType(inType),
refType(refType),
inputData(CreateTensor(inType, inputData)),
refData(CreateTensor(refType, refData)),
testcaseName(test_name) {}
PartialShape dynamicShape;
PartialShape inputShape;
element::Type inType;
element::Type refType;
runtime::Tensor inputData;
runtime::Tensor refData;
std::string testcaseName;
};
class ReferenceNonZeroLayerTest : public testing::TestWithParam<NonZeroParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params.dynamicShape, params.inType, params.refType);
inputData = {params.inputData};
refOutData = {params.refData};
}
static std::string getTestCaseName(const testing::TestParamInfo<NonZeroParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "dShape=" << param.dynamicShape << "_";
result << "iShape=" << param.inputShape << "_";
result << "iType=" << param.inType << "_";
if (param.testcaseName != "") {
result << "oType=" << param.refType << "_";
result << param.testcaseName;
} else {
result << "oType=" << param.refType;
}
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const PartialShape& input_shape, const element::Type& input_type,
const element::Type& output_type) {
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
const auto NonZero = std::make_shared<op::v3::NonZero>(in, output_type);
return std::make_shared<Function>(NodeVector {NonZero}, ParameterVector {in});
}
};
TEST_P(ReferenceNonZeroLayerTest, CompareWithHardcodedRefs) {
Exec();
}
INSTANTIATE_TEST_SUITE_P(smoke_NonZero_With_Hardcoded_Refs, ReferenceNonZeroLayerTest,
::testing::Values(
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i32,
element::i32,
std::vector<int32_t>{1, 1, 1, 1, 1, 1},
std::vector<int32_t>{0, 0, 1, 1, 2, 2, 0, 1, 0, 1, 0, 1},
"all_1s"),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i32,
element::i32,
std::vector<int32_t>{0, 0, 0, 0, 0, 0},
std::vector<int32_t>{},
"all_0s"),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i32,
element::i64,
std::vector<int32_t>{1, 1, 1, 1, 1, 1},
std::vector<int64_t>{0, 0, 1, 1, 2, 2, 0, 1, 0, 1, 0, 1},
"all_1s_int64"),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i32,
element::i64,
std::vector<int32_t>{0, 0, 0, 0, 0, 0},
std::vector<int64_t>{},
"all_0s_int64"),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::boolean,
element::i32,
std::vector<char>{false, false, false, false, true, true},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i8,
element::i32,
std::vector<int8_t>{0, 0, 0, 0, 1, 3},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i16,
element::i32,
std::vector<int16_t>{0, 0, 0, 0, 1, 3},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i32,
element::i32,
std::vector<int32_t>{0, 0, 0, 0, 1, 3},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i64,
element::i32,
std::vector<int64_t>{0, 0, 0, 0, 1, 3},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::u8,
element::i32,
std::vector<uint8_t>{0, 0, 0, 0, 1, 3},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::u16,
element::i32,
std::vector<uint16_t>{0, 0, 0, 0, 1, 3},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::u32,
element::i32,
std::vector<uint32_t>{0, 0, 0, 0, 1, 3},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::u64,
element::i32,
std::vector<uint64_t>{0, 0, 0, 0, 1, 3},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::bf16,
element::i32,
std::vector<bfloat16>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::f16,
element::i32,
std::vector<float16>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::f32,
element::i32,
std::vector<float>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::f64,
element::i32,
std::vector<double>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f},
std::vector<int32_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::boolean,
element::i64,
std::vector<char>{false, false, false, false, true, true},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i8,
element::i64,
std::vector<int8_t>{0, 0, 0, 0, 1, 3},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i16,
element::i64,
std::vector<int16_t>{0, 0, 0, 0, 1, 3},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i32,
element::i64,
std::vector<int32_t>{0, 0, 0, 0, 1, 3},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::i64,
element::i64,
std::vector<int64_t>{0, 0, 0, 0, 1, 3},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::u8,
element::i64,
std::vector<uint8_t>{0, 0, 0, 0, 1, 3},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::u16,
element::i64,
std::vector<uint16_t>{0, 0, 0, 0, 1, 3},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::u32,
element::i64,
std::vector<uint32_t>{0, 0, 0, 0, 1, 3},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::u64,
element::i64,
std::vector<uint64_t>{0, 0, 0, 0, 1, 3},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::bf16,
element::i64,
std::vector<bfloat16>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::f16,
element::i64,
std::vector<float16>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::f32,
element::i64,
std::vector<float>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f},
std::vector<int64_t>{2, 2, 0, 1}),
NonZeroParams(PartialShape{3, 2},
PartialShape{3, 2},
element::f64,
element::i64,
std::vector<double>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f},
std::vector<int64_t>{2, 2, 0, 1})),
ReferenceNonZeroLayerTest::getTestCaseName);
} // namespace
@@ -84,7 +84,12 @@ InferenceEngine::CNNNetwork clDNNEngine::CloneAndTransformNetwork(const Inferenc
if (clonedNetwork.getFunction()) {
auto nGraphFunc = clonedNetwork.getFunction();
TransformationsPipeline transformations(config);
auto transformation_config = CLDNNPlugin::Config(config);
#ifdef ENABLE_ONEDNN_FOR_GPU
if (GetDeviceInfo(config.key_config_map).supports_immad)
transformation_config.enable_fp16_for_quantized_models = false;
#endif
TransformationsPipeline transformations(transformation_config);
transformations.apply(nGraphFunc);
}
@@ -28,6 +28,7 @@
#include <transformations/common_optimizations/common_optimizations.hpp>
#include <transformations/common_optimizations/weights_dequantize_to_fake_quantize.hpp>
#include "transformations/common_optimizations/convert_quantize_dequantize.hpp"
#include <transformations/common_optimizations/nop_elimination.hpp>
#include <transformations/op_conversions/convert_depth_to_space.hpp>
#include <transformations/op_conversions/convert_shuffle_channels3.hpp>
#include <transformations/op_conversions/convert_space_to_depth.hpp>
@@ -184,6 +185,7 @@ static void TransformationUpToCPUSpecificOpSet(std::shared_ptr<ngraph::Function>
std::vector<ngraph::element::Type>{ ngraph::element::i8, ngraph::element::u8, ngraph::element::i4, ngraph::element::u4 });
}
manager.register_pass<ngraph::pass::ConvertPrecision>(precisions);
manager.register_pass<ngraph::pass::EliminateConvert>();
auto pass_config = manager.get_pass_config();
@@ -4,6 +4,7 @@
#include "mkldnn_matmul_node.h"
#include "ie_precision.hpp"
#include "memory_desc/cpu_blocked_memory_desc.h"
#include "cpu_types.h"
#include "mkldnn_eltwise_node.h"
@@ -120,6 +121,12 @@ void MKLDNNMatMulNode::getSupportedDescriptors() {
if (firstInPortPrec.size() != secondInPortPrec.size())
firstInPortPrec = secondInPortPrec = getMaxPrecision(getOriginalInputPrecisions());
// fallback to fp32 for any precision that cannot be handled natively
if ((!one_of(firstInPortPrec , Precision::U8, Precision::I8, Precision::BF16, Precision::FP32) ||
!one_of(secondInPortPrec , Precision::I8, Precision::BF16, Precision::FP32))) {
outPortPrec = firstInPortPrec = secondInPortPrec = Precision::FP32;
}
if (!fusedWith.empty()) {
outPortPrec = fusedWith[fusedWith.size() - 1]->getOriginalOutputPrecisionAtPort(0);
}
@@ -111,12 +111,13 @@ void FrontEnd::addPreProcessStages(const Model& model) {
"@after-std-scale");
bindData(newInput, ieData);
auto scale = 1 / preProcess[0]->stdScale;
_stageBuilder->addPowerStage(
model,
input->name() + "@stdScale=" + InferenceEngine::CNNLayer::ie_serialize_float(preProcess[0]->stdScale),
nullptr,
preProcess[0]->stdScale,
scale,
1.0f,
0.0f,
input,
@@ -18,6 +18,10 @@ const std::vector<std::map<std::string, std::string>> configs = {
{}
};
const std::vector<std::map<std::string, std::string>> HeteroConfigs = {
{{"TARGET_FALLBACK", CommonTestUtils::DEVICE_CPU}}
};
std::shared_ptr<ngraph::Function> getFunction1() {
const std::vector<size_t> inputShape = {1, 4, 20, 20};
const ngraph::element::Type_t ngPrc = ngraph::element::Type_t::f32;
@@ -76,4 +80,15 @@ INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests_2, InferRequestDynamicTests,
::testing::Values(CommonTestUtils::DEVICE_CPU),
::testing::ValuesIn(configs)),
InferRequestDynamicTests::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, InferRequestDynamicTests,
::testing::Combine(
::testing::Values(getFunction2()),
::testing::Values(std::vector<std::pair<std::vector<size_t>, std::vector<size_t>>>{
{{1, 4, 20, 20}, {1, 2, 20, 40}},
{{2, 4, 20, 20}, {2, 2, 20, 40}}}),
::testing::Values(CommonTestUtils::DEVICE_HETERO),
::testing::ValuesIn(HeteroConfigs)),
InferRequestDynamicTests::getTestCaseName);
} // namespace
@@ -13,10 +13,20 @@ const std::vector<std::map<std::string, std::string>> configs = {
{}
};
const std::vector<std::map<std::string, std::string>> HeteroConfigs = {
{{"TARGET_FALLBACK", CommonTestUtils::DEVICE_CPU}}
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, OVInferenceChaining,
::testing::Combine(
::testing::Values(CommonTestUtils::DEVICE_CPU),
::testing::ValuesIn(configs)),
OVInferenceChaining::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, OVInferenceChaining,
::testing::Combine(
::testing::Values(CommonTestUtils::DEVICE_HETERO),
::testing::ValuesIn(HeteroConfigs)),
OVInferenceChaining::getTestCaseName);
} // namespace
@@ -118,8 +118,11 @@ std::vector<std::string> disabledTestPatterns() {
// CPU does not support dynamic rank
// Issue: CVS-66778
R"(.*smoke_BehaviorTests.*InferFullyDynamicNetworkWith(S|G)etTensor.*)",
R"(.*smoke_Hetero_BehaviorTests.*InferFullyDynamicNetworkWith(S|G)etTensor.*)",
R"(.*smoke_BehaviorTests.*DynamicOutputToDynamicInput.*)",
R"(.*smoke_BehaviorTests.*DynamicInputToDynamicOutput.*)",
R"(.*smoke_Hetero_BehaviorTests.*DynamicOutputToDynamicInput.*)",
R"(.*smoke_Hetero_BehaviorTests.*DynamicInputToDynamicOutput.*)",
// CPU dynamism: empty tensor returns size() == 1. Looks like layout is SCALAR
// Issue: CVS-66780
@@ -33,9 +33,6 @@ std::vector<std::string> disabledTestPatterns() {
".*ProposalLayerTest.*",
// TODO: Issue 51804
".*InferRequestPreprocessConversionTest.*oPRC=U8.*",
// TODO: Issue: 56556
R"(.*(PreprocessTest).*(SetScalePreProcessSetBlob).*)",
R"(.*(PreprocessTest).*(SetScalePreProcessGetBlob).*)",
// TODO: Issue 54163
R"(.*ActivationLayerTest.*SoftPlus.*)",
// TODO: Issue 54722
@@ -459,7 +459,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
}
#define GET_DATA_BS_FS_YX_BSV16_FSV16_INDEX(prefix, b, f, y, x) \
get_bs_fs_zyx_bsv_fsv_index( \
get_bs_fs_zyx_bsv_fsv_index( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -475,7 +475,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 16, 16)
#define GET_DATA_BS_FS_YX_BSV32_FSV32_INDEX(prefix, b, f, y, x) \
get_bs_fs_zyx_bsv_fsv_index( \
get_bs_fs_zyx_bsv_fsv_index( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -491,7 +491,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 32, 32)
#define GET_DATA_BS_FS_YX_BSV4_FSV4_INDEX(prefix, b, f, y, x) \
get_bs_fs_zyx_bsv_fsv_index( \
get_bs_fs_zyx_bsv_fsv_index( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -507,7 +507,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 4, 4)
#define GET_DATA_BS_FS_YX_BSV4_FSV2_INDEX(prefix, b, f, y, x) \
get_bs_fs_zyx_bsv_fsv_index( \
get_bs_fs_zyx_bsv_fsv_index( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -523,7 +523,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 4, 2)
#define GET_DATA_BS_FS_YX_BSV32_FSV16_INDEX(prefix, b, f, y, x) \
get_bs_fs_zyx_bsv_fsv_index( \
get_bs_fs_zyx_bsv_fsv_index( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -539,7 +539,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 32, 16)
#define GET_DATA_BS_FS_ZYX_BSV16_FSV16_INDEX(prefix, b, f, z, y, x) \
get_bs_fs_zyx_bsv_fsv_index( \
get_bs_fs_zyx_bsv_fsv_index( \
b, f, z, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -555,7 +555,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 16, 16)
#define GET_DATA_BS_FS_YX_BSV16_FSV16_INDEX_SAFE(prefix, b, f, y, x) \
get_bs_fs_zyx_bsv_fsv_index_safe( \
get_bs_fs_zyx_bsv_fsv_index_safe( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -572,7 +572,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 16, 16)
#define GET_DATA_BS_FS_YX_BSV32_FSV32_INDEX_SAFE(prefix, b, f, y, x) \
FUNC_CALL(get_bs_fs_zyx_bsv_fsv_index_safe)( \
get_bs_fs_zyx_bsv_fsv_index_safe( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -589,7 +589,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 32, 32)
#define GET_DATA_BS_FS_YX_BSV4_FSV4_INDEX_SAFE(prefix, b, f, y, x) \
FUNC_CALL(get_bs_fs_zyx_bsv_fsv_index_safe)( \
get_bs_fs_zyx_bsv_fsv_index_safe( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -606,7 +606,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 4, 4)
#define GET_DATA_BS_FS_YX_BSV4_FSV2_INDEX_SAFE(prefix, b, f, y, x) \
FUNC_CALL(get_bs_fs_zyx_bsv_fsv_index_safe)( \
get_bs_fs_zyx_bsv_fsv_index_safe( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -623,7 +623,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 4, 2)
#define GET_DATA_BS_FS_YX_BSV32_FSV16_INDEX_SAFE(prefix, b, f, y, x) \
FUNC_CALL(get_bs_fs_zyx_bsv_fsv_index_safe)( \
get_bs_fs_zyx_bsv_fsv_index_safe( \
b, f, 0, y, x, \
CAT(prefix, _SIZE_X), \
CAT(prefix, _SIZE_Y), \
@@ -640,7 +640,7 @@ inline uint get_bs_fs_zyx_bsv_fsv_index(uint b, uint f, uint z, uint y, uint x,
CAT(prefix, _PAD_AFTER_SIZE_X), 32, 16)
#define GET_DATA_BS_FS_ZYX_BSV16_FSV16_INDEX_SAFE(prefix, b, f, z, y, x) \
get_bs_fs_zyx_bsv_fsv_index_safe( \
get_bs_fs_zyx_bsv_fsv_index_safe( \
b, f, z, y, x, \
CAT(prefix, _SIZE_X ), \
CAT(prefix, _SIZE_Y), \
@@ -377,8 +377,24 @@ void kernels_cache::build_batch(const engine& build_engine, const batch_program&
if (!err_log.empty()) {
GPU_DEBUG_GET_INSTANCE(debug_config);
GPU_DEBUG_IF(debug_config->verbose) {
std::cout << "-------- OpenCL build error" << std::endl;
std::cout << err_log << std::endl;
std::cout << "-------- End of OpenCL build error" << std::endl;
}
std::stringstream err_ss(err_log);
std::string line;
int cnt = 0;
while (std::getline(err_ss, line, '\n')) {
if (line.find("error") != std::string::npos)
cnt = 5;
cnt--;
if (cnt > 0)
std::cout << line << std::endl;
else if (cnt == 0)
std::cout << "...." << std::endl;
}
throw std::runtime_error("Program build failed. You may enable OCL source dump to see the error log.\n");
}
}
@@ -295,11 +295,57 @@ void prepare_primitive_fusing::fuse_bias(program &p) {
new_node.recalc_output_layout();
};
auto recalculate_biases = [&](data_node& original_node, data_node& new_node) -> bool {
auto original_mem = original_node.get_attached_memory_ptr();
auto new_mem = new_node.get_attached_memory_ptr();
if (original_mem->count() != new_mem->count() || original_mem->get_layout().data_type != new_mem->get_layout().data_type)
return false;
switch (original_mem->get_layout().data_type) {
case data_types::f32: {
mem_lock<float, mem_lock_type::write> original_bias_mem(original_mem, p.get_stream());
mem_lock<float, mem_lock_type::read> new_bias_mem(new_mem, p.get_stream());
float* original_data = original_bias_mem.data();
float* new_data = new_bias_mem.data();
for (size_t i = 0; i < original_bias_mem.size(); i++)
original_data[i] += new_data[i];
break;
}
case data_types::f16: {
mem_lock<uint16_t, mem_lock_type::write> original_bias_mem(original_mem, p.get_stream());
mem_lock<uint16_t, mem_lock_type::read> new_bias_mem(new_mem, p.get_stream());
uint16_t* original_data = original_bias_mem.data();
uint16_t* new_data = new_bias_mem.data();
for (size_t i = 0; i < original_bias_mem.size(); i++) {
float new_val = half_to_float(original_data[i]) + half_to_float(new_data[i]);
original_data[i] = float_to_half(new_val);
}
break;
}
default:
return false;
}
return true;
};
if (replace_candidate.is_type<convolution>()) {
auto& conv = replace_candidate.as<convolution>();
auto desc = conv.get_primitive();
std::vector<primitive_id> biases = {bias_name};
// If the primitive has biases, then we try to combine the values, or do nothing and keep as fused sum.
if (conv.bias_term()) {
if (conv.bias().is_type<data>() && bias_node.is_type<data>()) {
if (recalculate_biases(conv.bias().as<data>(), bias_node.as<data>())) {
p.replace_all_usages(eltw_node, conv);
p.add_optimized_primitive_info(eltw_node.id(), {conv.id()});
p.remove_all_connections(eltw_node);
p.remove_if_dangling(eltw_node);
}
}
continue;
}
auto conv_with_bias_prim = std::make_shared<convolution>(desc->id + "_tmp",
desc->input[0],
desc->weights,
@@ -325,6 +371,19 @@ void prepare_primitive_fusing::fuse_bias(program &p) {
auto desc = deconv.get_primitive();
std::vector<primitive_id> biases = {bias_name};
// If the primitive has biases, then we try to combine the values, or do nothing and keep as fused sum.
if (deconv.bias_term()) {
if (deconv.bias().is_type<data>() && bias_node.is_type<data>()) {
if (recalculate_biases(deconv.bias().as<data>(), bias_node.as<data>())) {
p.replace_all_usages(eltw_node, deconv);
p.add_optimized_primitive_info(eltw_node.id(), {deconv.id()});
p.remove_all_connections(eltw_node);
p.remove_if_dangling(eltw_node);
}
}
continue;
}
auto deconv_with_bias_prim = std::make_shared<deconvolution>(desc->id + "_tmp",
desc->input[0],
desc->weights,
@@ -340,6 +399,20 @@ void prepare_primitive_fusing::fuse_bias(program &p) {
} else if (replace_candidate.is_type<fully_connected>()) {
auto& fc = replace_candidate.as<fully_connected>();
auto desc = fc.get_primitive();
// If the primitive has biases, then we try to combine the values, or do nothing and keep as fused sum.
if (fc.bias_term()) {
if (fc.bias().is_type<data>() && bias_node.is_type<data>()) {
if (recalculate_biases(fc.bias().as<data>(), bias_node.as<data>())) {
p.replace_all_usages(eltw_node, fc);
p.add_optimized_primitive_info(eltw_node.id(), {fc.id()});
p.remove_all_connections(eltw_node);
p.remove_if_dangling(eltw_node);
}
}
continue;
}
auto fc_with_bias_prim = std::make_shared<fully_connected>(desc->id + "_tmp",
desc->input[0],
desc->weights,
@@ -85,7 +85,7 @@ protected:
} else {
throw std::runtime_error("Unsupported data type for activations zero points for oneDNN convolution");
}
a_zp.as<data>().attach_memory(s32_mem);
a_zp.as<data>().attach_memory(s32_mem, false);
int mask = a_zp.get_output_layout().count() > 1 ? 2 : 0;
@@ -211,6 +211,51 @@ attach_convolution_onednn::attach_convolution_onednn() {
std::make_tuple(data_types::f16, format::bfyx),
std::make_tuple(data_types::u8, format::bfyx),
std::make_tuple(data_types::i8, format::bfyx),
std::make_tuple(data_types::f32, format::bfzyx),
std::make_tuple(data_types::f16, format::bfzyx),
std::make_tuple(data_types::u8, format::bfzyx),
std::make_tuple(data_types::i8, format::bfzyx),
std::make_tuple(data_types::f32, format::b_fs_yx_fsv16),
std::make_tuple(data_types::f16, format::b_fs_yx_fsv16),
std::make_tuple(data_types::u8, format::b_fs_yx_fsv16),
std::make_tuple(data_types::i8, format::b_fs_yx_fsv16),
std::make_tuple(data_types::f32, format::b_fs_zyx_fsv16),
std::make_tuple(data_types::f16, format::b_fs_zyx_fsv16),
std::make_tuple(data_types::u8, format::b_fs_zyx_fsv16),
std::make_tuple(data_types::i8, format::b_fs_zyx_fsv16),
std::make_tuple(data_types::f32, format::b_fs_yx_fsv32),
std::make_tuple(data_types::f16, format::b_fs_yx_fsv32),
std::make_tuple(data_types::u8, format::b_fs_yx_fsv32),
std::make_tuple(data_types::i8, format::b_fs_yx_fsv32),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv16_fsv16),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv16_fsv16),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv16_fsv16),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv16_fsv16),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv32_fsv16),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv32_fsv16),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv32_fsv16),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv32_fsv16),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv32_fsv32),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv32_fsv32),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv32_fsv32),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv32_fsv32),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv4_fsv4),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv4_fsv4),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv4_fsv4),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv4_fsv4),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv4_fsv2),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv4_fsv2),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv4_fsv2),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv4_fsv2),
});
}
@@ -0,0 +1,212 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "deconvolution_inst.h"
#include "eltwise_inst.h"
#include "quantize_inst.h"
#include "primitive_onednn_base.h"
#include "impls/implementation_map.hpp"
#include "kernel_selector_common.h"
#include <oneapi/dnnl/dnnl.hpp>
#include <algorithm>
#include <memory>
namespace cldnn {
namespace onednn {
struct deconvolution_onednn : typed_primitive_onednn_impl<deconvolution, dnnl::deconvolution_forward::desc> {
using parent = typed_primitive_onednn_impl<deconvolution, dnnl::deconvolution_forward::desc>;
using parent::parent;
protected:
std::unique_ptr<primitive_impl> clone() const override {
return make_unique<deconvolution_onednn>(*this);
}
bool validate_impl(const typed_primitive_inst<deconvolution>& instance) const override {
bool res = true;
auto outer_id = _outer.id();
auto data_type = instance.node.input().get_output_layout().data_type;
// Integer signed/unsigned is ok for convoluiton
CLDNN_ERROR_DATA_TYPES_MISMATCH_IGNORE_SIGN(outer_id,
"Input memory",
data_type,
"filter memory",
instance.weights_memory(0)->get_layout().data_type,
"");
return res;
}
std::unordered_map<int, dnnl::memory> get_arguments(deconvolution_inst& instance) const override {
std::unordered_map<int, dnnl::memory> args = parent::get_arguments(instance);
auto& engine = instance.get_network().get_engine();
auto onednn_engine = engine.get_onednn_engine();
{
auto weights = instance.weights_memory(0);
args.insert({DNNL_ARG_WEIGHTS, weights->get_onednn_memory(_pd.weights_desc(0))});
}
if (instance.bias_term()) {
auto bias = instance.bias_memory(0);
args.insert({DNNL_ARG_BIAS, bias->get_onednn_memory(_pd.weights_desc(1))});
}
return args;
}
static std::shared_ptr<dnnl::primitive_attr> get_primitive_attributes(const typed_program_node<deconvolution>& arg) {
auto attrs = parent::get_primitive_attributes(arg);
return attrs;
}
static kernel_selector::WeightsReorderParams get_weights_reorder(const deconvolution_node& arg, const dnnl::primitive_desc& pd) {
kernel_selector::WeightsReorderParams weights_reorder_params;
auto& reorderKS = kernel_selector::ReorderWeightsKernelSelctor::Instance();
kernel_selector::reorder_weights_params r_params;
auto cldnn_prim = arg.get_primitive();
auto weights_layout = arg.get_dependency(1).get_output_layout();
auto grouped_weights = format::is_grouped(weights_layout.format) || arg.get_primitive()->grouped_weights_shape;
cldnn::format out_fmt = onednn::convert_format(onednn::get_format_by_desc(pd.weights_desc(0)), grouped_weights);
kernel_selector::WeightsLayout reqLayout = to_weights_layout(out_fmt, cldnn_prim->grouped_weights_shape);
set_params(arg, r_params);
r_params.layerID = arg.id() + "_reorder_";
r_params.input = convert_weights_tensor(weights_layout, cldnn_prim->grouped_weights_shape);
r_params.output = r_params.input.TransformIgnorePadding(reqLayout, r_params.input.GetDType(), arg.get_groups(), false);
r_params.rotate_180 = false;
kernel_selector::reorder_optional_params op;
kernel_selector::KernelsData kernels_data = reorderKS.GetBestKernels(r_params, op);
if (kernels_data.empty()) {
throw std::runtime_error("No suitable kernel found for weights reorder from " +
kernel_selector::toString(r_params.input.GetLayout()) + " to " +
kernel_selector::toString(r_params.output.GetLayout()));
}
weights_reorder_params.engine = kernel_selector::WeightsReorderParams::Engine::GPU;
weights_reorder_params.clKernel = std::make_shared<kernel_selector::clKernelData>(kernels_data[0].kernels[0]);
weights_reorder_params.dest = r_params.output;
return weights_reorder_params;
}
static std::shared_ptr<dnnl::deconvolution_forward::desc> get_deconvolution_descriptor(const deconvolution_node& arg) {
auto prim = arg.get_primitive();
auto& input = arg.get_dependency(0);
auto& weights = arg.get_dependency(1);
auto spatials_rank = cldnn::format::spatial_num(input.get_output_layout().format);
auto stride = onednn::convert_spatials(prim->stride, spatials_rank);
auto dilation = onednn::convert_spatials(cldnn::tensor{1}, spatials_rank);
auto pad_l = onednn::convert_spatials(prim->input_offset, spatials_rank);
auto pad_r = onednn::convert_spatials(prim->input_offset, spatials_rank);
auto input_md = onednn::layout_to_memory_desc(input.get_output_layout());
auto weights_md = onednn::layout_to_memory_desc(weights.get_output_layout(), dnnl::memory::format_tag::any);
auto output_md = onednn::layout_to_memory_desc(arg.get_output_layout());
auto grouped_weights = format::is_grouped(weights.get_output_layout().format) || prim->grouped_weights_shape;
for (size_t i = 0; i < dilation.size(); i++) {
dilation[i]--;
pad_l[i] = -pad_l[i];
int weights_offset = (grouped_weights ? 3 : 2) + static_cast<int>(i);
auto os = output_md.dims()[2 + i];
auto is = input_md.dims()[2 + i];
auto ks = weights_md.dims()[weights_offset];
auto kernel_range = 1 + (ks - 1) * (dilation[i] + 1);
pad_r[i] = (is - 1) * stride[i] - os + kernel_range - pad_l[i];
}
if (arg.bias_term()) {
auto bias_md = onednn::layout_to_memory_desc(arg.get_dependency(2).get_output_layout(), dnnl::memory::format_tag::any, true);
return std::make_shared<dnnl::deconvolution_forward::desc>(
dnnl::prop_kind::forward_inference,
dnnl::algorithm::deconvolution_direct,
input_md,
weights_md,
bias_md,
output_md,
stride,
dilation,
pad_l,
pad_r);
} else {
return std::make_shared<dnnl::deconvolution_forward::desc>(
dnnl::prop_kind::forward_inference,
dnnl::algorithm::deconvolution_direct,
input_md,
weights_md,
output_md,
stride,
dilation,
pad_l,
pad_r);
}
}
public:
static primitive_impl* create(const deconvolution_node& arg) {
auto& engine = arg.get_program().get_engine();
auto desc = get_deconvolution_descriptor(arg);
auto attr = get_primitive_attributes(arg);
dnnl::primitive_desc prim_desc{&desc->data, attr.get(), engine.get_onednn_engine(), nullptr};
return new deconvolution_onednn(arg, desc, attr, prim_desc, get_weights_reorder(arg, prim_desc));
}
};
namespace detail {
attach_deconvolution_onednn::attach_deconvolution_onednn() {
implementation_map<deconvolution>::add(impl_types::onednn, deconvolution_onednn::create, {
std::make_tuple(data_types::f32, format::bfyx),
std::make_tuple(data_types::f16, format::bfyx),
std::make_tuple(data_types::u8, format::bfyx),
std::make_tuple(data_types::i8, format::bfyx),
std::make_tuple(data_types::f32, format::b_fs_yx_fsv16),
std::make_tuple(data_types::f16, format::b_fs_yx_fsv16),
std::make_tuple(data_types::u8, format::b_fs_yx_fsv16),
std::make_tuple(data_types::i8, format::b_fs_yx_fsv16),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv16_fsv16),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv16_fsv16),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv16_fsv16),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv16_fsv16),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv32_fsv16),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv32_fsv16),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv32_fsv16),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv32_fsv16),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv32_fsv32),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv32_fsv32),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv32_fsv32),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv32_fsv32),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv4_fsv4),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv4_fsv4),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv4_fsv4),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv4_fsv4),
std::make_tuple(data_types::f32, format::bs_fs_yx_bsv4_fsv2),
std::make_tuple(data_types::f16, format::bs_fs_yx_bsv4_fsv2),
std::make_tuple(data_types::u8, format::bs_fs_yx_bsv4_fsv2),
std::make_tuple(data_types::i8, format::bs_fs_yx_bsv4_fsv2),
});
}
} // namespace detail
} // namespace onednn
} // namespace cldnn
@@ -12,6 +12,7 @@
#include "utils.hpp"
#include "quantize_inst.h"
#include "reorder_inst.h"
#include "reorder/reorder_weights_kernel_selector.h"
#include "reorder/reorder_kernel_base.h"
@@ -778,8 +779,10 @@ protected:
}
}
}
} else if (node->is_type<reorder>()) {
continue;
} else {
throw std::runtime_error("Unsupported fused op for onednn prim");
throw std::runtime_error("Unsupported fused op of " + node->get_primitive()->type_string() + " type for oneDNN primitive");
}
}
@@ -795,7 +798,12 @@ protected:
}
// Update total onednn post-ops info
onednn_fusing_map.emplace(arg.id(), std::move(fused_ops));
auto it = onednn_fusing_map.find(arg.id());
if (it != onednn_fusing_map.end()) {
it->second = std::move(fused_ops);
} else {
onednn_fusing_map.emplace(arg.id(), std::move(fused_ops));
}
// Trying to optimize more than 1 post-ops
auto post_ops_size = onednn_fusing_map[arg.id()].size();
@@ -12,6 +12,7 @@ namespace onednn {
void register_implementations() {
REGISTER_ONEDNN_IMPL(convolution);
REGISTER_ONEDNN_IMPL(deconvolution);
REGISTER_ONEDNN_IMPL(concatenation);
REGISTER_ONEDNN_IMPL(eltwise);
REGISTER_ONEDNN_IMPL(gemm);
@@ -18,6 +18,7 @@ namespace detail {
}
REGISTER_ONEDNN_IMPL(convolution);
REGISTER_ONEDNN_IMPL(deconvolution);
REGISTER_ONEDNN_IMPL(concatenation);
REGISTER_ONEDNN_IMPL(eltwise);
REGISTER_ONEDNN_IMPL(gemm);
@@ -153,6 +153,10 @@ private:
const layout& output_layout,
const layout& weights_layout,
std::shared_ptr<const convolution> conv);
bool convolution_bs_fs_yx_bsv32_fsv32_opt(const layout &input_layout,
const layout& output_layout,
const layout& weights_layout,
std::shared_ptr<const convolution> conv);
bool convolution_fs_b_yx_fsv32_opt(const layout& input_layout,
const layout& output_layout,
const layout& weights_layout,
@@ -173,6 +177,7 @@ public:
format get_preferred_format(program_node& node);
impl_types get_preferred_impl_type(program_node& node, format preferred_format);
bool are_data_types_suitable_for_onednn(program_node& node);
bool is_format_supported(program_node& node, format::type fmt);
// Returns whether reorder between "prev" with format fmt_prev and "next" with format fmt_next
+275 -137
View File
@@ -739,83 +739,158 @@ layout layout_optimizer::get_expected_layout(layout const& current_layout,
auto expected_data_type = current_layout.data_type;
auto expected_format = current_layout.format;
auto input_layout = node.get_dependency(0).get_output_layout();
auto output_layout = node.calc_output_layout();
const float cond_denom = _total_conv > 0 ? 1.0f / static_cast<float>(_total_conv) : 1.0f;
auto output_layout = node.calc_output_layout();
bool is_dw = input_layout.size.feature[0] == static_cast<int>(prim->groups);
int ofm_per_group = output_layout.size.feature[0] / prim->groups;
int ifm_per_group = input_layout.size.feature[0] / prim->groups;
int compute_block = 32;
bool valid_grouped = !is_dw && prim->groups > 1 && (ofm_per_group % compute_block == 0 && ifm_per_group % compute_block == 0);
bool valid_int8_dw = is_dw && output_layout.size.batch[0] % 16 == 0;
bool non_grouped = prim->groups == 1;
bool is_2d = input_layout.format.spatial_num() == 2;
bool onednn_valid_post_ops = get_post_ops_count(node) <= 32;
bool use_onednn_impls = _optimization_attributes.use_onednn_impls;
bool i8_u8_input = input_layout.data_type == data_types::u8 || input_layout.data_type == data_types::i8;
if ((input_layout.data_type == data_types::u8 || input_layout.data_type == data_types::i8)) {
if ((_optimization_attributes.bs_fs_yx_bsv16_fsv16_network && expected_tensor.batch[0] % 16 == 0 &&
convolution_bs_fs_yx_bsv16_fsv16_opt(input_layout, output_layout, weights_layout, prim))) {
expected_format = cldnn::format::bs_fs_yx_bsv16_fsv16;
} else if ((_optimization_attributes.b_fs_yx_fsv16_network &&
convolution_b_fs_yx_fsv16_opt(input_layout, output_layout, weights_layout, prim))) {
expected_format = cldnn::format::b_fs_yx_fsv16;
} else if ((_optimization_attributes.b_fs_zyx_fsv16_network &&
convolution_b_fs_zyx_fsv16_opt(input_layout, output_layout, weights_layout, prim))) {
expected_format = cldnn::format::b_fs_zyx_fsv16;
} else {
expected_format = imad_case(node);
if (use_onednn_impls && onednn_valid_post_ops) {
for (auto& fo : node.get_fused_primitives()) {
if (fo.node->is_type<eltwise>()) {
auto in_layout = node.get_dependency(fo.dep_start_idx).get_output_layout();
auto out_layout = node.get_output_layout();
auto in_dt = in_layout.data_type;
auto out_dt = out_layout.data_type;
if ((out_layout.count() == in_layout.count()) &&
(data_type_traits::is_floating_point(in_dt) || data_type_traits::is_floating_point(out_dt)) && in_dt != out_dt) {
onednn_valid_post_ops = false;
break;
}
}
}
expected_tensor = current_layout.size;
} else if (_optimization_attributes.b_fs_zyx_fsv16_network &&
convolution_b_fs_zyx_fsv16_opt(input_layout, output_layout, weights_layout, prim)) {
expected_tensor = current_layout.size;
if ((current_layout.data_type == data_types::f32 && expected_tensor.batch[0] % 16 == 0) ||
(current_layout.data_type == data_types::f16 && expected_tensor.batch[0] % 32 == 0))
expected_format = cldnn::format::bs_fs_zyx_bsv16_fsv16;
else
expected_format = cldnn::format::b_fs_zyx_fsv16;
}
} else if (current_layout.format == format::bfzyx) {
expected_tensor = current_layout.size;
expected_format = cldnn::format::bfzyx;
} else if (_optimization_attributes.bs_fs_yx_bsv16_fsv16_network &&
convolution_bs_fs_yx_bsv16_fsv16_opt(node.input().get_output_layout(), output_layout, weights_layout, prim)) {
expected_tensor = current_layout.size;
expected_format = cldnn::format::bs_fs_yx_bsv16_fsv16;
} else if (_optimization_attributes.fs_b_yx_fsv32_network && !node.get_transposed() &&
((convolution_fs_b_yx_fsv32_opt(input_layout,
output_layout,
weights_layout, prim) ||
(((node.get_dependency(0).is_type<convolution>() && is_format_optimized(node.get_dependency(0).as<convolution>(), format::fs_b_yx_fsv32))
|| (_optimized_conv_count.at({format::fs_b_yx_fsv32, false}) * cond_denom > 0.8f)) &&
convolution_fs_b_yx_fsv32_opt(input_layout,
output_layout,
weights_layout, prim, true))))) {
// Chose fs_b_yx_fsv32 layout in two cases: 1-st: the current conv primitive totally supports fs_b_yx_fsv32 layout
// 2-nd: the previous conv primitive supports fs_b_yx_fsv32 layout and
// current conv primitives supports this one with weak restrictions -
// that should be cheaper than reordering data to another layout
expected_tensor = current_layout.size;
expected_format = format::fs_b_yx_fsv32;
} else if (should_select_b_fs_yx_fsv16_layout(node, weights_layout)) {
expected_tensor = current_layout.size;
expected_format = cldnn::format::b_fs_yx_fsv16;
} else if (current_layout.data_type == data_types::f16 &&
layout_optimizer::convolution_byxf_opt(input_layout, current_layout, weights_layout, node) &&
(users_for_convolution_byxf_opt(node, 2) || deps_for_convolution_byxf_opt(node, 2)) &&
// todo: remove this condition when yxfb optimizations will be disabled
current_layout.format != cldnn::format::yxfb && current_layout.size.batch[0] == 1) {
expected_tensor = current_layout.size;
expected_format = cldnn::format::byxf;
} else if (current_layout.format == format::b_fs_yx_fsv4 ||
current_layout.format == format::os_is_yx_osv16_isv4) {
// imad case
// nothing to do, just go out from here.
} else if (layout_optimizer::convolution_bfyx_opt(current_layout, weights_layout, prim) ||
(_output_size_handling_enabled && prim->with_output_size) || node.get_transposed()) {
{
if (use_onednn_impls) {
/* ***************************** OneDNN impls format selection part ****************************** */
if (i8_u8_input) {
if ((non_grouped || valid_grouped || valid_int8_dw) && onednn_valid_post_ops && is_2d) {
if (input_layout.size.batch[0] % 16 == 0)
expected_format = cldnn::format::bs_fs_yx_bsv32_fsv32;
else
expected_format = cldnn::format::b_fs_yx_fsv32;
} else if ((_optimization_attributes.b_fs_yx_fsv16_network &&
convolution_b_fs_yx_fsv16_opt(input_layout, output_layout, weights_layout, prim)) && is_2d) {
if (is_dw)
expected_format = cldnn::format::b_fs_yx_fsv32;
else
expected_format = cldnn::format::b_fs_yx_fsv16;
} else {
expected_format = imad_case(node);
}
expected_tensor = current_layout.size;
} else if (input_layout.data_type == data_types::f16 && is_2d) {
expected_tensor = current_layout.size;
if (current_layout.format == format::b_fs_zyx_fsv16 || current_layout.format == format::bs_fs_zyx_bsv16_fsv16)
expected_format = cldnn::format::bfzyx;
else
expected_format = cldnn::format::bfyx;
}
if (input_layout.size.batch[0] >= 16 && onednn_valid_post_ops) {
if (output_layout.data_type == input_layout.data_type) {
if (non_grouped || valid_grouped || is_dw) {
expected_format = cldnn::format::bs_fs_yx_bsv32_fsv16;
} else {
expected_format = cldnn::format::b_fs_yx_fsv16;
}
} else {
expected_format = cldnn::format::bs_fs_yx_bsv16_fsv16;
}
} else {
expected_format = cldnn::format::b_fs_yx_fsv16;
}
} else if (input_layout.data_type == data_types::f16 &&
convolution_bs_fs_yx_bsv16_fsv16_opt(input_layout, output_layout, weights_layout, prim) &&
(output_layout.data_type == input_layout.data_type ||
!data_type_traits::is_floating_point(input_layout.data_type))) {
expected_tensor = current_layout.size;
if (prim->groups == 1 || (output_layout.size.feature[0] % 16 == 0 && input_layout.size.feature[0] % 16 == 0)) {
expected_format = cldnn::format::bs_fs_yx_bsv32_fsv16;
} else {
expected_format = cldnn::format::bs_fs_yx_bsv16_fsv16;
}
}
} else {
expected_tensor = current_layout.size;
expected_format = cldnn::format::yxfb;
/* *************************** Native impls format selection part ************************** */
if (i8_u8_input) {
if ((_optimization_attributes.bs_fs_yx_bsv16_fsv16_network && expected_tensor.batch[0] % 16 == 0 &&
convolution_bs_fs_yx_bsv16_fsv16_opt(input_layout, output_layout, weights_layout, prim))) {
expected_format = cldnn::format::bs_fs_yx_bsv16_fsv16;
} else if ((_optimization_attributes.b_fs_yx_fsv16_network &&
convolution_b_fs_yx_fsv16_opt(input_layout, output_layout, weights_layout, prim))) {
expected_format = cldnn::format::b_fs_yx_fsv16;
} else if ((_optimization_attributes.b_fs_zyx_fsv16_network &&
convolution_b_fs_zyx_fsv16_opt(input_layout, output_layout, weights_layout, prim))) {
expected_format = cldnn::format::b_fs_zyx_fsv16;
} else {
expected_format = imad_case(node);
}
expected_tensor = current_layout.size;
} else if (_optimization_attributes.b_fs_zyx_fsv16_network &&
convolution_b_fs_zyx_fsv16_opt(input_layout, output_layout, weights_layout, prim)) {
expected_tensor = current_layout.size;
if ((current_layout.data_type == data_types::f32 && expected_tensor.batch[0] % 16 == 0) ||
(current_layout.data_type == data_types::f16 && expected_tensor.batch[0] % 32 == 0))
expected_format = cldnn::format::bs_fs_zyx_bsv16_fsv16;
else
expected_format = cldnn::format::b_fs_zyx_fsv16;
} else if (current_layout.format == format::bfzyx) {
expected_tensor = current_layout.size;
expected_format = cldnn::format::bfzyx;
} else if (_optimization_attributes.bs_fs_yx_bsv16_fsv16_network &&
convolution_bs_fs_yx_bsv16_fsv16_opt(node.input().get_output_layout(), output_layout, weights_layout, prim)) {
expected_tensor = current_layout.size;
expected_format = cldnn::format::bs_fs_yx_bsv16_fsv16;
} else if (_optimization_attributes.fs_b_yx_fsv32_network && !node.get_transposed() &&
((convolution_fs_b_yx_fsv32_opt(input_layout,
output_layout,
weights_layout, prim) ||
(((node.get_dependency(0).is_type<convolution>() && is_format_optimized(node.get_dependency(0).as<convolution>(), format::fs_b_yx_fsv32))
|| (_optimized_conv_count.at({format::fs_b_yx_fsv32, false}) * cond_denom > 0.8f)) &&
convolution_fs_b_yx_fsv32_opt(input_layout,
output_layout,
weights_layout, prim, true))))) {
// Chose fs_b_yx_fsv32 layout in two cases: 1-st: the current conv primitive totally supports fs_b_yx_fsv32 layout
// 2-nd: the previous conv primitive supports fs_b_yx_fsv32 layout and
// current conv primitives supports this one with weak restrictions -
// that should be cheaper than reordering data to another layout
expected_tensor = current_layout.size;
expected_format = format::fs_b_yx_fsv32;
} else if (should_select_b_fs_yx_fsv16_layout(node, weights_layout)) {
expected_tensor = current_layout.size;
expected_format = cldnn::format::b_fs_yx_fsv16;
} else if (current_layout.data_type == data_types::f16 &&
layout_optimizer::convolution_byxf_opt(input_layout, current_layout, weights_layout, node) &&
(users_for_convolution_byxf_opt(node, 2) || deps_for_convolution_byxf_opt(node, 2)) &&
// todo: remove this condition when yxfb optimizations will be disabled
current_layout.format != cldnn::format::yxfb && current_layout.size.batch[0] == 1) {
expected_tensor = current_layout.size;
expected_format = cldnn::format::byxf;
} else if (current_layout.format == format::b_fs_yx_fsv4 ||
current_layout.format == format::os_is_yx_osv16_isv4) {
// imad case
// nothing to do, just go out from here.
} else if (layout_optimizer::convolution_bfyx_opt(current_layout, weights_layout, prim) ||
(_output_size_handling_enabled && prim->with_output_size) || node.get_transposed()) {
{
expected_tensor = current_layout.size;
if (current_layout.format == format::b_fs_zyx_fsv16 || current_layout.format == format::bs_fs_zyx_bsv16_fsv16)
expected_format = cldnn::format::bfzyx;
else
expected_format = cldnn::format::bfyx;
}
} else {
expected_tensor = current_layout.size;
expected_format = cldnn::format::yxfb;
}
}
return layout(expected_data_type, expected_format, expected_tensor);
@@ -828,8 +903,36 @@ layout layout_optimizer::get_expected_layout(layout const& current_layout,
auto expected_tensor = current_layout.size;
auto expected_data_type = current_layout.data_type;
auto expected_format = current_layout.format;
auto input_layout = node.get_dependency(0).get_output_layout();
auto spatial_dims_num = input_layout.format.spatial_num();
auto is_2d = spatial_dims_num == 2;
bool use_onednn_impls = _optimization_attributes.use_onednn_impls;
if (_optimization_attributes.b_fs_zyx_fsv16_network &&
bool onednn_valid_dt = input_layout.data_type == data_types::i8 ||
input_layout.data_type == data_types::u8 ||
input_layout.data_type == data_types::f16;
bool onednn_valid_params = onednn_valid_dt &&
input_layout.size.feature[0] >= 16 &&
prim->groups == 1 &&
get_post_ops_count(node) <= 32 &&
input_layout.size.batch[0] < 16; // oneDNNs optimized kernel doesn't support big batches yet
if (use_onednn_impls && onednn_valid_params && spatial_dims_num <= 3) {
if (input_layout.data_type == data_types::f16) {
if (input_layout.size.batch[0] < 16) {
expected_format = is_2d ? cldnn::format::b_fs_yx_fsv16 : cldnn::format::b_fs_zyx_fsv16;
} else {
expected_format = is_2d ? cldnn::format::bs_fs_yx_bsv32_fsv16 : cldnn::format::bs_fs_zyx_bsv32_fsv16;
}
} else {
if (input_layout.size.batch[0] < 16) {
expected_format = is_2d ? cldnn::format::b_fs_yx_fsv32 : cldnn::format::b_fs_zyx_fsv32;
} else {
expected_format = is_2d ? cldnn::format::bs_fs_yx_bsv32_fsv32 : cldnn::format::bs_fs_zyx_bsv32_fsv32;
}
}
} else if (_optimization_attributes.b_fs_zyx_fsv16_network &&
deconvolution_b_fs_zyx_fsv16_opt(current_layout, output_or_weights_layout, prim)) {
expected_tensor = current_layout.size;
if ((current_layout.data_type == data_types::f32 && expected_tensor.batch[0] % 16 == 0) ||
@@ -875,6 +978,41 @@ layout layout_optimizer::get_expected_layout(layout const& current_layout,
return layout(expected_data_type, expected_format, expected_tensor);
}
bool layout_optimizer::are_data_types_suitable_for_onednn(program_node& node) {
auto in_dt = node.get_dependency(0).get_output_layout().data_type;
auto out_dt = node.get_output_layout().data_type;
if (in_dt == data_types::f32)
return false;
if (node.is_type<pooling>()) {
if (!data_type_traits::is_floating_point(in_dt) && in_dt != out_dt)
return false;
if ((in_dt == data_types::i8 || in_dt == data_types::u8) && out_dt != data_types::f32)
return true;
if (in_dt == data_types::f16 || out_dt == data_types::f16)
return true;
if (out_dt == data_types::f32)
return true;
if (in_dt == data_types::i32 || out_dt == data_types::i32)
return true;
if ((in_dt == data_types::i8 || out_dt == data_types::i8) || (in_dt == data_types::u8 || out_dt == data_types::u8))
return true;
} else if (node.is_type<convolution>() || node.is_type<deconvolution>()) {
bool is_conv = node.is_type<convolution>();
auto wei_dt = is_conv ? node.as<convolution>().weights().get_output_layout().data_type :
node.as<deconvolution>().weights().get_output_layout().data_type;
if ((in_dt == data_types::f16 && wei_dt == data_types::f16) && (out_dt == data_types::f16 || out_dt == data_types::f32 || out_dt == data_types::i8))
return true;
if ((in_dt == data_types::i8 || in_dt == data_types::u8) && wei_dt == data_types::i8 &&
(out_dt == data_types::f32 || out_dt == data_types::i32 || out_dt == data_types::i8 || out_dt == data_types::u8))
return true;
}
return false;
}
impl_types layout_optimizer::get_preferred_impl_type(program_node& node, format preferred_format) {
impl_types preferred_impl = impl_types::any;
if (!_forcing_map.empty() && _forcing_map.count(node.id()) != 0) {
@@ -938,7 +1076,7 @@ impl_types layout_optimizer::get_preferred_impl_type(program_node& node, format
if (input_layout.format.dimension() != output_layout.format.dimension()) {
preferred_impl = impl_types::ocl;
}
} else if (node.is_type<pooling>()) {
} else if (node.is_type<pooling>() || node.is_type<convolution>() || node.is_type<deconvolution>()) {
if (!_optimization_attributes.use_onednn_impls)
return impl_types::ocl;
@@ -964,79 +1102,79 @@ impl_types layout_optimizer::get_preferred_impl_type(program_node& node, format
impl_candidate = impl_types::ocl;
}
// if (node.is_type<convolution>()) {
// // onednn doesn't have good support for groups with fsv16 fmt
// auto& conv = node.as<convolution>();
// auto input_layout = conv.input().get_output_layout();
// bool fp16_input = input_layout.data_type == data_types::f16;
// bool has_groups = conv.get_primitive()->groups > 1;
// bool is_depthwise = conv.get_primitive()->groups == input_layout.size.feature[0];
// bool first_conv = input_layout.size.feature[0] <= 4;
// bool enable_onednn_dw_fp16_conv = fp16_input && is_depthwise;
// if (((has_groups && !enable_onednn_dw_fp16_conv) || first_conv) &&
// (conv.get_output_layout().format == format::b_fs_yx_fsv16)) {
// impl_candidate = impl_types::ocl;
// }
// }
if (node.is_type<convolution>()) {
// oneDNN doesn't have good support for groups with fsv16 fmt
auto& conv = node.as<convolution>();
auto input_layout = conv.input().get_output_layout();
bool fp16_input = input_layout.data_type == data_types::f16;
bool has_groups = conv.get_primitive()->groups > 1;
bool is_depthwise = conv.get_primitive()->groups == input_layout.size.feature[0];
bool first_conv = input_layout.size.feature[0] <= 4;
bool enable_onednn_dw_fp16_conv = fp16_input && is_depthwise;
if (((has_groups && !enable_onednn_dw_fp16_conv) || first_conv) &&
(conv.get_output_layout().format == format::b_fs_yx_fsv16)) {
impl_candidate = impl_types::ocl;
}
}
// if (node.is_type<deconvolution>()) {
// auto& deconv = node.as<deconvolution>();
// auto input_layout = deconv.input().get_output_layout();
// bool valid_ic = input_layout.size.feature[0] >= 16;
// bool valid_groups = deconv.get_primitive()->groups == 1;
// bool valid_post_ops = get_post_ops_count(node) <= 10;
// bool valid_batch = input_layout.size.batch[0] < 16; // oneDNNs optimized kernel doesn't support big batches yet
// bool valid_params = valid_ic && valid_groups && valid_post_ops && valid_batch;
// if (!valid_params)
// impl_candidate = impl_types::ocl;
// }
if (node.is_type<deconvolution>()) {
auto& deconv = node.as<deconvolution>();
auto input_layout = deconv.input().get_output_layout();
bool valid_ic = input_layout.size.feature[0] >= 16;
bool valid_groups = deconv.get_primitive()->groups == 1;
bool onednn_valid_post_ops = get_post_ops_count(node) <= 32;
bool valid_batch = input_layout.size.batch[0] < 16; // oneDNN's optimized kernel doesn't support big batches yet
bool valid_params = valid_ic && valid_groups && onednn_valid_post_ops && valid_batch;
if (!valid_params)
impl_candidate = impl_types::ocl;
}
// // [WA] onednn doesn't support > 32 post-ops. Remove once onednn improve post-ops for GPU.
// if (get_post_ops_count(node) > 32) {
// impl_candidate = impl_types::ocl;
// }
// [WA] oneDNN doesn't support > 32 post-ops. Remove once oneDNN improve post-ops for GPU.
if (get_post_ops_count(node) > 32) {
impl_candidate = impl_types::ocl;
}
// if (!data_types_are_suitable_for_onednn(node)) {
// impl_candidate = impl_types::ocl;
// }
if (!are_data_types_suitable_for_onednn(node)) {
impl_candidate = impl_types::ocl;
}
// for (auto& fo : node.get_fused_primitives()) {
// if (fo.node->is_type<eltwise>()) {
// auto in_layout = node.get_dependency(fo.dep_start_idx).get_output_layout();
// auto out_layout = node.get_output_layout();
// auto in_dt = in_layout.data_type;
// auto out_dt = out_layout.data_type;
// if ((out_layout.count() == in_layout.count()) &&
// (data_type_traits::is_floating_point(in_dt) || data_type_traits::is_floating_point(out_dt)) && in_dt != out_dt) {
// impl_candidate = impl_types::ocl;
// break;
// }
// } else if (fo.node->is_type<activation>()) {
// // Some activations aren't implemented in oneDNN
// auto activation_prim = fo.node->as<activation>().get_primitive();
// if (activation_prim->activation_function == activation_func::negative ||
// activation_prim->activation_function == activation_func::negation ||
// activation_prim->activation_function == activation_func::sign)
// impl_candidate = impl_types::ocl;
// }
// }
for (auto& fo : node.get_fused_primitives()) {
if (fo.node->is_type<eltwise>()) {
auto in_layout = node.get_dependency(fo.dep_start_idx).get_output_layout();
auto out_layout = node.get_output_layout();
auto in_dt = in_layout.data_type;
auto out_dt = out_layout.data_type;
if ((out_layout.count() == in_layout.count()) &&
(data_type_traits::is_floating_point(in_dt) || data_type_traits::is_floating_point(out_dt)) && in_dt != out_dt) {
impl_candidate = impl_types::ocl;
break;
}
} else if (fo.node->is_type<activation>()) {
// Some activations aren't implemented in oneDNN
auto activation_prim = fo.node->as<activation>().get_primitive();
if (activation_prim->activation_function == activation_func::negative ||
activation_prim->activation_function == activation_func::negation ||
activation_prim->activation_function == activation_func::sign)
impl_candidate = impl_types::ocl;
}
}
// // oneDNN doesn't support asymmetric weights quantization
// if (node.is_type<convolution>() && node.as<convolution>().weights_zero_points_term())
// impl_candidate = impl_types::ocl;
// oneDNN doesn't support asymmetric weights quantization
if (node.is_type<convolution>() && node.as<convolution>().weights_zero_points_term())
impl_candidate = impl_types::ocl;
// // OneDNN doesn't support sum post ops for deconvolutions
// if (node.is_type<deconvolution>() && impl_candidate == impl_types::onednn) {
// for (auto& fused_op : node.get_fused_primitives()) {
// if (fused_op.node->is_type<eltwise>() && fused_op.deps.size() == 1) {
// auto eltw_in_layout = node.get_dependency(fused_op.dep_start_idx).get_output_layout();
// if (fused_op.node->as<eltwise>().get_primitive()->needs_onednn_sum_post_op(eltw_in_layout)) {
// impl_candidate = impl_types::ocl;
// break;
// }
// }
// }
// }
// oneDNN doesn't support sum post ops for deconvolutions
if (node.is_type<deconvolution>() && impl_candidate == impl_types::onednn) {
for (auto& fused_op : node.get_fused_primitives()) {
if (fused_op.node->is_type<eltwise>() && fused_op.deps.size() == 1) {
auto eltw_in_layout = node.get_dependency(fused_op.dep_start_idx).get_output_layout();
if (fused_op.node->as<eltwise>().get_primitive()->needs_onednn_sum_post_op(eltw_in_layout)) {
impl_candidate = impl_types::ocl;
break;
}
}
}
}
preferred_impl = impl_candidate;
} else if (node.is_type<concatenation>()) {
@@ -2838,3 +2838,56 @@ INSTANTIATE_TEST_SUITE_P(DISABLED_extended, deconvolution_random_test, testing::
.add_all_3d(data_types::i8, data_types::i8, data_types::f32, format::bs_fs_zyx_bsv16_fsv16, format::bs_fs_zyx_bsv16_fsv16)
.add_all_3d(data_types::u8, data_types::i8, data_types::f32, format::bs_fs_zyx_bsv16_fsv16, format::bs_fs_zyx_bsv16_fsv16)
), deconvolution_random_test_params::print_params);
#ifdef ENABLE_ONEDNN_FOR_GPU
TEST(deconvolution_f32_fw_gpu_onednn, basic_wsiz2x2_in2x2x1x1_stride2_nopad) {
// Filter : 1x1
// Input : 2x2
// Output : 4x4
// Stride : 2x2
auto& engine = get_onednn_test_engine();
auto input = engine.allocate_memory({ data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
auto weights = engine.allocate_memory({ data_types::f32, format::oiyx, { 1, 1, 2, 2 } });
auto biases = engine.allocate_memory({ data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
set_values(input, { 8.f, 0.5f, 6.f, 9.f });
set_values(weights, { -2.0f, 0.5f, 3.5f, 1.5f });
set_values(biases, { 1.0f });
topology topology(
input_layout("input", input->get_layout()),
data("weights", weights),
data("biases", biases),
deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1,1,2,2 })
);
build_options bo;
implementation_desc conv_impl = { format::yxfb, "", impl_types::onednn };
bo.set_option(build_option::force_implementations({ {"deconv", conv_impl} }));
network network(engine, topology, bo);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "deconv");
auto output_prim = outputs.begin()->second.get_memory();
cldnn::mem_lock<float> output_ptr (output_prim, get_test_stream());
std::vector<float> expected_output_vec = {
-15.f, 5.f, 0.f, 1.25f,
29.f, 13.f, 2.75f, 1.75,
-11.f, 4.f, -17.f, 5.5f,
22.f, 10.f, 32.5f, 14.5f
};
for (unsigned int i = 0; i < expected_output_vec.size(); i++)
{
EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
}
}
#endif
@@ -27,6 +27,7 @@
#include <cldnn/primitives/batch_to_space.hpp>
#include <cldnn/primitives/space_to_batch.hpp>
#include <cldnn/primitives/reduce.hpp>
#include <cldnn/primitives/crop.hpp>
#include <cmath>
@@ -130,7 +131,11 @@ struct normalize_test_params {
template<typename T>
class BaseFusingTest : public ::testing::TestWithParam<T> {
public:
#ifdef ENABLE_ONEDNN_FOR_GPU
cldnn::engine& engine = get_onednn_test_engine();
#else
cldnn::engine& engine = get_test_engine();
#endif
cldnn::topology topology_fused;
cldnn::topology topology_non_fused;
cldnn::build_options bo_fused;
@@ -234,6 +239,12 @@ public:
} else if (l.data_type == data_types::f32) {
VF<float> rnd_vec(s.count(), fill_value);
set_values(prim, rnd_vec);
} else if (l.data_type == data_types::u8) {
VF<uint8_t> rnd_vec(s.count(), static_cast<uint8_t>(fill_value));
set_values(prim, rnd_vec);
} else if (l.data_type == data_types::i8) {
VF<int8_t> rnd_vec(s.count(), static_cast<int8_t>(fill_value));
set_values(prim, rnd_vec);
} else {
throw std::runtime_error("get_mem: Unsupported precision");
}
@@ -274,8 +285,10 @@ public:
} else if (l.data_type == data_types::i8) {
VF<int8_t> rnd_vec = generate_random_1d<int8_t>(s.count(), min, max);
set_values(prim, rnd_vec);
}
else if (l.data_type == data_types::bin) {
} else if (l.data_type == data_types::u8) {
VF<uint8_t> rnd_vec = generate_random_1d<uint8_t>(s.count(), min, max);
set_values(prim, rnd_vec);
} else if (l.data_type == data_types::bin) {
VF<int32_t> rnd_vec = generate_random_1d<int32_t>(s.count() / 32, min, max);
set_values(prim, rnd_vec);
}
@@ -528,6 +541,10 @@ public:
#define CASE_CONV_U8S8_8 {1, 3, 4, 5}, {1, 32, 4, 5}, {1, 1, 3, 3}, tensor{1}, tensor{0, 0, -1, -1, 0, 0}, tensor{1}, 1, data_types::u8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
#define CASE_CONV_U8S8_9 {16, 32, 5, 5}, {16, 32, 3, 3}, {1, 1, 1, 1}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::u8, format::bs_fs_yx_bsv16_fsv16, data_types::i8, format::os_is_yx_osv16_isv16, data_types::f32, format::bfyx
#define CASE_CONV_U8S8_10 {16, 32, 5, 5}, {16, 32, 3, 3}, {1, 1, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::u8, format::bs_fs_yx_bsv16_fsv16, data_types::i8, format::os_is_yx_osv16_isv16, data_types::f32, format::bfyx
#define CASE_CONV_U8S8_11 {32, 15, 4, 5}, {32, 30, 2, 3}, {1, 1, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::u8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
#define CASE_CONV_U8S8_12 {32, 15, 5, 5}, {32, 30, 3, 3}, {1, 1, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::u8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
#define CASE_CONV_U8S8_13 {32, 16, 4, 5}, {32, 32, 4, 5}, {1, 1, 1, 1}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::u8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
#define CASE_CONV_U8S8_14 {32, 17, 4, 5}, {32, 17, 4, 5}, {1, 1, 3, 3}, tensor{1}, tensor{0, 0, -1, -1, 0, 0}, tensor{1}, 17, data_types::u8, format::bfyx, data_types::i8, format::goiyx, data_types::f32, format::bfyx
#define CASE_CONV_S8S8_1 {1, 15, 4, 5}, {1, 30, 2, 3}, {1, 1, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::i8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
#define CASE_CONV_S8S8_2 {1, 15, 5, 5}, {1, 30, 3, 3}, {1, 1, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::i8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
@@ -540,6 +557,10 @@ public:
#define CASE_CONV_S8S8_9 {16, 32, 5, 5}, {16, 32, 3, 3}, {1, 1, 1, 1}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::i8, format::bs_fs_yx_bsv16_fsv16, data_types::i8, format::os_is_yx_osv16_isv16, data_types::f32, format::bfyx
#define CASE_CONV_S8S8_10 {16, 32, 5, 5}, {16, 32, 3, 3}, {1, 1, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::i8, format::bs_fs_yx_bsv16_fsv16, data_types::i8, format::os_is_yx_osv16_isv16, data_types::f32, format::bfyx
#define CASE_CONV_S8S8_11 {1, 4, 1280, 720}, {1, 4, 1280, 720}, {1, 1, 5, 5}, tensor{1}, tensor{0, 0, -2, -2}, tensor{1}, 1, data_types::i8, format::b_fs_yx_fsv4, data_types::i8, format::os_is_yx_osv16_isv4, data_types::f32, format::bfyx
#define CASE_CONV_S8S8_12 {32, 15, 4, 5}, {32, 30, 2, 3}, {1, 1, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::i8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
#define CASE_CONV_S8S8_13 {32, 15, 5, 5}, {32, 30, 3, 3}, {1, 1, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::i8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
#define CASE_CONV_S8S8_14 {32, 16, 4, 5}, {32, 32, 4, 5}, {1, 1, 1, 1}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::i8, format::bfyx, data_types::i8, format::bfyx, data_types::f32, format::bfyx
#define CASE_CONV_S8S8_15 {32, 17, 4, 5}, {32, 17, 4, 5}, {1, 1, 3, 3}, tensor{1}, tensor{0, 0, -1, -1, 0, 0}, tensor{1}, 17, data_types::i8, format::bfyx, data_types::i8, format::goiyx, data_types::f32, format::bfyx
#define CASE_CONV3D_U8S8_1 {1, 15, 5, 4, 5}, {1, 30, 3, 2, 3}, {1, 1, 3, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::u8, format::bfzyx, data_types::i8, format::bfzyx, data_types::f32, format::bfzyx
#define CASE_CONV3D_U8S8_2 {1, 15, 5, 5, 5}, {1, 30, 3, 3, 3}, {1, 1, 3, 3, 3}, tensor{1}, tensor{0}, tensor{1}, 1, data_types::u8, format::bfzyx, data_types::i8, format::bfzyx, data_types::f32, format::bfzyx
@@ -771,6 +792,29 @@ INSTANTIATE_TEST_SUITE_P(fusings_gpu, conv_fp32_bias,
bc_test_params{CASE_CONV_FP16_10, 2, 3},
}));
class conv_fp32_double_bias : public ConvFusingTest {};
TEST_P(conv_fp32_double_bias, basic) {
auto p = GetParam();
create_topologies(input_layout("input", get_input_layout(p)),
data("weights", get_mem(get_weights_layout(p))),
data("bias1", get_mem(get_bias_layout(p))),
data("bias2", get_mem(get_bias_layout(p))),
convolution("conv_prim", "input", {"weights"}, std::vector<primitive_id>{}, p.groups, p.stride, p.pad, p.dilation),
eltwise("add_bias1", {"conv_prim", "bias1"}, eltwise_mode::sum),
eltwise("add_bias2", {"add_bias1", "bias2"}, eltwise_mode::sum),
reorder("reorder_bfyx", "add_bias2", p.default_format, data_types::f32)
);
tolerance = 1e-5f;
execute(p);
}
INSTANTIATE_TEST_SUITE_P(fusings_gpu, conv_fp32_double_bias,
::testing::ValuesIn(std::vector<bc_test_params>{
bc_test_params{CASE_CONV_U8S8_1, 2, 4},
bc_test_params{CASE_CONV_S8S8_1, 2, 4},
}));
class conv_fp32_prelu_eltwise : public ConvFusingTest {};
TEST_P(conv_fp32_prelu_eltwise, basic_sum) {
auto p = GetParam();
@@ -4864,7 +4908,7 @@ TEST_P(deconv_scale_actv_quant_u8_eltw_scale_actv_quant_i8, basic) {
reorder("out", "quant2", p.default_format, data_types::f32)
);
tolerance = 1.0f;
tolerance = 2.1f;
execute(p);
}
@@ -8795,3 +8839,272 @@ INSTANTIATE_TEST_SUITE_P(fusings_gpu, gather_elements_activation_scale_eltwise,
gather_elements_test_params{ CASE_GATHER_ELEMENTS_FP32_6D_2, 2, 5 },
gather_elements_test_params{ CASE_GATHER_ELEMENTS_FP32_6D_3, 2, 5 },
}));
#ifdef ENABLE_ONEDNN_FOR_GPU
class ConvFusingTestOneDNN : public WeightsPrimitiveFusingTest<bc_test_params> {
public:
void execute(bc_test_params& p) {
// Onednn post operation has issue in a machine that does not support imad.
if (!engine.get_device_info().supports_imad)
return;
auto input_prim = p.data_type == data_types::u8 ? get_mem(get_input_layout(p), 0, 10) : get_mem(get_input_layout(p));
auto impl_forcing_bo = bo_fused.get<build_option_type::force_implementations>();
const auto& impl_forcing = impl_forcing_bo->forcing;
auto forcing_format = p.input_format;
for (auto& forcing : impl_forcing) {
if (forcing.first == "conv_prim") {
forcing_format = forcing.second.output_format;
}
}
implementation_desc conv_impl = { forcing_format, "", impl_types::onednn };
bo_fused.set_option(build_option::force_implementations({ {"conv_prim", conv_impl} }));
network network_not_fused(this->engine, this->topology_non_fused, bo_not_fused);
network network_fused(this->engine, this->topology_fused, bo_fused);
network_fused.set_input_data("input", input_prim);
network_not_fused.set_input_data("input", input_prim);
compare(network_not_fused, network_fused, p);
auto find_conv = [](primitive_info& p) -> bool {
if (p.original_id == "conv_prim")
return true;
return false;
};
auto pi_fused = network_fused.get_primitives_info();
auto info_fused = std::find_if(pi_fused.begin(), pi_fused.end(), find_conv);
if (info_fused != pi_fused.end())
std::cout << "kernel: " << info_fused->kernel_id << std::endl;
}
};
class conv_int8_eltwise_onednn : public ConvFusingTestOneDNN {};
TEST_P(conv_int8_eltwise_onednn, u8_eltwise_sum_out) {
auto p = GetParam();
auto shift_layout = get_output_layout(p);
shift_layout.data_type = data_types::f32;
create_topologies(input_layout("input", get_input_layout(p)),
data("weights", get_mem(get_weights_layout(p), 0, 2)),
data("bias", get_mem(get_bias_layout(p))),
data("shift_data", get_mem(shift_layout)),
convolution("conv_prim", "input", {"weights"}, {"bias"}, p.groups, p.stride, p.pad, p.dilation),
eltwise("shift", {"conv_prim", "shift_data"}, eltwise_mode::sum, data_types::f32),
// Add 'not fusable' primitive to be able to test full size tensor sum
crop("crop", "shift", get_output_layout(p).size, {0, 0, 0, 0}),
reorder("reorder_bfyx", "crop", p.default_format, data_types::f32)
);
tolerance = 1.f;
execute(p);
}
TEST_P(conv_int8_eltwise_onednn, u8_eltwise_prod_out) {
auto p = GetParam();
create_topologies(input_layout("input", get_input_layout(p)),
data("weights", get_mem(get_weights_layout(p), -2, 2)),
data("bias", get_mem(get_bias_layout(p))),
data("scale_data", get_mem(get_per_channel_layout(p), 1.0f/p.kernel.count()) ),
convolution("conv_prim", "input", {"weights"}, {"bias"}, p.groups, p.stride, p.pad, p.dilation),
eltwise("scale", {"conv_prim", "scale_data"}, eltwise_mode::prod, data_types::u8),
crop("crop", "scale", get_output_layout(p).size, {0, 0, 0, 0}),
reorder("reorder_bfyx", "crop", p.default_format, data_types::f32)
);
tolerance = 1.f;
execute(p);
}
INSTANTIATE_TEST_SUITE_P(fusings_gpu, conv_int8_eltwise_onednn,
::testing::ValuesIn(std::vector<bc_test_params>{
bc_test_params{CASE_CONV_U8S8_1, 2, 4},
bc_test_params{CASE_CONV_U8S8_2, 2, 4},
bc_test_params{CASE_CONV_U8S8_3, 2, 4},
bc_test_params{CASE_CONV_S8S8_1, 2, 4},
bc_test_params{CASE_CONV_S8S8_2, 2, 4},
bc_test_params{CASE_CONV_S8S8_3, 2, 4},
bc_test_params{CASE_CONV_U8S8_11, 2, 4},
bc_test_params{CASE_CONV_U8S8_12, 2, 4},
bc_test_params{CASE_CONV_U8S8_13, 2, 4},
bc_test_params{CASE_CONV_S8S8_12, 2, 4},
bc_test_params{CASE_CONV_S8S8_13, 2, 4},
bc_test_params{CASE_CONV_S8S8_14, 2, 4},
bc_test_params{CASE_CONV3D_U8S8_1, 3, 4},
bc_test_params{CASE_CONV3D_U8S8_2, 3, 4},
bc_test_params{CASE_CONV3D_U8S8_3, 3, 4},
bc_test_params{CASE_CONV3D_U8S8_5, 3, 4},
bc_test_params{CASE_CONV3D_S8S8_1, 3, 4},
bc_test_params{CASE_CONV3D_S8S8_2, 3, 4},
bc_test_params{CASE_CONV3D_S8S8_3, 3, 4},
bc_test_params{CASE_CONV3D_S8S8_5, 3, 4},
}));
class conv_fp32_activation_onednn : public ConvFusingTestOneDNN {};
TEST_P(conv_fp32_activation_onednn, basic) {
auto p = GetParam();
create_topologies(input_layout("input", get_input_layout(p)),
data("weights", get_mem(get_weights_layout(p))),
data("bias", get_mem(get_bias_layout(p))),
convolution("conv_prim", "input", {"weights"}, {"bias"}, p.groups, p.stride, p.pad, p.dilation),
activation("activation", "conv_prim", activation_func::abs),
reorder("reorder_bfyx", "activation", p.default_format, data_types::f32)
);
tolerance = 1e-2f;
execute(p);
}
INSTANTIATE_TEST_SUITE_P(fusings_gpu, conv_fp32_activation_onednn,
::testing::ValuesIn(std::vector<bc_test_params>{
bc_test_params{CASE_CONV_FP16_1, 2, 3},
bc_test_params{CASE_CONV_FP16_2, 2, 3},
bc_test_params{CASE_CONV_FP16_3, 2, 3},
bc_test_params{CASE_CONV_FP16_4, 2, 3},
}));
class conv_int8_quantize_u8_onednn : public ConvFusingTestOneDNN {};
TEST_P(conv_int8_quantize_u8_onednn, per_channel) {
auto p = GetParam();
create_topologies(input_layout("input", get_input_layout(p)),
data("weights", get_mem(get_weights_layout(p), -2, 2)),
data("bias", get_mem(get_bias_layout(p))),
data("in_lo", get_mem(get_per_channel_layout(p), -10, 0)),
data("in_hi", get_mem(get_per_channel_layout(p), 0, 10)),
data("out_lo", get_mem(get_single_element_layout(p), 0)),
data("out_hi", get_mem(get_single_element_layout(p), 255)),
convolution("conv_prim", "input", {"weights"}, {"bias"}, p.groups, p.stride, p.pad, p.dilation),
quantize("quantize", "conv_prim", "in_lo", "in_hi", "out_lo", "out_hi", 256, data_types::u8),
reorder("reorder_bfyx", "quantize", p.default_format, data_types::f32)
);
tolerance = 1.0f;
execute(p);
}
TEST_P(conv_int8_quantize_u8_onednn, per_tensor) {
auto p = GetParam();
create_topologies(input_layout("input", get_input_layout(p)),
data("weights", get_mem(get_weights_layout(p), -2, 2)),
data("bias", get_mem(get_bias_layout(p), 0)),
data("in_lo", get_mem(get_single_element_layout(p), -10)),
data("in_hi", get_mem(get_single_element_layout(p), 10)),
data("out_lo", get_mem(get_single_element_layout(p), 0)),
data("out_hi", get_mem(get_single_element_layout(p), 255)),
convolution("conv_prim", "input", {"weights"}, {"bias"}, p.groups, p.stride, p.pad, p.dilation),
quantize("quantize", "conv_prim", "in_lo", "in_hi", "out_lo", "out_hi", 256, data_types::u8),
reorder("reorder_bfyx", "quantize", p.default_format, data_types::f32)
);
tolerance = 1.0f;
execute(p);
}
INSTANTIATE_TEST_SUITE_P(fusings_gpu, conv_int8_quantize_u8_onednn,
::testing::ValuesIn(std::vector<bc_test_params>{
bc_test_params{CASE_CONV_U8S8_1, 2, 3},
bc_test_params{CASE_CONV_U8S8_2, 2, 3},
bc_test_params{CASE_CONV_U8S8_3, 2, 3},
bc_test_params{CASE_CONV_S8S8_1, 2, 3},
bc_test_params{CASE_CONV_S8S8_2, 2, 3},
bc_test_params{CASE_CONV_S8S8_3, 2, 3},
}));
class conv_int8_activation_eltwise_quantize_onednn : public ConvFusingTestOneDNN {};
TEST_P(conv_int8_activation_eltwise_quantize_onednn, bsv32_fsv32) {
auto p = GetParam();
layout eltwise_layout = get_output_layout(p);
eltwise_layout.format = format::bs_fs_yx_bsv32_fsv32;
create_topologies(input_layout("input", get_input_layout(p)),
data("weights", get_mem(get_weights_layout(p), -1, 1)),
data("bias", get_mem(get_bias_layout(p))),
data("eltwise_data", get_mem(eltwise_layout, -0.5, 0.5)),
data("in_lo", get_mem(get_per_channel_layout(p), min_random, 0)),
data("in_hi", get_mem(get_per_channel_layout(p), 1, max_random)),
data("out_lo", get_mem(get_single_element_layout(p), -127)),
data("out_hi", get_mem(get_single_element_layout(p), 127)),
convolution("conv_prim", "input", { "weights" }, { "bias" }, p.groups, p.stride, p.pad, p.dilation),
activation("activation", "conv_prim", activation_func::abs),
eltwise("eltwise", "activation", "eltwise_data", eltwise_mode::sum),
quantize("quantize", "eltwise", "in_lo", "in_hi", "out_lo", "out_hi", 255, data_types::i8),
reorder("reorder_bfyx", "quantize", p.default_format, data_types::f32)
);
implementation_desc conv_impl = { format::bs_fs_yx_bsv32_fsv32, "", impl_types::onednn };
bo_fused.set_option(build_option::force_implementations({ {"conv_prim", conv_impl} }));
tolerance = 1.f;
execute(p);
}
INSTANTIATE_TEST_SUITE_P(fusings_gpu, conv_int8_activation_eltwise_quantize_onednn,
::testing::ValuesIn(std::vector<bc_test_params>{
bc_test_params{CASE_CONV_U8S8_1, 2, 5},
bc_test_params{CASE_CONV_U8S8_2, 2, 5},
bc_test_params{CASE_CONV_U8S8_3, 2, 5},
bc_test_params{CASE_CONV_U8S8_4, 2, 5},
bc_test_params{CASE_CONV_U8S8_7, 2, 5},
bc_test_params{CASE_CONV_U8S8_8, 2, 5},
bc_test_params{CASE_CONV_U8S8_11, 2, 5},
bc_test_params{CASE_CONV_U8S8_12, 2, 5},
bc_test_params{CASE_CONV_U8S8_13, 2, 5},
bc_test_params{CASE_CONV_U8S8_14, 2, 5},
bc_test_params{CASE_CONV_S8S8_1, 2, 5},
bc_test_params{CASE_CONV_S8S8_2, 2, 5},
bc_test_params{CASE_CONV_S8S8_3, 2, 5},
bc_test_params{CASE_CONV_S8S8_4, 2, 5},
bc_test_params{CASE_CONV_S8S8_7, 2, 5},
bc_test_params{CASE_CONV_S8S8_8, 2, 5},
bc_test_params{CASE_CONV_S8S8_12, 2, 5},
bc_test_params{CASE_CONV_S8S8_13, 2, 5},
bc_test_params{CASE_CONV_S8S8_14, 2, 5},
bc_test_params{CASE_CONV_S8S8_15, 2, 5},
}));
class conv_int8_scale_shift_swish_onednn : public ConvFusingTestOneDNN {};
TEST_P(conv_int8_scale_shift_swish_onednn, bsv32_fsv32) {
auto p = GetParam();
create_topologies(input_layout("input", get_input_layout(p)),
data("weights", get_mem(get_weights_layout(p), -1, 1)),
data("bias", get_mem(get_bias_layout(p))),
data("scale_data", get_mem(get_per_channel_layout(p), 1.0f/p.kernel.count())),
data("shift_data", get_mem(get_per_channel_layout(p), 1)),
convolution("conv_prim", "input", {"weights"}, {"bias"}, p.groups, p.stride, p.pad, p.dilation),
eltwise("scale0", {"conv_prim", "scale_data"}, eltwise_mode::sum),
eltwise("shift0", {"scale0", "shift_data"}, eltwise_mode::sum),
activation("sigmoid", "shift0", activation_func::swish),
eltwise("scale1", {"sigmoid", "scale_data"}, eltwise_mode::sum),
eltwise("shift1", {"scale1", "shift_data"}, eltwise_mode::sum),
reorder("reorder_bfyx", "shift1", p.default_format, data_types::f32)
);
implementation_desc conv_impl = { format::bs_fs_yx_bsv32_fsv32, "", impl_types::onednn };
bo_fused.set_option(build_option::force_implementations({ {"conv_prim", conv_impl} }));
tolerance = 1.f;
execute(p);
}
INSTANTIATE_TEST_SUITE_P(fusings_gpu, conv_int8_scale_shift_swish_onednn,
::testing::ValuesIn(std::vector<bc_test_params>{
bc_test_params{CASE_CONV_U8S8_1, 2, 7},
bc_test_params{CASE_CONV_U8S8_2, 2, 7},
bc_test_params{CASE_CONV_S8S8_1, 2, 7},
bc_test_params{CASE_CONV_S8S8_2, 2, 7},
bc_test_params{CASE_CONV_U8S8_11, 2, 7},
bc_test_params{CASE_CONV_U8S8_12, 2, 7},
bc_test_params{CASE_CONV_U8S8_14, 2, 7},
bc_test_params{CASE_CONV_S8S8_12, 2, 7},
bc_test_params{CASE_CONV_S8S8_13, 2, 7},
bc_test_params{CASE_CONV_S8S8_15, 2, 7},
}));
#endif
+56 -19
View File
@@ -3,8 +3,8 @@
import numpy as np
from mo.front.common.partial_infer.utils import is_fully_defined
from mo.graph.graph import Node, Graph
from mo.front.common.partial_infer.utils import compatible_shapes, dynamic_dimension, shape_array, is_fully_defined
from mo.graph.graph import Node, Graph, Error
from mo.ops.op import Op
from mo.utils.broadcasting import bi_directional_shape_broadcasting, bi_directional_broadcasting
@@ -35,31 +35,68 @@ class Select(Op):
"Select operation must have 3 inputs: 'condition', 'then' and 'else' tensors for node {}".format(node_name)
condition_value = node.in_port(0).data.get_value()
condition_shape = node.in_port(0).data.get_shape()
resulting_tensors = [node.in_port(1).data.get_value(), node.in_port(2).data.get_value()]
a_shape = node.in_port(1).data.get_shape()
b_shape = node.in_port(2).data.get_shape()
output_shape = bi_directional_shape_broadcasting(a_shape, b_shape)
assert output_shape is not None, 'Input shapes for node {} are not broadcast-able'.format(node_name)
broadcast_rule = node.soft_get('auto_broadcast', 'numpy')
if broadcast_rule == 'numpy':
msg = "In Select node '{}' condition and then/else shapes must be broadcastable. " \
"But instead got: cond_shape={}, then_shape={}, else_shape={}".format(
node_name, condition_shape, a_shape, b_shape)
output_shape = bi_directional_shape_broadcasting(a_shape, b_shape)
assert output_shape is not None, msg
# if Select was created from TF Where operations then 1D condition must have the same size
# as 0-index dimension of output_shape. This condition is different from being numpy compatible
# but by adding ones to the end we can achieve numpy compatibility, as in transformation SelectBroadcast.py
if node.has_valid('format') and node['format'] == 'tf' and len(condition_shape) == 1:
# https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/array_ops.py#L4596-L4598
msg_tf = "In Select node '{}' if 'condition' is a 1D tensor then it's size " \
"must be matching with the first dimension of then/else branches. " \
"But instead got: cond_shape={}, then_shape={}, else_shape={}".format(
node_name, condition_shape, a_shape, b_shape)
assert condition_shape[0] == output_shape[0], msg_tf
condition_shape = np.concatenate((condition_shape, np.ones(len(output_shape) - 1)))
output_shape = bi_directional_shape_broadcasting(output_shape, condition_shape)
assert output_shape is not None, msg
elif broadcast_rule == 'pdpd':
# todo: add pdpd broadcasting rule
# note that additionally to output_shape resulting_tensors must be broadcasted as well
raise Error("PDPD broadcasting rule is not implemented yet")
else: # broadcasting is not allowed
assert compatible_shapes(a_shape, b_shape) and compatible_shapes(condition_shape, a_shape), \
'In node \'{}\' for Select operation when broadcasting is off all inputs must be of the same shape. ' \
'But instead got: cond_shape={}, then_shape={}, else_shape={}'.format(
node_name, condition_shape, a_shape, b_shape)
output_shape = shape_array([i if i is not dynamic_dimension else j for i, j in zip(a_shape, b_shape)])
node.out_port(0).data.set_shape(output_shape)
if condition_value is not None:
if resulting_tensors[0] is not None:
resulting_tensors[0] = bi_directional_broadcasting(resulting_tensors[0], b_shape)
if resulting_tensors[1] is not None:
resulting_tensors[1] = bi_directional_broadcasting(resulting_tensors[1], a_shape)
condition_value = bi_directional_broadcasting(condition_value, output_shape)
if is_fully_defined(condition_value) and np.all(condition_value == condition_value.item(0)):
# in some graphs Select condition is always True[False] and
# one of the branches is None (which is not selected)
# if we use np.where for such cases then dtype of output_value will be object (non numeric type)
# and subsequent numpy operation on such tensors will fail
output_value = resulting_tensors[not np.bool(condition_value.item(0))]
if output_value is None:
return
if broadcast_rule == 'numpy':
output_value = bi_directional_broadcasting(output_value, output_shape)
elif broadcast_rule == 'pdpd':
# todo: add pdpd broadcasting rule
raise Error("PDPD broadcasting rule is not implemented yet")
output_value = np.ma.where(condition_value, resulting_tensors[0], resulting_tensors[1])
if condition_value.size != 1:
if np.any(output_value == None):
# If any element of output value is None that means that we use the value from the 'then' or the
# 'else' tensor which is not defined, this means that we cannot perform value propagation.
output_value = None
else:
output_value = output_value.astype(resulting_tensors[not np.bool(condition_value.item(0))].dtype)
if output_value is not None:
node.out_port(0).data.set_value(output_value)
elif resulting_tensors[0] is not None and resulting_tensors[1] is not None:
output_value = np.ma.where(condition_value, resulting_tensors[0], resulting_tensors[1])
node.out_port(0).data.set_value(output_value)
@staticmethod
@@ -63,6 +63,11 @@ def strict_compare_tensors(tensor1, tensor2):
:param tensor2: the second tensor to compare
:return: boolean result of the comparison
"""
if tensor1 is None and tensor2 is None:
return True
if tensor1 is None or tensor2 is None:
return False
if not isinstance(tensor1, np.ma.masked_array):
tensor1 = shape_array(tensor1)
if not isinstance(tensor2, np.ma.masked_array):
@@ -97,7 +97,7 @@ class TestElementwiseTypeAlignment(unittest.TestCase):
**shaped_parameter('input_1', input_shape, {'data_type': input_1_type}),
**shaped_parameter('input_2', input_shape, {'data_type': input_2_type}),
**regular_op_with_empty_data('add', {'op': 'Add', 'type': 'Add', 'type_infer': Elementwise.type_infer}),
**valued_const_with_data('const', const_value, {'data_type': const_type}),
**valued_const_with_data('const', const_value, kwargs={'data_type': const_type}),
**result('result'),
}
graph = build_graph(nodes, edges, nodes_with_edges_only=True)
@@ -4,181 +4,287 @@
import unittest
import numpy as np
from generator import generator, generate
from extensions.ops.select import Select
from mo.front.common.partial_infer.utils import dynamic_dimension, shape_array, dynamic_dimension_value
from mo.front.common.partial_infer.utils import strict_compare_tensors, int64_array
from mo.graph.graph import Node
from mo.utils.ir_engine.compare_graphs import compare_graphs
from unit_tests.utils.graph import build_graph_with_attrs
from mo.utils.error import Error
from unit_tests.utils.graph import build_graph, valued_const_with_data, result, regular_op_with_empty_data, \
connect
@generator
class TestSelect(unittest.TestCase):
nodes = [
('than', {'kind': 'op'}),
('than_data', {'value': np.ones((2, 2)), 'kind': 'data', 'executable': True, 'shape': np.array([2, 2])}),
('else', {'kind': 'op'}),
('else_data', {'value': np.zeros((2, 2)), 'kind': 'data', 'executable': True, 'shape': np.array([2, 2])}),
('condition', {'value': None, 'kind': 'op'}),
('condition_data', {'value': None, 'kind': 'data', 'executable': True, 'shape': np.array([2, 2])}),
('select', {'type': 'Select', 'kind': 'op', 'op': 'Select', 'infer': Select.infer}),
('select_output', {'value': None, 'kind': 'data', 'executable': True, 'shape': None}),
]
edges = [
('condition', 'condition_data'),
('condition_data', 'select', {'in': 0}),
('than', 'than_data'),
('than_data', 'select', {'in': 1}),
('else', 'else_data'),
('else_data', 'select', {'in': 2}),
('select', 'select_output', {'out': 0}),
]
@staticmethod
def build_select_graph_and_infer(condition_value, then_value, else_value, out_value,
condition_shape=None, then_shape=None, else_shape=None, out_shape=None,
auto_broadcast='numpy', fw_format=None):
if then_value is not None:
then_shape = int64_array(then_value.shape)
if else_value is not None:
else_shape = int64_array(else_value.shape)
nodes = {
**valued_const_with_data('then', then_value, then_shape),
**valued_const_with_data('else', else_value, else_shape),
**valued_const_with_data('condition', condition_value, condition_shape),
**regular_op_with_empty_data('select', {'op': 'Select', 'auto_broadcast': auto_broadcast, 'format': fw_format}),
**result('out'),
}
edges = [
*connect('condition', '0:select'),
*connect('then', '1:select'),
*connect('else', '2:select'),
*connect('select', 'out'),
]
graph = build_graph(nodes, edges)
select_node = Node(graph, 'select')
Select.infer(select_node)
select_out_node = Node(graph, 'select_d')
value_desc = 'values'
ref_val = out_value
actual_val = select_out_node['value']
if out_shape is not None:
value_desc = 'shapes'
ref_val = out_shape
actual_val = select_out_node['shape']
assert select_out_node['value'] is None, "if 'out_shape' is defined manually 'value' must be None"
flag = strict_compare_tensors(actual_val, ref_val)
msg = '' if flag else 'reference {} and actual {} {} do not match\n'.format(ref_val, actual_val, value_desc)
return flag, msg
def test_1(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([5, 6], dtype=bool),
then_value=np.ones([5, 6], dtype=np.float),
else_value=np.zeros([5, 6], dtype=np.float),
out_value=np.ones([5, 6], dtype=np.float))
self.assertTrue(flag, msg)
def test_2(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([15, 3, 5], dtype=bool),
then_value=np.ones([15, 3, 5], dtype=np.float),
else_value=np.zeros([15, 1, 5], dtype=np.float),
out_value=np.ones([15, 3, 5], dtype=np.float))
self.assertTrue(flag, msg)
def test_select_infer_no_condition(self):
graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges)
# We should propagate only shapes
graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes,
edges_with_attrs=self.edges,
update_nodes_attributes=[('select_output', {'shape': np.array([2, 2])})])
node = Node(graph, 'select')
node.infer(node)
(flag, resp) = compare_graphs(graph, graph_ref, 'select_output', check_op_attrs=True)
self.assertTrue(flag, resp)
flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=[2],
then_value=None, then_shape=[2],
else_value=None, else_shape=[2],
out_value=None, out_shape=[2])
self.assertTrue(flag, msg)
def test_select_infer_condition_true(self):
graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges,
update_nodes_attributes=[('condition', {'value': np.array([True])}),
('select_output', {'shape': np.array([2, 2]),
'value': np.ones((2, 2))})
])
# We should propagate shapes and values
graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes,
edges_with_attrs=self.edges,
update_nodes_attributes=[('select_output', {'shape': np.array([2, 2]),
'value': np.ones((2, 2))})])
node = Node(graph, 'select')
node.infer(node)
(flag, resp) = compare_graphs(graph, graph_ref, 'select_output', check_op_attrs=True)
self.assertTrue(flag, resp)
flag, msg = self.build_select_graph_and_infer(condition_value=np.array([True, True], dtype=bool),
then_value=np.array([1, 1], dtype=np.int8),
else_value=np.array([2, 2], dtype=np.int8),
out_value=np.array([1, 1], dtype=np.int8))
self.assertTrue(flag, msg)
def test_select_infer_condition_false(self):
graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges,
update_nodes_attributes=[('condition', {'value': np.array([False])}),
('select_output', {'shape': np.array([2, 2]),
'value': np.zeros((2, 2))})
])
flag, msg = self.build_select_graph_and_infer(condition_value=np.array([False, False], dtype=bool),
then_value=np.array([1, 1], dtype=np.int8),
else_value=np.array([2, 2], dtype=np.int8),
out_value=np.array([2, 2], dtype=np.int8))
self.assertTrue(flag, msg)
# We should propagate shapes and values
graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes,
edges_with_attrs=self.edges,
update_nodes_attributes=[('select_output', {'shape': np.array([2, 2]),
'value': np.zeros((2, 2))})])
def test_select_infer_condition_true_2(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.array([True], dtype=bool),
then_value=np.ones([15, 3, 5], dtype=np.float),
else_value=np.zeros([15, 1, 5], dtype=np.float),
out_value=np.ones([15, 3, 5], dtype=np.float))
self.assertTrue(flag, msg)
node = Node(graph, 'select')
node.infer(node)
def test_select_infer_condition_false_2(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.array([False], dtype=bool),
then_value=np.ones([15, 3, 5], dtype=np.float),
else_value=np.zeros([15, 1, 5], dtype=np.float),
out_value=np.zeros([15, 3, 5], dtype=np.float))
self.assertTrue(flag, msg)
(flag, resp) = compare_graphs(graph, graph_ref, 'select_output', check_op_attrs=True)
self.assertTrue(flag, resp)
# if one of the branches is None then np.where shouldn't be used to avoid object dtype in output
# res = np.where(condition, numpy_array_of_int[float]_dtype, None)
# print(res.dtype) => object which is not compatible with other numeric dtypes, will fail further without
# clear explanation, need to catch such cases as soon as possible
def test_select_infer_None_then_branch_1(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.zeros([15, 3, 5], dtype=bool),
then_value=None, then_shape=[15, 3, 5],
else_value=np.ones([15, 1, 5], dtype=np.float),
out_value=np.ones([15, 3, 5], dtype=np.float))
self.assertTrue(flag, msg)
def test_select_infer_None_then_branch_2(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([15, 3, 5], dtype=bool),
then_value=None, then_shape=[15, 3, 5],
else_value=np.ones([15, 1, 5], dtype=np.float),
out_value=None)
self.assertTrue(flag, msg)
def test_select_infer_None_else_branch_1(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([15, 3, 5], dtype=bool),
then_value=np.ones([15, 1, 5], dtype=np.float),
else_value=None, else_shape=[15, 3, 5],
out_value=np.ones([15, 3, 5], dtype=np.float))
self.assertTrue(flag, msg)
def test_select_infer_None_else_branch_2(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.zeros([15, 3, 5], dtype=bool),
then_value=np.ones([15, 1, 5], dtype=np.float),
else_value=None, else_shape=[15, 3, 5],
out_value=None)
self.assertTrue(flag, msg)
def test_select_broadcast_1(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([2, 3, 4, 5], dtype=bool),
then_value=np.ones([], dtype=np.float),
else_value=np.zeros([2, 3, 4, 5], dtype=np.float),
out_value=np.ones([2, 3, 4, 5], dtype=np.float))
self.assertTrue(flag, msg)
def test_select_broadcast_2(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([2, 3, 4, 1], dtype=bool),
then_value= np.ones([1, 3, 1, 5], dtype=np.float),
else_value=np.zeros([2, 1, 1, 5], dtype=np.float),
out_value=np.ones([2, 3, 4, 5], dtype=np.float))
self.assertTrue(flag, msg)
def test_select_broadcast_3(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([2, 3, 1, 1], dtype=bool),
then_value= np.ones([2, 3, 4, 5], dtype=np.float),
else_value=np.zeros([2, 1, 1, 5], dtype=np.float),
out_value=np.ones([2, 3, 4, 5], dtype=np.float))
self.assertTrue(flag, msg)
def test_select_broadcast_4(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([2, 3, 4, 5], dtype=bool),
then_value= np.ones([5], dtype=np.float),
else_value=np.zeros([2, 3, 4, 5], dtype=np.float),
out_value=np.ones([2, 3, 4, 5], dtype=np.float))
self.assertTrue(flag, msg)
# when output shape is broadcasted from condition, then, and else shapes
def test_select_broadcast_with_shape(self):
flag, msg = self.build_select_graph_and_infer(condition_shape=[2, 3, 4, 1], condition_value=None,
then_shape=[1, 3, 1, 5], then_value=None,
else_shape=[2, 1, 1, 5], else_value=None,
out_shape=[2, 3, 4, 5], out_value=None)
self.assertTrue(flag, msg)
def test_select_infer_assert_shapes(self):
graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges,
update_nodes_attributes=[('else_data', {'shape': np.array([3, 3]),
'value':np.zeros((3, 3))})])
with self.assertRaisesRegex(AssertionError, "must be broadcastable"):
self.build_select_graph_and_infer(condition_value=None, condition_shape=[2, 2],
then_value=None, then_shape=[2, 2],
else_value=None, else_shape=[3, 3],
out_value=None, out_shape=[42, 42])
tested_class = Select(graph=graph, attrs={})
def test_select_infer_assert_condition_shapes_are_compatible(self):
with self.assertRaisesRegex(AssertionError, "must be broadcastable"):
self.build_select_graph_and_infer(condition_value=None, condition_shape=[42, 3],
then_value=None, then_shape=[1, 3],
else_value=None, else_shape=[3, 3],
out_value=None, out_shape=[3, 3])
node = Node(graph, 'select')
with self.assertRaisesRegex(AssertionError, "Input shapes for node select are not broadcast-able"):
tested_class.infer(node)
def test_select_infer_masked_1(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([True, True], mask=[1, 1]),
# condition_value = [dynamic_dimension, dynamic_dimension])
then_value=None, then_shape=[2],
else_value=np.zeros((2, 2), dtype=np.int64),
out_value=None)
self.assertTrue(flag, msg)
@generate(*[
([5, 6], [1], [5, 6]),
([15, 3, 5], [15, 1, 5], [15, 3, 5]),
([2, 3, 4, 5], [], [2, 3, 4, 5]),
([2, 3, 4, 5], [5], [2, 3, 4, 5]),
([2, 3, 4, 5], [2, 1, 1, 5], [2, 3, 4, 5]),
([2, 3, 4, 5], [1, 3, 1, 5], [2, 3, 4, 5]),
])
def test_select_infer_condition_shapes_broadcast(self, else_data_shape, than_data_shape, select_output_shape):
graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges,
update_nodes_attributes=
[('else_data', {'shape': np.array(else_data_shape),
'value': np.zeros(else_data_shape, dtype=np.float)}),
('than_data', {'shape': np.array(than_data_shape),
'value': np.zeros(than_data_shape, dtype=np.float)}),
('select_output', {'shape': None, 'value': None})
])
def test_select_infer_masked_2(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([False, False], mask=[1, 1]),
# condition_value = [dynamic_dimension, dynamic_dimension])
then_value=None, then_shape=[2],
else_value=np.zeros((2, 2), dtype=np.int64),
out_value=None)
self.assertTrue(flag, msg)
node = Node(graph, 'select')
node.infer(node)
def test_select_infer_masked_3(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([True, True], mask=[1, 1]),
# condition_value = [dynamic_dimension, dynamic_dimension])
then_value=None, then_shape=[2],
else_value=np.zeros((2, 2), dtype=np.int64),
out_value=None)
self.assertTrue(flag, msg)
self.assertTrue(np.array_equal(graph.nodes['select_output']['shape'], np.array(select_output_shape)))
def test_select_infer_masked_4(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([True, False], mask=[0, 1]),
# condition_value = [True, dynamic_dimension])
then_value=np.ones((2, 2), dtype=np.int64),
else_value=np.zeros((2, 2), dtype=np.int64),
out_value=np.ma.array([[1, 42], [1, 42]], mask=[[0, 1], [0, 1]]))
# out_value = [[1, dynamic_dimension], [1, dynamic_dimension]]
self.assertTrue(flag, msg)
@generate(*[
([5, 6], [5, 6], [5, 6], [5, 6], lambda x: np.ones(x, dtype=np.float),
lambda x: np.zeros(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float)),
([15, 3, 5], [15, 3, 5], [15, 1, 5], [15, 3, 5], lambda x: np.ones(x, dtype=np.float),
lambda x: np.zeros(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float)),
([15, 3, 5], [15, 3, 5], [15, 1, 5], [15, 3, 5], lambda x: np.ones(x, dtype=np.float),
lambda x: None, lambda x: np.ones(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float)),
([15, 3, 5], [15, 3, 5], [15, 1, 5], [15, 3, 5], lambda x: np.ones(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float), lambda x: None, lambda x: None),
([15, 3, 5], [15, 3, 5], [15, 1, 5], [15, 3, 5], lambda x: np.zeros(x, dtype=np.float),
lambda x: None, lambda x: np.ones(x, dtype=np.float), lambda x: None),
([15, 3, 5], [15, 3, 5], [15, 1, 5], [15, 3, 5], lambda x: np.zeros(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float), lambda x: None, lambda x: np.ones(x, dtype=np.float)),
([15, 3, 5], [15, 3, 5], [15, 1, 5], [15, 3, 5], lambda x: np.array([True], np.bool),
lambda x: np.zeros(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float)),
([15, 3, 5], [15, 3, 5], [15, 1, 5], [15, 3, 5], lambda x: np.array([False], np.bool),
lambda x: np.zeros(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float),
lambda x: np.zeros(x, dtype=np.float)),
([2, 3, 4, 5], [2, 3, 4, 5], [], [2, 3, 4, 5], lambda x: np.ones(x, dtype=np.float),
lambda x: np.zeros(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float)),
([2, 3, 4, 5], [2, 3, 4, 5], [5], [2, 3, 4, 5], lambda x: np.ones(x, dtype=np.float),
lambda x: np.zeros(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float)),
([2, 3, 1, 1], [2, 1, 1, 5], [2, 3, 4, 5], [2, 3, 4, 5], lambda x: np.ones(x, dtype=np.float),
lambda x: np.zeros(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float)),
([2, 3, 4, 1], [2, 1, 1, 5], [1, 3, 1, 5], [2, 3, 4, 5], lambda x: np.ones(x, dtype=np.float),
lambda x: np.zeros(x, dtype=np.float), lambda x: np.ones(x, dtype=np.float),
lambda x: np.ones(x, dtype=np.float)),
])
def test_select_infer_condition_with_value(self, condition_shape, else_data_shape, than_data_shape,
select_output_shape, condition_value, else_value, than_value,
output_value):
"""
Unit tests generator can sporadic throw exception if we try
to run generator with call numpy array generation functions.
So we need to use lambda function for escape the problem.
"""
condition_value = condition_value(condition_shape)
else_value = else_value(else_data_shape)
than_value = than_value(than_data_shape)
output_value = output_value(select_output_shape)
graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges,
update_nodes_attributes=[('condition_data', {'shape': np.array(condition_shape),
'value': condition_value}),
('else_data', {'shape': np.array(else_data_shape),
'value': else_value}),
('than_data', {'shape': np.array(than_data_shape),
'value': than_value}),
('select_output',
{'shape': np.array(select_output_shape),
'value': None})
])
def test_select_infer_masked_5(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([False, True], mask=[0, 1]),
# condition_value = [True, dynamic_dimension])
then_value=np.ones((2, 2), dtype=np.int64),
else_value=np.zeros((2, 2), dtype=np.int64),
out_value=np.ma.array([[0, 42], [0, 42]], mask=[[0, 1], [0, 1]]))
# out_value = [[0, dynamic_dimension], [0, dynamic_dimension]]
self.assertTrue(flag, msg)
node = Node(graph, 'select')
node.infer(node)
def test_select_infer_masked_6(self):
flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([True, False], mask=[1, 0]),
# condition_value = [True, dynamic_dimension])
then_value=np.ones((2, 2), dtype=np.int64),
else_value=np.zeros((2, 2), dtype=np.int64),
out_value=np.ma.array([[42, 0], [42, 0]], mask=[[1, 0], [1, 0]]))
# out_value = [[dynamic_dimension, 0], [dynamic_dimension, 0]]
self.assertTrue(flag, msg)
def test_select_infer_no_broadcast_dynamic_then_else_shapes(self):
flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([100, 100]),
then_value=None, then_shape=shape_array([100, dynamic_dimension_value]),
else_value=None, else_shape=shape_array([dynamic_dimension_value, 100]),
out_value=None, out_shape=shape_array([100, 100]),
auto_broadcast='none')
self.assertTrue(flag, msg)
def test_select_infer_no_broadcast_dynamic_then_else_shapes_2(self):
flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([100, 100]),
then_value=None, then_shape=shape_array([dynamic_dimension_value, 100]),
else_value=None, else_shape=shape_array([100, dynamic_dimension_value]),
out_value=None, out_shape=shape_array([100, 100]),
auto_broadcast='none')
self.assertTrue(flag, msg)
def test_select_infer_no_broadcast_dynamic_shapes(self):
flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([100, 100]),
then_value=None, then_shape=shape_array([100, dynamic_dimension_value]),
else_value=None, else_shape=shape_array([dynamic_dimension_value, 100]),
out_value=None, out_shape=shape_array([100, 100]),
auto_broadcast='none')
self.assertTrue(flag, msg)
def test_select_infer_tf_condition(self):
flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([100]),
then_value=None, then_shape=shape_array([100, 20]),
else_value=None, else_shape=shape_array([100, 20]),
out_value=None, out_shape=shape_array([100, 20]),
auto_broadcast='numpy', fw_format='tf')
self.assertTrue(flag, msg)
def test_select_infer_tf_condition_assert_raises(self):
with self.assertRaisesRegex(AssertionError, "if 'condition' is a 1D tensor then it's size"):
self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([42]),
then_value=None, then_shape=shape_array([100, 20]),
else_value=None, else_shape=shape_array([100, 20]),
out_value=None, out_shape=shape_array([100, 20]),
auto_broadcast='numpy', fw_format='tf')
def test_select_infer_assert_pdpd(self):
with self.assertRaisesRegex(Error, "PDPD broadcasting rule is not implemented yet"):
self.build_select_graph_and_infer(condition_value=None, condition_shape=[2, 2],
then_value=None, then_shape=[2, 2],
else_value=None, else_shape=[3, 3],
out_value=None, out_shape=[42, 42],
auto_broadcast='pdpd')
self.assertTrue(np.array_equal(graph.nodes['select_output']['value'], output_value))
+26 -11
View File
@@ -134,7 +134,7 @@ def build_graph_with_attrs(nodes_with_attrs: list, edges_with_attrs: list, new_n
def build_graph(nodes_attrs: dict, edges: list, update_attributes: dict = None, nodes_with_edges_only: bool = False,
cli: Namespace = Namespace(static_shape=False, data_type='FP32')):
cli: Namespace = None):
"""
Build the Graph with specific nodes and edges.
:param nodes_attrs: dictionary where key is the node name and the value is the dictionary with node attributes.
@@ -145,6 +145,8 @@ def build_graph(nodes_attrs: dict, edges: list, update_attributes: dict = None,
:param cli: Namespace with cli keys to associate with the graph
:return: generated graph.
"""
# no mutable values must be set as default function argument
cli = Namespace(static_shape=False, data_type='FP32') if cli is None else cli
graph = Graph()
for node_name, attrs in nodes_attrs.items():
@@ -270,11 +272,29 @@ class FakeNode:
return getattr(self, item)
# regular units
def const(name, value, shape=None, kwargs=None):
# no mutable default arguments must be passed
kwargs = {} if kwargs is None else kwargs
if value is not None:
shape = int64_array(value.shape)
elif value is None and shape is not None:
shape = shape_array(shape)
res = {name: {'kind': 'op', 'type': 'Const', 'op': 'Const',
'value': value, 'shape': shape,
'infer': Const.infer, 'type_infer': Const.type_infer, **kwargs}}
return res
def valued_data(name, value, shape=None):
if value is not None:
shape = int64_array(value.shape)
elif value is None and shape is not None:
shape = shape_array(shape)
return {name: {'kind': 'data', 'value': value, 'shape': shape}}
regular_op = lambda name, kwargs: {name: {'kind': 'op', 'type': 'NoType', **kwargs}}
valued_data = lambda name, value: {name: {'kind': 'data', 'value': value,
'shape': int64_array(value.shape) if value is not None else None}}
shaped_data = lambda name, shape: {name: {'kind': 'data', 'value': None,
'shape': shape_array(shape) if shape is not None else None}}
empty_data = lambda name: valued_data(name, None)
@@ -290,11 +310,6 @@ regular_op_with_shaped_data = lambda name, shape, kwargs: {**regular_op(name, kw
**shaped_data(name + '_d', shape)}
regular_op_with_empty_data = lambda name, kwargs: {**regular_op(name, kwargs), **empty_data(name + '_d')}
# constants
const = lambda name, value, kwargs={}: {name: {'kind': 'op', 'type': 'Const', 'op': 'Const',
'value': value, 'shape': int64_array(value.shape),
'infer': Const.infer, 'type_infer': Const.type_infer, **kwargs}}
fake_const = lambda name, shape, kwargs={}: {name: {'kind': 'op', 'op': 'Const', 'type': 'Const',
'value': None, 'infer': Const.infer, **kwargs,
'shape': shape_array(shape) if shape is not None else None}}
@@ -302,8 +317,8 @@ fake_const = lambda name, shape, kwargs={}: {name: {'kind': 'op', 'op': 'Const',
shaped_const_with_data = lambda name, shape, kwargs={}: {**fake_const(name, shape, kwargs),
**shaped_data(name + '_d', shape)}
valued_const_with_data = lambda name, value, kwargs={}: {**const(name, value, kwargs),
**valued_data(name + '_d', value)}
valued_const_with_data = lambda name, value, shape=None, kwargs={}: {**const(name, value, shape, kwargs),
**valued_data(name + '_d', value, shape)}
def extract_port_from_string(node_name: str):
@@ -160,9 +160,9 @@ public:
explicit operator bool() const noexcept;
/**
* @brief Checks if the RemoteTensor object can be cast to the type T
* @brief Checks if the Tensor object can be cast to the type T
*
* @tparam T Type to be checked. Must represent a class derived from the RemoteTensor
* @tparam T Type to be checked. Must represent a class derived from the Tensor
* @return true if this object can be dynamically cast to the type const T*. Otherwise, false
*/
template <typename T>
@@ -177,7 +177,7 @@ public:
}
/**
* @brief Casts this RemoteTensor object to the type T.
* @brief Casts this Tensor object to the type T.
*
* @tparam T Type to cast to. Must represent a class derived from the Tensor
* @return T object
@@ -190,9 +190,9 @@ public:
}
/**
* @brief Casts this RemoteTensor object to the type T.
* @brief Casts this Tensor object to the type T.
*
* @tparam T Type to cast to. Must represent a class derived from the RemoteTensor
* @tparam T Type to cast to. Must represent a class derived from the Tensor
* @return T object
*/
template <typename T>
-2
View File
@@ -460,7 +460,6 @@ set(MULTI_TEST_SRC
backend/batch_norm.in.cpp
backend/batch_to_space.in.cpp
backend/broadcast.in.cpp
backend/bucketize.in.cpp
backend/builder_reduce_ops_opset1.in.cpp
backend/ceiling.in.cpp
backend/concat.in.cpp
@@ -507,7 +506,6 @@ set(MULTI_TEST_SRC
backend/node_name.in.cpp
backend/normalize_l2.in.cpp
backend/non_max_suppression.in.cpp
backend/non_zero.in.cpp
backend/one_hot.in.cpp
backend/pad.in.cpp
backend/parameter_as_output.in.cpp
-57
View File
@@ -1,57 +0,0 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "engines_util/test_case.hpp"
#include "engines_util/test_engines.hpp"
#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "util/test_control.hpp"
NGRAPH_SUPPRESS_DEPRECATED_START
using namespace std;
using namespace ngraph;
static string s_manifest = "${MANIFEST}";
using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
NGRAPH_TEST(${BACKEND_NAME}, bucketize_right_edge) {
Shape data_shape{10, 1};
Shape bucket_shape{4};
const auto data = make_shared<op::Parameter>(element::f32, data_shape);
const auto buckets = make_shared<op::Parameter>(element::i32, bucket_shape);
const auto bucketize = make_shared<op::v3::Bucketize>(data, buckets, element::i32, true);
const auto f = make_shared<Function>(bucketize, ParameterVector{data, buckets});
vector<float> data_vect = {8.f, 1.f, 2.f, 1.1f, 8.f, 10.f, 1.f, 10.2f, 0.f, 20.f};
vector<int32_t> buckets_vect = {1, 4, 10, 20};
vector<int32_t> expected_vect = {2, 0, 1, 1, 2, 2, 0, 3, 0, 3};
auto test_case = test::TestCase<TestEngine>(f);
test_case.add_input<float>(data_shape, data_vect);
test_case.add_input<int32_t>(bucket_shape, buckets_vect);
test_case.add_expected_output<int32_t>(data_shape, expected_vect);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, bucketize_left_edge) {
Shape data_shape{1, 1, 10};
Shape bucket_shape{4};
const auto data = make_shared<op::Parameter>(element::i32, data_shape);
const auto buckets = make_shared<op::Parameter>(element::f32, bucket_shape);
const auto bucketize = make_shared<op::v3::Bucketize>(data, buckets, element::i32, false);
const auto f = make_shared<Function>(bucketize, ParameterVector{data, buckets});
vector<int32_t> data_vect = {8, 1, 2, 1, 8, 5, 1, 5, 0, 20};
vector<float> buckets_vect = {1.f, 4.f, 10.f, 20.f};
vector<int32_t> expected_vect = {2, 1, 1, 1, 2, 2, 1, 2, 0, 4};
auto test_case = test::TestCase<TestEngine>(f);
test_case.add_input<int32_t>(data_shape, data_vect);
test_case.add_input<float>(bucket_shape, buckets_vect);
test_case.add_expected_output<int32_t>(data_shape, expected_vect);
test_case.run();
}
-90
View File
@@ -1,90 +0,0 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "engines_util/execute_tools.hpp"
#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "util/all_close_f.hpp"
#include "util/ndarray.hpp"
#include "util/test_control.hpp"
using namespace std;
using namespace ngraph;
static string s_manifest = "${MANIFEST}";
NGRAPH_TEST(${BACKEND_NAME}, non_zero) {
PartialShape p_shape = PartialShape::dynamic();
auto p = make_shared<op::Parameter>(element::f32, p_shape);
auto non_zero = make_shared<op::v3::NonZero>(p, element::i32);
auto fun = make_shared<Function>(OutputVector{non_zero}, ParameterVector{p});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto cfun = backend->compile(fun);
auto input = backend->create_tensor(element::f32, Shape{3, 2});
copy_data(input, vector<float>{0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 3.0f});
std::vector<int32_t> expected_result{2, 2, 0, 1};
Shape expected_output_shape{2, 2};
auto result = make_shared<HostTensor>();
cfun->call_with_validate({result}, {input});
EXPECT_EQ(result->get_element_type(), element::i32);
EXPECT_EQ(result->get_shape(), expected_output_shape);
auto result_data = read_vector<int32_t>(result);
ASSERT_EQ(result_data, expected_result);
}
NGRAPH_TEST(${BACKEND_NAME}, non_zero_all_1s) {
PartialShape p_shape = PartialShape::dynamic();
auto p = make_shared<op::Parameter>(element::i32, p_shape);
auto non_zero = make_shared<op::v3::NonZero>(p, element::i64);
auto fun = make_shared<Function>(OutputVector{non_zero}, ParameterVector{p});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto cfun = backend->compile(fun);
Shape input_shape{3, 2};
vector<int32_t> input_data(shape_size(input_shape), 1);
auto input = backend->create_tensor(element::i32, input_shape);
copy_data(input, input_data);
std::vector<int64_t> expected_result{0, 0, 1, 1, 2, 2, 0, 1, 0, 1, 0, 1};
Shape expected_output_shape{2, 6};
auto result = make_shared<HostTensor>();
cfun->call_with_validate({result}, {input});
EXPECT_EQ(result->get_element_type(), element::i64);
EXPECT_EQ(result->get_shape(), expected_output_shape);
auto result_data = read_vector<int64_t>(result);
ASSERT_EQ(result_data, expected_result);
}
NGRAPH_TEST(${BACKEND_NAME}, non_zero_all_0s) {
PartialShape p_shape = PartialShape::dynamic();
auto p = make_shared<op::Parameter>(element::i32, p_shape);
auto non_zero = make_shared<op::v3::NonZero>(p, element::i64);
auto fun = make_shared<Function>(OutputVector{non_zero}, ParameterVector{p});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto cfun = backend->compile(fun);
Shape input_shape{3, 2};
vector<int32_t> input_data(shape_size(input_shape), 0);
auto input = backend->create_tensor(element::i32, input_shape);
copy_data(input, input_data);
Shape expected_output_shape{input_shape.size(), 0};
auto result = make_shared<HostTensor>();
cfun->call_with_validate({result}, {input});
EXPECT_EQ(result->get_element_type(), element::i64);
EXPECT_EQ(result->get_shape(), expected_output_shape);
auto result_data = read_vector<int64_t>(result);
ASSERT_EQ(result_data.data(), nullptr);
}
-10
View File
@@ -31,16 +31,6 @@ onnx_model_conv_integer_no_zero_point
onnx_model_conv_integer_pads
# Unsupported operator detected in the graph: QuantizedDot
onnx_model_matmul_integer_2d_simple_zero_point
onnx_model_matmul_integer_int8
onnx_model_matmul_integer_vectorized_zero_point
onnx_model_matmul_integer_no_zero_point
onnx_model_matmul_integer_2d_x_3d
onnx_model_matmul_integer_3d_x_2d
onnx_model_matmul_integer_3d
onnx_model_matmul_integer_4d
onnx_model_matmul_integer_4d_zero_point
onnx_model_matmul_integer_matrix_zero_point
onnx_model_qlinear_matmul
onnx_model_qlinear_matmul_3d
@@ -333,7 +333,6 @@ tests_expected_to_fail = [
),
(
xfail_issue_38722,
"OnnxBackendNodeModelTest.test_matmulinteger_cpu",
"OnnxBackendNodeModelTest.test_qlinearmatmul_2D_cpu",
"OnnxBackendNodeModelTest.test_qlinearmatmul_3D_cpu",
),
+1
View File
@@ -12,6 +12,7 @@ ie_shellcheck_process(DIRECTORY "${OpenVINO_SOURCE_DIR}"
"${OpenVINO_SOURCE_DIR}/thirdparty"
"${OpenVINO_SOURCE_DIR}/runtime/bindings/python/thirdparty/pybind11"
"${IE_MAIN_SOURCE_DIR}/thirdparty"
"${OpenVINO_SOURCE_DIR}/tools/pot/thirdparty"
"${TEMP}"
# TODO fix and enable back:
"${OpenVINO_SOURCE_DIR}/inference-engine/scripts/dependencies.sh"
+107
View File
@@ -0,0 +1,107 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# PyCharm
.idea
# snapshots
*.tar
+29
View File
@@ -0,0 +1,29 @@
[MASTER]
disable = fixme,
invalid-name,
missing-docstring,
no-self-use,
too-few-public-methods,
too-many-arguments,
too-many-locals
max-attributes=20
max-line-length = 120
ignore-docstrings = yes
ignored-modules = mo,accuracy_checker,extensions,openvino.inference_engine,cv2,open_model_zoo.model_tools._configuration,open_model_zoo.model_tools._common
ignore-patterns = ac_imports.py
extension-pkg-whitelist = numpy
[SIMILARITIES]
min-similarity-lines = 19
ignore-imports = yes
[BASIC]
good-names=logger,fn
[DESIGN]
max-statements=120
max-branches=14
max-nested-blocks=7
[OPTIONS]
generated-members=torch.*
+5
View File
@@ -0,0 +1,5 @@
# See help here: https://docs.gitlab.com/ee/user/project/code_owners.html
# Control 3d party dependencies
**/*requirements*.* openvino.configuration.mgmt@intel.com
**/setup.py openvino.configuration.mgmt@intel.com
+59
View File
@@ -0,0 +1,59 @@
# Post-Training Optimization Tool {#pot_README}
## Introduction
Post-training Optimization Tool (POT) is designed to accelerate the inference of deep learning models by applying
special methods without model retraining or fine-tuning, like post-training quantization. Therefore, the tool does not
require a training dataset or a pipeline. To apply post-training algorithms from the POT, you need:
* A floating-point precision model, FP32 or FP16, converted into the OpenVINO&trade; Intermediate Representation (IR) format
and run on CPU with the OpenVINO&trade;.
* A representative calibration dataset representing a use case scenario, for example, 300 images.
Post-training Optimization Tool provides the following key
features:
* Two post-training 8-bit quantization algorithms: fast [DefaultQuantization](openvino/tools/pot/algorithms/quantization/default/README.md) and precise [AccuracyAwareQuantization](openvino/tools/pot/algorithms/quantization/accuracy_aware/README.md).
* Compression for different hardware targets such as CPU and GPU.
* Multiple domains: Computer Vision, Natural Language Processing, Recommendation Systems, Speech Recognition.
* [API](openvino/tools/pot/api/README.md) that helps to apply optimization methods within a custom inference script written with OpenVINO Python* API.
* Symmetric and asymmetric quantization schemes. For details, see the [Quantization](openvino/tools/pot/algorithms/quantization/README.md) section.
* Per-channel quantization for Convolutional and Fully-Connected layers.
* Global optimization of post-training quantization parameters using the [Tree-Structured Parzen Estimator](openvino/tools/pot/optimization/tpe/README.md).
The tool is aimed to fully automate the model transformation process without a need to change the model on the user's side.
The POT is available only in the Intel&reg; distribution of OpenVINO&trade; toolkit and is not opensourced. For details
about the low-precision flow in OpenVINO&trade;, see the [Low Precision Optimization Guide](docs/LowPrecisionOptimizationGuide.md).
For benchmarking results collected for the models optimized with POT tool, see [INT8 vs FP32 Comparison on Select Networks and Platforms](@ref openvino_docs_performance_int8_vs_fp32).
Further documentation presumes that you are familiar with the basic Deep Learning concepts, such as model inference,
dataset preparation, model optimization, as well as with the OpenVINO&trade; toolkit and its components such
as [Model Optimizer](@ref openvino_docs_MO_DG_Deep_Learning_Model_Optimizer_DevGuide)
and [Accuracy Checker Tool](@ref omz_tools_accuracy_checker_README).
## Use POT
![](docs/images/workflow.png)
The POT provides three basic usage scenarios:
* **[Command-line interface](docs/CLI.md)**: this is the recommended path if the model from OpenVINO&trade;
[Model Zoo](https://github.com/openvinotoolkit/open_model_zoo) or there is a valid [Accuracy Checker Tool](@ref omz_tools_accuracy_checker_README)
configuration file for the model that allows validating model accuracy using [Accuracy Checker Tool](@ref omz_tools_accuracy_checker_README).
* **[Python* API](openvino/tools/pot/api/README.md)**: it allows integrating optimization methods implemented in POT into
a Python* inference script written with [Python* API](@ref openvino_inference_engine_ie_bridges_python_docs_api_overview).
This flow is recommended if it is not possible to use [Accuracy Checker Tool](@ref omz_tools_accuracy_checker_README)
for validation on the dedicated dataset.
* **[Deep Learning Workbench](@ref workbench_docs_Workbench_DG_Introduction) (DL Workbench)**: a web-based graphical environment
that enables you to optimize, fine-tune, analyze, visualize, and compare performance of deep learning models.
Note: POT also supports optimization in the so-called [**Simplified mode**](@ref pot_configs_README) which is essentially a local
implementation of the POT Python API aimed at quantizing Computer Vision with simple pre-processing and inference flow. But
please note that this mode can lead to an inaccurate model after optimization due to the difference in the model preprocessing.
To get started with POT, follow the [Installation Guide](docs/InstallationGuide.md).
## See Also
* [Low Precision Optimization Guide](docs/LowPrecisionOptimizationGuide.md)
* [Post-Training Optimization Best Practices](docs/BestPractices.md)
* [POT Frequently Asked Questions](docs/FrequentlyAskedQuestions.md)
* [INT8 Quantization by Using Web-Based Interface of the DL Workbench](https://docs.openvinotoolkit.org/latest/workbench_docs_Workbench_DG_Int_8_Quantization.html)
+54
View File
@@ -0,0 +1,54 @@
# Post-training Optimization Tool {#pot_README_dev}
Starting with the 2020.1 version, OpenVINO&trade; toolkit delivers the Post-Training Optimization Tool designed to accelerate the inference of DL models by converting them into a more hardware-friendly representation by applying specific methods that do not require re-training, for example, post-training quantization.
For more details about the low-precision flow in OpenVINO&trade;, refer to the [Low Precision Optimization Guide](docs/LowPrecisionOptimizationGuide.md).
Post-Training Optimization Tool includes standalone command-line tool and Python* API that provide the following key features:
## Key features:
* Two supported post-training quantization algorithms: fast [DefaultQuantization](openvino/tools/pot/algorithms/quantization/default/README.md) and precise [AccuracyAwareQuantization](openvino/tools/pot/algorithms/quantization/accuracy_aware/README.md), as well as multiple experimental methods.
* Global optimization of post-training quantization parameters using [Tree-structured Parzen Estimator](openvino/tools/pot/optimization/tpe/README.md).
* Symmetric and asymmetric quantization schemes. For more details, see the [Quantization](openvino/tools/pot/algorithms/quantization/README.md) section.
* Per-channel quantization for Convolutional and Fully-Connected layers.
* Multiple domains: Computer Vision, Recommendation Systems.
* Ability to implement custom calibration pipeline via supported [API](openvino/tools/pot/api/README.md).
* Compression for different HW targets such as CPU, GPU, VPU.
* Post-training sparsity.
## Usage
### System requirements
- Ubuntu 18.04 or later (64-bit)
- Python 3.6 or later
- OpenVINO
### Installation (Temporary)
1) Clone compression tool repo: `git clone git@gitlab-icv.inn.intel.com:algo/post-training-compression-tool.git`
2) Download submodules:
```
git submodule init
git submodule update
```
3) Clone DLDT repo: `git clone https://gitlab-icv.inn.intel.com/inference-engine/dldt` (Not into the post-training-compression-tool)
4) Switch dldt to required branch: `feature/low_precision/develop_fp_v10`
5) Build inference engine (Instruction can be found in dldt repo)
6) Switch dldt to _mkaglins/poc_ branch (Inference engine is built from _feature/low_precision/develop_fp_v10_ branch to support `FakeQuantize` layers. ModelOptimizer is used from _mkaglins/poc_ branch. So stay on _mkaglins/poc_ branch as you've built IE and don't build it from there again)
7) Set _PYTHONPATH_ variable: `export PYTHONPATH=<path to DLDT bins>/bin/intel64/Release/lib/python_api/python3.6:<path to DLDT>/dldt/model-optimizer`
8) Install requirements for accuracy checker:
- From POT root: `cd ./thirdparty/open_model_zoo/tools/accuracy_checker`
- Call setup script: `python3 setup.py install`
- Get back to root POT dir: `cd <PATH_TO_POT_DIR>`
9) Install requirements for the tool:
- Call setup script: `python3 setup.py install`
### Run
1) Prepare configuration file for the tool based on the examples in the `configs` folder
2) Navigate to compression tool directory
3) Launch the tool running the following command:
`python3 main.py -c <path to config file> -e`
To test the tool you can use PyTorch Mobilenet_v2 model from `tests/data/models/mobilenetv2/mobilenetv2.onnx`
- If there're some errors with imports in ModelOptimizer first of all make the following steps:
- Checkout _mkaglins/poc_ branch in DLDT (It's important!)
+2
View File
@@ -0,0 +1,2 @@
# Copyright (C) 2020-2021 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
+64
View File
@@ -0,0 +1,64 @@
# Configuration File Description {#pot_configs_README}
In the instructions below, the Post-training Optimization Tool directory `<INSTALL_DIR>/deployment_tools/tools/post_training_optimization_toolkit` is referred to as `<POT_DIR>`. `<INSTALL_DIR>` is the directory where Intel&reg; Distribution of OpenVINO&trade; toolkit is installed.
> **NOTE**: Installation directory is different in the case of PyPI installation and does not contain examples of
> configuration files.
The tool is designed to work with the configuration file where all the parameters required for the optimization are specified. These parameters are organized as a dictionary and stored in
a JSON file. JSON file allows using comments that are supported by the `jstyleson` Python* package.
Logically all parameters are divided into three groups:
- **Model parameters** that are related to the model definition (e.g. model name, model path, etc.)
- **Engine parameters** that define parameters of the engine which is responsible for the model inference and data preparation used for optimization and evaluation (e.g. preprocessing parameters, dataset path, etc.)
- **Compression parameters** that are related to the optimization algorithm (e.g. algorithm name and specific parameters)
## Model Parameters
```json
"model": {
"model_name": "model_name",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
}
```
This section contains only three parameters:
- `"model_name"` - string parameter that defines a model name, e.g. `"MobileNetV2"`
- `"model"` - string parameter that defines the path to an input model topology (.xml)
- `"weights"` - string parameter that defines the path to an input model weights (.bin)
## Engine Parameters
```json
"engine": {
"type": "accuracy_checker",
"config": "./configs/examples/accuracy_checker/mobilenet_v2.yaml"
}
```
The main parameter is `"type"` which can take two possible options: `"accuracy_checher"` (default) and `"simplified"`,
which specify the engine that is used for model inference and validation (if supported):
- **Simplified mode** engine. This engine can be used only with `DefaultQuantization` algorithm to get fully quantized model
using a subset of images. It does not use the Accuracy Checker tool and annotation. To measure accuracy, you should implement
your own validation pipeline with OpenVINO API.
- To run the simplified mode, define engine section similar to the example `mobilenetV2_tf_int8_simple_mode.json` file from the `<POT_DIR>/configs/examples/quantization/classification/` directory.
- **Accuracy Checker** engine. It relies on the [Deep Learning Accuracy Validation Framework](@ref omz_tools_accuracy_checker_README) (Accuracy Checker) when inferencing DL models and working with datasets.
The benefit of this mode is you can compute accuracy in case you have annotations. It is possible to use accuracy aware
algorithms family when this mode is selected.
There are two options to define engine parameters in that mode:
- Refer to the existing Accuracy Checker configuration file which is represented by the YAML file. It can be a file used for full-precision model validation. In this case, you should define only the `"config"` parameter containing a path to the AccuracyChecker configuration file.
- Define all the [required Accuracy Checker parameters](@ref omz_tools_accuracy_checker_accuracy_checker_launcher_dlsdk_launcher_readme)
directly in the JSON file. In this case, POT just passes the corresponding dictionary of parameters to the Accuracy Checker when instantiating it.
For more details, refer to the corresponding Accuracy Checker information and examples of configuration files provided with the tool:
- For the SSD-MobileNet model:<br>\<POT_DIR\>/configs/examples/quantization/object_detection/ssd_mobilenetv1_int8.json
## Compression Parameters
This section defines optimization algorithms and their parameters. For more details about parameters of the concrete optimization algorithm, please refer to the corresponding
[documentation](@ref pot_compression_algorithms_quantization_README).
## Examples of the Configuration File
For a quick start, many examples of configuration files are provided and placed to the `<POT_DIR>/configs/examples`
folder. There you can find ready-to-use configurations for the models from various domains: Computer Vision (Image
Classification, Object Detection, Segmentation), Natural Language Processing, Recommendation Systems. We basically
put configuration files for the models which require non-default configuration settings in order to get accurate results.
For details on how to run the Post-Training Optimization Tool with a sample configuration file, see the [example](@ref pot_configs_examples_README).
@@ -0,0 +1,204 @@
{
/* Model parameters */
"model": {
"model_name": "model_name", // Model name
"model": "<MODEL_PATH>", // Path to model (.xml format)
"weights": "<PATH_TO_WEIGHTS>" // Path to weights (.bin format)
},
/* Parameters of the engine used for model inference */
// Post-Training Optimization Tool supports engine based on accuracy checker and custom engine.
// For custom engine you should specify your own set of parameters.
// The engine based on accuracy checker uses accuracy checker parameters.
// You can specify the parameters via accuracy checker config file or directly in engine section.
// More information about accuracy checker parameters can be found here:
// https://github.com/opencv/open_model_zoo/tree/master/tools/accuracy_checker
"engine": {
"stat_requests_number": 8, // Number of requests during statistcs collection
"eval_requests_number": 8, // Number of requests during evaluation
"config": "<CONFIG_PATH>",
/* OR */
"name": "model_name",
"launchers": [
{
"framework": "dlsdk",
"device": "CPU",
"adapter": "classification"
}
],
"datasets": [
{
"name": "dataset_name",
"data_source": "<DATASET_PATH>",
"annotation": "<ANNOTATION_PATH>",
"preprocessing": [
{
"type": "resize",
"interpolation": "BILINEAR",
"aspect_ratio_scale": "greater",
"size": 224
}
],
"metrics": [
{
"name": "accuracy@top1",
"type": "accuracy",
"top_k": 1
}
]
}
]
},
/* Optimization hyperparameters */
"compression": {
"target_device": "ANY", // Target device, the specificity of which will be taken
// into account during optimization
"inplace_statistic": true, // An optional parameter, change method collect statistics,
// reduces the amount of memory consumed,
// but increases the calibration time
// the default value is true
"model_type": "None", // An optional parameter, needed for additional patterns in the model,
// default value is None (supported only transformer now)
"algorithms": [
{
"name": "AccuracyAwareQuantization", // Optimization algorithm name
"params": {
"ranking_subset_size": 300, // A size of a subset which is used to rank layers by their
// contribution to the accuracy drop
"max_iter_num": 20, // Maximum number of iterations of the algorithm (maximum of layers
// that may be reverted back to full-precision)
"maximal_drop": 0.005, // Maximum accuracy drop which has to be achieved after the quantization
"drop_type": "absolute", // Drop type of the accuracy metric: relative or absolute (default)
"use_prev_if_drop_increase": false, // Whether to use NN snapshot from the previous algorithm
// iteration in case if drop increases
"base_algorithm": "DefaultQuantization", // Base algorithm that is used to quantize model
// at the beginning
"annotation_free": false, // Whether to compute accuracy drop on a dataset without annotation
"annotation_conf_threshold": 0.6, // Threshold for annotation creation in case of annotation free
// algorithm execution. Images on which original model predicts
// with confidence below this threshold will be skipped during
// evaluation
"convert_to_mixed_preset": false, // Whether to convert the model to mixed mode if
// the accuracy criteria of the symmetrically quantized
// model are not satisfied
// An optional list of metrics that are taken into account during optimization.
// If not specified, all metrics defined in engine config are used
"metrics": [
{
"name": "accuracy", // Metric name to optimize
"baseline_value": 0.72 // Baseline metric value of the original model
}
],
"metric_subset_ratio": 0.5, // A part of the validation set that is used to compare element-wise
// full-precision and quantized models in case of predefined metric
// values of the original model
"tune_hyperparams": false, // Whether to search the best quantization parameters for model.
// This algo uses grid search engine based on a special subset of samples from the dataset
"ignored": {
// List of nodes that are excluded from optimization
"scope": [
"<NODE_NAME>"
],
// List of types that are excluded from optimization
"operations": [
{
"type": "<NODE_TYPE>",
// Includes excluding by attributes
"attributes": {
"<NAME>": "<VALUE>" // Lists of values is not included
}
},
{
"type": "<NODE_TYPE>" // Excluding only by type
}
]
},
"preset": "mixed", // A preset is a collection of optimization algorithm parameters
// that will specify to the algorithm to improve which metric
// the algorithm needs to concentrate. Each optimization algorithm
// supports [performance, accuracy, mixed] presets
"stat_subset_size": 100, // Size of subset to calculate activations statistics that can be used
// for quantization parameters calculation
/* Manually specification quantization parametrs */
/* Quantization parameters for weights */
"weights": {
"bits": 8, // Number of quantization bits
"mode": "symmetric", // Quantization mode
"granularity": "perchannel", // Granularity: a scale for each output channel
"level_low": -127, // Low quantization level
"level_high": 127, // High quantization level
/* Parameters specify how to calculate the minimum and maximum of quantization range */
"range_estimator": {
"max": {
"type": "quantile",
"outlier_prob": 0.0001
}
}
},
/* Quantization parameters for activations */
"activations": {
"bits": 8, // Number of quantization bits
"mode": "asymmetric", // Quantization mode
"granularity": "pertensor", // Granularity: one scale for output tensor
/* Parameters specify how to calculate the minimum and maximum of quantization range */
"range_estimator": {
"preset": "quantile",
/* OR */
/* Minimum of quantization range */
"min": {
"aggregator": "mean", // Batch aggregation type [mean, max, min, median,
// mean_no_outliers, median_no_outliers, hl_estimator]
"type": "quantile", // Estimator type [min, max, abs_max, quantile, abs_quantile]
"outlier_prob": 0.0001 // Outlier probability: estimator consider samples which
},
/* Maximum of quantization range */
"max": {
"aggregator": "mean", // Batch aggregation type [mean, max, min, median,
// mean_no_outliers, median_no_outliers, hl_estimator]
"type": "quantile", // Estimator type [min, max, abs_max, quantile, abs_quantile]
"outlier_prob": 0.0001 // Outlier probability: estimator consider samples which
}
}
}
}
}
]
}
}
@@ -0,0 +1,44 @@
/* This configuration file is the fastest way to get started with the accuracy aware
quantization algorithm. It contains only mandatory options with commonly used
values. All other options can be considered as an advanced mode and requires
deep knowledge of the quantization process. An overall description of all possible
parameters can be found in the accuracy_aware_quantization_spec.json */
{
/* Model parameters */
"model": {
"model_name": "model_name", // Model name
"model": "<MODEL_PATH>", // Path to model (.xml format)
"weights": "<PATH_TO_WEIGHTS>" // Path to weights (.bin format)
},
/* Parameters of the engine used for model inference */
"engine": {
"config": "<CONFIG_PATH>" // Path to Accuracy Checker config
},
/* Optimization hyperparameters */
"compression": {
"target_device": "ANY", // Target device, the specificity of which will be taken
// into account during optimization
"algorithms": [
{
"name": "AccuracyAwareQuantization", // Optimization algorithm name
"params": {
"preset": "performance", // Preset [performance, mixed, accuracy] which control the quantization
// mode (symmetric, mixed (weights symmetric and activations asymmetric)
// and fully asymmetric respectively)
"stat_subset_size": 300, // Size of subset to calculate activations statistics that can be used
// for quantization parameters calculation
"maximal_drop": 0.01, // Maximum accuracy drop which has to be achieved after the quantization
"tune_hyperparams": false // Whether to search the best quantization parameters for model
}
}
]
}
}
@@ -0,0 +1,84 @@
{
"model": {
"model_name": "model_name",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"launchers": [
{
"framework": "dlsdk",
"device": "CPU",
"adapter": "classification"
}
],
"datasets": {
/* Global dataset preprocessing that will be used for all datasets
if no local configuration is spesified */
"preprocessing": [
{
"type": "crop",
"central_fraction": 0.875
},
{
"type": "resize",
"size": 224
}
],
/* Dataset for statistics collection */
"optimization": {
"name": "classification_dataset",
"data_source": "<DATASET_PATH>"
},
/* Dataset for final evaluation */
"evaluation": {
"name": "classification_dataset",
"data_source": "<DATASET_PATH>",
"annotation_conversion": {
"converter": "imagenet",
"annotation_file": "<ANNOTATION_FILE_PATH>"
},
/* Local preprocessing config. Overwrites global config */
"preprocessing": [
{
"type": "crop",
"central_fraction": 0.875
},
{
"type": "resize",
"size": 224
}
],
"metrics": [
{
"name": "accuracy@top1",
"type": "accuracy",
"top_k": 1
}
]
}
},
"stat_requests_number": 8,
"eval_requests_number": 8
},
"compression": {
"target_device": "ANY", // Target device, the specificity of which will be taken
// into account during optimization
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,251 @@
{
/* Model parameters */
"model": {
"model_name": "model_name", // Model name (name of whole cascade)
/* List of models in cascade */
"cascade": [
{
/* The first model of cascade */
"name": "<FIRST_MODEL_NAME>", // Name of the first model of cascade (should be taken from engine section)
"model": "<MODEL_PATH>", // Path to the first model (.xml format)
"weights": "<PATH_TO_WEIGHTS>" // Path to the first model weights (.bin format)
},
/* ... */
{
/* The last model of cascade */
"name": "<LAST_MODEL_NAME>", // Name of the last model of cascade (should be taken from engine section)
"model": "<MODEL_PATH>", // Path to the last model (.xml format)
"weights": "<PATH_TO_WEIGHTS>" // Path to the last model weights (.bin format)
}
]
},
/* Parameters of the engine used for model inference */
// Post-Training Optimization Tool supports engine based on accuracy checker and custom engine.
// For custom engine you should specify your own set of parameters.
// The engine based on accuracy checker uses accuracy checker parameters.
// You can specify the parameters via accuracy checker config file or directly in engine section.
// More information about accuracy checker parameters can be found here:
// https://github.com/opencv/open_model_zoo/tree/master/tools/accuracy_checker
"engine": {
/* Accuracy checker mode (default) */
"config": "<CONFIG_PATH>",
/* OR */
"module": "<EVALUATOR_CORRESPONDING_TO_CURRENT_CASCADE>",
"module_config": {
"network_info": {
"<FIRST_MODEL_NAME>": { // Name of the first model of cascade (this name should be used in model section)
"outputs": {
"probability_out": "prob1",
"region_out": "conv4-2"
},
"inputs": [
{
"name": "data",
"type": "INPUT",
"layout": "NCWH"
}
],
"preprocessing": [
{
"type": "bgr_to_rgb"
},
{
"type": "pyramid",
"min_size": 10,
"factor": 0.79
}
]
},
/* ... */
"<LAST_MODEL_NAME>": { // Name of the last model of cascade (this name should be used in model section)
"outputs": {
"probability_out": "prob1",
"region_out": "conv6-2"
},
"inputs": [
{
"name": "data",
"type": "INPUT",
"layout": "NCWH"
}
],
"preprocessing": [
{
"type": "bgr_to_rgb"
}
]
}
},
"launchers": [
{
"framework": "dlsdk"
}
],
"datasets": [
{
"name": "<DATASET_NAME>",
"data_source": "<DATASET_PATH>",
"postprocessing": [
{
"type": "filter",
"apply_to": "prediction",
"is_empty": true
},
{
"type": "filter",
"height_range": 60,
"apply_to": "annotation"
}
],
"metrics": [
{
"type": "map",
"ignore_difficult": true,
"include_boundaries": true,
"allow_multiple_matches_per_ignored": true,
"distinct_conf": false
}
]
}
]
}
},
/* Optimization hyperparameters */
"compression": {
"target_device": "ANY", // Target device, the specificity of which will be taken
// into account during optimization
"algorithms": [
{
"name": "DefaultQuantization", // Optimization algorithm name
"params": {
"ignored": {
/* Ignored block for the first model of cascade */
"<FIRST_MODEL_NAME>": {
// List of nodes that are excluded from optimization
"scope": [
"<NODE_NAME>"
],
// List of types that are excluded from optimization
"operations": [
{
"type": "<NODE_TYPE>",
// Includes excluding by attributes
"attributes": {
"<NAME>": "<VALUE>" // Lists of values is not included
}
},
{
"type": "<NODE_TYPE>" // Excluding only by type
}
]
},
/* ... */
/* Ignored block for the last model of cascade */
"<LAST_MODEL_NAME>": {
// List of nodes that are excluded from optimization
"scope": [
"<NODE_NAME>"
],
// List of types that are excluded from optimization
"operations": [
{
"type": "<NODE_TYPE>",
// Includes excluding by attributes
"attributes": {
"<NAME>": "<VALUE>" // Lists of values is not included
}
},
{
"type": "<NODE_TYPE>" // Excluding only by type
}
]
}
},
"preset": "accuracy", // A preset is a collection of optimization algorithm parameters
// that will specify to the algorithm to improve which metric
// the algorithm needs to concentrate. Each optimization algorithm
// supports [performance, mixed, accuracy] presets
"stat_subset_size": 100, // Size of subset to calculate activations statistics that can be used
// for quantization parameters calculation
/* Manually specification quantization parametrs */
/* Quantization parameters for weights */
"weights": {
"bits": 8, // Number of quantization bits
"mode": "symmetric", // Quantization mode
"granularity": "perchannel", // Granularity: a scale for each output channel
"level_low": -127, // Low quantization level
"level_high": 127, // High quantization level
/* Parameters specify how to calculate the minimum and maximum of quantization range */
"range_estimator": {
"max": {
"type": "quantile",
"outlier_prob": 0.0001
}
}
},
/* Quantization parameters for activations */
"activations": {
"bits": 8, // Number of quantization bits
"mode": "asymmetric", // Quantization mode
"granularity": "pertensor", // Granularity: one scale for output tensor
/* Parameters specify how to calculate the minimum and maximum of quantization range */
"range_estimator": {
"preset": "quantile",
/* OR */
/* Minimum of quantization range */
"min": {
"clipping_value": 0, // Threshold for min statistic value clipping (lower bound)
"aggregator": "mean", // Batch aggregation type [mean, max, min, median,
// mean_no_outliers, median_no_outliers, hl_estimator]
"type": "quantile", // Estimator type [min, max, abs_max, quantile, abs_quantile]
"outlier_prob": 0.0001 // Outlier probability: estimator consider samples which
},
/* Maximum of quantization range */
"max": {
"clipping_value": 6, // Threshold for max statistic value clipping (upper bound)
"aggregator": "mean", // Batch aggregation type [mean, max, min, median,
// mean_no_outliers, median_no_outliers, hl_estimator]
"type": "quantile", // Estimator type [min, max, abs_max, quantile, abs_quantile]
"outlier_prob": 0.0001 // Outlier probability: estimator consider samples which
}
}
}
}
}
]
}
}
@@ -0,0 +1,182 @@
{
/* Model parameters */
"model": {
"model_name": "model_name", // Model name
"model": "<MODEL_PATH>", // Path to model (.xml format)
"weights": "<PATH_TO_WEIGHTS>" // Path to weights (.bin format)
},
/* Parameters of the engine used for model inference */
// Post-Training Optimization Tool supports engine based on accuracy checker and custom engine.
// For custom engine you should specify your own set of parameters.
// The engine based on accuracy checker uses accuracy checker parameters.
// You can specify the parameters via accuracy checker config file or directly in engine section.
// More information about accuracy checker parameters can be found here:
// https://github.com/opencv/open_model_zoo/tree/master/tools/accuracy_checker
"engine": {
/* Accuracy checker mode (default) */
"stat_requests_number": 8, // Number of requests during statistcs collection
"eval_requests_number": 8, // Number of requests during evaluation
"config": "<CONFIG_PATH>",
/* OR */
"name": "model_name",
"launchers": [
{
"framework": "dlsdk",
"device": "CPU",
"adapter": "classification"
}
],
"datasets": [
{
"name": "dataset_name",
"data_source": "<DATASET_PATH>",
"annotation": "<ANNOTATION_PATH>",
"preprocessing": [
{
"type": "resize",
"interpolation": "BILINEAR",
"aspect_ratio_scale": "greater",
"size": 224
}
],
"metrics": [
{
"name": "accuracy@top1",
"type": "accuracy",
"top_k": 1
}
]
}
],
/* OR */
/* Simplified mode */
"type": "simplified", // OR default value "type": "accuracy_checker" for non simplified mode
"data_source": "PATH_TO_SOURCE" // You can specify path to directory with images. Also you can
// specify template for file names to filter images to load.
// Templates are unix style (This option valid only in simplified mode)
},
/* Optimization hyperparameters */
"compression": {
"target_device": "ANY", // Target device, the specificity of which will be taken
// into account during optimization
"model_type": "None", // An optional parameter, needed for additional patterns in the model,
// default value is None (supported only transformer now)
"dump_intermediate_model": false, // Save intermediate models for DefaultAlgorithm
"inplase_statistics": true, // An optional parameter, change method collect statistics,
// reduces the amount of memory consumed,
// but increases the calibration time
// the default value is true
"algorithms": [
{
"name": "DefaultQuantization", // Optimization algorithm name
"params": {
"ignored": {
// List of nodes that are excluded from optimization
"scope": [
"<NODE_NAME>"
],
// List of types that are excluded from optimization
"operations": [
{
"type": "<NODE_TYPE>",
// Includes excluding by attributes
"attributes": {
"<NAME>": "<VALUE>" // Lists of values is not included
}
},
{
"type": "<NODE_TYPE>" // Excluding only by type
}
]
},
"preset": "mixed", // A preset is a collection of optimization algorithm parameters
// that will specify to the algorithm to improve which metric
// the algorithm needs to concentrate. Each optimization algorithm
// supports [performance, mixed, accuracy] presets
"stat_subset_size": 100, // Size of subset to calculate activations statistics that can be used
// for quantization parameters calculation
"shuffle_data": false, // Shuffle data before selecting the subset to calculate activation
// statistics. An optional parameter, the default value is false
"seed": 0, // Seed for data shuffle. An optional parameter, the default value is 0
/* Manually specification quantization parametrs */
/* Quantization parameters for weights */
"weights": {
"bits": 8, // Number of quantization bits
"mode": "symmetric", // Quantization mode
"granularity": "perchannel", // Granularity: a scale for each output channel
"level_low": -127, // Low quantization level
"level_high": 127, // High quantization level
/* Parameters specify how to calculate the minimum and maximum of quantization range */
"range_estimator": {
"max": {
"type": "quantile",
"outlier_prob": 0.0001
}
}
},
/* Quantization parameters for activations */
"activations": {
"bits": 8, // Number of quantization bits
"mode": "symmetric", // Quantization mode
"granularity": "pertensor", // Granularity: one scale for output tensor
/* Parameters specify how to calculate the minimum and maximum of quantization range */
"range_estimator": {
"preset": "quantile",
/* OR */
/* Minimum of quantization range */
"min": {
"clipping_value": 0, // Threshold for min statistic value clipping (lower bound)
"aggregator": "mean", // Batch aggregation type [mean, max, min, median,
// mean_no_outliers, median_no_outliers, hl_estimator]
"type": "quantile", // Estimator type [min, max, abs_max, quantile, abs_quantile]
"outlier_prob": 0.0001 // Outlier probability: estimator consider samples which
},
/* Maximum of quantization range */
"max": {
"clipping_value": 6, // Threshold for max statistic value clipping (upper bound)
"aggregator": "mean", // Batch aggregation type [mean, max, min, median,
// mean_no_outliers, median_no_outliers, hl_estimator]
"type": "quantile", // Estimator type [min, max, abs_max, quantile, abs_quantile]
"outlier_prob": 0.0001 // Outlier probability: estimator consider samples which
}
}
}
}
}
]
}
}
@@ -0,0 +1,41 @@
/* This configuration file is the fastest way to get started with the default
quantization algorithm. It contains only mandatory options with commonly used
values. All other options can be considered as an advanced mode and requires
deep knowledge of the quantization process. An overall description of all possible
parameters can be found in the default_quantization_spec.json */
{
/* Model parameters */
"model": {
"model_name": "model_name", // Model name
"model": "<MODEL_PATH>", // Path to model (.xml format)
"weights": "<PATH_TO_WEIGHTS>" // Path to weights (.bin format)
},
/* Parameters of the engine used for model inference */
"engine": {
"config": "<CONFIG_PATH>" // Path to Accuracy Checker config
},
/* Optimization hyperparameters */
"compression": {
"target_device": "ANY", // Target device, the specificity of which will be taken
// into account during optimization
"algorithms": [
{
"name": "DefaultQuantization", // Optimization algorithm name
"params": {
"preset": "performance", // Preset [performance, mixed, accuracy] which control the quantization
// mode (symmetric, mixed (weights symmetric and activations asymmetric)
// and fully asymmetric respectively)
"stat_subset_size": 300 // Size of subset to calculate activations statistics that can be used
// for quantization parameters calculation
}
}
]
}
}
@@ -0,0 +1,54 @@
models:
- name: bert_base_squad1_1
launchers:
- framework: dlsdk
device: cpu
batch: 1
adapter:
type: bert_question_answering
start_token_logits_output: "unstack/Squeeze_"
end_token_logits_output: "unstack/Split.1"
mo_params:
data_type: FP32
input: input_ids_1,input_mask_1,segment_ids_1
input_shape: "[1,384], [1,384], [1,384]"
output: unstack/Squeeze_,unstack/Split.1
mo_flags:
- disable_nhwc_to_nchw
inputs:
- name: "input_ids_1"
type: INPUT
value: "input_ids"
precision: I32
- name: "input_mask_1"
type: INPUT
value: 'input_mask'
- name: "segment_ids_1"
type: INPUT
value: 'segment_ids'
precision: I32
datasets:
- name: squad
data_source: <PATH_TO_DATASET>/squad1.1/
annotation: <PATH_TO_DATASET>/squad.pickle
reader:
type: annotation_features_extractor
features:
- input_ids
- input_mask
- segment_ids
postprocessing:
- type: extract_answers_tokens
max_answer: 30
n_best_size: 20
metrics:
- name: 'F1'
type: 'f1'
reference: 88.57
threshold: 0.01
- name: 'EM'
type: 'exact_match'
reference: 81.25
threshold: 0.01
@@ -0,0 +1,54 @@
models:
- name: bert_large_squad1_1
launchers:
- framework: dlsdk
device: cpu
batch: 1
adapter:
type: bert_question_answering
start_token_logits_output: "unstack/Squeeze_"
end_token_logits_output: "unstack/Split.1"
mo_params:
data_type: FP32
input: input_ids_1,input_mask_1,segment_ids_1
input_shape: "[1,384], [1,384], [1,384]"
output: unstack/Squeeze_,unstack/Split.1
mo_flags:
- disable_nhwc_to_nchw
inputs:
- name: "input_ids_1"
type: INPUT
value: "input_ids"
precision: I32
- name: "input_mask_1"
type: INPUT
value: 'input_mask'
- name: "segment_ids_1"
type: INPUT
value: 'segment_ids'
precision: I32
datasets:
- name: squad
data_source: <PATH_TO_DATASET>/squad1.1/
annotation: <PATH_TO_DATASET>/squad.pickle
reader:
type: annotation_features_extractor
features:
- input_ids
- input_mask
- segment_ids
postprocessing:
- type: extract_answers_tokens
max_answer: 30
n_best_size: 20
metrics:
- name: 'F1'
type: 'f1'
reference: 90.63
threshold: 0.05
- name: 'EM'
type: 'exact_match'
reference: 83.59
threshold: 0.05
@@ -0,0 +1,29 @@
models:
- name: DensNet-121
launchers:
- framework: dlsdk
device: CPU
adapter: classification
datasets:
- name: classification_dataset
data_source: <PATH TO VALIDATION DATASET>
annotation_conversion:
converter: imagenet
annotation_file: <PATH TO ANNOTATION FILE>
preprocessing:
- type: resize
size: 256
- type: crop
size: 224
metrics:
- name: accuracy@top1
type: accuracy
top_k: 1
- name: accuracy@top5
type: accuracy
top_k: 5
@@ -0,0 +1,29 @@
models:
- name: east
launchers:
- framework: dlsdk
device: CPU
allow_reshape_input: True
adapter:
type: east_text_detection
score_map_out: feature_fusion/Conv_7/Sigmoid
geometry_map_out: feature_fusion/concat_3
datasets:
- name: ICDAR2015
data_source: <PATH_TO_DATASET>
annotation_conversion:
converter: icdar_detection
data_dir: <PATH_TO_GROUND_TRUTH>
preprocessing:
- type: resize
dst_height: 2400
dst_width: 32
aspect_ratio_scale: east_keep_aspect_ratio
- type: bgr_to_rgb
metrics:
- type: incidental_text_hmean
name: f-measure
ignore_difficult: True
@@ -0,0 +1,37 @@
models:
- name: faster_rcnn_resnet101_coco
launchers:
- framework: dlsdk
device: CPU
adapter: ssd
inputs:
- name: image_info
type: CONST_INPUT
value: [[600, 1024, 1]]
datasets:
- name: ms_coco_detection_91_classes
annotation_conversion:
converter: mscoco_detection
annotation_file: <ANNOTATION_PATH>/instances_val2017.json
has_background: True
sort_annotations: True
use_full_label_map: True
data_source: <DATA_PATH>/val2017
preprocessing:
- type: resize
aspect_ratio_scale: fit_to_window
dst_height: 600
dst_width: 1024
- type: padding
dst_height: 600
dst_width: 1024
pad_type: right_bottom
postprocessing:
- type: faster_rcnn_postprocessing_resize
dst_height: 600
dst_width: 1024
metrics:
- type: coco_precision
max_detections: 100
@@ -0,0 +1,37 @@
models:
- name: faster_rcnn_resnet50_coco
launchers:
- framework: dlsdk
device: CPU
adapter: ssd
inputs:
- name: image_info
type: CONST_INPUT
value: [[600, 1024, 1]]
datasets:
- name: ms_coco_detection_91_classes
annotation_conversion:
converter: mscoco_detection
annotation_file: <ANNOTATION_PATH>/instances_val2017.json
has_background: True
sort_annotations: True
use_full_label_map: True
data_source: <DATA_PATH>/val2017
preprocessing:
- type: resize
aspect_ratio_scale: fit_to_window
dst_height: 600
dst_width: 1024
- type: padding
dst_height: 600
dst_width: 1024
pad_type: right_bottom
postprocessing:
- type: faster_rcnn_postprocessing_resize
dst_height: 600
dst_width: 1024
metrics:
- type: coco_precision
max_detections: 100
@@ -0,0 +1,40 @@
models:
- name: mask_rcnn_resnet50_atrous_coco
launchers:
- framework: dlsdk
tags:
- FP32
adapter:
type: mask_rcnn
detection_out: reshape_do_2d
raw_masks_out: masks
inputs:
- name: image_info
type: CONST_INPUT
value: [[800, 1365, 1]]
datasets:
- name: ms_coco_mask_rcnn_short_91_classes
annotation_conversion:
converter: mscoco_mask_rcnn
annotation_file: <ANNOTATION_PATH>/instances_val2017.json
has_background: True
sort_annotations: True
use_full_label_map: True
data_source: <DATA_PATH>/val2017
preprocessing:
- type: resize
aspect_ratio_scale: fit_to_window
dst_height: 800
dst_width: 1365
- type: padding
dst_height: 800
dst_width: 1365
pad_type: right_bottom
postprocessing:
- type: faster_rcnn_postprocessing_resize
dst_height: 800
dst_width: 1365
metrics:
- type: coco_orig_segm_precision
- type: coco_orig_precision
@@ -0,0 +1,31 @@
models:
- name: MobileNet_v1
launchers:
- framework: dlsdk
device: CPU
adapter: classification
datasets:
- name: classification_dataset
data_source: <PATH TO VALIDATION DATASET>
annotation_conversion:
converter: imagenet
annotation_file: <PATH TO ANNOTATION FILE>
has_background: true
preprocessing:
- type: resize
size: 256
aspect_ratio_scale: greater
- type: crop
size: 224
metrics:
- name: accuracy@top1
type: accuracy
top_k: 1
- name: accuracy@top5
type: accuracy
top_k: 5
@@ -0,0 +1,34 @@
models:
- name: MobileNet_v2
launchers:
- framework: dlsdk
device: CPU
adapter: classification
datasets:
- name: classification_dataset
data_source: <PATH TO VALIDATION DATASET>
annotation_conversion:
converter: imagenet
annotation_file: <PATH TO ANNOTATION FILE>
reader: pillow_imread
preprocessing:
- type: resize
size: 256
aspect_ratio_scale: greater
use_pillow: True
- type: crop
size: 224
use_pillow: True
- type: bgr_to_rgb
metrics:
- name: accuracy@top1
type: accuracy
top_k: 1
- name: accuracy@top5
type: accuracy
top_k: 5
@@ -0,0 +1,73 @@
evaluations:
- name: mtcnn
module: custom_evaluators.mtcnn_evaluator.MTCNNEvaluator
module_config:
network_info:
pnet:
outputs:
probability_out: prob1
region_out: conv4-2
inputs:
- name: data
type: INPUT
layout: NCWH
preprocessing:
- type: bgr_to_rgb
- type: pyramid
min_size: 10
factor: 0.79
rnet:
outputs:
probability_out: prob1
region_out: conv5-2
inputs:
- name: data
type: INPUT
layout: NCWH
preprocessing:
- type: bgr_to_rgb
onet:
outputs:
probability_out: prob1
region_out: conv6-2
inputs:
- name: data
type: INPUT
layout: NCWH
preprocessing:
- type: bgr_to_rgb
launchers:
- framework: dlsdk
device: CPU
datasets:
- name: wider
data_source: <PATH_TO_DATASET>/WIDER_val/images
annotation_conversion:
converter: wider
annotation_file: <PATH_TO_DATASET>/wider_face_split/wider_face_val_bbx_gt.txt
postprocessing:
- type: filter
apply_to: prediction
is_empty: True
- type: filter
height_range: 60
apply_to: annotation
metrics:
- type: recall
ignore_difficult: True
include_boundaries: True
allow_multiple_matches_per_ignored: True
distinct_conf: False
- type: map
ignore_difficult: True
include_boundaries: True
allow_multiple_matches_per_ignored: True
distinct_conf: False
@@ -0,0 +1,38 @@
models:
- name: NCF
launchers:
- framework: dlsdk
device: CPU
adapter: hit_ratio_adapter
batch: 2048
inputs:
- type: INPUT
value: "u"
name: embedding/embedding_lookup/placeholder_port_1
- type: INPUT
value: "i"
name: embedding_1/embedding_lookup/placeholder_port_1
- type: INPUT
value: "u"
name: embedding_2/embedding_lookup/placeholder_port_1
- type: INPUT
value: "i"
name: embedding_3/embedding_lookup/placeholder_port_1
allow_reshape_input: True
datasets:
- name: ncf_dataset
data_source: ncf
annotation: <EXISTING FOLDER PATH TO STORE ANNOTATION FILES>/ncf_converter.pickle
dataset_meta: <EXISTING FOLDER PATH TO STORE ANNOTATION FILES>/ncf_converter.json
annotation_conversion:
converter: movie_lens_converter
rating_file: <PATH TO RATING FILE>/ml-20m-test-ratings.csv
negative_file: <PATH TO NEGATIVE FILE>/ml-20m-test-negative.csv
users_max_number: 2048
reader: ncf_data_reader
metrics:
- type: hit_ratio
- type: ndcg
@@ -0,0 +1,31 @@
models:
- name: ssd-mobilenetv1
launchers:
- framework: dlsdk
device: CPU
adapter: ssd
batch: 1
datasets:
- name: classification_dataset
data_source: <PATH TO VALIDATION DATASET>/VOC2007/JPEGImages
annotation_conversion:
converter: "voc_detection"
annotations_dir: <PATH TO VALIDATION DATASET>/VOC2007/Annotations
images_dir: <PATH TO VALIDATION DATASET>/VOC2007/JPEGImages
imageset_file: <PATH TO VALIDATION DATASET>/VOC2007/ImageSets/Main/test.txt
has_background: true
preprocessing:
- type: resize
size: 300
postprocessing:
- type: resize_prediction_boxes
metrics:
- type: map
integral: 11point
ignore_difficult: true
presenter: print_scalar
@@ -0,0 +1,37 @@
models:
- name: SSD_ResNet34
launchers:
- framework: dlsdk
adapter:
type: ssd_onnx
scores_out: .*scores.*
labels_out: .*labels.*
bboxes_out: .*bboxes.*
datasets:
- name: COCO2017_80cl_bkgr
data_source: <PATH TO VALIDATION DATASET>/val2017
annotation_conversion:
converter: mscoco_detection
annotation_file: <PATH TO VALIDATION DATASET>/annotations/instances_val2017.json
has_background: True
use_full_label_map: False
reader: pillow_imread
preprocessing:
- type: resize
size: 1200
use_pillow: true
interpolation: BILINEAR
postprocessing:
- type: resize_prediction_boxes
metrics:
- type: map
integral: 11point
ignore_difficult: true
presenter: print_scalar
- type: coco_precision
- type: coco_orig_precision
@@ -0,0 +1,30 @@
models:
- name: ssd_resnet_50_512
launchers:
- framework: dlsdk
device: CPU
adapter: ssd
datasets:
- name: VOC2007_bkgr
data_source: <PATH TO VALIDATION DATASET>/VOC2007/JPEGImages
annotation_conversion:
converter: voc_detection
has_background: False
annotations_dir: <PATH TO VALIDATION DATASET>/VOC2007/Annotations
images_dir: <PATH TO VALIDATION DATASET>/VOC2007/JPEGImages
imageset_file: <PATH TO VALIDATION DATASET>/VOC2007/ImageSets/Main/test.txt
preprocessing:
- type: resize
size: 512
postprocessing:
- type: resize_prediction_boxes
metrics:
- type: map
integral: 11point
ignore_difficult: True
presenter: print_scalar
@@ -0,0 +1,21 @@
{
"model": {
"model_name": "densnet-121",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/densnet_121.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "mixed",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,60 @@
{
"model": {
"model_name": "inceptionv3",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"datasets": [
{
"name": "imagenet_1001_classes",
"data_source": "PATH_TO_DATASET",
"annotation_conversion": {
"annotation_file": "PATH_TO_ANNOTATION_FILE",
"has_background": true,
"converter": "imagenet"
},
"preprocessing": [
{
"type": "crop",
"central_fraction": 0.875
},
{
"type": "resize",
"size": 299
}
],
"metrics": [
{
"type": "accuracy",
"name": "accuracy@top1",
"top_k": 1
},
{
"type": "accuracy",
"name": "accuracy@top5",
"top_k": 5
}
]
}
],
"launchers": [
{
"framework": "dlsdk",
"device": "CPU",
"adapter": "classification"
}
]
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,21 @@
{
"model": {
"model_name": "mobilenetv1",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/mobilenet_v1_tf.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "mixed",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,68 @@
{
"model": {
"model_name": "mobilenet_v2_1.0_224",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"launchers":
[
{
"framework": "dlsdk",
"adapter": "classification"
}
],
"datasets":
[
{
"name": "imagenet_1000_classes",
"reader": "pillow_imread",
"annotation_conversion": {
"converter": "imagenet",
"annotation_file": "PATH_TO_ANNOTATION_FILE"
},
"data_source": "PATH_TO_VALIDATION_IMAGES",
"preprocessing": [
{
"type": "bgr_to_rgb"
},
{
"type": "resize",
"size": 256,
"aspect_ratio_scale": "greater",
"use_pillow": true,
"interpolation": "BILINEAR"
},
{
"type": "crop",
"size": 224,
"use_pillow": true
}
],
"metrics": [
{
"name": "accuracy@top1",
"type": "accuracy",
"top_k": 1
},
{
"name": "accuracy@top5",
"type": "accuracy",
"top_k": 5
}
]
}
]
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,21 @@
{
"model": {
"model_name": "mobilenetv2",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/mobilenet_v2.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "mixed",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,21 @@
{
"model": {
"model_name": "mobilenet_v2_1.0_224",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "<CONFIG_PATH>"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,21 @@
{
"model": {
"model_name": "mobilenet_v2_1.0_224",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "<CONFIG_PATH>"
},
"compression": {
"algorithms": [
{
"name": "AccuracyAwareQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,25 @@
{
"model": {
"model_name": "mobilenet_v2_1.0_224",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"type": "simplified",
// you can specify path to directory with images or video file
// also you can specify template for file names to filter images to load
// templates are unix style
"data_source": "PATH_TO_IMAGES"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,30 @@
{
"model": {
"model_name": "mobilenet_v2_1.0_224",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "<CONFIG_PATH>"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
},
{
"name": "QuantNoiseEstimator",
"params": {
"stat_subset_size": 100,
"mode": "full_fq_noise",
"type": "sqnr",
"results_dump_filename": "./mobilenetv2_sqnr_data.csv"
}
}
]
}
}
@@ -0,0 +1,29 @@
{
"model": {
"model_name": "mobilenet_v2_1.0_224",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "<CONFIG_PATH>"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
},
{
"name": "INT4MixedQuantization",
"params": {
"stat_subset_size": 300,
"ranking_subset_size": 300,
"maximal_drop": 0.01
}
}
]
}
}
@@ -0,0 +1,102 @@
{
"model": {
"model_name": "se_resnet50",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"launchers": [
{
"framework": "dlsdk",
"device": "CPU",
"adapter": "classification"
}
],
"datasets": [{
"name": "classification_dataset",
"data_source": "<PATH_TO_DATASET>",
"annotation_conversion": {
"converter": "imagenet",
"annotation_file": "<PATH_TO_ANNOTATION_FILE>"
},
"reader": "pillow_imread",
"preprocessing":[
{
"type": "bgr_to_rgb"
},
{
"use_pillow": true,
"type": "resize",
"size": 256,
"interpolation": "BILINEAR",
"aspect_ratio_scale": "greater"
},
{
"type": "crop",
"size": 224,
"use_pillow": true
}
],
"metrics": [
{
"name": "accuracy@top1",
"type": "accuracy",
"top_k": 1
},
{
"name": "accuracy@top5",
"type": "accuracy",
"top_k": 5
}
]
}]
},
"compression": {
"algorithms": [
{
"name": "MinMaxQuantization",
"params": {
"target_device": "CPU",
"preset": "mixed",
"stat_subset_size": 1000,
"ignored": {
"scope": [
"400", "402",
"416", "418",
"432", "434",
"450", "452",
"466", "468",
"482", "484",
"498", "500",
"516", "518",
"532", "534",
"548", "550",
"564", "566",
"580", "582",
"596", "598",
"614", "616",
"630", "632",
"646", "648"
]
},
"weights": {
"bits": 8,
"mode": "symmetric",
"granularity": "perchannel"
},
"activations": {
"bits": 8,
"mode": "symmetric",
"granularity": "pertensor"
}
}
},
{
"name": "FastBiasCorrection",
"params": {
"stat_subset_size": 1000
}
}
]
}
}
@@ -0,0 +1,77 @@
{
"model": {
"model_name": "squeezenet1_1",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"launchers": [
{
"framework": "dlsdk",
"device": "CPU",
"adapter": "classification"
}
],
"datasets": [
{
"name": "classification_dataset",
"data_source": "<PATH_TO_DATASET>",
"annotation_conversion": {
"converter": "imagenet",
"annotation_file": "<PATH_TO_ANNOTATION_FILE>",
"has_background": false
},
"reader": "pillow_imread",
"preprocessing":[
{
"type": "bgr_to_rgb"
},
{
"use_pillow": true,
"type": "resize",
"size": 256,
"interpolation": "BILINEAR",
"aspect_ratio_scale": "greater"
},
{
"type": "crop",
"size": 224,
"use_pillow": true
}
],
"metrics": [
{
"name": "accuracy@top1",
"type": "accuracy",
"top_k": 1
},
{
"name": "accuracy@top5",
"type": "accuracy",
"top_k": 5
}
]
}
]
},
"compression": {
"algorithms": [{
"name": "DefaultQuantization",
"params": {
"preset": "mixed",
"stat_subset_size": 1000,
"weights": {
"bits": 8,
"mode": "symmetric",
"granularity": "perchannel"
},
"activations": {
"bits": 8,
"mode": "symmetric",
"granularity": "pertensor"
}
}
}]
}
}
@@ -0,0 +1,72 @@
{
"model": {
"name": "bert_base_squad_1_1",
"model": "<PATH_TO_MODEL>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/bert_base_squad_1_1_tf_int8.yml"
},
"compression": {
"model_type": "transformer",
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "accuracy",
"stat_subset_size": 1000,
"weights": {
"bits": 8,
"mode": "symmetric",
"granularity": "perchannel",
"level_low": -127,
"level_high": 127
},
"activations": {
"bits": 8,
"mode": "symmetric",
"granularity": "pertensor"
},
"ignored": {
"scope" : [
"bert/encoder/layer_0/output/dense/MatMul",
"bert/encoder/layer_0/intermediate/dense/MatMul",
"bert/encoder/layer_0/attention/self/key/MatMul",
"bert/encoder/layer_0/attention/output/dense/MatMul",
"bert/encoder/layer_0/attention/self/MatMul",
"bert/encoder/layer_0/attention/self/MatMul_1",
"bert/encoder/layer_1/attention/self/key/MatMul",
"bert/encoder/layer_1/attention/self/MatMul",
"bert/encoder/layer_1/attention/self/MatMul_1",
"bert/encoder/layer_2/attention/self/MatMul",
"bert/encoder/layer_2/attention/self/MatMul_1",
"bert/encoder/layer_3/output/dense/MatMul",
"bert/encoder/layer_3/intermediate/dense/MatMul",
"bert/encoder/layer_3/attention/output/dense/MatMul",
"bert/encoder/layer_3/attention/self/MatMul",
"bert/encoder/layer_3/attention/self/MatMul_1",
"bert/encoder/layer_4/attention/self/value/MatMul",
"bert/encoder/layer_4/attention/self/MatMul",
"bert/encoder/layer_4/attention/self/MatMul_1",
"bert/encoder/layer_5/attention/self/MatMul",
"bert/encoder/layer_5/attention/self/MatMul_1",
"bert/encoder/layer_6/attention/self/MatMul",
"bert/encoder/layer_6/attention/self/MatMul_1",
"bert/encoder/layer_7/attention/self/MatMul",
"bert/encoder/layer_7/attention/self/MatMul_1",
"bert/encoder/layer_8/attention/self/MatMul",
"bert/encoder/layer_8/attention/self/MatMul_1",
"bert/encoder/layer_9/attention/self/MatMul",
"bert/encoder/layer_9/attention/self/MatMul_1",
"bert/encoder/layer_10/attention/self/MatMul",
"bert/encoder/layer_10/attention/self/MatMul_1",
"bert/encoder/layer_11/attention/self/MatMul",
"bert/encoder/layer_11/attention/self/MatMul_1",
"loss/MatMul"
]
}
}
}
]
}
}
@@ -0,0 +1,69 @@
{
"model": {
"name": "bert_base_squad_1_1",
"model": "<PATH_TO_MODEL>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/bert_base_squad_1_1_tf_int8.yml"
},
"compression": {
"model_type": "transformer",
"algorithms": [
{
"name": "AccuracyAwareQuantization",
"params": {
"metric_subset_ratio": 1,
"ranking_subset_size": 300,
"max_iter_num": 500,
"maximal_drop": 0.01,
"drop_type": "relative",
"base_algorithm": "DefaultQuantization",
"use_prev_if_drop_increase": true,
"range_estimator": {
"preset": "default"
},
"stat_subset_size": 1000,
"ignored": {
"scope" : [
"bert/encoder/layer_0/output/dense/MatMul",
"bert/encoder/layer_0/intermediate/dense/MatMul",
"bert/encoder/layer_0/attention/self/key/MatMul",
"bert/encoder/layer_0/attention/output/dense/MatMul",
"bert/encoder/layer_0/attention/self/MatMul",
"bert/encoder/layer_0/attention/self/MatMul_1",
"bert/encoder/layer_1/attention/self/key/MatMul",
"bert/encoder/layer_1/attention/self/MatMul",
"bert/encoder/layer_1/attention/self/MatMul_1",
"bert/encoder/layer_2/attention/self/MatMul",
"bert/encoder/layer_2/attention/self/MatMul_1",
"bert/encoder/layer_3/output/dense/MatMul",
"bert/encoder/layer_3/intermediate/dense/MatMul",
"bert/encoder/layer_3/attention/output/dense/MatMul",
"bert/encoder/layer_3/attention/self/MatMul",
"bert/encoder/layer_3/attention/self/MatMul_1",
"bert/encoder/layer_4/attention/self/value/MatMul",
"bert/encoder/layer_4/attention/self/MatMul",
"bert/encoder/layer_4/attention/self/MatMul_1",
"bert/encoder/layer_5/attention/self/MatMul",
"bert/encoder/layer_5/attention/self/MatMul_1",
"bert/encoder/layer_6/attention/self/MatMul",
"bert/encoder/layer_6/attention/self/MatMul_1",
"bert/encoder/layer_7/attention/self/MatMul",
"bert/encoder/layer_7/attention/self/MatMul_1",
"bert/encoder/layer_8/attention/self/MatMul",
"bert/encoder/layer_8/attention/self/MatMul_1",
"bert/encoder/layer_9/attention/self/MatMul",
"bert/encoder/layer_9/attention/self/MatMul_1",
"bert/encoder/layer_10/attention/self/MatMul",
"bert/encoder/layer_10/attention/self/MatMul_1",
"bert/encoder/layer_11/attention/self/MatMul",
"bert/encoder/layer_11/attention/self/MatMul_1",
"loss/MatMul"
]
}
}
}
]
}
}
@@ -0,0 +1,86 @@
{
"model": {
"name": "bert_large_squad_1_1",
"model": "<PATH_TO_MODEL>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/bert_large_squad_1_1_tf_int8.yml"
},
"compression": {
"model_type": "transformer",
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 100,
"ignored": {
"scope": [
"bert/encoder/layer_0/attention/self/MatMul",
"bert/encoder/layer_1/attention/self/MatMul",
"bert/encoder/layer_2/attention/self/MatMul",
"bert/encoder/layer_3/attention/self/MatMul",
"bert/encoder/layer_4/attention/self/MatMul",
"bert/encoder/layer_5/attention/self/MatMul",
"bert/encoder/layer_6/attention/self/MatMul",
"bert/encoder/layer_7/attention/self/MatMul",
"bert/encoder/layer_8/attention/self/MatMul",
"bert/encoder/layer_9/attention/self/MatMul",
"bert/encoder/layer_10/attention/self/MatMul",
"bert/encoder/layer_11/attention/self/MatMul",
"bert/encoder/layer_12/attention/self/MatMul",
"bert/encoder/layer_13/attention/self/MatMul",
"bert/encoder/layer_14/attention/self/MatMul",
"bert/encoder/layer_15/attention/self/MatMul",
"bert/encoder/layer_16/attention/self/MatMul",
"bert/encoder/layer_17/attention/self/MatMul",
"bert/encoder/layer_18/attention/self/MatMul",
"bert/encoder/layer_19/attention/self/MatMul",
"bert/encoder/layer_20/attention/self/MatMul",
"bert/encoder/layer_21/attention/self/MatMul",
"bert/encoder/layer_22/attention/self/MatMul",
"bert/encoder/layer_23/attention/self/MatMul",
"bert/encoder/layer_23/attention/self/MatMul_1",
"bert/encoder/layer_22/attention/self/MatMul_1",
"bert/encoder/layer_21/attention/self/MatMul_1",
"bert/encoder/layer_20/attention/self/MatMul_1",
"bert/encoder/layer_19/attention/self/MatMul_1",
"bert/encoder/layer_18/attention/self/MatMul_1",
"bert/encoder/layer_17/attention/self/MatMul_1",
"bert/encoder/layer_16/attention/self/MatMul_1",
"bert/encoder/layer_15/attention/self/MatMul_1",
"bert/encoder/layer_14/attention/self/MatMul_1",
"bert/encoder/layer_13/attention/self/MatMul_1",
"bert/encoder/layer_12/attention/self/MatMul_1",
"bert/encoder/layer_11/attention/self/MatMul_1",
"bert/encoder/layer_10/attention/self/MatMul_1",
"bert/encoder/layer_9/attention/self/MatMul_1",
"bert/encoder/layer_8/attention/self/MatMul_1",
"bert/encoder/layer_7/attention/self/MatMul_1",
"bert/encoder/layer_6/attention/self/MatMul_1",
"bert/encoder/layer_5/attention/self/MatMul_1",
"bert/encoder/layer_4/attention/self/MatMul_1",
"bert/encoder/layer_3/attention/self/MatMul_1",
"bert/encoder/layer_2/attention/self/MatMul_1",
"bert/encoder/layer_1/attention/self/MatMul_1",
"bert/encoder/layer_0/attention/self/MatMul_1",
"bert/encoder/layer_0/attention/output/dense/MatMul",
"bert/encoder/layer_3/attention/output/dense/MatMul",
"bert/encoder/layer_4/attention/self/value/MatMul",
"bert/encoder/layer_0/attention/self/key/MatMul",
"bert/encoder/layer_1/attention/self/key/MatMul",
"bert/encoder/layer_0/intermediate/dense/MatMul",
"bert/encoder/layer_0/output/dense/MatMul",
"bert/encoder/layer_3/intermediate/dense/MatMul",
"bert/encoder/layer_3/output/dense/MatMul",
"bert/encoder/layer_7/attention/self/key/MatMul"
]
}
}
}
]
}
}
@@ -0,0 +1,87 @@
{
"model": {
"name": "bert_large_squad_1_1",
"model": "<PATH_TO_MODEL>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/bert_large_squad_1_1_tf_int8.yml"
},
"compression": {
"target_device": "CPU",
"model_type": "transformer",
"algorithms": [
{
"name": "AccuracyAwareQuantization",
"params": {
"max_iter_num": 500,
"stat_subset_size": 100,
"ignored": {
"scope": [
"bert/encoder/layer_0/attention/self/MatMul",
"bert/encoder/layer_1/attention/self/MatMul",
"bert/encoder/layer_2/attention/self/MatMul",
"bert/encoder/layer_3/attention/self/MatMul",
"bert/encoder/layer_4/attention/self/MatMul",
"bert/encoder/layer_5/attention/self/MatMul",
"bert/encoder/layer_6/attention/self/MatMul",
"bert/encoder/layer_7/attention/self/MatMul",
"bert/encoder/layer_8/attention/self/MatMul",
"bert/encoder/layer_9/attention/self/MatMul",
"bert/encoder/layer_10/attention/self/MatMul",
"bert/encoder/layer_11/attention/self/MatMul",
"bert/encoder/layer_12/attention/self/MatMul",
"bert/encoder/layer_13/attention/self/MatMul",
"bert/encoder/layer_14/attention/self/MatMul",
"bert/encoder/layer_15/attention/self/MatMul",
"bert/encoder/layer_16/attention/self/MatMul",
"bert/encoder/layer_17/attention/self/MatMul",
"bert/encoder/layer_18/attention/self/MatMul",
"bert/encoder/layer_19/attention/self/MatMul",
"bert/encoder/layer_20/attention/self/MatMul",
"bert/encoder/layer_21/attention/self/MatMul",
"bert/encoder/layer_22/attention/self/MatMul",
"bert/encoder/layer_23/attention/self/MatMul",
"bert/encoder/layer_23/attention/self/MatMul_1",
"bert/encoder/layer_22/attention/self/MatMul_1",
"bert/encoder/layer_21/attention/self/MatMul_1",
"bert/encoder/layer_20/attention/self/MatMul_1",
"bert/encoder/layer_19/attention/self/MatMul_1",
"bert/encoder/layer_18/attention/self/MatMul_1",
"bert/encoder/layer_17/attention/self/MatMul_1",
"bert/encoder/layer_16/attention/self/MatMul_1",
"bert/encoder/layer_15/attention/self/MatMul_1",
"bert/encoder/layer_14/attention/self/MatMul_1",
"bert/encoder/layer_13/attention/self/MatMul_1",
"bert/encoder/layer_12/attention/self/MatMul_1",
"bert/encoder/layer_11/attention/self/MatMul_1",
"bert/encoder/layer_10/attention/self/MatMul_1",
"bert/encoder/layer_9/attention/self/MatMul_1",
"bert/encoder/layer_8/attention/self/MatMul_1",
"bert/encoder/layer_7/attention/self/MatMul_1",
"bert/encoder/layer_6/attention/self/MatMul_1",
"bert/encoder/layer_5/attention/self/MatMul_1",
"bert/encoder/layer_4/attention/self/MatMul_1",
"bert/encoder/layer_3/attention/self/MatMul_1",
"bert/encoder/layer_2/attention/self/MatMul_1",
"bert/encoder/layer_1/attention/self/MatMul_1",
"bert/encoder/layer_0/attention/self/MatMul_1",
"bert/encoder/layer_0/attention/output/dense/MatMul",
"bert/encoder/layer_3/attention/output/dense/MatMul",
"bert/encoder/layer_4/attention/self/value/MatMul",
"bert/encoder/layer_0/attention/self/key/MatMul",
"bert/encoder/layer_1/attention/self/key/MatMul",
"bert/encoder/layer_0/intermediate/dense/MatMul",
"bert/encoder/layer_0/output/dense/MatMul",
"bert/encoder/layer_3/intermediate/dense/MatMul",
"bert/encoder/layer_3/output/dense/MatMul",
"bert/encoder/layer_7/attention/self/key/MatMul"
]
}
}
}
]
}
}
@@ -0,0 +1,34 @@
{
"model": {
"model_name": "faster_rcnn_resnet101_coco",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/faster_rcnn_resnet101_coco.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300,
"ignored": {
"scope": [
"proposals/conv"
]
},
"activations": {
"range_estimator": {
"max": {
"aggregator": "max",
"type": "abs_max"
}
}
}
}
}
]
}
}
@@ -0,0 +1,34 @@
{
"model": {
"model_name": "faster_rcnn_resnet50_coco",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/faster_rcnn_resnet50_coco.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300,
"ignored": {
"scope": [
"proposals/conv"
]
},
"activations": {
"range_estimator": {
"max": {
"aggregator": "max",
"type": "abs_max"
}
}
}
}
}
]
}
}
@@ -0,0 +1,32 @@
{
"model": {
"model_name": "mask_rcnn_resnet50_atrous_coco",
"model": "<MODEL_PATH>",
"weights": "<WEIGHTS_PATH>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/mask_rcnn_resnet50_atrous_coco.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300,
"ignored": {
"scope": [
"FirstStageFeatureExtractor/resnet_v1_50/resnet_v1_50/block1/unit_1/bottleneck_v1/add",
"proposals/conv",
"proposals/reshape_4d",
"SecondStageFeatureExtractor_1/resnet_v1_50/block4/unit_1/bottleneck_v1/shortcut/Conv2D",
"SecondStageFeatureExtractor_1/resnet_v1_50/block4/unit_1/bottleneck_v1/conv1/Conv2D",
"SecondStageFeatureExtractor/resnet_v1_50/block4/unit_1/bottleneck_v1/shortcut/Conv2D",
"SecondStageFeatureExtractor/resnet_v1_50/block4/unit_1/bottleneck_v1/conv1/Conv2D"
]
}
}
}
]
}
}
@@ -0,0 +1,36 @@
{
"model": {
"model_name": "mtcnn",
"cascade": [
{
"name": "pnet",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
{
"name": "rnet",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
{
"name": "onet",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
}
]
},
"engine": {
"config": "./configs/examples/accuracy_checker/mtcnn.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "mixed",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,21 @@
{
"model": {
"model_name": "mobilenet_ssd",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "<CONFIG_PATH>"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,59 @@
{
"model": {
"model_name": "mobilenet-ssd",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"launchers": [
{
"framework": "dlsdk",
"device": "CPU",
"adapter": "ssd"
}
],
"datasets": [
{
"name": "VOC2007",
"data_source": "<PATH TO VALIDATION DATASET>/VOC2007/JPEGImages",
"annotation_conversion": {
"converter": "voc_detection",
"annotations_dir": "<PATH TO VALIDATION DATASET>/VOC2007/Annotations",
"images_dir": "<PATH TO VALIDATION DATASET>/VOC2007/JPEGImages",
"imageset_file": "<PATH TO VALIDATION DATASET>/VOC2007/ImageSets/Main/test.txt"
},
"preprocessing":[
{
"type": "resize",
"size": 300
}
],
"postprocessing":[{
"type": "resize_prediction_boxes"
}],
"metrics": [
{
"type": "map",
"integral": "11point",
"ignore_difficult": true,
"presenter": "print_scalar"
}
]
}
]
},
"compression": {
"algorithms": [
{
"name": "MinMaxQuantization",
"params": {
"preset": "mixed",
"range_estimator": {
"preset": "quantile"
},
"stat_subset_size": 1000
}
}
]
}
}
@@ -0,0 +1,42 @@
{
"model": {
"model_name": "ssd_resnet34_1200",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/ssd_resnet34.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"stat_subset_size": 300,
"preset": "performance",
"ignored":{
"scope": [
"Mul_490",
"Mul_509",
"Add_511",
"Mul_507",
"Exp_512",
"Mul_514",
"Mul_548/Fused_Mul_",
"Mul_583/Fused_Mul_",
"Mul_618",
"Mul_653",
"Sub_549/add_",
"Sub_584/add_",
"Add_619",
"Add_654",
"Mul_703",
"Add_704",
"Add_labels"
]
}
}
}
]
}
}
@@ -0,0 +1,57 @@
{
"model": {
"model_name": "ssd_resnet50_512_mxnet",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"launchers": [
{
"framework": "dlsdk",
"device": "CPU",
"adapter": "ssd"
}
],
"datasets": [
{
"name": "VOC2007",
"data_source": "<PATH TO VALIDATION DATASET>/VOC2007/JPEGImages",
"annotation_conversion": {
"converter": "voc_detection",
"has_background": false,
"annotations_dir": "<PATH TO VALIDATION DATASET>/VOC2007/Annotations",
"images_dir": "<PATH TO VALIDATION DATASET>/VOC2007/JPEGImages",
"imageset_file": "<PATH TO VALIDATION DATASET>/VOC2007/ImageSets/Main/test.txt"
},
"preprocessing":[
{
"type": "resize",
"size": 512
}
],
"postprocessing":[{
"type": "resize_prediction_boxes"
}],
"metrics": [
{
"type": "map",
"integral": "11point",
"ignore_difficult": true,
"presenter": "print_scalar"
}
]
}
]
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,56 @@
{
"model": {
"model_name": "mobilenetv1",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/mobilenet_v1_tf.yaml"
},
"optimizer": {
"name": "Tpe",
"params": {
"max_trials": 200,
"max_minutes": 1440,
"trials_load_method": "cold_start",
"accuracy_loss": 0.1,
"latency_reduce": 1.5,
"accuracy_weight": 1.0,
"latency_weight": 1.0,
"benchmark": {
"performance_count": false,
"batch_size": 1,
"nthreads": 8,
"nstreams": 1,
"nireq": 1,
"api_type": "async",
"niter": 1,
"duration_seconds": 30
}
}
},
"compression": {
"algorithms": [
{
"name": "ActivationChannelAlignment",
"params": {
"stat_subset_size": 1000
}
},
{
"name": "TunableQuantization",
"params": {
"stat_subset_size": 1000,
"preset": "performance",
"tuning_scope": ["layer"]
}
},
{
"name": "FastBiasCorrection",
"params": {
"stat_subset_size": 1000
}
}
]
}
}
@@ -0,0 +1,47 @@
{
"model": {
"model_name": "mobilenetv2",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/mobilenet_v2.yaml"
},
"compression": {
"algorithms": [
{
"name": "MinMaxQuantization",
"params": {
"preset": "mixed",
"stat_subset_size": 1000,
"weights": {
"bits": 8,
"mode": "asymmetric",
"granularity": "perchannel"
},
"activations": {
"bits": 8,
"mode": "asymmetric",
"granularity": "pertensor"
}
}
},
{
"name": "RangeOptimization",
"params": {
"stat_subset_size": 5000,
"result_filename": "rangeopt_results.csv",
"lower_boxsize": 0.1,
"upper_boxsize": 0.1,
"maxiter": 1500,
"optimization_scope": ["317", "315"],
"metric_name": "accuracy@top1",
"opt_backend": "nevergrad",
"optimizer_name": "CMA"
// use the below option to validate range values
// "activation_ranges_to_set": {"317": [-0.0380698, 2.35978142]}
}
}
]
}
}
@@ -0,0 +1,56 @@
{
"model": {
"model_name": "mobilenetv2",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/mobilenet_v2.yaml"
},
"optimizer": {
"name": "Tpe",
"params": {
"max_trials": 200,
"max_minutes": 1440,
"trials_load_method": "cold_start",
"accuracy_loss": 0.1,
"latency_reduce": 1.5,
"accuracy_weight": 1.0,
"latency_weight": 1.0,
"benchmark": {
"performance_count": false,
"batch_size": 1,
"nthreads": 8,
"nstreams": 1,
"nireq": 1,
"api_type": "async",
"niter": 1,
"duration_seconds": 30
}
}
},
"compression": {
"algorithms": [
{
"name": "ActivationChannelAlignment",
"params": {
"stat_subset_size": 1000
}
},
{
"name": "TunableQuantization",
"params": {
"stat_subset_size": 1000,
"preset": "performance",
"tuning_scope": ["layer"]
}
},
{
"name": "FastBiasCorrection",
"params": {
"stat_subset_size": 1000
}
}
]
}
}
@@ -0,0 +1,56 @@
{
"model": {
"model_name": "mobilenetv2",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/mobilenet_v2.yaml"
},
"compression": {
"algorithms": [
{
"name": "QuantileTuningAlgorithm",
"params": {
"opt_backend": "skopt",
"maxiter": 100,
"optimization_subset_size": 1000,
"preset": "mixed",
"stat_subset_size": 1000,
"weights": {
"bits": 8,
"mode": "asymmetric",
"granularity": "perchannel",
"range_estimator": {
"min": {
"type": "quantile",
"outlier_prob": 0.0015
},
"max": {
"type": "quantile",
"outlier_prob": 0.0015
}
}
},
"activations": {
"bits": 8,
"mode": "asymmetric",
"granularity": "pertensor",
"range_estimator": {
"min": {
"aggregator": "mean",
"type": "quantile",
"outlier_prob": 1e-3
},
"max": {
"aggregator": "mean",
"type": "quantile",
"outlier_prob": 1e-3
}
}
}
}
}
]
}
}
@@ -0,0 +1,59 @@
{
"model": {
"model_name": "mobilenet-ssd",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/ssd_mobilenet_v1.yaml"
},
"optimizer": {
"name": "Tpe",
"params": {
"max_trials": 200,
"max_minutes": 1440,
"trials_load_method": "cold_start",
"accuracy_loss": 0.1,
"latency_reduce": 1.5,
"accuracy_weight": 1.0,
"latency_weight": 0.0,
"benchmark": {
"performance_count": false,
"batch_size": 1,
"nthreads": 8,
"nstreams": 1,
"nireq": 1,
"api_type": "async",
"niter": 1,
"duration_seconds": 30
}
}
},
"compression": {
"algorithms": [
{
"name": "ActivationChannelAlignment",
"params": {
"stat_subset_size": 1000
}
},
{
"name": "TunableQuantization",
"params": {
"stat_subset_size": 1000,
"preset": "performance",
"tuning_scope": ["range_estimator"],
"estimator_tuning_scope": ["preset", "outlier_prob"],
"outlier_prob_choices": [1e-3, 1e-4, 1e-5]
}
},
{
"name": "FastBiasCorrection",
"params": {
"stat_subset_size": 1000
}
}
]
}
}
@@ -0,0 +1,33 @@
{
"model": {
"model_name": "ncf",
"model": "<PATH_TO_MODEL>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/ncf.yaml"
},
"compression": {
"algorithms": [
{
"name": "MinMaxQuantization",
"params": {
"preset": "mixed",
"stat_subset_size": 1000,
"weights": {
"bits": 8,
"mode": "symmetric",
"granularity": "perchannel",
"level_low": -127,
"level_high": 127
},
"activations": {
"bits": 8,
"mode": "symmetric",
"granularity": "pertensor"
}
}
}
]
}
}
@@ -0,0 +1,60 @@
{
"model": {
"model_name": "ncf",
"model": "<PATH_TO_MODEL>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/ncf.yaml"
},
"optimizer": {
"name": "Tpe",
"params": {
"max_trials": 100,
"max_minutes": 10,
"trials_load_method": "cold_start",
"accuracy_loss": 0.1,
"latency_reduce": 1.5,
"expected_quantization_ratio": 0.5,
"accuracy_weight": 1.0,
"latency_weight": 1.0,
"quantization_ratio_weight": 1.0,
"benchmark": {
"cpu_bind_thread": "YES",
"nthreads": 4,
"nstreams": 0,
"nireq": 0,
"api_type": "async",
"duration_seconds": 30,
"benchmark_app_dir":""
}
}
},
"compression": {
"algorithms": [
{
"name": "ActivationChannelAlignment",
"params": {
"stat_subset_size": 1000
}
},
{
"name": "TunableQuantization",
"params": {
"stat_subset_size": 1000,
"preset": "performance",
"tuning_scope": ["range_estimator"],
"estimator_tuning_scope": ["preset", "aggregator", "type", "outlier_prob"],
"outlier_prob_choices": [1e-3, 1e-4, 1e-5]
}
},
{
"name": "FastBiasCorrection",
"params": {
"stat_subset_size": 1000
}
}
]
}
}
@@ -0,0 +1,49 @@
{
"model": {
"model_name": "brain-tumor-segmentation-0001",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"launchers": [
{
"framework": "dlsdk",
"adapter": {
"type": "brain_tumor_segmentation"
}
}
],
"datasets": [
{
"name": "BraTS",
"data_source": "<PATH_TO_DATASET>",
"annotation_conversion": {
"converter": "brats_numpy",
"data_dir": "<PATH_TO_DATASET>",
"ids_file": "<PATH_TO_IDS_FILE>",
"labels_file": "<PATH_TO_LABELS_FILE>"
},
"reader": "numpy_reader",
"metrics": [
{
"type": "dice_index",
"median": true,
"presenter": "print_vector"
}
]
}
]
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"stat_subset_size": 72,
"preset": "performance"
}
}
]
}
}
@@ -0,0 +1,26 @@
{
"model": {
"model_name": "east",
"model": "<MODEL_PATH>",
"weights": "<WEIGHTS_PATH>"
},
"engine": {
"config": "./configs/examples/accuracy_checker/east_resnet_v1_50.yaml"
},
"compression": {
"algorithms": [
{
"name": "DefaultQuantization",
"params": {
"ignored": {
"scope": [
"feature_fusion/Conv_4/Conv2D"
]
},
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,30 @@
{
"model": {
"model_name": "resnet-50-pytorch",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "<CONFIG_PATH>"
},
"compression": {
"algorithms": [
{
"name": "WeightSparsity",
"params": {
"sparsity_level": 0.5,
"apply_for_all_nodes": true,
"stat_subset_size": 300,
"use_layerwise_tuning": true,
}
},
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,29 @@
{
"model": {
"model_name": "ssd_resnet50_512",
"model": "<MODEL_PATH>",
"weights": "<PATH_TO_WEIGHTS>"
},
"engine": {
"config": "<CONFIG_PATH>"
},
"compression": {
"algorithms": [
{
"name": "WeightSparsity",
"params": {
"sparsity_level": 0.5,
"apply_for_all_nodes": true,
"stat_subset_size": 300
}
},
{
"name": "DefaultQuantization",
"params": {
"preset": "performance",
"stat_subset_size": 300
}
}
]
}
}
@@ -0,0 +1,44 @@
/* This configuration file is the fastest way to get started with the default
quantization algorithm in simplified mode. It contains only mandatory options
with commonly used values. All other options can be considered as an advanced
mode and requires deep knowledge of the quantization process. An overall description
of all possible parameters can be found in the default_quantization_spec.json */
{
/* Model parameters */
"model": {
"model_name": "model_name", // Model name
"model": "<MODEL_PATH>", // Path to model (.xml format)
"weights": "<PATH_TO_WEIGHTS>" // Path to weights (.bin format)
},
/* Parameters of the engine used for model inference */
"engine": {
"type": "simplified",
"data_source": "PATH_TO_SOURCE" // You can specify path to directory with images. Also you can
// specify template for file names to filter images to load.
// Templates are unix style (This option valid only in simplified mode)
},
/* Optimization hyperparameters */
"compression": {
"target_device": "ANY", // Target device, the specificity of which will be taken
// into account during optimization
"algorithms": [
{
"name": "DefaultQuantization", // Optimization algorithm name
"params": {
"preset": "performance", // Preset [performance, mixed, accuracy] which control the quantization
// mode (symmetric, mixed (weights symmetric and activations asymmetric)
// and fully asymmetric respectively)
"stat_subset_size": 300 // Size of subset to calculate activations statistics that can be used
// for quantization parameters calculation
}
}
]
}
}
@@ -0,0 +1,44 @@
/* This configuration file is the fastest way to get started with the default
sparsity and default quantization algorithm. It contains only mandatory options
with commonly used values. All other options can be considered as an advanced
mode and requires deep knowledge of the quantization process. An overall description
of all possible parameters can be found in the default_quantization_spec.json */
{
/* Model parameters */
"model": {
"model_name": "model_name", // Model name
"model": "<MODEL_PATH>", // Path to model (.xml format)
"weights": "<PATH_TO_WEIGHTS>" // Path to weights (.bin format)
},
/* Parameters of the engine used for model inference */
"engine": {
"config": "<CONFIG_PATH>" // Path to Accuracy Checker config
},
/* Optimization hyperparameters */
"compression": {
"target_device": "ANY", // Target device, the specificity of which will be taken
// into account during optimization
"algorithms": [
{
"name": "WeightSparsity",
"params": {
"sparsity_level": 0.3,
"stat_subset_size": 300 // Size of subset to calculate activations statistics that can be used
// for quantization parameters calculation
}
},
{
"name": "DefaultQuantization", // Optimization algorithm name
"params": {
// Preset [performance, mixed, accuracy] which control the quantization mode
// (symmetric, mixed (weights symmetric and activations asymmetric) and fully
// asymmetric respectively)
"preset": "performance",
"stat_subset_size": 300 // Size of subset to calculate activations statistics that can be used
// for quantization parameters calculation
}
}
]
}
}
Loaded 100 of 445 files, more files were not shown because too many files have changed in this diff. Show more