mv_machine_learning: introduce _status member to remaining tasks
authorVibhav Aggarwal <v.aggarwal@samsung.com>
Wed, 28 Aug 2024 06:37:29 +0000 (15:37 +0900)
committerKwanghoon Son <k.son@samsung.com>
Thu, 29 Aug 2024 04:16:18 +0000 (13:16 +0900)
[Issue type] bug fix

Introduce _status member to tasks other than ImageClassification
in a way similar to this patch[1].

[1] https://review.tizen.org/gerrit/#/c/platform/core/api/mediavision/+/316729/

Change-Id: Ie80450d4048436cb69c82d7fa79f9c9861ad67f2
Signed-off-by: Vibhav Aggarwal <v.aggarwal@samsung.com>
mv_machine_learning/image_segmentation/include/ImageSegmentation.h
mv_machine_learning/image_segmentation/src/ImageSegmentation.cpp
mv_machine_learning/landmark_detection/include/LandmarkDetection.h
mv_machine_learning/landmark_detection/src/LandmarkDetection.cpp
mv_machine_learning/object_detection/include/ObjectDetection.h
mv_machine_learning/object_detection/src/ObjectDetection.cpp
mv_machine_learning/object_detection_3d/include/ObjectDetection3d.h
mv_machine_learning/object_detection_3d/src/ObjectDetection3d.cpp

