From 2a3cdba724aaf9871b988f8d7887c1899afb0f6d Mon Sep 17 00:00:00 2001 From: Anatoliy Talamanov Date: Tue, 3 Nov 2020 20:47:05 +0300 Subject: [PATCH] Merge pull request #18701 from TolyaTalamanov:at/introduce-config-for-ie-params Expand ie::Params to support config * Add config to IE params * Add test * Remove comments from tests * Rename to pluginConfig * Add one more overloads for pluginConfig * Add more tests --- .../gapi/include/opencv2/gapi/infer/ie.hpp | 34 +++++- modules/gapi/src/backends/ie/giebackend.cpp | 4 +- .../gapi/test/infer/gapi_infer_ie_test.cpp | 102 ++++++++++++++++++ 3 files changed, 135 insertions(+), 5 deletions(-) diff --git a/modules/gapi/include/opencv2/gapi/infer/ie.hpp b/modules/gapi/include/opencv2/gapi/infer/ie.hpp index a8bc0bb05d..53e31fbb09 100644 --- a/modules/gapi/include/opencv2/gapi/infer/ie.hpp +++ b/modules/gapi/include/opencv2/gapi/infer/ie.hpp @@ -11,6 +11,7 @@ #include #include #include // tuple, tuple_size +#include #include #include @@ -42,6 +43,8 @@ enum class TraitAs: int IMAGE //!< G-API traits an associated cv::Mat as an image so creates an "image" blob (NCHW/NHWC, etc) }; +using IEConfig = std::map; + namespace detail { struct ParamDesc { std::string model_path; @@ -63,6 +66,7 @@ namespace detail { enum class Kind { Load, Import }; Kind kind; bool is_generic; + IEConfig config; }; } // namespace detail @@ -86,7 +90,8 @@ public: , std::tuple_size::value // num_in , std::tuple_size::value // num_out , detail::ParamDesc::Kind::Load - , false} { + , false + , {}} { }; Params(const std::string &model, @@ -95,7 +100,8 @@ public: , std::tuple_size::value // num_in , std::tuple_size::value // num_out , detail::ParamDesc::Kind::Import - , false} { + , false + , {}} { }; Params& cfgInputLayers(const typename PortCfg::In &ll) { @@ -121,6 +127,16 @@ public: return *this; } + Params& pluginConfig(IEConfig&& cfg) { + desc.config = std::move(cfg); + return *this; + } + + Params& pluginConfig(const IEConfig& cfg) { + desc.config = cfg; + return *this; + } + // BEGIN(G-API's network parametrization API) GBackend backend() const { return cv::gapi::ie::backend(); } std::string tag() const { return Net::tag(); } @@ -138,15 +154,25 @@ public: const std::string &model, const std::string &weights, const std::string &device) - : desc{ model, weights, device, {}, {}, {}, 0u, 0u, detail::ParamDesc::Kind::Load, true}, m_tag(tag) { + : desc{ model, weights, device, {}, {}, {}, 0u, 0u, detail::ParamDesc::Kind::Load, true, {}}, m_tag(tag) { }; Params(const std::string &tag, const std::string &model, const std::string &device) - : desc{ model, {}, device, {}, {}, {}, 0u, 0u, detail::ParamDesc::Kind::Import, true}, m_tag(tag) { + : desc{ model, {}, device, {}, {}, {}, 0u, 0u, detail::ParamDesc::Kind::Import, true, {}}, m_tag(tag) { }; + Params& pluginConfig(IEConfig&& cfg) { + desc.config = std::move(cfg); + return *this; + } + + Params& pluginConfig(const IEConfig& cfg) { + desc.config = cfg; + return *this; + } + // BEGIN(G-API's network parametrization API) GBackend backend() const { return cv::gapi::ie::backend(); } std::string tag() const { return m_tag; } diff --git a/modules/gapi/src/backends/ie/giebackend.cpp b/modules/gapi/src/backends/ie/giebackend.cpp index c66fa44361..85c0236ff1 100644 --- a/modules/gapi/src/backends/ie/giebackend.cpp +++ b/modules/gapi/src/backends/ie/giebackend.cpp @@ -185,7 +185,8 @@ struct IEUnit { inputs = net.getInputsInfo(); outputs = net.getOutputsInfo(); } else if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import) { - this_plugin = cv::gimpl::ie::wrap::getPlugin(params); + this_plugin = cv::gimpl::ie::wrap::getPlugin(params); + this_plugin.SetConfig(params.config); this_network = cv::gimpl::ie::wrap::importNetwork(this_plugin, params); // FIXME: ICNNetwork returns InputsDataMap/OutputsDataMap, // but ExecutableNetwork returns ConstInputsDataMap/ConstOutputsDataMap @@ -225,6 +226,7 @@ struct IEUnit { // FIXME: In case importNetwork for fill inputs/outputs need to obtain ExecutableNetwork, but // for loadNetwork they can be obtained by using readNetwork non_const_this->this_plugin = cv::gimpl::ie::wrap::getPlugin(params); + non_const_this->this_plugin.SetConfig(params.config); non_const_this->this_network = cv::gimpl::ie::wrap::loadNetwork(non_const_this->this_plugin, net, params); } diff --git a/modules/gapi/test/infer/gapi_infer_ie_test.cpp b/modules/gapi/test/infer/gapi_infer_ie_test.cpp index 3125705365..547c7c7d33 100644 --- a/modules/gapi/test/infer/gapi_infer_ie_test.cpp +++ b/modules/gapi/test/infer/gapi_infer_ie_test.cpp @@ -403,6 +403,108 @@ TEST(TestAgeGenderIE, GenericInfer) normAssert(cv::gapi::ie::util::to_ocv(ie_gender), gapi_gender, "Test gender output"); } +TEST(TestAgeGenderIE, InvalidConfigGeneric) +{ + initDLDTDataPath(); + + std::string model_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.xml"); + std::string weights_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.bin"); + std::string device_id = "CPU"; + + // Configure & run G-API + cv::GMat in; + GInferInputs inputs; + inputs["data"] = in; + + auto outputs = cv::gapi::infer("age-gender-generic", inputs); + auto age = outputs.at("age_conv3"); + auto gender = outputs.at("prob"); + cv::GComputation comp(cv::GIn(in), cv::GOut(age, gender)); + + auto pp = cv::gapi::ie::Params{"age-gender-generic", + model_path, + weights_path, + device_id}.pluginConfig({{"unsupported_config", "some_value"}}); + + EXPECT_ANY_THROW(comp.compile(cv::GMatDesc{CV_8U,3,cv::Size{320, 240}}, + cv::compile_args(cv::gapi::networks(pp)))); +} + +TEST(TestAgeGenderIE, CPUConfigGeneric) +{ + initDLDTDataPath(); + + std::string model_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.xml"); + std::string weights_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.bin"); + std::string device_id = "CPU"; + + // Configure & run G-API + cv::GMat in; + GInferInputs inputs; + inputs["data"] = in; + + auto outputs = cv::gapi::infer("age-gender-generic", inputs); + auto age = outputs.at("age_conv3"); + auto gender = outputs.at("prob"); + cv::GComputation comp(cv::GIn(in), cv::GOut(age, gender)); + + auto pp = cv::gapi::ie::Params{"age-gender-generic", + model_path, + weights_path, + device_id}.pluginConfig({{"ENFORCE_BF16", "NO"}}); + + EXPECT_NO_THROW(comp.compile(cv::GMatDesc{CV_8U,3,cv::Size{320, 240}}, + cv::compile_args(cv::gapi::networks(pp)))); +} + +TEST(TestAgeGenderIE, InvalidConfig) +{ + initDLDTDataPath(); + + std::string model_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.xml"); + std::string weights_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.bin"); + std::string device_id = "CPU"; + + using AGInfo = std::tuple; + G_API_NET(AgeGender, , "test-age-gender"); + + cv::GMat in; + cv::GMat age, gender; + std::tie(age, gender) = cv::gapi::infer(in); + cv::GComputation comp(cv::GIn(in), cv::GOut(age, gender)); + + auto pp = cv::gapi::ie::Params { + model_path, weights_path, device_id + }.cfgOutputLayers({ "age_conv3", "prob" }).pluginConfig({{"unsupported_config", "some_value"}}); + + EXPECT_ANY_THROW(comp.compile(cv::GMatDesc{CV_8U,3,cv::Size{320, 240}}, + cv::compile_args(cv::gapi::networks(pp)))); +} + +TEST(TestAgeGenderIE, CPUConfig) +{ + initDLDTDataPath(); + + std::string model_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.xml"); + std::string weights_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.bin"); + std::string device_id = "CPU"; + + using AGInfo = std::tuple; + G_API_NET(AgeGender, , "test-age-gender"); + + cv::GMat in; + cv::GMat age, gender; + std::tie(age, gender) = cv::gapi::infer(in); + cv::GComputation comp(cv::GIn(in), cv::GOut(age, gender)); + + auto pp = cv::gapi::ie::Params { + model_path, weights_path, device_id + }.cfgOutputLayers({ "age_conv3", "prob" }).pluginConfig({{"ENFORCE_BF16", "NO"}}); + + EXPECT_NO_THROW(comp.compile(cv::GMatDesc{CV_8U,3,cv::Size{320, 240}}, + cv::compile_args(cv::gapi::networks(pp)))); +} + } // namespace opencv_test #endif // HAVE_INF_ENGINE