inference: apply self-registeration factory pattern 26/310126/3
authorInki Dae <inki.dae@samsung.com>
Tue, 23 Apr 2024 01:03:33 +0000 (10:03 +0900)
committerInki Dae <inki.dae@samsung.com>
Tue, 23 Apr 2024 05:54:09 +0000 (14:54 +0900)
Apply self-registeration factory pattern to inference service.

With this patch, InferenceServiceDefault and InferenceServiceExternal classes
will be registered to inference factory table in build time, and
it will create InferenceServiceDefault or InferenceServiceExternal class
with a given class name in runtime. Regarding this, this patch
modifies existing build script so that inference service directory
can be built-in.

This patch is just a previous step for applying abstract factory pattern
as we discussed.

Change-Id: Icb21dc066bdf940926a9e764e40a48a82ffefed5
Signed-off-by: Inki Dae <inki.dae@samsung.com>
16 files changed:
inference/CMakeLists.txt
inference/backends/CMakeLists.txt [deleted file]
inference/backends/mediavision/CMakeLists.txt [new file with mode: 0644]
inference/backends/mediavision/include/MvInferenceServiceFactory.h [new file with mode: 0644]
inference/backends/mediavision/src/MvInferenceServiceFactory.cpp [new file with mode: 0644]
inference/include/IInferenceServiceFactory.h [new file with mode: 0644]
inference/include/IInferenceServiceInterface.h
inference/include/InferenceServiceDefault.h
inference/include/InferenceServiceExternal.h
inference/include/InferenceServiceFactory.h [new file with mode: 0644]
inference/src/InferenceServiceDefault.cpp
inference/src/InferenceServiceExternal.cpp
packaging/singleo.spec
services/CMakeLists.txt
services/auto_zoom/CMakeLists.txt
services/auto_zoom/src/AutoZoom.cpp

index 42bab6ba3c25a2b465d32920e46cc4306272a5b6..5f0701e4d32f8077f4b79f08e64047de48652c4f 100644 (file)
@@ -1,19 +1,13 @@
-PROJECT("singleo_inference")
 CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
 
-ADD_SUBDIRECTORY(backends)
+SET(INFERENCE_DIRECTORY ${ROOT_DIRECTORY}/inference)
 
 IF (${USE_EXTERNAL_INFERENCE_SERVICE})
-    SET(SINGLEO_INFERENCE_HEADER_DIRECTORY "")
-    SET(SINGLEO_INFERENCE_SERVUCE_FILE "InferenceServiceExternal.cpp")
+    SET(SINGLEO_SERVICE_SOURCE_FILES ${SINGLEO_SERVICE_SOURCE_FILES} ${INFERENCE_DIRECTORY}/src/InferenceServiceExternal.cpp)
 ELSE()
-    SET(SINGLEO_INFERENCE_HEADER_DIRECTORY /usr/include/media backends/mediavision/include)
-    SET(SINGLEO_INFERENCE_SERVUCE_FILE "InferenceServiceDefault.cpp")
+    SET(SINGLEO_SERVICE_SOURCE_FILES ${SINGLEO_SERVICE_SOURCE_FILES} ${INFERENCE_DIRECTORY}/src/InferenceServiceDefault.cpp)
 ENDIF()
 
-FILE(GLOB SINGLEO_INFERENCE_SOURCE_FILES "${PROJECT_SOURCE_DIR}/src/${SINGLEO_INFERENCE_SERVUCE_FILE}")
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${SINGLEO_INFERENCE_SOURCE_FILES})
+INCLUDE(${INFERENCE_DIRECTORY}/backends/mediavision/CMakeLists.txt)
 
-TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE include ../common/include ${SINGLEO_INFERENCE_HEADER_DIRECTORY})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE singleo_inference_backend)
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
\ No newline at end of file
+LIST(APPEND INFERENCE_HEADER_LIST ${INFERENCE_HEADER_LIST} ${INFERENCE_DIRECTORY}/include)
diff --git a/inference/backends/CMakeLists.txt b/inference/backends/CMakeLists.txt
deleted file mode 100644 (file)
index 5e07a50..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 3.13)  
-PROJECT("singleo_inference_backend")
-
-FILE(GLOB MEDIAVISION_SOURCE_FILES "${PROJECT_SOURCE_DIR}/mediavision/src/*.cpp")
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${MEDIAVISION_SOURCE_FILES})
-
-FIND_PACKAGE(PkgConfig REQUIRED)
-PKG_CHECK_MODULES(${PROJECT_NAME}_DEP REQUIRED capi-media-vision)
-
-TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE ../include ../../common/include ../../log/include mediavision/include /usr/include/media)
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE mv_common singleo_log mv_inference mv_object_detection)
-
-# Install the library  
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/inference/backends/mediavision/CMakeLists.txt b/inference/backends/mediavision/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a32329e
--- /dev/null
@@ -0,0 +1,15 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
+
+FIND_PACKAGE(PkgConfig REQUIRED)
+PKG_CHECK_MODULES(${PROJECT_NAME}_DEP REQUIRED capi-media-vision)
+
+SET(INFERENCE_MEDIAVISION_BACKEND_DIRECTORY ${INFERENCE_DIRECTORY}/backends/mediavision)
+
+SET(SINGLEO_SERVICE_SOURCE_FILES
+    ${SINGLEO_SERVICE_SOURCE_FILES}
+    ${INFERENCE_MEDIAVISION_BACKEND_DIRECTORY}/src/MvFaceDetection.cpp
+    ${INFERENCE_MEDIAVISION_BACKEND_DIRECTORY}/src/MvObjectDetection.cpp
+)
+
+LIST(APPEND INFERENCE_LIBRARY_LIST ${INFERENCE_LIBRARY_LIST} mv_common mv_inference mv_object_detection)
+LIST(APPEND INFERENCE_HEADER_LIST ${INFERENCE_HEADER_LIST} ${INFERENCE_MEDIAVISION_BACKEND_DIRECTORY}/include /usr/include/media)
diff --git a/inference/backends/mediavision/include/MvInferenceServiceFactory.h b/inference/backends/mediavision/include/MvInferenceServiceFactory.h
new file mode 100644 (file)
index 0000000..7ab72c9
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MV_INFERENCE_SERVICE_FACTORY_H__
+#define __MV_INFERENCE_SERVICE_FACTORY_H__
+
+#include "IInferenceServiceFactory.h"
+
+namespace singleo
+{
+namespace inference
+{
+class MvInferenceServiceFactory : public IInferenceServiceFactory
+{
+private:
+       std::unique_ptr<IInferenceServiceInterface>createInferenceService(TaskType taskType);
+
+public:
+       MvInferenceServiceFactory() = default;
+       virtual ~MvInferenceServiceFactory() = default;
+
+       std::unique_ptr<IInferenceServiceInterface> createImageClassification() override;
+       std::unique_ptr<IInferenceServiceInterface> createObjectDetection() override;
+       std::unique_ptr<IInferenceServiceInterface> createFaceDetection() override;
+       std::unique_ptr<IInferenceServiceInterface> createFaceLandmarkDetection() override;
+};
+
+}
+}
+
+#endif
diff --git a/inference/backends/mediavision/src/MvInferenceServiceFactory.cpp b/inference/backends/mediavision/src/MvInferenceServiceFactory.cpp
new file mode 100644 (file)
index 0000000..b53abf6
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MvInferenceServiceFactory.h"
+#include "InferenceServiceDefault.h"
+#include "SingleoLog.h"
+#include "SingleoException.h"
+
+using namespace std;
+using namespace singleo::exception;
+
+namespace singleo
+{
+namespace inference
+{
+namespace backends
+{
+
+std::unique_ptr<IInferenceServiceInterface>MvInferenceServiceFactory::createInferenceService(TaskType taskType)
+{
+       auto service = make_unique<InferenceServiceDefault>();
+
+       service->configure(taskType);
+
+       return service;
+}
+
+std::unique_ptr<IInferenceServiceInterface> MvInferenceServiceFactory::createImageClassification()
+{
+       throw InvalidOperation("Interface not supported yet.");
+}
+
+std::unique_ptr<IInferenceServiceInterface> MvInferenceServiceFactory::createObjectDetection()
+{
+       return createInferenceService(TaskType::OBJECT_DETECTION);
+}
+
+std::unique_ptr<IInferenceServiceInterface> MvInferenceServiceFactory::createFaceDetection()
+{
+       return createInferenceService(TaskType::FACE_DETECTION);
+}
+
+std::unique_ptr<IInferenceServiceInterface> MvInferenceServiceFactory::createFaceLandmarkDetection()
+{
+       throw InvalidOperation("Interface not supported yet.");
+}
+
+}
+}
+}
diff --git a/inference/include/IInferenceServiceFactory.h b/inference/include/IInferenceServiceFactory.h
new file mode 100644 (file)
index 0000000..5dfdbbe
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IINFERENCE_SERVICE_FACTORY_H__
+#define __IINFERENCE_SERVICE_FACTORY_H__
+
+#include <memory>
+
+#include "IInferenceServiceInterface.h"
+
+namespace singleo
+{
+namespace inference
+{
+class IInferenceServiceFactory
+{
+public:
+       virtual ~IInferenceServiceFactory() {};
+
+       virtual std::unique_ptr<IInferenceServiceInterface> createImageClassification() = 0;
+       virtual std::unique_ptr<IInferenceServiceInterface> createObjectDetection() = 0;
+       virtual std::unique_ptr<IInferenceServiceInterface> createFaceDetection() = 0;
+       virtual std::unique_ptr<IInferenceServiceInterface> createFaceLandmarkDetection() = 0;
+}
+
+}
+}
+
+#endif
\ No newline at end of file
index 6acd6f5586d226fdb8bfe8e6523000167c89c1fb..3e5a0e86cdf6cf37336284621ccce9a5a512ebf8 100644 (file)
@@ -17,7 +17,8 @@
 #ifndef __IINFERENCE_SERVICE_INTERFACE_H__
 #define __IINFERENCE_SERVICE_INTERFACE_H__
 
