task_manager: add new test case 70/313570/7
authorVibhav Aggarwal <v.aggarwal@samsung.com>
Fri, 28 Jun 2024 01:12:26 +0000 (10:12 +0900)
committerInki Dae <inki.dae@samsung.com>
Mon, 1 Jul 2024 02:04:49 +0000 (02:04 +0000)
This testcase checks whether the nodes after bridge node
are run if bridge node dependencies fail.
The graph looks as follows:
input -----> OD ----- bridge -----> IC -----bridge -----> IC -----> endpoint ----> output
             |                                                          |
             ------------------------------------------------------------

The input is a blank image so that object detection fails.
The intended behaviour is that endpoint node should not
be invoked.

Change-Id: I8cceb0710c6aed206d718c1ed10f18f3f952439a
Signed-off-by: Vibhav Aggarwal <v.aggarwal@samsung.com>
test/services/test_task_manager.cpp

index cba9d13edb2471eab8856051c888b1f07c35fd43..24bdd765f3de2f8c391b00a29529581746ec1349 100644 (file)
@@ -35,7 +35,7 @@ using namespace singleo;
 using namespace singleo::inference;
 using namespace singleo::services;
 
-void BridgeNodeCallback(INode *node)
+void BridgeNodeCallbackFD(INode *node)
 {
        auto callbackNode = dynamic_cast<CallbackNode *>(node);
        auto &inputBuffer = callbackNode->getInputBuffer();
@@ -94,7 +94,7 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphAShouldWork)
                taskManager->addNode(face_detection_node);
 
                auto bridge_node = make_shared<BridgeNode>("bridge");
-               bridge_node->setCb(BridgeNodeCallback);
+               bridge_node->setCb(BridgeNodeCallbackFD);
                bridge_node->addDependency(face_detection_node);
                taskManager->addNode(bridge_node);
 
@@ -160,7 +160,7 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphBShouldWork)
                taskManager->addNode(face_detection_node_b);
 
                auto bridge_node = make_shared<BridgeNode>("bridge");
-               bridge_node->setCb(BridgeNodeCallback);
+               bridge_node->setCb(BridgeNodeCallbackFD);
                bridge_node->addDependency(face_detection_node_a);
                bridge_node->addDependency(face_detection_node_b);
                taskManager->addNode(bridge_node);
@@ -235,7 +235,7 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphCShouldWork)
                taskManager->addNode(face_detection_node);
 
                auto bridge_node = make_shared<BridgeNode>("bridge");
-               bridge_node->setCb(BridgeNodeCallback);
+               bridge_node->setCb(BridgeNodeCallbackFD);
                bridge_node->addDependency(face_detection_node);
                taskManager->addNode(bridge_node);
 
@@ -312,7 +312,7 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphDShouldWork)
                taskManager->addNode(face_detection_node_a);
 
                auto bridge_node = make_shared<BridgeNode>("bridge");
-               bridge_node->setCb(BridgeNodeCallback);
+               bridge_node->setCb(BridgeNodeCallbackFD);
                bridge_node->addDependency(face_detection_node_a);
                taskManager->addNode(bridge_node);
 
@@ -360,3 +360,116 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphDShouldWork)
                taskManager->clear();
        }
 }
