[ML][common] Add tizen.ml.checkNNFWAvailability method 88/250788/10
authorRafal Walczyna <r.walczyna@samsung.com>
Wed, 23 Dec 2020 07:54:06 +0000 (08:54 +0100)
committerRafal Walczyna <r.walczyna@samsung.com>
Mon, 18 Jan 2021 13:35:29 +0000 (14:35 +0100)
ACR: TWDAPI-273

Test code:

var HWType = ["ANY", "AUTO", "CPU", "CPU_NEON", "CPU_SIMD", "GPU", "NPU",
    "NPU_EDGE_TPU", "NPU_MOVIDIUS", "NPU_SR", "NPU_VIVANTE"];

var NNFWType = ["ANY", "ARM_NN", "CUSTOM_FILTER", "EDGE_TPU", "MVNC", "NNFW", "OPEN_VINO",
    "SNPE", "TENSORFLOW", "TENSORFLOW_LITE", "VIVANTE"];

HWType.forEach(hw => {
    NNFWType.forEach(nnfw => {
        console.log(nnfw + ", " + hw + ": " + tizen.ml.checkNNFWAvailability(nnfw, hw))
    });
});

[Verificaion] Tested in Google Chrome Dev Console

Change-Id: I2ac7752f410a70e98d8c0cd387ac5dfcabdbef88
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
src/ml/js/ml_common.js
src/ml/js/ml_manager.js
src/ml/ml_instance.cc
src/ml/ml_instance.h
src/ml/ml_utils.cc
src/ml/ml_utils.h

index c8bc981..415ff53 100755 (executable)
@@ -70,7 +70,7 @@ var TensorsData = function() {
                 throw new WebAPIException(WebAPIException.ABORT_ERR, 'Not implemented');
             }
         },
-        tensorsInfo : {
+        tensorsInfo: {
             enumerable: true,
             get: function() {
                 throw new WebAPIException(WebAPIException.ABORT_ERR, 'Not implemented');
index 549bcdd..69d96a3 100755 (executable)
@@ -20,8 +20,60 @@ MachineLearningManager.prototype.single = new MachineLearningSingle();
 
 MachineLearningManager.prototype.pipeline = new MachineLearningPipeline();
 
+var NNFWType = {
+    ANY: 'ANY',
+    ARM_NN: 'ARM_NN',
+    CUSTOM_FILTER: 'CUSTOM_FILTER',
+    EDGE_TPU: 'EDGE_TPU',
+    MVNC: 'MVNC',
+    NNFW: 'NNFW',
+    OPEN_VINO: 'OPEN_VINO',
+    SNPE: 'SNPE',
+    TENSORFLOW: 'TENSORFLOW',
+    TENSORFLOW_LITE: 'TENSORFLOW_LITE',
+    VIVANTE: 'VIVANTE'
+};
+
+var HWType = {
+    ANY: 'ANY',
+    AUTO: 'AUTO',
+    CPU: 'CPU',
+    CPU_NEON: 'CPU_NEON',
+    CPU_SIMD: 'CPU_SIMD',
+    GPU: 'GPU',
+    NPU: 'NPU',
+    NPU_EDGE_TPU: 'NPU_EDGE_TPU',
+    NPU_MOVIDIUS: 'NPU_MOVIDIUS',
+    NPU_SR: 'NPU_SR',
+    NPU_VIVANTE: 'NPU_VIVANTE'
+};
+
 MachineLearningManager.prototype.checkNNFWAvailability = function() {
-    throw new WebAPIException(WebAPIException.ABORT_ERR, 'Not implemented');
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'nnfw',
+            type: types_.ENUM,
+            values: Object.values(NNFWType),
+            optional: false
+        },
+        {
+            name: 'hw',
+            type: types_.ENUM,
+            values: Object.values(HWType),
+            optional: false
+        }
+    ]);
+    var callArgs = {
+        nnfw: args.nnfw,
+        hw: args.hw
+    };
+
+    var result = native_.callSync('MLCheckNNFWAvailability', callArgs);
+
+    if (native_.isFailure(result)) {
+        return false;
+    }
+    return native_.getResultObject(result);
 };
 
 exports = new MachineLearningManager();
index 1741550..3aaad4c 100644 (file)
  */
 
 #include "ml_instance.h"
+#include "ml_utils.h"
 
 #include "common/logger.h"
 #include "common/picojson.h"
