diff --git a/modules/gapi/samples/pipeline_modeling_tool.cpp b/modules/gapi/samples/pipeline_modeling_tool.cpp index 7a0f94655c..a10cb5f052 100644 --- a/modules/gapi/samples/pipeline_modeling_tool.cpp +++ b/modules/gapi/samples/pipeline_modeling_tool.cpp @@ -190,6 +190,15 @@ CallParams read(const cv::FileNode& fn) { return CallParams{std::move(name), static_cast(call_every_nth)}; } +template +std::map readMap(const cv::FileNode& fn) { + std::map map; + for (auto item : fn) { + map.emplace(item.name(), read(item)); + } + return map; +} + template <> InferParams read(const cv::FileNode& fn) { auto name = @@ -200,7 +209,7 @@ InferParams read(const cv::FileNode& fn) { params.device = check_and_read(fn, "device", name); params.input_layers = readList(fn, "input_layers", name); params.output_layers = readList(fn, "output_layers", name); - + params.config = readMap(fn["config"]); return params; } @@ -309,13 +318,13 @@ int main(int argc, char* argv[]) { cv::FileStorage::MEMORY); } - std::map config; + std::map gconfig; if (!load_config.empty()) { - loadConfig(load_config, config); + loadConfig(load_config, gconfig); } // NB: Takes priority over config from file if (!cached_dir.empty()) { - config = + gconfig = std::map{{"CACHE_DIR", cached_dir}}; } @@ -371,7 +380,10 @@ int main(int argc, char* argv[]) { builder.addDummy(call_params, read(node_fn)); } else if (node_type == "Infer") { auto infer_params = read(node_fn); - infer_params.config = config; + RETHROW_WITH_MSG_IF_FAILED( + utils::intersectMapWith(infer_params.config, gconfig), + "Failed to combine global and local configs for Infer node: " + + call_params.name); builder.addInfer(call_params, infer_params); } else { throw std::logic_error("Unsupported node type: " + node_type); diff --git a/modules/gapi/samples/pipeline_modeling_tool/utils.hpp b/modules/gapi/samples/pipeline_modeling_tool/utils.hpp index c110bf3b47..c8f0101fe1 100644 --- a/modules/gapi/samples/pipeline_modeling_tool/utils.hpp +++ b/modules/gapi/samples/pipeline_modeling_tool/utils.hpp @@ -1,6 +1,8 @@ #ifndef OPENCV_GAPI_PIPELINE_MODELING_TOOL_UTILS_HPP #define OPENCV_GAPI_PIPELINE_MODELING_TOOL_UTILS_HPP +#include + #include #if defined(_WIN32) @@ -91,6 +93,26 @@ typename duration_t::rep timestamp() { return duration_cast(now.time_since_epoch()).count(); } +#define RETHROW_WITH_MSG_IF_FAILED(expr, msg) \ + try { \ + expr; \ + } catch (const std::exception& e) { \ + std::stringstream ss; \ + ss << msg << "\n caused by: " << e.what(); \ + throw std::logic_error(ss.str()); \ + } \ + +template +void intersectMapWith(std::map& target, const std::map& second) { + for (auto&& item : second) { + auto it = target.find(item.first); + if (it != target.end()) { + throw std::logic_error("Met already existing key: " + item.first); + } + target.insert(item); + } +} + } // namespace utils #endif // OPENCV_GAPI_PIPELINE_MODELING_TOOL_UTILS_HPP