-#include "IInferenceTaskInterface.h"
+#include "SingleoInferenceTypes.h"
+#include "SingleoCommonTypes.h"
 
 namespace singleo
 {
@@ -28,7 +29,7 @@ class IInferenceServiceInterface
 public:
        virtual ~IInferenceServiceInterface() {};
 
-       virtual void configure() = 0;
+       virtual void configure(TaskType task_type) = 0;
        virtual void prepare() = 0;
        virtual void invoke(BaseDataType &input, bool async = false) = 0;
        virtual BaseResultType &result() = 0;
index 77d0efd692d0f413d7d7c8db00bfcb2e5c1a2a99..a269b75bd31098a909c2c844b65bd3ed5a47442e 100644 (file)
@@ -31,12 +31,13 @@ class InferenceServiceDefault : public IInferenceServiceInterface
 {
 private:
        std::unique_ptr<IInferenceTaskInterface> _task;
+       static bool _registered;
 
 public:
-       explicit InferenceServiceDefault(TaskType task_type);
-       virtual ~InferenceServiceDefault();
+       InferenceServiceDefault() = default;
+       virtual ~InferenceServiceDefault() = default;
 
-       void configure() override;
+       void configure(TaskType task_type) override;
        void prepare() override;
        void invoke(BaseDataType &input, bool async = false) override;
        BaseResultType &result() override;
index 2df0f31e39d5f4f864b6f7be4e642858705921f2..955ae1d699698e57545989b36182187da9a42fe5 100644 (file)
@@ -32,7 +32,7 @@ public:
        explicit InferenceServiceExternal(TaskType task_type);
        virtual ~InferenceServiceExternal();
 
-       void configure() override;
+       void configure(TaskType task_type) override;
        void prepare() override;
        void invoke(BaseDataType &input, bool async = false) override;
        BaseResultType &result() override;
diff --git a/inference/include/InferenceServiceFactory.h b/inference/include/InferenceServiceFactory.h
new file mode 100644 (file)
index 0000000..bb2f099
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __INFERENCE_SERVICE_FACTORY_H__
+#define __INFERENCE_SERVICE_FACTORY_H__
+
+#include <unordered_map>
+#include <vector>
+#include <string>
+#include <memory>
+#include <stdexcept>
+#include "IInferenceServiceInterface.h"
+#include "SingleoException.h"
+#include "SingleoLog.h"
+
+namespace singleo
+{
+namespace inference
+{
+class InferenceServiceFactory
+{
+public:
+       using createFunc = std::unique_ptr<IInferenceServiceInterface> (*)();
+
+       static InferenceServiceFactory &instance()
+       {
+               static InferenceServiceFactory factory;
+               return factory;
+       }
+
+       std::unique_ptr<IInferenceServiceInterface> create(const std::string &name)
+       {
+               auto it = _inference_service_table.find(name);
+               if (it != _inference_service_table.end())
+                       return it->second();
+
+               throw singleo::exception::InvalidParameter("Invalid inference service.");
+       }
+
+       void registerBackend(const std::string &name, const createFunc &func)
+       {
+               _inference_service_table[name] = func;
+       }
+
+private:
+       InferenceServiceFactory() = default;
+       ~InferenceServiceFactory() = default;
+
+       std::unordered_map<std::string, createFunc> _inference_service_table;
+};
+
+template<typename ServiceType> bool registerInferenceService(const std::string &name)
+{
+       InferenceServiceFactory::instance().registerBackend(name, []() {
+               return std::unique_ptr<IInferenceServiceInterface>(new ServiceType());
+       });
+
+       return true;
+}
+
+}
+}
+
+#endif
\ No newline at end of file
index b6f058de991994434c396db518c3422b879f2d54..46d4c947d1bd50c18ee757ec20d14af8b139bfd4 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "InferenceServiceFactory.h"
 #include "InferenceServiceDefault.h"
 #include "MvObjectDetection.h"
 #include "MvFaceDetection.h"
@@ -25,7 +26,10 @@ namespace singleo
 {
 namespace inference
 {
-InferenceServiceDefault::InferenceServiceDefault(TaskType task_type)
+bool InferenceServiceDefault::_registered =
+               registerInferenceService<InferenceServiceDefault>("InferenceServiceDefault");
+
+void InferenceServiceDefault::configure(TaskType task_type)
 {
        // TODO. add other task types later.
        if (task_type != TaskType::OBJECT_DETECTION && task_type != TaskType::FACE_DETECTION)
@@ -39,13 +43,7 @@ InferenceServiceDefault::InferenceServiceDefault(TaskType task_type)
                _task = make_unique<MvFaceDetection>();
                break;
        }
-}
 
-InferenceServiceDefault::~InferenceServiceDefault()
-{}
-
-void InferenceServiceDefault::configure()
-{
        _task->configure();
 }
 
index 4b7abedd63a609cab6b6cedd318f7fdd36fc7a18..76fa63a579b58ddfde0ed62f201578db13382002 100644 (file)
@@ -28,7 +28,7 @@ InferenceServiceExternal::InferenceServiceExternal(TaskType task_type)
 InferenceServiceExternal::~InferenceServiceExternal()
 {}
 
-void InferenceServiceExternal::configure()
+void InferenceServiceExternal::configure(TaskType task_type)
 {
        throw runtime_error("Not support yet.");
 }
index 807103416e69d7ca153186c715773e61df20b38e..6d7e9aec0671e9f0f079eb43dbd4542343a85ef6 100644 (file)
@@ -83,8 +83,6 @@ rm -rf %{buildroot}
 %files devel
 %{_libdir}/pkgconfig/*.pc
 %{_libdir}/libsingleo_log.so
-%{_libdir}/libsingleo_inference.so
-%{_libdir}/libsingleo_inference_backend.so
 %{_libdir}/libsingleo_service.so
 %{_libdir}/libsingleo_visualizer.so
 
index 6e3886291ae3b1784e3ed7a5df131835c1e3fe49..c4fb763047da4cb9e2eb20d937852cb6470b0595 100644 (file)
@@ -7,6 +7,7 @@ FILE(GLOB SINGLEO_SERVICE_SOURCE_FILES "${PROJECT_SOURCE_DIR}/*.cpp"
                                        "${PROJECT_SOURCE_DIR}/../common/src/*.cpp")
 
 INCLUDE(${ROOT_DIRECTORY}/input/CMakeLists.txt)
+INCLUDE(${ROOT_DIRECTORY}/inference/CMakeLists.txt)
 
 IF (${USE_AUTOZOOM_API})
     INCLUDE(auto_zoom/CMakeLists.txt)
@@ -14,7 +15,7 @@ ENDIF()
 
 ADD_LIBRARY(${PROJECT_NAME} SHARED ${SINGLEO_SERVICE_SOURCE_FILES})
 
-TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE include common/include ${ROOT_DIRECTORY}/capi/ ${ROOT_DIRECTORY}/log/include ${ROOT_DIRECTORY}/inference/include ${ROOT_DIRECTORY}/common/include ${INPUT_HEADER_LIST} ${SERVICE_HEADER_LIST})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE opencv_core opencv_imgcodecs opencv_highgui opencv_videoio singleo_log ${SERVICE_LIBRARY_LIST})
+TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE include common/include ${ROOT_DIRECTORY}/capi/ ${ROOT_DIRECTORY}/log/include ${ROOT_DIRECTORY}/common/include ${INPUT_HEADER_LIST} ${INFERENCE_HEADER_LIST} ${SERVICE_HEADER_LIST})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE opencv_core opencv_imgcodecs opencv_highgui opencv_videoio singleo_log ${INFERENCE_LIBRARY_LIST} ${SERVICE_LIBRARY_LIST})
 
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
\ No newline at end of file
index 934f4090b4163ccbc06d3e3f472808945be2d4cb..230c5307eff0f4e3a4ca1b6184d2639f2fe6e55c 100644 (file)
@@ -4,5 +4,5 @@ SET(SINGLEO_SERVICE_SOURCE_FILES
     auto_zoom/src/Postprocessor.cpp
 )
 
-LIST(APPEND SERVICE_LIBRARY_LIST ${SERVICE_LIBRARY_LIST} singleo_inference)
+LIST(APPEND SERVICE_LIBRARY_LIST ${SERVICE_LIBRARY_LIST})
 LIST(APPEND SERVICE_HEADER_LIST ${SERVICE_HEADER_LIST} ${CMAKE_CURRENT_SOURCE_DIR}/auto_zoom/include)
\ No newline at end of file
index 2a5363b0f3e9bcc26c027135426fef5c333785eb..c6388d583c9ad18391df68ca1b1d177520b93e74 100644 (file)
@@ -17,7 +17,7 @@
 #include <algorithm>
 #include "SingleoException.h"
 #include "AutoZoom.h"
-#include "InferenceServiceDefault.h"
+#include "InferenceServiceFactory.h"
 #include "SingleoLog.h"
 #include "ImagePreprocessor.h"
 #include "ServiceFactory.h"
@@ -42,7 +42,7 @@ AutoZoom::AutoZoom(InputConfigBase &config)
 {
        // In default, we will use InferenceServiceDefault class to use Mediavision framework
        // for inference service. TODO. introduce meta config file approach later.
-       _inference_service = make_unique<InferenceServiceDefault>(_task_type);
+       _inference_service = InferenceServiceFactory::instance().create("InferenceServiceDefault");
 
        // Create InputCamera service if input service type is CAMERA.
        if (config._input_feed_type == InputFeedType::CAMERA) {
@@ -62,7 +62,7 @@ AutoZoom::AutoZoom(InputConfigBase &config)
                SINGLEO_LOGD("Camera input service has been initialized.");
        }
 
-       _inference_service->configure();
+       _inference_service->configure(_task_type);
        _inference_service->prepare();
        _postprocessor = make_unique<Postprocessor>();
 }