Fix infer hanging
authorAnatoliy Talamanov <anatoliy.talamanov@intel.com>
Sat, 24 Apr 2021 15:02:35 +0000 (18:02 +0300)
committerAnatoliy Talamanov <anatoliy.talamanov@intel.com>
Sat, 24 Apr 2021 15:02:35 +0000 (18:02 +0300)
modules/gapi/src/backends/ie/giebackend.cpp
modules/gapi/test/infer/gapi_infer_ie_test.cpp

index 13daf5d6df8b09351bb8514a9ee128a243871042..820ee8e11ce797800808f8bd2fbe794fbc526c28 100644 (file)
@@ -530,10 +530,11 @@ public:
     explicit RequestPool(std::vector<InferenceEngine::InferRequest>&& requests);
 
     void execute(Task&& t);
-    void waitAndShutdown();
+    void waitAll();
 
 private:
     void callback(Task task, InferenceEngine::InferRequest& request, size_t id);
+    void setup();
 
     QueueClass<size_t>                         m_idle_ids;
     std::vector<InferenceEngine::InferRequest> m_requests;
@@ -542,11 +543,15 @@ private:
 // RequestPool implementation //////////////////////////////////////////////
 cv::gimpl::ie::RequestPool::RequestPool(std::vector<InferenceEngine::InferRequest>&& requests)
     : m_requests(std::move(requests)) {
-        for (size_t i = 0; i < m_requests.size(); ++i) {
-            m_idle_ids.push(i);
-        }
+        setup();
     }
 
+void cv::gimpl::ie::RequestPool::setup() {
+    for (size_t i = 0; i < m_requests.size(); ++i) {
+        m_idle_ids.push(i);
+    }
+}
+
 void cv::gimpl::ie::RequestPool::execute(cv::gimpl::ie::RequestPool::Task&& t) {
     size_t id = 0u;
     m_idle_ids.pop(id);
@@ -566,12 +571,13 @@ void cv::gimpl::ie::RequestPool::callback(cv::gimpl::ie::RequestPool::Task task,
 }
 
 // NB: Not thread-safe.
-void cv::gimpl::ie::RequestPool::waitAndShutdown() {
+void cv::gimpl::ie::RequestPool::waitAll() {
     // NB: It will be blocked if at least one request is busy.
     for (size_t i = 0; i < m_requests.size(); ++i) {
         size_t id = 0u;
         m_idle_ids.pop(id);
     }
+    setup();
 }
 
 // GCPUExcecutable implementation //////////////////////////////////////////////
@@ -632,7 +638,7 @@ void cv::gimpl::ie::GIEExecutable::run(cv::gimpl::GIslandExecutable::IInput  &in
     if (cv::util::holds_alternative<cv::gimpl::EndOfStream>(in_msg))
     {
         // (3) Wait until all passed task are done.
-        m_reqPool->waitAndShutdown();
+        m_reqPool->waitAll();
         out.post(cv::gimpl::EndOfStream{});
         return;
     }
@@ -671,7 +677,7 @@ void cv::gimpl::ie::GIEExecutable::run(cv::gimpl::GIslandExecutable::IInput  &in
     // (5) In non-streaming mode need to wait until the all tasks are done
     // FIXME: Is there more graceful way to handle this case ?
     if (!m_gm.metadata().contains<Streaming>()) {
-        m_reqPool->waitAndShutdown();
+        m_reqPool->waitAll();
     }
 }
 
index 366b7b18f29dd65d353b63fb5bca213796fbcc8f..4ea33f7713d0c7c96c6807287fd5e3ff6924b8ff 100644 (file)
@@ -2005,6 +2005,29 @@ TEST_F(InferWithReshapeNV12, TestInferListYUV)
     // Validate
     validate();
 }
+
+TEST_F(ROIList, CallInferMultipleTimes)
+{
+    cv::GArray<cv::Rect> rr;
+    cv::GMat in;
+    cv::GArray<cv::GMat> age, gender;
+    std::tie(age, gender) = cv::gapi::infer<AgeGender>(rr, in);
+    cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
+
+    auto pp = cv::gapi::ie::Params<AgeGender> {
+        params.model_path, params.weights_path, params.device_id
+    }.cfgOutputLayers({ "age_conv3", "prob" });
+
+    auto cc = comp.compile(cv::descr_of(cv::gin(m_in_mat, m_roi_list)),
+                           cv::compile_args(cv::gapi::networks(pp)));
+
+    for (int i = 0; i < 10; ++i) {
+        cc(cv::gin(m_in_mat, m_roi_list), cv::gout(m_out_gapi_ages, m_out_gapi_genders));
+    }
+
+    validate();
+}
+
 } // namespace opencv_test
 
 #endif //  HAVE_INF_ENGINE