[ML][Single] Added manager file and implementation for openModel() 93/251893/7
authorPiotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/Samsung Electronics <p.kosko@samsung.com>
Wed, 20 Jan 2021 10:55:36 +0000 (11:55 +0100)
committerPiotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/Samsung Electronics <p.kosko@samsung.com>
Mon, 25 Jan 2021 08:53:36 +0000 (09:53 +0100)
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-273

[Verification] Code compiles without errors.
Checked in chrome console with few calls:
Success calls:
tizen.ml.single.openModel("documents/mobilenet_v1_1.0_224_quant.tflite")
tizen.ml.single.openModel("documents/mobilenet_v1_1.0_224_quant.tflite", null, null, "TENSORFLOW_LITE")
tizen.ml.single.openModel("documents/mobilenet_v1_1.0_224_quant.tflite", null, null, "TENSORFLOW_LITE", "ANY", true)

Fail for invalid or not-existing file:
tizen.ml.single.openModel("documents/fail.tflite") // Abort Error
tizen.ml.single.openModel("documents/notexisting") // NotFound
tizen.ml.single.openModel("notexisting") // NotFound

Change-Id: I8b2b89e60d8f265185d3ddcafcc224f4e5c15fa1

src/ml/js/ml_single.js
src/ml/ml.gyp
src/ml/ml_instance.cc
src/ml/ml_instance.h
src/ml/ml_single_manager.cc [new file with mode: 0644]
src/ml/ml_single_manager.h [new file with mode: 0644]
src/ml/ml_singleshot.cc [new file with mode: 0644]
src/ml/ml_singleshot.h [new file with mode: 0644]

index f9aa0d82a8025a46d5c01d61c04ef7c21d6ed1ef..22cf5ba94bcdc1c2d52a8a46ec5bfab1078e5be5 100755 (executable)
 var MachineLearningSingle = function() {};
 
 // MachineLearningSingle::openModel()
+var ValidOpenModelExceptions = [
+    'InvalidValuesError',
+    'NotFoundError',
+    'NotSupportedError',
+    'SecurityError',
+    'AbortError'
+];
+
+var NO_ID = -1;
+MachineLearningSingle.prototype.openModel = function() {
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'modelPath',
+            type: types_.STRING
+        },
+        {
+            name: 'inTensorsInfo',
+            type: types_.PLATFORM_OBJECT,
+            values: TensorsInfo,
+            optional: true,
+            nullable: true
+        },
+        {
+            name: 'outTensorsInfo',
+            type: types_.PLATFORM_OBJECT,
+            values: TensorsInfo,
+            optional: true,
+            nullable: true
+        },
+        {
+            name: 'fwType',
+            type: types_.ENUM,
+            values: Object.keys(NNFWType),
+            optional: true
+        },
+        {
+            name: 'hwType',
+            type: types_.ENUM,
+            values: Object.keys(HWType),
+            optional: true
+        },
+        {
+            name: 'isDynamicMode',
+            type: types_.BOOLEAN,
+            optional: true
+        }
+    ]);
+    try {
+        // get normalized URI of a file
+        args.modelPath = tizen.filesystem.toURI(args.modelPath);
+    } catch (e) {
+        throw new WebAPIException(WebAPIException.NOT_FOUND_ERR, 'Path is invalid');
+    }
+
+    var nativeArgs = {
+        modelPath: args.modelPath,
+        inTensorsInfo: args.inTensorsInfo ? args.inTensorsInfo._id : NO_ID,
+        outTensorsInfo: args.outTensorsInfo ? args.outTensorsInfo._id : NO_ID,
+        fwType: args.fwType ? args.fwType : 'ANY',
+        hwType: args.hwType ? args.hwType : 'ANY',
+        isDynamicMode: args.isDynamicMode ? args.isDynamicMode : false
+    };
+
+    var result = native_.callSync('MLSingleManagerOpenModel', nativeArgs);
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObjectAndValidate(
+            result,
+            ValidOpenModelExceptions,
+            AbortError
+        );
+    }
+
+    return new SingleShot(result.id);
+};
 
 // MachineLearningSingle::openModelAsync()
 
 // OpenModelSuccessCallback
 
 // SingleShot interface (input & output)