+
+void BridgeNodeCallbackOD(INode *node)
+{
+       auto callbackNode = dynamic_cast<CallbackNode *>(node);
+       auto &inputBuffer = callbackNode->getInputBuffer();
+       auto inputBaseData = inputBuffer->getInputs()[0]->clone();
+       auto inputImage = dynamic_pointer_cast<ImageDataType>(inputBaseData);
+
+       cv::Mat cv_input_image(cv::Size(inputImage->width, inputImage->height), CV_MAKETYPE(CV_8U, 3), inputImage->ptr);
+
+       auto outputBuffer = make_shared<SharedBuffer>();
+
+       auto &results = callbackNode->results();
+       for (auto r : results) {
+               ASSERT_EQ(r->_type, ResultType::OBJECT_DETECTION);
+
+               auto obj_r = dynamic_pointer_cast<OdResultType>(r);
+
+               for (auto rect : obj_r->_rects) {
+                       cv::Mat roi(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+                       cv::Mat cropped;
+                       cv_input_image(roi).copyTo(cropped);
+
+                       auto image_data = make_shared<ImageDataType>();
+
+                       image_data->width = cropped.cols;
+                       image_data->height = cropped.rows;
+                       image_data->byte_per_pixel = cropped.channels();
+                       image_data->ptr = cropped.data;
+
+                       outputBuffer->addInput(static_pointer_cast<BaseDataType>(image_data));
+               }
+       }
+       // Object detection failed so do not go forward.
+       if (outputBuffer->getInputs().size() == 0)
+               return;
+       callbackNode->setOutputBuffer(outputBuffer);
+}
+
+void BridgeNodeCallbackIC(INode *node)
+{
+       auto callbackNode = dynamic_cast<CallbackNode *>(node);
+       auto &inputBuffer = callbackNode->getInputBuffer();
+       auto newBaseData = inputBuffer->getInputs()[0]->clone();
+
+       // For now, just copy the input to the output without any processing.
+       auto outputBuffer = make_shared<SharedBuffer>();
+       outputBuffer->addInput(newBaseData);
+       callbackNode->setOutputBuffer(outputBuffer);
+}
+
+// GraphE:
+//         input -----> object_detection ----- bridge -----> IC -----bridge -----> IC -----> endpoint ----> output
+//                            |                                                               |
+//                            -----------------------------------------------------------------
+TEST(SingloTaskManager, MultipleNodesBasedGraphEShouldWork)
+{
+       cv::Mat cv_image(640, 480, CV_8UC3, cv::Scalar(0, 0, 0)); // Create a black image so that object detection fails
+       ASSERT_FALSE(cv_image.empty());
+
+       ImageDataType image_data;
+
+       image_data.width = cv_image.cols;
+       image_data.height = cv_image.rows;
+       image_data.byte_per_pixel = cv_image.channels();
+       image_data.ptr = cv_image.data;
+
+       auto factory = InferenceTaskFactory::instance().create("MvInferenceTaskFactory");
+
+       auto taskManager = make_unique<TaskManager>();
+       const unsigned int maxIteration = 10;
+
+       for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
+               taskManager->addInput(image_data);
+
+               auto object_detection_node = make_shared<InferenceNode>("object_detection");
+               object_detection_node->setInferenceTask(factory->createObjectDetection());
+               taskManager->addNode(object_detection_node);
+
+               auto bridge_node_1 = make_shared<BridgeNode>("bridge_1");
+               bridge_node_1->setCb(BridgeNodeCallbackOD);
+               bridge_node_1->addDependency(object_detection_node);
+               taskManager->addNode(bridge_node_1);
+
+               auto image_classification_node_1 = make_shared<InferenceNode>("image_classification_1");
+               image_classification_node_1->setInferenceTask(factory->createImageClassification());
+               image_classification_node_1->addDependency(bridge_node_1);
+               taskManager->addNode(image_classification_node_1);
+
+               auto bridge_node_2 = make_shared<BridgeNode>("bridge_2");
+               bridge_node_2->setCb(BridgeNodeCallbackIC);
+               bridge_node_2->addDependency(image_classification_node_1);
+               taskManager->addNode(bridge_node_2);
+
+               auto image_classification_node_2 = make_shared<InferenceNode>("image_classification_2");
+               image_classification_node_2->setInferenceTask(factory->createImageClassification());
+               image_classification_node_2->addDependency(bridge_node_2);
+               taskManager->addNode(image_classification_node_2);
+
+               int endpoint_node_run = 0;
+               auto endpoint_node = make_shared<EndpointNode>("endpoint");
+               endpoint_node->addDependency(object_detection_node);
+               endpoint_node->addDependency(image_classification_node_2);
+               endpoint_node->setCb([&](INode *node) { endpoint_node_run += 1; });
+               taskManager->addNode(endpoint_node);
+
+               taskManager->run();
+
+               ASSERT_EQ(endpoint_node_run, 0); // Since OD node fails, endpoint node should not be run.
+
+               taskManager->clear();
+       }
+}
\ No newline at end of file