From 16a21310c7b8048d21f014173f13a62983ae6d2a Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Wed, 23 Dec 2020 08:54:06 +0100 Subject: [PATCH] [ML][common] Add tizen.ml.checkNNFWAvailability method 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 --- src/ml/js/ml_common.js | 2 +- src/ml/js/ml_manager.js | 54 +++++++++++++++++++++++++++++++++++++- src/ml/ml_instance.cc | 27 +++++++++++++++++++ src/ml/ml_instance.h | 1 + src/ml/ml_utils.cc | 57 ++++++++++++++++++++++++++++++++++++++--- src/ml/ml_utils.h | 12 +++++++++ 6 files changed, 148 insertions(+), 5 deletions(-) diff --git a/src/ml/js/ml_common.js b/src/ml/js/ml_common.js index c8bc9811..415ff53f 100755 --- a/src/ml/js/ml_common.js +++ b/src/ml/js/ml_common.js @@ -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'); diff --git a/src/ml/js/ml_manager.js b/src/ml/js/ml_manager.js index 549bcdda..69d96a3f 100755 --- a/src/ml/js/ml_manager.js +++ b/src/ml/js/ml_manager.js @@ -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(); diff --git a/src/ml/ml_instance.cc b/src/ml/ml_instance.cc index 17415507..3aaad4c7 100644 --- a/src/ml/ml_instance.cc +++ b/src/ml/ml_instance.cc @@ -15,15 +15,28 @@ */ #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 hw = args.get(kHw).get(); + 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 diff --git a/src/ml/ml_instance.h b/src/ml/ml_instance.h index 975fd7a5..7d455f87 100644 --- a/src/ml/ml_instance.h +++ b/src/ml/ml_instance.h @@ -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 diff --git a/src/ml/ml_utils.cc b/src/ml/ml_utils.cc index 7babe96e..d29605dc 100644 --- a/src/ml/ml_utils.cc +++ b/src/ml/ml_utils.cc @@ -16,12 +16,38 @@ #include -#include "ml_utils.h" - #include "common/logger.h" +#include "ml_utils.h" namespace extension { namespace ml { + +namespace types { +const PlatformEnum 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 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 diff --git a/src/ml/ml_utils.h b/src/ml/ml_utils.h index 725c7d96..bc476b1e 100644 --- a/src/ml/ml_utils.h +++ b/src/ml/ml_utils.h @@ -20,17 +20,29 @@ #include #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 HWTypeEnum; +extern const PlatformEnum 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 -- 2.34.1