From: Piotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/Samsung Electronics
Date: Wed, 20 Jan 2021 10:55:36 +0000 (+0100)
Subject: [ML][Single] Added manager file and implementation for openModel()
X-Git-Tag: submit/tizen/20210128.113801~7^2
X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F93%2F251893%2F7;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git
[ML][Single] Added manager file and implementation for openModel()
[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
---
diff --git a/src/ml/js/ml_single.js b/src/ml/js/ml_single.js
index f9aa0d82..22cf5ba9 100755
--- a/src/ml/js/ml_single.js
+++ b/src/ml/js/ml_single.js
@@ -17,12 +17,91 @@
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()
diff --git a/src/ml/ml.gyp b/src/ml/ml.gyp
index a8fb82f2..62490a50 100644
--- a/src/ml/ml.gyp
+++ b/src/ml/ml.gyp
@@ -27,8 +27,10 @@
#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',
],
diff --git a/src/ml/ml_instance.cc b/src/ml/ml_instance.cc
index 1677d389..260b3c32 100644
--- a/src/ml/ml_instance.cc
+++ b/src/ml/ml_instance.cc
@@ -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());
+ 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(args.get(kInTensorsInfo).get());
+ 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(args.get(kOutTensorsInfo).get());
+ 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(), &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(), &hw_e);
+ if (!result) {
+ LogAndReportError(result, &out);
+ return;
+ }
+
+ auto is_dynamic_mode = args.get(kIsDynamicMode).get();
+
+ 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(res_id));
+ ReportSuccess(out);
+}
// MachineLearningSingle::openModelAsync()
diff --git a/src/ml/ml_instance.h b/src/ml/ml_instance.h
index d511e8da..5afbba36 100644
--- a/src/ml/ml_instance.h
+++ b/src/ml/ml_instance.h
@@ -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
index 00000000..00f813ff
--- /dev/null
+++ b/src/ml/ml_single_manager.cc
@@ -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(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
index 00000000..034fbff6
--- /dev/null
+++ b/src/ml/ml_single_manager.h
@@ -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> 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
index 00000000..a9fb3a07
--- /dev/null
+++ b/src/ml/ml_singleshot.cc
@@ -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
+
+#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
index 00000000..0a02b0ee
--- /dev/null
+++ b/src/ml/ml_singleshot.h
@@ -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