+#include "common/platform_result.h"
 
 namespace extension {
 namespace ml {
 
+namespace {
+const std::string kNnfw = "nnfw";
+const std::string kHw = "hw";
+}
+
 using namespace common;
 
+#define CHECK_EXIST(args, name, out)                                                            \
+  if (!args.contains(name)) {                                                                   \
+    LogAndReportError(TypeMismatchException(std::string(name) + " is required argument"), out); \
+    return;                                                                                     \
+  }
+
 MlInstance::MlInstance() : pipeline_manager_{this} {
   ScopeLogger();
   using namespace std::placeholders;
@@ -31,6 +44,7 @@ MlInstance::MlInstance() : pipeline_manager_{this} {
 #define REGISTER_METHOD(M) RegisterSyncHandler(#M, std::bind(&MlInstance::M, this, _1, _2))
 
   // Common ML API begin
+  REGISTER_METHOD(MLCheckNNFWAvailability);
 
   // Common ML API end
 
@@ -52,7 +66,18 @@ MlInstance::~MlInstance() {
 }
 
 // Common ML API begin
+void MlInstance::MLCheckNNFWAvailability(const picojson::value& args, picojson::object& out) {
+  ScopeLogger("args: %s", args.serialize().c_str());
+  CHECK_EXIST(args, kNnfw, out)
+  CHECK_EXIST(args, kHw, out)
+
+  std::string nnfw = args.get(kNnfw).get<std::string>();
+  std::string hw = args.get(kHw).get<std::string>();
+  bool availability_val = util::CheckNNFWAvailability(nnfw, hw);
 
+  picojson::value available = picojson::value{availability_val};
+  ReportSuccess(available, out);
+}
 // Common ML API end
 
 // Single API begin
@@ -223,5 +248,7 @@ void MlInstance::MLPipelineDispose(const picojson::value& args, picojson::object
 // Valve::setOpen() end
 // Pipeline API end
 
+#undef CHECK_EXIST
+
 }  // namespace ml
 }  // namespace extension
index 975fd7a..7d455f8 100644 (file)
@@ -33,6 +33,7 @@ class MlInstance : public common::ParsedInstance {
 
  private:
   // Common ML API begin
+  void MLCheckNNFWAvailability(const picojson::value& args, picojson::object& out);
 
   // Common ML API end
 
index 7babe96..d29605d 100644 (file)
 
 #include <memory>
 
-#include "ml_utils.h"
-
 #include "common/logger.h"
+#include "ml_utils.h"
 
 namespace extension {
 namespace ml {
+
+namespace types {
+const PlatformEnum<ml_nnfw_hw_e> HWTypeEnum{{"ANY", ML_NNFW_HW_ANY},
+                                            {"AUTO", ML_NNFW_HW_AUTO},
+                                            {"CPU", ML_NNFW_HW_CPU},
+                                            {"CPU_NEON", ML_NNFW_HW_CPU_NEON},
+                                            {"CPU_SIMD", ML_NNFW_HW_CPU_SIMD},
+                                            {"GPU", ML_NNFW_HW_GPU},
+                                            {"NPU", ML_NNFW_HW_NPU},
+                                            {"NPU_EDGE_TPU", ML_NNFW_HW_NPU_EDGE_TPU},
+                                            {"NPU_MOVIDIUS", ML_NNFW_HW_NPU_MOVIDIUS},
+                                            {"NPU_SR", ML_NNFW_HW_NPU_SR},
+                                            {"NPU_VIVANTE", ML_NNFW_HW_NPU_VIVANTE}};
+
+const PlatformEnum<ml_nnfw_type_e> NNFWTypeEnum{{"ANY", ML_NNFW_TYPE_ANY},
+                                                {"ARM_NN", ML_NNFW_TYPE_ARMNN},
+                                                {"CUSTOM_FILTER", ML_NNFW_TYPE_CUSTOM_FILTER},
+                                                {"EDGE_TPU", ML_NNFW_TYPE_EDGE_TPU},
+                                                {"MVNC", ML_NNFW_TYPE_MVNC},
+                                                {"NNFW", ML_NNFW_TYPE_NNFW},
+                                                {"OPEN_VINO", ML_NNFW_TYPE_OPENVINO},
+                                                {"SNPE", ML_NNFW_TYPE_SNPE},
+                                                {"TENSORFLOW", ML_NNFW_TYPE_TENSORFLOW},
+                                                {"TENSORFLOW_LITE", ML_NNFW_TYPE_TENSORFLOW_LITE},
+                                                {"VIVANTE", ML_NNFW_TYPE_VIVANTE}};
+}  // types
+
 namespace util {
 
 PlatformResult ToPlatformResult(int ml_error_code, const std::string& error_message_beginning) {
@@ -53,7 +79,32 @@ PlatformResult ToPlatformResult(int ml_error_code, const std::string& error_mess
   }
 }
 
-using namespace common;
+bool CheckNNFWAvailability(const std::string& nnfw, const std::string& hw) {
+  ScopeLogger();
+  ml_nnfw_type_e nnfw_e = ML_NNFW_TYPE_ANY;
+  ml_nnfw_hw_e hw_e = ML_NNFW_HW_ANY;
+
+  PlatformResult result = types::NNFWTypeEnum.getValue(nnfw, &nnfw_e);
+  if (!result) {
+    LoggerE("NNFWTypeEnum.getValue() failed, error: %s", result.message().c_str());
+    return false;
+  }
+  result = types::HWTypeEnum.getValue(hw, &hw_e);
+  if (!result) {
+    LoggerE("HWTypeEnum.getValue() failed, error: %s", result.message().c_str());
+    return false;
+  }
+  bool available = false;
+  int ret = ml_check_nnfw_availability(nnfw_e, hw_e, &available);
+
+  if (ML_ERROR_NONE != ret) {
+    LoggerE("ml_check_nnfw_availability failed: %d (%s)", ret, get_error_message(ret));
+    return false;
+  }
+
+  LoggerD("ml_check_nnfw_availability: %s", available ? "true" : "false");
+  return available;
+}
 
 }  // util
 }  // ml
index 725c7d9..bc476b1 100644 (file)
 #include <nnstreamer/nnstreamer.h>
 
 #include "common/picojson.h"
+#include "common/platform_enum.h"
 #include "common/platform_result.h"
 
+using common::PlatformEnum;
 using common::PlatformResult;
 using common::ErrorCode;
 
 namespace extension {
 namespace ml {
+
+namespace types {
+
+extern const PlatformEnum<ml_nnfw_hw_e> HWTypeEnum;
+extern const PlatformEnum<ml_nnfw_type_e> NNFWTypeEnum;
+
+}  // types
+
 namespace util {
 
 PlatformResult ToPlatformResult(int ml_error_code, const std::string& error_message);
 
+bool CheckNNFWAvailability(const std::string& nnfw, const std::string& hw);
+
 }  // util
 }  // ml
 }  // extension