+var SingleShot = function(id) {
+    Object.defineProperties(this, {
+        _id: { value: id, writable: false, enumerable: false }
+    });
+};
 
 // SingleShot::invoke()
 
index a8fb82f2dddfe7814d3a015bfc5b546a74728ee4..62490a50ed83dba65aafff94d89cdf85c3ed51a8 100644 (file)
         #TODO pipeline Valve
         'ml_tensors_info_manager.cc',
         'ml_tensors_info_manager.h',
-        #TODO single SingleShotManager
-        #TODO single SingleShot
+        'ml_single_manager.cc',
+        'ml_single_manager.h',
+        'ml_singleshot.cc',
+        'ml_singleshot.h',
         'ml_utils.cc',
         'ml_utils.h',
       ],
index 1677d3890938ed6000f7aec82ee84d932d188728..260b3c32d62262e0e913dce7f1c3342776ef2ca1 100644 (file)
@@ -21,6 +21,7 @@
 #include "common/logger.h"
 #include "common/picojson.h"
 #include "common/platform_result.h"
+#include "common/tools.h"
 
 namespace extension {
 namespace ml {
@@ -89,7 +90,7 @@ MlInstance::MlInstance() : pipeline_manager_{this} {
   REGISTER_METHOD(MLTensorsInfoDispose);
 
   // Single API begin
-  // MachineLearningSingle::openModel()
+  REGISTER_METHOD(MLSingleManagerOpenModel);
   // MachineLearningSingle::openModelAsync()
   // OpenModelSuccessCallback
   // SingleShot input
@@ -534,7 +535,84 @@ void MlInstance::MLTensorsInfoDispose(const picojson::value& args, picojson::obj
 
 // Single API begin
 
-// MachineLearningSingle::openModel()
+// TODO move to the up section with field names
+namespace {
+const std::string kModelPath = "modelPath";
+const std::string kInTensorsInfo = "inTensorsInfo";
+const std::string kOutTensorsInfo = "outTensorsInfo";
+const std::string kFwType = "fwType";
+const std::string kHwType = "hwType";
+const std::string kIsDynamicMode = "isDynamicMode";
+
+const int kNoId = -1;
+}  //  namespace
+void MlInstance::MLSingleManagerOpenModel(const picojson::value& args, picojson::object& out) {
+  ScopeLogger("args: %s", args.serialize().c_str());
+  CHECK_ARGS(args, kModelPath, std::string, out);
+  CHECK_ARGS(args, kInTensorsInfo, double, out);
+  CHECK_ARGS(args, kOutTensorsInfo, double, out);
+  CHECK_ARGS(args, kFwType, std::string, out);
+  CHECK_ARGS(args, kHwType, std::string, out);
+  CHECK_ARGS(args, kIsDynamicMode, bool, out);
+
+  const auto& model_path = common::tools::ConvertUriToPath(args.get(kModelPath).get<std::string>());
+  PlatformResult result = common::tools::CheckFileAvailability(model_path);
+  if (!result) {
+    LogAndReportError(
+        PlatformResult(ErrorCode::NOT_FOUND_ERR, "File does not exist or is not accessible"), &out,
+        ("File does not exist or is not accessible: %s", model_path.c_str()));
+    return;
+  }
+
+  TensorsInfo* in_tensors_info = nullptr;
+  auto inTensorId = static_cast<int>(args.get(kInTensorsInfo).get<double>());
+  if (kNoId != inTensorId) {
+    in_tensors_info = GetTensorsInfoManager().GetTensorsInfo(inTensorId);
+    if (nullptr == in_tensors_info) {
+      LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
+                        ("Could not find TensorsInfo handle with given id: %d", inTensorId));
+      return;
+    }
+  }
+
+  TensorsInfo* out_tensors_info = nullptr;
+  auto outTensorId = static_cast<int>(args.get(kOutTensorsInfo).get<double>());
+  if (kNoId != outTensorId) {
+    out_tensors_info = GetTensorsInfoManager().GetTensorsInfo(outTensorId);
+    if (nullptr == out_tensors_info) {
+      LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
+                        ("Could not find TensorsInfo handle with given id: %d", outTensorId));
+      return;
+    }
+  }
+
+  ml_nnfw_type_e nnfw_e = ML_NNFW_TYPE_ANY;
+  result = types::NNFWTypeEnum.getValue(args.get(kFwType).get<std::string>(), &nnfw_e);
+  if (!result) {
+    LogAndReportError(result, &out);
+    return;
+  }
+
+  ml_nnfw_hw_e hw_e = ML_NNFW_HW_ANY;
+  result = types::HWTypeEnum.getValue(args.get(kHwType).get<std::string>(), &hw_e);
+  if (!result) {
+    LogAndReportError(result, &out);
+    return;
+  }
+
+  auto is_dynamic_mode = args.get(kIsDynamicMode).get<bool>();
+
+  int res_id = -1;
+  result = single_manager_.OpenModel(model_path, in_tensors_info, out_tensors_info, nnfw_e, hw_e,
+                                       is_dynamic_mode, &res_id);
+  if (!result) {
+    ReportError(result, &out);
+    return;
+  }
+
+  out["id"] = picojson::value(static_cast<double>(res_id));
+  ReportSuccess(out);
+}
 
 // MachineLearningSingle::openModelAsync()
 
index d511e8dac2ad939789edfb31fc1c041b0effe501..5afbba3622d8334dfce7427204b5b8ddea2537c0 100644 (file)
@@ -20,6 +20,7 @@
 #include "common/extension.h"
 
 #include "ml/ml_pipeline_manager.h"
+#include "ml/ml_single_manager.h"
 #include "nnstreamer/nnstreamer-single.h"
 #include "nnstreamer/nnstreamer.h"
 
@@ -54,7 +55,8 @@ class MlInstance : public common::ParsedInstance {
   // Common ML API end
 
   // Single API begin
-  // MachineLearningSingle::openModel()
+  SingleManager single_manager_;
+  void MLSingleManagerOpenModel(const picojson::value& args, picojson::object& out);
   // MachineLearningSingle::openModelAsync()
   // OpenModelSuccessCallback
   // SingleShot input
diff --git a/src/ml/ml_single_manager.cc b/src/ml/ml_single_manager.cc
new file mode 100644 (file)
index 0000000..00f813f
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2021 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 "ml_single_manager.h"
+#include "common/tools.h"
+
+using common::PlatformResult;
+using common::ErrorCode;
+
+namespace extension {
+namespace ml {
+
+SingleManager::SingleManager() : nextId_{0} {
+  ScopeLogger();
+}
+
+SingleManager::~SingleManager() {
+  ScopeLogger();
+}
+
+// MachineLearningSingle::openModel()
+PlatformResult SingleManager::OpenModel(const std::string& modelPath, TensorsInfo* inTensorsInfo,
+                                        TensorsInfo* outTensorsInfo, ml_nnfw_type_e nnfw_e,
+                                        ml_nnfw_hw_e hw_e, bool isDynamicMode, int* res_id) {
+  ScopeLogger();
+
+  ml_single_h handle = nullptr;
+
+  ml_tensors_info_h in_info = inTensorsInfo ? inTensorsInfo->Handle() : nullptr;
+  ml_tensors_info_h out_info = outTensorsInfo ? outTensorsInfo->Handle() : nullptr;
+
+  int ret = ml_single_open(&handle, modelPath.c_str(), in_info, out_info, nnfw_e, hw_e);
+  if (ML_ERROR_NONE != ret) {
+    LoggerE("ml_single_open failed: %d (%s)", ret, get_error_message(ret));
+    return util::ToPlatformResult(ret, "Failed to open model");
+  }
+
+  int id = nextId_++;
+  singles_[id] = std::make_unique<SingleShot>(id, handle);
+  *res_id = id;
+  return PlatformResult{};
+}
+
+// MachineLearningSingle::openModelAsync()
+// OpenModelSuccessCallback
+// SingleShot input
+// SingleShot output
+// SingleShot::invoke()
+// SingleShot::getValue()
+// SingleShot::setValue()
+// SingleShot::setTimeout()
+// SingleShot::close()
+
+}  // namespace ml
+}  // namespace extension
diff --git a/src/ml/ml_single_manager.h b/src/ml/ml_single_manager.h
new file mode 100644 (file)
index 0000000..034fbff
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021 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 ML_ML_SINGLE_MANAGER_H_
+#define ML_ML_SINGLE_MANAGER_H_
+
+#include "common/platform_result.h"
+
+#include "ml_singleshot.h"
+#include "ml_tensors_info_manager.h"
+#include "nnstreamer/nnstreamer-single.h"
+
+using common::PlatformResult;
+
+namespace extension {
+namespace ml {
+
+class SingleManager {
+ public:
+  SingleManager();
+  ~SingleManager();
+
+  SingleManager(const SingleManager&) = delete;
+  SingleManager& operator=(const SingleManager&) = delete;
+
+  // MachineLearningSingle::openModel()
+  PlatformResult OpenModel(const std::string& modelPath, TensorsInfo* inTensorsInfo,
+                           TensorsInfo* outTensorsInfo, ml_nnfw_type_e nnfw_e, ml_nnfw_hw_e hw_e,
+                           bool isDynamicMode, int* res_id);
+  // MachineLearningSingle::openModelAsync()
+  // OpenModelSuccessCallback
+  // SingleShot input
+  // SingleShot output
+  // SingleShot::invoke()
+  // SingleShot::getValue()
+  // SingleShot::setValue()
+  // SingleShot::setTimeout()
+  // SingleShot::close()
+
+ private:
+  int nextId_;
+  std::map<int, std::unique_ptr<SingleShot>> singles_;
+};
+
+}  // namespace ml
+}  // namespace extension
+
+#endif  // ML_ML_SINGLE_MANAGER_H_
diff --git a/src/ml/ml_singleshot.cc b/src/ml/ml_singleshot.cc
new file mode 100644 (file)
index 0000000..a9fb3a0
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021 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 <tizen.h>
+
+#include "common/logger.h"
+#include "ml_singleshot.h"
+#include "ml_utils.h"
+
+using common::PlatformResult;
+using common::ErrorCode;
+
+namespace extension {
+namespace ml {
+
+SingleShot::SingleShot(int id, ml_single_h handle) : id_{id}, handle_{handle} {
+  ScopeLogger("id: %d", id_);
+}
+
+// 'this' owns a handle_, and invalidates 'o'
+SingleShot::SingleShot(SingleShot&& o) : id_(o.id_), handle_(o.handle_) {
+  ScopeLogger("id: %d", id_);
+  o.handle_ = nullptr;
+}
+
+SingleShot::~SingleShot() {
+  ScopeLogger("id: %d", id_);
+  int ret = ml_single_close(handle_);
+  if (ML_ERROR_NONE != ret) {
+    LoggerW("ml_single_close failed: %d (%s)", ret, get_error_message(ret));
+  }
+}
+
+// SingleShot input
+
+// SingleShot output
+
+// SingleShot::invoke()
+
+// SingleShot::getValue()
+
+// SingleShot::setValue()
+
+// SingleShot::setTimeout()
+
+// SingleShot::close()
+
+}  // namespace extension
+}  // namespace ml
diff --git a/src/ml/ml_singleshot.h b/src/ml/ml_singleshot.h
new file mode 100644 (file)
index 0000000..0a02b0e
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2021 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 ML_ML_SINGLESHOT_H_
+#define ML_ML_SINGLESHOT_H_
+
+#include <map>
+#include <string>
+
+#include <nnstreamer/nnstreamer-single.h>
+
+#include "common/platform_result.h"
+
+using common::PlatformResult;
+
+namespace extension {
+namespace ml {
+
+class SingleShot {
+ public:
+  SingleShot(int id, ml_single_h handle);
+  SingleShot() = delete;
+  // copy semantics
+  SingleShot(const SingleShot&) = delete;
+  SingleShot& operator=(const SingleShot&) = delete;
+  // move semantics
+  SingleShot(SingleShot&& o);
+  SingleShot& operator=(SingleShot&& o) = delete;
+  ~SingleShot();
+
+  // SingleShot input
+
+  // SingleShot output
+
+  // SingleShot::invoke()
+
+  // SingleShot::getValue()
+
+  // SingleShot::setValue()
+
+  // SingleShot::setTimeout()
+
+  // SingleShot::close()
+
+ private:
+  const int id_;
+  ml_single_h handle_;
+};
+
+}  // namespace ml
+}  // namespace extension
+
+#endif  // ML_ML_SINGLESHOT_H_