diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_extension_utils.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_extension_utils.cpp index bcb2deedb20..046fdf0a69c 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_extension_utils.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_extension_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -137,3 +137,15 @@ std::string MKLDNNExtensionUtils::getReorderArgs(const InferenceEngine::TensorDe } return inArgs + "_" + outArgs; } + +InferenceEngine::Precision MKLDNNExtensionUtils::getMaxPrecision(std::vector precisions) { + if (!precisions.empty()) { + std::sort(precisions.begin(), precisions.end(), + [](const InferenceEngine::Precision &lhs, const InferenceEngine::Precision &rhs) { + return lhs.size() > rhs.size(); + }); + return precisions[0]; + } + + return InferenceEngine::Precision::UNSPECIFIED; +} diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_extension_utils.h b/inference-engine/src/mkldnn_plugin/mkldnn_extension_utils.h index a73b16f5dee..09b05756ea1 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_extension_utils.h +++ b/inference-engine/src/mkldnn_plugin/mkldnn_extension_utils.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -23,6 +23,7 @@ public: static InferenceEngine::TensorDesc getUninitTensorDesc(const InferenceEngine::TensorDesc& desc); static bool initTensorsAreEqual(const InferenceEngine::TensorDesc &desc1, const InferenceEngine::TensorDesc &desc2); static std::string getReorderArgs(const InferenceEngine::TensorDesc &parentDesc, const InferenceEngine::TensorDesc &childDesc); + static InferenceEngine::Precision getMaxPrecision(std::vector precisions); }; } // namespace MKLDNNPlugin diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_graph_dumper.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_graph_dumper.cpp index 0c7c36b2541..a69cead1506 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_graph_dumper.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_graph_dumper.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -281,6 +281,8 @@ std::map extract_node_metadata(const MKLDNNNodePtr &no serialization_info[ExecGraphInfoSerialization::EXECUTION_ORDER] = std::to_string(node->getExecIndex()); + serialization_info[ExecGraphInfoSerialization::RUNTIME_PRECISION] = node->getRuntimePrecision().name(); + return serialization_info; } diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp index 58ff8c5ac7d..4ede2b474bd 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -1130,6 +1130,45 @@ void MKLDNNNode::appendPostOps(mkldnn::post_ops& ops) { THROW_IE_EXCEPTION << "Fusing of " << this->getType() << " operation is not implemented"; } +std::vector MKLDNNNode::getInputPrecisions() const { + std::vector inputPrecisions; + for (size_t i = 0; i < getParentEdges().size(); i++) { + auto parentEdge = getParentEdgeAt(i); + if (parentEdge && parentEdge->getStatus() == MKLDNNEdge::Status::Validated) { + inputPrecisions.emplace_back(MKLDNNExtensionUtils::DataTypeToIEPrecision((parentEdge->getMemoryPtr()->GetDataType()))); + } + } + return inputPrecisions; +} + +std::vector MKLDNNNode::getOutputPrecisions() const { + std::vector outputPrecisions; + for (size_t i = 0; i < getChildEdges().size(); i++) { + auto childEdge = getChildEdgeAt(i); + if (childEdge && childEdge->getStatus() == MKLDNNEdge::Status::Validated) { + outputPrecisions.emplace_back(MKLDNNExtensionUtils::DataTypeToIEPrecision((childEdge->getMemoryPtr()->GetDataType()))); + } + } + return outputPrecisions; +} + +InferenceEngine::Precision MKLDNNNode::getRuntimePrecision() const { + // Base implementation consider precision only on data path and + // assumes it is placed on 0-th port (which is true for almost all layers) + InferenceEngine::Precision runtimePrecision = Precision::UNSPECIFIED; + auto inputPrecisions = getInputPrecisions(); + if (!inputPrecisions.empty()) { + runtimePrecision = inputPrecisions[0]; + } else { + auto outputPrecisions = getOutputPrecisions(); + if (!outputPrecisions.empty()) { + runtimePrecision = outputPrecisions[0]; + } + } + + return runtimePrecision; +} + MKLDNNNode* MKLDNNNode::NodesFactory::create(const InferenceEngine::CNNLayerPtr& layer, const mkldnn::engine& eng, const MKLDNNExtensionManager::Ptr& extMgr, MKLDNNWeightsSharing::Ptr &w_cache) { MKLDNNNode *newNode = nullptr; diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_node.h b/inference-engine/src/mkldnn_plugin/mkldnn_node.h index 2c17c757eb2..b2b44c03a94 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_node.h +++ b/inference-engine/src/mkldnn_plugin/mkldnn_node.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -517,6 +517,12 @@ public: return profiling; } + /** + * @brief Returns runtime node precision based on input/output data types or data type used for computations + * @return Runtime node precision + */ + virtual InferenceEngine::Precision getRuntimePrecision() const; + protected: // TODO: It is necessary only in order to avoid modifications of cnnLayers and original topology std::vector outDims; @@ -591,6 +597,18 @@ protected: InferenceEngine::Layout getWeightsLayoutByDims(InferenceEngine::SizeVector dims, bool isGrouped); + /** + * @brief Auxiliary function to get node input precisions + * @return Vector of precisions based on information from node input edges. Return empty vector in case edges are not initialized yet. + */ + virtual std::vector getInputPrecisions() const; + + /** + * @brief Auxiliary function to get node output precisions + * @return Vector of precisions based on information from node output edges. Return empty vector in case edges are not initialized yet. + */ + virtual std::vector getOutputPrecisions() const; + private: std::vector parentEdges; std::vector childEdges; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_concat_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_concat_node.cpp index be5fb6182ec..d04b2531594 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_concat_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_concat_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -653,4 +653,8 @@ void MKLDNNConcatNode::execute(mkldnn::stream strm) { } } +InferenceEngine::Precision MKLDNNConcatNode::getRuntimePrecision() const { + return MKLDNNExtensionUtils::getMaxPrecision(getInputPrecisions()); +} + REG_MKLDNN_PRIM_FOR(MKLDNNConcatNode, Concatenation); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_concat_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_concat_node.h index 1ff8631b521..d337232a592 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_concat_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_concat_node.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -26,6 +26,8 @@ public: bool isOptimized() const; + InferenceEngine::Precision getRuntimePrecision() const override; + private: size_t axis = 0; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_conv_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_conv_node.cpp index ff40438f1b3..bf4768a7bbb 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_conv_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_conv_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -913,4 +913,18 @@ const mkldnn::memory& MKLDNNConvolutionNode::getBias() const { return baseInputsNumber > 2 ? getParentEdgeAt(2)->getMemory().GetPrimitive() : internalBlobMemory[1]->GetPrimitive(); } +InferenceEngine::Precision MKLDNNConvolutionNode::getRuntimePrecision() const { + std::vector inputPrecisions; + // Don't take bias precision into account + size_t inputsNumLimit = 2; + for (size_t i = 0; i < std::min(getParentEdges().size(), inputsNumLimit); i++) { + auto parentEdge = getParentEdgeAt(i); + if (parentEdge && parentEdge->getStatus() == MKLDNNEdge::Status::Validated) { + inputPrecisions.emplace_back(MKLDNNExtensionUtils::DataTypeToIEPrecision((parentEdge->getMemoryPtr()->GetDataType()))); + } + } + + return MKLDNNExtensionUtils::getMaxPrecision(inputPrecisions); +} + REG_MKLDNN_PRIM_FOR(MKLDNNConvolutionNode, Convolution); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_conv_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_conv_node.h index d031724d9cb..85c1ee30f18 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_conv_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_conv_node.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -49,6 +49,8 @@ public: bool canBeExecutedInInt8(); + InferenceEngine::Precision getRuntimePrecision() const override; + std::vector inputZeroPoints; std::vector weightsZeroPoints; std::vector outputCompensation; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_deconv_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_deconv_node.cpp index c7ec1d089c6..d5cf338caa9 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_deconv_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_deconv_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -283,4 +283,18 @@ const mkldnn::memory& MKLDNNDeconvolutionNode::getWeights() const { return getParentEdges().size() > 1 ? getParentEdgeAt(1)->getMemory().GetPrimitive() : internalBlobMemory[0]->GetPrimitive(); } +InferenceEngine::Precision MKLDNNDeconvolutionNode::getRuntimePrecision() const { + std::vector inputPrecisions; + // Don't take bias precision into account + size_t inputsNumLimit = 2; + for (size_t i = 0; i < std::min(getParentEdges().size(), inputsNumLimit); i++) { + auto parentEdge = getParentEdgeAt(i); + if (parentEdge && parentEdge->getStatus() == MKLDNNEdge::Status::Validated) { + inputPrecisions.emplace_back(MKLDNNExtensionUtils::DataTypeToIEPrecision((parentEdge->getMemoryPtr()->GetDataType()))); + } + } + + return MKLDNNExtensionUtils::getMaxPrecision(inputPrecisions); +} + REG_MKLDNN_PRIM_FOR(MKLDNNDeconvolutionNode, Deconvolution); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_deconv_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_deconv_node.h index fefe885baf1..1888404061e 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_deconv_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_deconv_node.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -36,6 +36,8 @@ public: MKLDNNMemoryDesc getSrcMemDesc(mkldnn::primitive_desc_iterator &primitive_desc_it, size_t idx) override; MKLDNNMemoryDesc getDstMemDesc(mkldnn::primitive_desc_iterator &primitive_desc_it, size_t idx) override; + InferenceEngine::Precision getRuntimePrecision() const override; + private: bool withGroups = false; bool isDW = false; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.cpp index f09611b9676..3fdcd048663 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -279,4 +279,9 @@ void MKLDNNDeformableConvolutionNode::initDescriptor(const InferenceEngine::Laye } selectedPD->getConfig() = rightConfig; } + +InferenceEngine::Precision MKLDNNDeformableConvolutionNode::getRuntimePrecision() const { + return MKLDNNExtensionUtils::getMaxPrecision(getInputPrecisions()); +} + REG_MKLDNN_PRIM_FOR(MKLDNNDeformableConvolutionNode, DeformableConvolution); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.h index fdf2c4cbe4d..8c5decca910 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_def_conv_node.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -28,6 +28,8 @@ public: return false; } + InferenceEngine::Precision getRuntimePrecision() const override; + private: bool withBiases = false; bool isDW = false; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp index df6fd85f3c2..856bac838f2 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -1788,4 +1788,17 @@ bool MKLDNNEltwiseNode::canFuse(const MKLDNNNodePtr& node) const { return false; } +InferenceEngine::Precision MKLDNNEltwiseNode::getRuntimePrecision() const { + std::vector inputPrecisions; + // Don't take bias precision into account + for (size_t i = 0; i < getParentEdges().size(); i++) { + auto parentEdge = getParentEdgeAt(i); + if (parentEdge && parentEdge->getStatus() == MKLDNNEdge::Status::Validated && !parentEdge->getParent()->isConstant()) { + inputPrecisions.emplace_back(MKLDNNExtensionUtils::DataTypeToIEPrecision((parentEdge->getMemoryPtr()->GetDataType()))); + } + } + + return MKLDNNExtensionUtils::getMaxPrecision(inputPrecisions); +} + REG_MKLDNN_PRIM_FOR(MKLDNNEltwiseNode, Eltwise); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.h index 1590d378e32..abf527a25a2 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -130,6 +130,8 @@ public: void appendPostOps(mkldnn::post_ops& ops) override; + InferenceEngine::Precision getRuntimePrecision() const override; + private: void init() override; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_fullyconnected_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_fullyconnected_node.cpp index bcb97ca61f0..49ff46df77a 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_fullyconnected_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_fullyconnected_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -438,4 +438,18 @@ const mkldnn::memory& MKLDNNFullyConnectedNode::getBias() const { return baseInputsNumber > 2 ? getParentEdgeAt(2)->getMemory().GetPrimitive() : internalBlobMemory[1]->GetPrimitive(); } +InferenceEngine::Precision MKLDNNFullyConnectedNode::getRuntimePrecision() const { + std::vector inputPrecisions; + // Don't take bias precision into account + size_t inputsNumLimit = 2; + for (size_t i = 0; i < std::min(getParentEdges().size(), inputsNumLimit); i++) { + auto parentEdge = getParentEdgeAt(i); + if (parentEdge && parentEdge->getStatus() == MKLDNNEdge::Status::Validated) { + inputPrecisions.emplace_back(MKLDNNExtensionUtils::DataTypeToIEPrecision((parentEdge->getMemoryPtr()->GetDataType()))); + } + } + + return MKLDNNExtensionUtils::getMaxPrecision(inputPrecisions); +} + REG_MKLDNN_PRIM_FOR(MKLDNNFullyConnectedNode, FullyConnected); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_fullyconnected_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_fullyconnected_node.h index fe9a6001942..98d2b693137 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_fullyconnected_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_fullyconnected_node.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -37,6 +37,8 @@ public: const mkldnn::memory& getWeights() const; const mkldnn::memory& getBias() const; + InferenceEngine::Precision getRuntimePrecision() const override; + protected: std::shared_ptr initPrimitiveAttr(); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_gemm_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_gemm_node.cpp index a1c42af1cec..1ae11d5a938 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_gemm_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_gemm_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -322,4 +322,9 @@ int MKLDNNGemmNode::getMaxBatch() { return outDims[0][0]; return 0; } + +InferenceEngine::Precision MKLDNNGemmNode::getRuntimePrecision() const { + return MKLDNNExtensionUtils::getMaxPrecision(getInputPrecisions()); +} + REG_MKLDNN_PRIM_FOR(MKLDNNGemmNode, Gemm); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_gemm_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_gemm_node.h index def510010b1..24c31bcddb5 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_gemm_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_gemm_node.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -24,6 +24,8 @@ public: bool created() const override; int getMaxBatch() override; + InferenceEngine::Precision getRuntimePrecision() const override; + private: float alpha = 1.0f; float beta = 1.0f; diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_quantize_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_quantize_node.cpp index 4d29101698c..a9ed4481dd1 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_quantize_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_quantize_node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -369,7 +369,7 @@ void MKLDNNQuantizeNode::initSupportedPrimitiveDescriptors() { if (i == 0) { dataConfig.desc = MKLDNNMemoryDesc(getParentEdgeAt(i)->getDims(), inputDataType, fmt); } else { - dataConfig.desc = MKLDNNMemoryDesc(getParentEdgeAt(i)->getDims(), inputDataType, MKLDNNMemory::GetPlainFormat(getParentEdgeAt(i)->getDims())); + dataConfig.desc = MKLDNNMemoryDesc(getParentEdgeAt(i)->getDims(), memory::f32, MKLDNNMemory::GetPlainFormat(getParentEdgeAt(i)->getDims())); } config.inConfs.push_back(dataConfig); } diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/execution_graph_tests/runtime_precision.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/execution_graph_tests/runtime_precision.cpp new file mode 100644 index 00000000000..4f518345caa --- /dev/null +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/execution_graph_tests/runtime_precision.cpp @@ -0,0 +1,32 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "execution_graph_tests/runtime_precision.hpp" +#include "common_test_utils/test_constants.hpp" + +using namespace ExecutionGraphTests; +using namespace InferenceEngine; + +namespace { + +const std::vector params = { + /* {Ngraph function builder, function input precision, expected runtime precisions} */ + {makeEltwiseFunction, {Precision::FP32, Precision::FP32}, {{"Eltwise", Precision::FP32}}}, + {makeEltwiseFunction, {Precision::U16, Precision::U16}, {{"Eltwise", Precision::I32}}}, + {makeEltwiseFunction, {Precision::BF16, Precision::BF16}, {{"Eltwise", Precision::BF16}}}, + {makeEltwiseFunction, {Precision::U8, Precision::U8}, {{"Eltwise", Precision::U8}}}, + {makeEltwiseFunction, {Precision::I8, Precision::I8}, {{"Eltwise", Precision::I8}}}, + {makeFakeQuantizeReluFunction, {Precision::FP32}, {{"FakeQuantize", Precision::FP32}, {"Relu", Precision::U8}}}, + {makeFakeQuantizeReluFunction, {Precision::U8}, {{"FakeQuantize", Precision::U8}, {"Relu", Precision::U8}}}, + {makeFakeQuantizeBinaryConvolutionFunction, {Precision::FP32}, {{"FakeQuantize", Precision::FP32}, {"BinaryConvolution", Precision::BIN}}}, +}; + +INSTANTIATE_TEST_CASE_P(smoke_ExecGraph, ExecGraphRuntimePrecision, + ::testing::Combine( + ::testing::ValuesIn(params), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ExecGraphRuntimePrecision::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/convolution_transformation.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/convolution_transformation.cpp index 0bc65667cfa..e05f97ef344 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/convolution_transformation.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/convolution_transformation.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Intel Corporation +// Copyright (C) 2019-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -44,7 +44,7 @@ const std::vector params { 255ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 254.f }, { -12.7f }, { 12.7f } }, false, "output_original", - "I8" + "U8" }, { { 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -12.7f }, { 12.8f } }, @@ -52,7 +52,7 @@ const std::vector params { 255ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 254.f }, { -12.7f }, { 12.7f } }, false, "output_original", - "I8" + "U8" }, { { 256ul, ngraph::Shape { 1 }, { 0.f }, { 255.f }, { -18.7f }, { 18.8f } }, @@ -60,7 +60,7 @@ const std::vector params { 255ul, ngraph::Shape { 1 }, { 0.f }, { 254.f }, { -18.7f }, { 18.7f } }, false, "output_original", - "I8" + "U8" }, }; diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/mat_mul_with_constant_transformation.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/mat_mul_with_constant_transformation.cpp index 2ae02ad1c38..e19d3959899 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/mat_mul_with_constant_transformation.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/low_precision_transformations/mat_mul_with_constant_transformation.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // @@ -20,7 +20,7 @@ std::vector testValues = { std::vector(32 * 10, 1.f), { 256ul, ngraph::Shape({}), {-12.8f}, {12.7f}, {-12.8f}, {12.7f} }, "matMul/1", - "I8" + "U8" } }; diff --git a/inference-engine/tests/functional/plugin/shared/include/execution_graph_tests/runtime_precision.hpp b/inference-engine/tests/functional/plugin/shared/include/execution_graph_tests/runtime_precision.hpp new file mode 100644 index 00000000000..840a0f8b40a --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/execution_graph_tests/runtime_precision.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +#include "shared_test_classes/base/layer_test_utils.hpp" +#include "ngraph_functions/builders.hpp" + +namespace ExecutionGraphTests { + +std::shared_ptr makeEltwiseFunction(const std::vector& inputPrecisions); +std::shared_ptr makeFakeQuantizeReluFunction(const std::vector& inputPrecisions); +std::shared_ptr makeFakeQuantizeBinaryConvolutionFunction(const std::vector &inputPrecisions); + +struct RuntimePrecisionSpecificParams { + std::function(const std::vector& inputPrecisions)> makeFunction; + std::vector inputPrecisions; + std::map expectedPrecisions; +}; + +using ExecGraphRuntimePrecisionParams = std::tuple< + RuntimePrecisionSpecificParams, + std::string // Target Device +>; + +class ExecGraphRuntimePrecision : public testing::WithParamInterface, + public CommonTestUtils::TestsCommon { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + std::string targetDevice; + std::shared_ptr fnPtr; + std::map expectedPrecisions; +protected: + void SetUp() override; + + void TearDown() override; +}; + +} // namespace ExecutionGraphTests diff --git a/inference-engine/tests/functional/plugin/shared/src/execution_graph_tests/exec_graph_serialization.cpp b/inference-engine/tests/functional/plugin/shared/src/execution_graph_tests/exec_graph_serialization.cpp index 36a059c0a91..46c25e74fff 100644 --- a/inference-engine/tests/functional/plugin/shared/src/execution_graph_tests/exec_graph_serialization.cpp +++ b/inference-engine/tests/functional/plugin/shared/src/execution_graph_tests/exec_graph_serialization.cpp @@ -139,7 +139,7 @@ const char expected_serialized_model[] = R"V0G0N( - + 1 @@ -147,7 +147,7 @@ const char expected_serialized_model[] = R"V0G0N( - + 1 @@ -155,7 +155,7 @@ const char expected_serialized_model[] = R"V0G0N( - + 1 @@ -163,7 +163,7 @@ const char expected_serialized_model[] = R"V0G0N( - + 1 @@ -179,7 +179,7 @@ const char expected_serialized_model[] = R"V0G0N( - + 1 @@ -201,7 +201,7 @@ const char expected_serialized_model[] = R"V0G0N( - + 1 @@ -217,7 +217,7 @@ const char expected_serialized_model[] = R"V0G0N( - + 1 diff --git a/inference-engine/tests/functional/plugin/shared/src/execution_graph_tests/runtime_precision.cpp b/inference-engine/tests/functional/plugin/shared/src/execution_graph_tests/runtime_precision.cpp new file mode 100644 index 00000000000..816002ceaa5 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/src/execution_graph_tests/runtime_precision.cpp @@ -0,0 +1,136 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common_test_utils/common_utils.hpp" +#include "functional_test_utils/plugin_cache.hpp" +#include "shared_test_classes/base/layer_test_utils.hpp" +#include "functional_test_utils/blob_utils.hpp" +#include "functional_test_utils/skip_tests_config.hpp" + +#include "execution_graph_tests/runtime_precision.hpp" + +namespace ExecutionGraphTests { + +std::shared_ptr makeEltwiseFunction(const std::vector& inputPrecisions) { + IE_ASSERT(inputPrecisions.size() == 2); + + auto inputs = ngraph::builder::makeParams(FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(inputPrecisions[0]), {{1, 16, 5, 4}}); + auto secondaryInput = ngraph::builder::makeInputLayer(FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(inputPrecisions[1]), + ngraph::helpers::InputLayerType::PARAMETER, {{1, 16, 5, 4}}); + inputs.push_back(std::dynamic_pointer_cast(secondaryInput)); + + auto eltwise = ngraph::builder::makeEltwise(inputs[0], secondaryInput, ngraph::helpers::EltwiseTypes::ADD); + eltwise->set_friendly_name("Eltwise"); + + auto function = std::make_shared(eltwise, inputs, "EltwiseWithTwoDynamicInputs"); + return function; +} + +std::shared_ptr makeFakeQuantizeReluFunction(const std::vector& inputPrecisions) { + IE_ASSERT(inputPrecisions.size() == 1); + + auto inputs = ngraph::builder::makeParams(FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(inputPrecisions[0]), {{1, 16, 5, 4}}); + + auto inputLowNode = ngraph::builder::makeConstant(ngraph::element::f32, {1, 1, 1, 1}, {0}); + auto inputHighNode = ngraph::builder::makeConstant(ngraph::element::f32, {1, 1, 1, 1}, {255}); + auto outputLowNode = ngraph::builder::makeConstant(ngraph::element::f32, {1, 1, 1, 1}, {0}); + auto outputHighNode = ngraph::builder::makeConstant(ngraph::element::f32, {1, 1, 1, 1}, {255}); + auto fakeQuantize = std::make_shared(inputs[0], inputLowNode, inputHighNode, outputLowNode, outputHighNode, 256); + fakeQuantize->set_friendly_name("FakeQuantize"); + + auto relu = std::make_shared(fakeQuantize); + relu->set_friendly_name("Relu"); + + auto function = std::make_shared(relu, inputs, "FakeQuantizeRelu"); + return function; +} + +std::shared_ptr makeFakeQuantizeBinaryConvolutionFunction(const std::vector &inputPrecisions) { + IE_ASSERT(inputPrecisions.size() == 1); + + auto inputs = ngraph::builder::makeParams(FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(inputPrecisions[0]), {{1, 16, 5, 4}}); + + auto inputLowNode = ngraph::builder::makeConstant(ngraph::element::f32, {1, 1, 1, 1}, {1}); + auto inputHighNode = ngraph::builder::makeConstant(ngraph::element::f32, {1, 1, 1, 1}, {1}); + auto outputLowNode = ngraph::builder::makeConstant(ngraph::element::f32, {1, 1, 1, 1}, {0}); + auto outputHighNode = ngraph::builder::makeConstant(ngraph::element::f32, {1, 1, 1, 1}, {1}); + auto fakeQuantize = std::make_shared(inputs[0], inputLowNode, inputHighNode, outputLowNode, outputHighNode, 2); + fakeQuantize->set_friendly_name("FakeQuantize"); + + auto binConv = ngraph::builder::makeBinaryConvolution(fakeQuantize, {3, 3}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, ngraph::op::PadType::EXPLICIT, 32, 0); + binConv->set_friendly_name("BinaryConvolution"); + + auto function = std::make_shared(binConv, inputs, "FakeQuantizeBinaryConvolution"); + return function; +} + +std::string ExecGraphRuntimePrecision::getTestCaseName(testing::TestParamInfo obj) { + RuntimePrecisionSpecificParams specificParams; + std::string targetDevice; + std::tie(specificParams, targetDevice) = obj.param; + + std::ostringstream result; + result << "Function=" << specificParams.makeFunction(specificParams.inputPrecisions)->get_friendly_name() << "_"; + result << "InPrcs=" << CommonTestUtils::vec2str(specificParams.inputPrecisions) << "_"; + result << "targetDevice=" << targetDevice; + + return result.str(); +} + +void ExecGraphRuntimePrecision::SetUp() { + RuntimePrecisionSpecificParams specificParams; + std::tie(specificParams, targetDevice) = this->GetParam(); + expectedPrecisions = specificParams.expectedPrecisions; + fnPtr = specificParams.makeFunction(specificParams.inputPrecisions); +} + +void ExecGraphRuntimePrecision::TearDown() { +} + +TEST_P(ExecGraphRuntimePrecision, CheckRuntimePrecision) { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + + InferenceEngine::CNNNetwork cnnNet(fnPtr); + auto ie = PluginCache::get().ie(); + auto execNet = ie->LoadNetwork(cnnNet, targetDevice); + const auto execGraph = execNet.GetExecGraphInfo().getFunction(); + + auto ops = execGraph->get_ops(); + for (auto expectedPrc : expectedPrecisions) { + auto opIter = std::find_if(ops.begin(), ops.end(), [&expectedPrc](std::shared_ptr op) { + return op->get_friendly_name() == expectedPrc.first; + }); + + if (opIter == ops.end()) + FAIL() << "Execution graph doesn't contain node with name: " << expectedPrc.first; + + const auto& rtInfo = opIter->get()->get_rt_info(); + const auto& rtIter = rtInfo.find("runtimePrecision"); + + if (rtIter == rtInfo.end()) + FAIL() << "Runtime precision is not found for node: " << opIter->get()->get_friendly_name(); + + const auto rtPrecisionPtr = ngraph::as_type_ptr>(rtIter->second); + + if (expectedPrc.second.name() != rtPrecisionPtr->get()) + FAIL() << "`" << expectedPrc.first << "' node runtime precision mismatch: actual = " << + expectedPrc.second.name() << ", expected = " << rtPrecisionPtr->get(); + } + + fnPtr.reset(); +}; + +} // namespace ExecutionGraphTests diff --git a/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp b/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp index 9fc0d0895a9..6c5dabc8039 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2020 Intel Corporation +// Copyright (C) 2019-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // #include @@ -449,17 +449,10 @@ std::string LayerTestsCommon::getRuntimePrecision(const std::string& layerName) const auto& rtInfo = op->get_rt_info(); const auto& it = rtInfo.find("runtimePrecision"); - if (it == rtInfo.end()) { - // WA: CPU impl doesn't contain runtimePrecision attribute - const auto& it1 = rtInfo.find("primitiveType"); - const auto rtPrecisionPtr = ngraph::as_type_ptr>(it1->second); - const std::string kernel = rtPrecisionPtr->get(); - const std::string kernelPrecision = kernel.substr(kernel.find_last_of("_") + 1ul); - return kernelPrecision; - } else { - const auto rtPrecisionPtr = ngraph::as_type_ptr>(it->second); - return rtPrecisionPtr->get(); - } + IE_ASSERT(it != rtInfo.end()) << "Runtime precision is not found for node: " << name; + + const auto rtPrecisionPtr = ngraph::as_type_ptr>(it->second); + return rtPrecisionPtr->get(); } }