index 4f48595684081ca0c1a5aef44c2c0c1ce2dab04d..3dfb7b6a4c3d09f7737dc7167a7be71d6d700507 100644 (file)
@@ -41,11 +41,16 @@ namespace mediavision
 {
 namespace machine_learning
 {
+namespace image_segmentation
+{
+enum class WorkingStatus { NONE, CONFIGURED, PREPARED, INFERENCED, RESULT_FETCHED };
+}
 template<typename T> class ImageSegmentation : public IImageSegmentation
 {
 private:
        std::unique_ptr<AsyncManager<T, ImageSegmentationResult> > _async_manager;
        ImageSegmentationResult _current_result {};
+       image_segmentation::WorkingStatus _status { image_segmentation::WorkingStatus::NONE };
 
        void loadLabel();
        void getEngineList();
index 55870eb1398f17153ee881db5ce0d9dc10b92372..de36f49e05a74b706268a00ad7576efcf13d87f2 100644 (file)
@@ -29,6 +29,7 @@ using namespace mediavision::inference;
 using namespace MediaVision::Common;
 using namespace mediavision::common;
 using namespace mediavision::machine_learning::exception;
+using namespace mediavision::machine_learning::image_segmentation;
 
 namespace mediavision
 {
@@ -176,10 +177,15 @@ template<typename T> void ImageSegmentation<T>::configure()
        int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to bind a backend engine.");
+
+       _status = WorkingStatus::CONFIGURED;
 }
 
 template<typename T> void ImageSegmentation<T>::prepare()
 {
+       if (_status < WorkingStatus::CONFIGURED)
+               throw InvalidOperation("Model is not configured yet.");
+
        int ret = _inference->configureInputMetaInfo(_config->getInputMetaMap());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to configure input tensor info from meta file.");
@@ -196,6 +202,8 @@ template<typename T> void ImageSegmentation<T>::prepare()
                throw InvalidOperation("Fail to load model files.");
 
        configurePreprocess();
+
+       _status = WorkingStatus::PREPARED;
 }
 
 template<typename T> shared_ptr<MetaInfo> ImageSegmentation<T>::getInputMetaInfo()
@@ -254,11 +262,18 @@ template<typename T> void ImageSegmentation<T>::inference(vector<vector<T> > &in
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to run inference");
 
+       // Here status can be higher than PREPARED in case async manager is used.
+       if (_status == WorkingStatus::PREPARED)
+               _status = WorkingStatus::INFERENCED;
+
        LOGI("LEAVE");
 }
 
 template<typename T> void ImageSegmentation<T>::perform(mv_source_h &mv_src)
 {
+       if (_status < WorkingStatus::PREPARED)
+               throw InvalidOperation("The model is not prepared");
+
        vector<vector<T> > inputVectors(1);
 
        _preprocess.run<T>(mv_src, inputVectors[0]);
@@ -268,6 +283,9 @@ template<typename T> void ImageSegmentation<T>::perform(mv_source_h &mv_src)
 
 template<typename T> void ImageSegmentation<T>::performAsync(ImageSegmentationInput &input)
 {
+       if (_status < WorkingStatus::PREPARED)
+               throw InvalidOperation("The model is not prepared");
+
        if (!_async_manager) {
                _async_manager = make_unique<AsyncManager<T, ImageSegmentationResult> >([this]() {
                        AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
@@ -295,10 +313,13 @@ template<typename T> ImageSegmentationResult &ImageSegmentation<T>::getOutput()
                        throw InvalidOperation("Object detection has been already destroyed so invalid operation.");
 
                _current_result = _async_manager->pop();
+               _status = WorkingStatus::RESULT_FETCHED;
        } else {
-               // TODO. Check if inference request is completed or not here.
-               //       If not then throw an exception.
+               if (_status < WorkingStatus::INFERENCED)
+                       throw InvalidOperation("Inference not called or failed.");
+
                _current_result = result();
+               _status = WorkingStatus::RESULT_FETCHED;
        }
 
        return _current_result;
@@ -306,6 +327,9 @@ template<typename T> ImageSegmentationResult &ImageSegmentation<T>::getOutput()
 
 template<typename T> ImageSegmentationResult &ImageSegmentation<T>::getOutputCache()
 {
+       if (_status < WorkingStatus::RESULT_FETCHED)
+               throw InvalidOperation("Result not fetched.");
+
        return _current_result;
 }
 
index 0fb5774eb2ec67d26d57745b7847ab3b809d8067..d029162fc787880c9bd958b2fc828ca09a127c78 100644 (file)
@@ -36,12 +36,17 @@ namespace mediavision
 {
 namespace machine_learning
 {
+namespace landmark_detection
+{
+enum class WorkingStatus { NONE, CONFIGURED, PREPARED, INFERENCED, RESULT_FETCHED };
+}
 template<typename T> class LandmarkDetection : public ILandmarkDetection
 {
 private:
        std::unique_ptr<AsyncManager<T, LandmarkDetectionResult> > _async_manager;
        LandmarkDetectionResult _current_result {};
        LandmarkDetectionTaskType _task_type;
+       landmark_detection::WorkingStatus _status { landmark_detection::WorkingStatus::NONE };
 
        void loadLabel();
        void getEngineList();
index 54bbf4beef35cc0981a17abdf17f386ced7a3aaf..1e26b83cce8b5de9e11765332896627fbf9ff7da 100644 (file)
@@ -29,6 +29,7 @@ using namespace mediavision::inference;
 using namespace MediaVision::Common;
 using namespace mediavision::common;
 using namespace mediavision::machine_learning::exception;
+using namespace mediavision::machine_learning::landmark_detection;
 
 namespace mediavision
 {
@@ -178,10 +179,15 @@ template<typename T> void LandmarkDetection<T>::configure()
        int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to bind a backend engine.");
+
+       _status = WorkingStatus::CONFIGURED;
 }
 
 template<typename T> void LandmarkDetection<T>::prepare()
 {
+       if (_status < WorkingStatus::CONFIGURED)
+               throw InvalidOperation("Model is not configured yet.");
+
        int ret = _inference->configureInputMetaInfo(_config->getInputMetaMap());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to configure input tensor info from meta file.");
@@ -198,6 +204,8 @@ template<typename T> void LandmarkDetection<T>::prepare()
                throw InvalidOperation("Fail to load model files.");
 
        configurePreprocess();
+
+       _status = WorkingStatus::PREPARED;
 }
 
 template<typename T> shared_ptr<MetaInfo> LandmarkDetection<T>::getInputMetaInfo()
@@ -256,11 +264,18 @@ template<typename T> void LandmarkDetection<T>::inference(vector<vector<T> > &in
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to run inference");
 
+       // Here status can be higher than PREPARED in case async manager is used.
+       if (_status == WorkingStatus::PREPARED)
+               _status = WorkingStatus::INFERENCED;
+
        LOGI("LEAVE");
 }
 
 template<typename T> void LandmarkDetection<T>::perform(mv_source_h &mv_src)
 {
+       if (_status < WorkingStatus::PREPARED)
+               throw InvalidOperation("The model is not prepared");
+
        vector<vector<T> > inputVectors(1);
 
        _preprocess.run<T>(mv_src, inputVectors[0]);
@@ -275,10 +290,13 @@ template<typename T> LandmarkDetectionResult &LandmarkDetection<T>::getOutput()
                        throw InvalidOperation("landmark detection has been already destroyed so invalid operation.");
 
                _current_result = _async_manager->pop();
+               _status = WorkingStatus::RESULT_FETCHED;
        } else {
-               // TODO. Check if inference request is completed or not here.
-               //       If not then throw an exception.
+               if (_status < WorkingStatus::INFERENCED)
+                       throw InvalidOperation("Inference not called or failed.");
+
                _current_result = result();
+               _status = WorkingStatus::RESULT_FETCHED;
        }
 
        return _current_result;
@@ -286,11 +304,17 @@ template<typename T> LandmarkDetectionResult &LandmarkDetection<T>::getOutput()
 
 template<typename T> LandmarkDetectionResult &LandmarkDetection<T>::getOutputCache()
 {
+       if (_status < WorkingStatus::RESULT_FETCHED)
+               throw InvalidOperation("Result not fetched.");
+
        return _current_result;
 }
 
 template<typename T> void LandmarkDetection<T>::performAsync(LandmarkDetectionInput &input)
 {
+       if (_status < WorkingStatus::PREPARED)
+               throw InvalidOperation("The model is not prepared");
+
        if (!_async_manager) {
                _async_manager = make_unique<AsyncManager<T, LandmarkDetectionResult> >([this]() {
                        AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
index 0ee398c94319c797769e563ca418c3d58b513cd0..0fd91392d348d6a893cf23bcbe1dd8fe243e1aeb 100644 (file)
@@ -41,12 +41,17 @@ namespace mediavision
 {
 namespace machine_learning
 {
+namespace object_detection
+{
+enum class WorkingStatus { NONE, CONFIGURED, PREPARED, INFERENCED, RESULT_FETCHED };
+}
 template<typename T> class ObjectDetection : public IObjectDetection
 {
 private:
        ObjectDetectionTaskType _task_type { ObjectDetectionTaskType::OBJECT_DETECTION_TASK_NONE };
        std::unique_ptr<AsyncManager<T, ObjectDetectionResult> > _async_manager;
        ObjectDetectionResult _current_result;
+       object_detection::WorkingStatus _status { object_detection::WorkingStatus::NONE };
 
        void loadLabel();
        void getEngineList();
index d2d346e8e66feef4a27f1f0363a800d388a402db..50c7a416d0926c45e3eba3cb6a22b3b1d97ffeac 100644 (file)
@@ -29,6 +29,7 @@ using namespace mediavision::inference;
 using namespace MediaVision::Common;
 using namespace mediavision::common;
 using namespace mediavision::machine_learning::exception;
+using namespace mediavision::machine_learning::object_detection;
 
 namespace mediavision
 {
@@ -178,10 +179,15 @@ template<typename T> void ObjectDetection<T>::configure()
        int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to bind a backend engine.");
+
+       _status = WorkingStatus::CONFIGURED;
 }
 
 template<typename T> void ObjectDetection<T>::prepare()
 {
+       if (_status < WorkingStatus::CONFIGURED)
+               throw InvalidOperation("Model is not configured yet.");
+
        int ret = _inference->configureInputMetaInfo(_config->getInputMetaMap());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to configure input tensor info from meta file.");
@@ -198,6 +204,8 @@ template<typename T> void ObjectDetection<T>::prepare()
                throw InvalidOperation("Fail to load model files.");
 
        configurePreprocess();
+
+       _status = WorkingStatus::PREPARED;
 }
 
 template<typename T> shared_ptr<MetaInfo> ObjectDetection<T>::getInputMetaInfo()
@@ -256,11 +264,18 @@ template<typename T> void ObjectDetection<T>::inference(vector<vector<T> > &inpu
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to run inference");
 
+       // Here status can be higher than PREPARED in case async manager is used.
+       if (_status == WorkingStatus::PREPARED)
+               _status = WorkingStatus::INFERENCED;
+
        LOGI("LEAVE");
 }
 
 template<typename T> void ObjectDetection<T>::perform(mv_source_h &mv_src)
 {
+       if (_status < WorkingStatus::PREPARED)
+               throw InvalidOperation("The model is not prepared");
+
        vector<vector<T> > inputVectors(1);
 
        _preprocess.run<T>(mv_src, inputVectors[0]);
@@ -270,6 +285,9 @@ template<typename T> void ObjectDetection<T>::perform(mv_source_h &mv_src)
 
 template<typename T> void ObjectDetection<T>::performAsync(ObjectDetectionInput &input)
 {
+       if (_status < WorkingStatus::PREPARED)
+               throw InvalidOperation("The model is not prepared");
+
        if (!_async_manager) {
                _async_manager = make_unique<AsyncManager<T, ObjectDetectionResult> >([this]() {
                        AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
@@ -297,10 +315,13 @@ template<typename T> ObjectDetectionResult &ObjectDetection<T>::getOutput()
                        throw InvalidOperation("Object detection has been already destroyed so invalid operation.");
 
                _current_result = _async_manager->pop();
+               _status = WorkingStatus::RESULT_FETCHED;
        } else {
-               // TODO. Check if inference request is completed or not here.
-               //       If not then throw an exception.
+               if (_status < WorkingStatus::INFERENCED)
+                       throw InvalidOperation("Inference not called or failed.");
+
                _current_result = result();
+               _status = WorkingStatus::RESULT_FETCHED;
        }
 
        return _current_result;
@@ -308,6 +329,9 @@ template<typename T> ObjectDetectionResult &ObjectDetection<T>::getOutput()
 
 template<typename T> ObjectDetectionResult &ObjectDetection<T>::getOutputCache()
 {
+       if (_status < WorkingStatus::RESULT_FETCHED)
+               throw InvalidOperation("Result not fetched.");
+
        return _current_result;
 }
 
index fb941d65299ff899cb85ab54e499de784cd853bd..724d931ec7726f15df8072c5902978f6effde7df 100644 (file)
@@ -35,11 +35,16 @@ namespace mediavision
 {
 namespace machine_learning
 {
+namespace object_detection_3d
+{
+enum class WorkingStatus { NONE, CONFIGURED, PREPARED, INFERENCED, RESULT_FETCHED };
+}
 template<typename T> class ObjectDetection3d : public IObjectDetection3d
 {
 private:
        ObjectDetection3dTaskType _task_type;
        ObjectDetection3dResult _current_result;
+       object_detection_3d::WorkingStatus _status { object_detection_3d::WorkingStatus::NONE };
 
        void loadLabel();
        void getEngineList();
index abc8f6be2c9c068a95bf2951eb1c536661c3f926..d972b962fb6d9453710d6a346ee0ef4ddfb714ac 100644 (file)
@@ -29,6 +29,7 @@ using namespace mediavision::inference;
 using namespace MediaVision::Common;
 using namespace mediavision::common;
 using namespace mediavision::machine_learning::exception;
+using namespace mediavision::machine_learning::object_detection_3d;
 
 namespace mediavision
 {
@@ -163,10 +164,15 @@ template<typename T> void ObjectDetection3d<T>::configure()
        int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to bind a backend engine.");
+
+       _status = WorkingStatus::CONFIGURED;
 }
 
 template<typename T> void ObjectDetection3d<T>::prepare()
 {
+       if (_status < WorkingStatus::CONFIGURED)
+               throw InvalidOperation("Model is not configured yet.");
+
        int ret = _inference->configureInputMetaInfo(_config->getInputMetaMap());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to configure input tensor info from meta file.");
@@ -183,6 +189,8 @@ template<typename T> void ObjectDetection3d<T>::prepare()
                throw InvalidOperation("Fail to load model files.");
 
        configurePreprocess();
+
+       _status = WorkingStatus::PREPARED;
 }
 
 template<typename T> shared_ptr<MetaInfo> ObjectDetection3d<T>::getInputMetaInfo()
@@ -241,11 +249,18 @@ template<typename T> void ObjectDetection3d<T>::inference(vector<vector<T> > &in
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to run inference");
 
+       // Here status can be higher than PREPARED in case async manager is used.
+       if (_status == WorkingStatus::PREPARED)
+               _status = WorkingStatus::INFERENCED;
+
        LOGI("LEAVE");
 }
 
 template<typename T> void ObjectDetection3d<T>::perform(mv_source_h &mv_src)
 {
+       if (_status < WorkingStatus::PREPARED)
+               throw InvalidOperation("The model is not prepared");
+
        vector<vector<T> > inputVectors(1);
 
        _preprocess.run<T>(mv_src, inputVectors[0]);
@@ -282,13 +297,21 @@ template<typename T> void ObjectDetection3d<T>::getOutputTensor(string &target_n
 template<typename T> ObjectDetection3dResult &ObjectDetection3d<T>::getOutput()
 {
        // TODO. consider for async API later.
+
+       if (_status < WorkingStatus::INFERENCED)
+               throw InvalidOperation("Inference not called or failed.");
+
        _current_result = result();
+       _status = WorkingStatus::RESULT_FETCHED;
 
        return _current_result;
 }
 
 template<typename T> ObjectDetection3dResult &ObjectDetection3d<T>::getOutputCache()
 {
+       if (_status < WorkingStatus::RESULT_FETCHED)
+               throw InvalidOperation("Result not fetched.");
+
        return _current_result;
 }