Merge pull request #21579 from TolyaTalamanov:at/handle-errors-in-iebackend

[G-API] Handle errors in IEBackend & modeling tool

* Handle errors in IEBackend & modeling tool

* Handle exceptions in callback

* Add const cv to exception
pull/21596/head
Anatoliy Talamanov 3 years ago committed by GitHub
parent 3eeec4faae
commit 619b6dfae3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      modules/gapi/samples/pipeline_modeling_tool.cpp
  2. 1
      modules/gapi/samples/pipeline_modeling_tool/pipeline.hpp
  3. 87
      modules/gapi/src/backends/ie/giebackend.cpp
  4. 2
      modules/gapi/src/logger.hpp

@ -379,10 +379,15 @@ int main(int argc, char* argv[]) {
}
// NB: Execute pipelines
std::vector<std::exception_ptr> eptrs(pipelines.size(), nullptr);
std::vector<std::thread> threads(pipelines.size());
for (size_t i = 0; i < pipelines.size(); ++i) {
threads[i] = std::thread([&, i]() {
pipelines[i]->run(work_time_ms);
try {
pipelines[i]->run(work_time_ms);
} catch (...) {
eptrs[i] = std::current_exception();
}
});
}
@ -393,12 +398,22 @@ int main(int argc, char* argv[]) {
for (size_t i = 0; i < threads.size(); ++i) {
threads[i].join();
}
for (size_t i = 0; i < threads.size(); ++i) {
if (eptrs[i] != nullptr) {
try {
std::rethrow_exception(eptrs[i]);
} catch (std::exception& e) {
throw std::logic_error(pipelines[i]->name() + " failed: " + e.what());
}
}
if (file.is_open()) {
file << pipelines[i]->report().toStr(true) << std::endl;
}
std::cout << pipelines[i]->report().toStr() << std::endl;
}
} catch (std::exception& e) {
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
throw;
}

@ -46,6 +46,7 @@ public:
void compile();
void run(double work_time_ms);
const PerfReport& report() const;
const std::string& name() const { return m_name;}
virtual ~Pipeline() = default;

@ -2,7 +2,7 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018-2021 Intel Corporation
// Copyright (C) 2018-2022 Intel Corporation
#include "precomp.hpp"
@ -216,6 +216,39 @@ inline void copyFromIE(const IE::Blob::Ptr &blob, MatType &mat) {
}
}
template <typename MapT>
void checkLayerNames(const MapT& network_map,
const std::vector<std::string>& layer_names,
const std::string& layer_type) {
for (const auto& layer_name : layer_names) {
const auto it = network_map.find(layer_name);
if (it == network_map.end()) {
std::stringstream ss;
ss << "Failed to find " << layer_type << " layer with name: "
<< "\"" << layer_name << "\"" << std::endl;
ss << "Network " << layer_type << " layers: " << std::endl;
for (const auto& p : network_map) {
const auto& desc = p.second->getTensorDesc();
ss << p.first << " : " << desc.getPrecision()
<< " / " << desc.getLayout() << std::endl;
}
throw std::logic_error(ss.str());
}
}
}
template <typename MapT>
void checkInputLayerNames(const MapT& network_map,
const std::vector<std::string>& layer_names) {
checkLayerNames(network_map, layer_names, "input");
}
template <typename MapT>
void checkOutputLayerNames(const MapT& network_map,
const std::vector<std::string>& layer_names) {
checkLayerNames(network_map, layer_names, "output");
}
// IE-specific metadata, represents a network with its parameters
struct IEUnit {
static const char *name() { return "IEModelConfig"; }
@ -293,6 +326,16 @@ struct IEUnit {
params.num_in &&
"Number of layers to reshape must be less than or equal to number of inputs");
}
if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
checkInputLayerNames(net.getInputsInfo(), params.input_names);
checkOutputLayerNames(net.getOutputsInfo(), params.output_names);
} else if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import) {
checkInputLayerNames(this_network.GetInputsInfo(), params.input_names);
checkOutputLayerNames(this_network.GetOutputsInfo(), params.output_names);
} else {
cv::util::throw_error(std::logic_error("Unsupported ParamDesc::Kind"));
}
}
// This method is [supposed to be] called at Island compilation stage
@ -627,7 +670,10 @@ public:
void waitAll();
private:
void callback(Task task, InferenceEngine::InferRequest& request, size_t id);
void callback(Task task,
size_t id,
IE::InferRequest request,
IE::StatusCode code);
void setup();
QueueClass<size_t> m_idle_ids;
@ -652,21 +698,38 @@ void cv::gimpl::ie::RequestPool::execute(cv::gimpl::ie::RequestPool::Task&& t) {
auto& request = m_requests[id];
using namespace std::placeholders;
using callback_t = std::function<void(IE::InferRequest, IE::StatusCode)>;
request.SetCompletionCallback(
std::bind(&cv::gimpl::ie::RequestPool::callback, this, t, std::ref(request), id));
static_cast<callback_t>(
std::bind(&cv::gimpl::ie::RequestPool::callback, this,
t, id, _1, _2)));
t.run(request);
}
void cv::gimpl::ie::RequestPool::callback(cv::gimpl::ie::RequestPool::Task task,
InferenceEngine::InferRequest& request,
size_t id) {
task.callback(request);
// NB: IE::InferRequest keeps the callback until the new one is set.
// Since user's callback might keep resources that should be released,
// need to destroy its after execution.
// Let's set the empty one to cause the destruction of a callback.
request.SetCompletionCallback([](){});
m_idle_ids.push(id);
size_t id,
IE::InferRequest request,
IE::StatusCode code) {
// FIXME: Any exception which is arrised here must not leave this callback,
// because it won't be handled.
try {
if (code != IE::StatusCode::OK) {
throw std::logic_error("IE::InferRequest finished with not OK status");
}
task.callback(request);
// NB: IE::InferRequest keeps the callback until the new one is set.
// Since user's callback might keep resources that should be released,
// need to destroy its after execution.
// Let's set the empty one to cause the destruction of a callback.
request.SetCompletionCallback([](){});
m_idle_ids.push(id);
} catch (const std::exception& e) {
GAPI_LOG_FATAL(NULL, "Callback failed with error: " << e.what());
//FIXME: Exception CAN't be rethrown here, since this callback works
// in separate IE thread and such scenarios aren't handled properly in
// G-API so far.
}
}
// NB: Not thread-safe.

@ -14,10 +14,12 @@
# define GAPI_LOG_INFO(tag, ...) CV_LOG_INFO(tag, __VA_ARGS__)
# define GAPI_LOG_WARNING(tag, ...) CV_LOG_WARNING(tag, __VA_ARGS__)
# define GAPI_LOG_DEBUG(tag, ...) CV_LOG_DEBUG(tag, __VA_ARGS__)
# define GAPI_LOG_FATAL(tag, ...) CV_LOG_FATAL(tag, __VA_ARGS__)
#else
# define GAPI_LOG_INFO(tag, ...)
# define GAPI_LOG_WARNING(tag, ...)
# define GAPI_LOG_DEBUG(tag, ...)
# define GAPI_LOG_FATAL(tag, ...)
#endif // !defined(GAPI_STANDALONE)

Loading…
Cancel
Save