1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 07:43:03 +04:00

Merge pull request #21731 from AsyaPronina:asyadev/fix_new_stream_event

Fixed handling of new stream, especially for stateful OCV kernels

* Fixed handling of new stream, especially for stateful OCV kernels

* Removed duplication from StateInitOnce tests

* Addressed review comments for PR #21731
- Fixed explanation comments
- Expanded test for stateful OCV kernels in Regular mode

* Addressed review comments for PR #21731
- Moved notification about new stream to the constructor
- Added test on state reset for Regular mode

* Addresed review comments

* Addressed review comments

Co-authored-by: Ruslan Garnov <ruslan.garnov@intel.com>
This commit is contained in:
Anastasiya(Asya) Pronina
2022-04-04 20:39:02 +03:00
committed by GitHub
parent 4754b0e253
commit 91a5e75151
5 changed files with 213 additions and 39 deletions
+14 -18
View File
@@ -27,6 +27,7 @@
#include "api/gbackend_priv.hpp" // FIXME: Make it part of Backend SDK!
#include "utils/itt.hpp"
#include "logger.hpp"
// FIXME: Is there a way to take a typed graph (our GModel),
// and create a new typed graph _ATOP_ of that (by extending with a couple of
@@ -113,8 +114,6 @@ cv::gimpl::GCPUExecutable::GCPUExecutable(const ade::Graph &g,
}
}
makeReshape();
// For each stateful kernel call 'setup' user callback to initialize state.
setupKernelStates();
}
// FIXME: Document what it does
@@ -190,18 +189,23 @@ void cv::gimpl::GCPUExecutable::makeReshape() {
void cv::gimpl::GCPUExecutable::reshape(ade::Graph&, const GCompileArgs& args) {
m_compileArgs = args;
makeReshape();
// Signal to reset stateful kernels` state.
// There can be no handleNewStream() call to set this flag
// if user didn't call GCompiled`s prepareForNewStream()
m_newStreamStarted = true;
// TODO: Add an input meta sensitivity flag to stateful kernels.
// When reshape() happens, reset state for meta-sensitive kernels only
if (!m_nodesToStates.empty()) {
std::call_once(m_warnFlag,
[](){
GAPI_LOG_WARNING(NULL,
"\nGCPUExecutable::reshape was called. Resetting states of stateful kernels.");
});
setupKernelStates();
}
}
void cv::gimpl::GCPUExecutable::handleNewStream()
{
// Signal to reset stateful kernels` state.
// No need to call reshape() here since it'll
// be called automatically if input meta was changed
m_newStreamStarted = true;
// In case if new video-stream happens - for each stateful kernel
// call 'setup' user callback to re-initialize state.
setupKernelStates();
}
void cv::gimpl::GCPUExecutable::run(std::vector<InObj> &&input_objs,
@@ -231,14 +235,6 @@ void cv::gimpl::GCPUExecutable::run(std::vector<InObj> &&input_objs,
}
}
// In case if new video-stream happens - for each stateful kernel
// call 'setup' user callback to re-initialize state.
if (m_newStreamStarted)
{
setupKernelStates();
m_newStreamStarted = false;
}
// OpenCV backend execution is not a rocket science at all.
// Simply invoke our kernels in the proper order.
GConstGCPUModel gcm(m_g);
@@ -56,8 +56,8 @@ class GCPUExecutable final: public GIslandExecutable
// Actual data of all resources in graph (both internal and external)
Mag m_res;
// Flag which identifies if new stream was started
bool m_newStreamStarted = false;
// A flag for call_once() (used for log warnings)
std::once_flag m_warnFlag;
GArg packArg(const GArg &arg);
void setupKernelStates();
+11 -7
View File
@@ -30,10 +30,11 @@ cv::gimpl::GExecutor::GExecutor(std::unique_ptr<ade::Graph> &&g_model)
// 1. Allocate all internal resources first (NB - CPU plugin doesn't do it)
// 2. Put input/output GComputation arguments to the storage
// 3. For every Island, prepare vectors of input/output parameter descs
// 4. Iterate over a list of operations (sorted in the topological order)
// 5. For every operation, form a list of input/output data objects
// 6. Run GIslandExecutable
// 7. writeBack
// 4. Ask every GIslandExecutable to prepare its internal states for a new stream
// 5. Iterate over a list of operations (sorted in the topological order)
// 6. For every operation, form a list of input/output data objects
// 7. Run GIslandExecutable
// 8. writeBack
auto sorted = m_gim.metadata().get<ade::passes::TopologicalSortData>();
for (auto nh : sorted.nodes())
@@ -82,6 +83,9 @@ cv::gimpl::GExecutor::GExecutor(std::unique_ptr<ade::Graph> &&g_model)
break;
} // switch(kind)
} // for(gim nodes)
// (4)
prepareForNewStream();
}
namespace cv {
@@ -401,10 +405,10 @@ void cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs &&args)
magazine::resetInternalData(m_res, data);
}
// Run the script
// Run the script (5)
for (auto &op : m_ops)
{
// (5), (6)
// (6), (7)
Input i{m_res, op.in_objects};
Output o{m_res, op.out_objects};
op.isl_exec->run(i, o);
@@ -412,7 +416,7 @@ void cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs &&args)
o.verify();
}
// (7)
// (8)
for (auto it : ade::util::zip(ade::util::toRange(proto.outputs),
ade::util::toRange(args.outObjs)))
{
@@ -1564,7 +1564,7 @@ void cv::gimpl::GStreamingExecutor::setSource(GRunArgs &&ins)
}
}
};
bool islandsRecompiled = false;
const auto new_meta = cv::descr_of(ins); // 0
if (gm.metadata().contains<OriginalInputMeta>()) // (1)
{
@@ -1586,8 +1586,6 @@ void cv::gimpl::GStreamingExecutor::setSource(GRunArgs &&ins)
}
update_int_metas(); // (7)
m_reshapable = util::make_optional(is_reshapable);
islandsRecompiled = true;
}
else // (8)
{
@@ -1709,14 +1707,8 @@ void cv::gimpl::GStreamingExecutor::setSource(GRunArgs &&ins)
island_meta_info = GIslandModel::traceIslandName(op.nh, m_gim);
#endif // OPENCV_WITH_ITT
// If Island Executable is recompiled, all its stuff including internal kernel states
// are recreated and re-initialized automatically.
// But if not, we should notify Island Executable about new started stream to let it update
// its internal variables.
if (!islandsRecompiled)
{
op.isl_exec->handleNewStream();
}
// Notify island executable about a new stream to let it update its internal variables.
op.isl_exec->handleNewStream();
m_threads.emplace_back(islandActorThread,
op.in_objects,