mirror of
https://github.com/opencv/opencv.git
synced 2025-06-11 03:33:28 +08:00
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
This commit is contained in:
parent
3eeec4faae
commit
619b6dfae3
@ -379,10 +379,15 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NB: Execute pipelines
|
// NB: Execute pipelines
|
||||||
|
std::vector<std::exception_ptr> eptrs(pipelines.size(), nullptr);
|
||||||
std::vector<std::thread> threads(pipelines.size());
|
std::vector<std::thread> threads(pipelines.size());
|
||||||
for (size_t i = 0; i < pipelines.size(); ++i) {
|
for (size_t i = 0; i < pipelines.size(); ++i) {
|
||||||
threads[i] = std::thread([&, i]() {
|
threads[i] = std::thread([&, i]() {
|
||||||
|
try {
|
||||||
pipelines[i]->run(work_time_ms);
|
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) {
|
for (size_t i = 0; i < threads.size(); ++i) {
|
||||||
threads[i].join();
|
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()) {
|
if (file.is_open()) {
|
||||||
file << pipelines[i]->report().toStr(true) << std::endl;
|
file << pipelines[i]->report().toStr(true) << std::endl;
|
||||||
}
|
}
|
||||||
std::cout << pipelines[i]->report().toStr() << 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;
|
std::cout << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ public:
|
|||||||
void compile();
|
void compile();
|
||||||
void run(double work_time_ms);
|
void run(double work_time_ms);
|
||||||
const PerfReport& report() const;
|
const PerfReport& report() const;
|
||||||
|
const std::string& name() const { return m_name;}
|
||||||
|
|
||||||
virtual ~Pipeline() = default;
|
virtual ~Pipeline() = default;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// 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.
|
// 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"
|
#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
|
// IE-specific metadata, represents a network with its parameters
|
||||||
struct IEUnit {
|
struct IEUnit {
|
||||||
static const char *name() { return "IEModelConfig"; }
|
static const char *name() { return "IEModelConfig"; }
|
||||||
@ -293,6 +326,16 @@ struct IEUnit {
|
|||||||
params.num_in &&
|
params.num_in &&
|
||||||
"Number of layers to reshape must be less than or equal to number of inputs");
|
"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
|
// This method is [supposed to be] called at Island compilation stage
|
||||||
@ -627,7 +670,10 @@ public:
|
|||||||
void waitAll();
|
void waitAll();
|
||||||
|
|
||||||
private:
|
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();
|
void setup();
|
||||||
|
|
||||||
QueueClass<size_t> m_idle_ids;
|
QueueClass<size_t> m_idle_ids;
|
||||||
@ -652,14 +698,25 @@ void cv::gimpl::ie::RequestPool::execute(cv::gimpl::ie::RequestPool::Task&& t) {
|
|||||||
|
|
||||||
auto& request = m_requests[id];
|
auto& request = m_requests[id];
|
||||||
|
|
||||||
|
using namespace std::placeholders;
|
||||||
|
using callback_t = std::function<void(IE::InferRequest, IE::StatusCode)>;
|
||||||
request.SetCompletionCallback(
|
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);
|
t.run(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::gimpl::ie::RequestPool::callback(cv::gimpl::ie::RequestPool::Task task,
|
void cv::gimpl::ie::RequestPool::callback(cv::gimpl::ie::RequestPool::Task task,
|
||||||
InferenceEngine::InferRequest& request,
|
size_t 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);
|
task.callback(request);
|
||||||
// NB: IE::InferRequest keeps the callback until the new one is set.
|
// NB: IE::InferRequest keeps the callback until the new one is set.
|
||||||
// Since user's callback might keep resources that should be released,
|
// Since user's callback might keep resources that should be released,
|
||||||
@ -667,6 +724,12 @@ void cv::gimpl::ie::RequestPool::callback(cv::gimpl::ie::RequestPool::Task task,
|
|||||||
// Let's set the empty one to cause the destruction of a callback.
|
// Let's set the empty one to cause the destruction of a callback.
|
||||||
request.SetCompletionCallback([](){});
|
request.SetCompletionCallback([](){});
|
||||||
m_idle_ids.push(id);
|
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.
|
// NB: Not thread-safe.
|
||||||
|
@ -14,10 +14,12 @@
|
|||||||
# define GAPI_LOG_INFO(tag, ...) CV_LOG_INFO(tag, __VA_ARGS__)
|
# 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_WARNING(tag, ...) CV_LOG_WARNING(tag, __VA_ARGS__)
|
||||||
# define GAPI_LOG_DEBUG(tag, ...) CV_LOG_DEBUG(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
|
#else
|
||||||
# define GAPI_LOG_INFO(tag, ...)
|
# define GAPI_LOG_INFO(tag, ...)
|
||||||
# define GAPI_LOG_WARNING(tag, ...)
|
# define GAPI_LOG_WARNING(tag, ...)
|
||||||
# define GAPI_LOG_DEBUG(tag, ...)
|
# define GAPI_LOG_DEBUG(tag, ...)
|
||||||
|
# define GAPI_LOG_FATAL(tag, ...)
|
||||||
#endif // !defined(GAPI_STANDALONE)
|
#endif // !defined(GAPI_STANDALONE)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user