From b33b431abbacc69132377aca203859c5466eb68d Mon Sep 17 00:00:00 2001 From: fangzhou0329 Date: Mon, 5 Jun 2023 17:55:14 +0800 Subject: [PATCH] add ohos js callback api and bugfix --- include/js_api/@ohos.ai.mindSporeLite.d.ts | 485 ++++++++++++++++++ include/js_api/@ohos.ai.mindspore.d.ts | 222 -------- mindspore/lite/BUILD.gn | 2 +- mindspore/lite/src/runtime/js_api/BUILD.gn | 2 +- .../lite/src/runtime/js_api/common_napi.cc | 38 +- .../src/runtime/js_api/mslite_model_napi.cc | 231 ++++++--- .../lite/src/runtime/js_api/mstensor_napi.cc | 12 +- 7 files changed, 662 insertions(+), 330 deletions(-) create mode 100644 include/js_api/@ohos.ai.mindSporeLite.d.ts delete mode 100644 include/js_api/@ohos.ai.mindspore.d.ts diff --git a/include/js_api/@ohos.ai.mindSporeLite.d.ts b/include/js_api/@ohos.ai.mindSporeLite.d.ts new file mode 100644 index 00000000..005f68eb --- /dev/null +++ b/include/js_api/@ohos.ai.mindSporeLite.d.ts @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +import { Callback } from './@ohos.base'; + +/** + * @namespace mindSporeLite + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ +declare namespace mindSporeLite { + /** + * Create a Model instance from file path. + * @param { string } model - model indicates model path to be loaded + * @param { callback: Callback } callback - the callback of model + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromFile( + model: string, callback: Callback): void; + + /** + * Create a Model instance from file path. + * @param { string } model - model indicates model path to be loaded + * @param { Context } [context] - context indicates model context information + * @param { callback: Callback } callback - the callback of model + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromFile( + model: string, + context: Context, callback: Callback): void; + + /** + * Create a Model instance from file path + * @param { string } model - model indicates model path to be loaded + * @param { Context } context - context indicates model context information + * @return { Promise } the promise returned by the function. + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromFile( + model: string, + context?: Context): Promise; + + /** + * Create a Model instance from buffer + * @param { ArrayBuffer } model - model indicates model buffer to be loaded + * @param { callback: Callback } callback - the callback of model + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromBuffer( + model: ArrayBuffer, callback: Callback): void; + + /** + * Create a Model instance from buffer + * @param { ArrayBuffer } model - model indicates model buffer to be loaded + * @param { Context } [context] - context indicates model context information + * @param { callback: Callback } callback - the callback of model + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromBuffer( + model: ArrayBuffer, + context: Context, callback: Callback): void; + + /** + * Create a Model instance from buffer + * @param { ArrayBuffer } model - model indicates model buffer to be loaded + * @param { Context } context - context indicates model context information + * @return { Promise } the promise returned by the function. + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromBuffer( + model: ArrayBuffer, + context?: Context): Promise; + + /** + * Create a Model instance from file description + * @param { number } model - model indicates model file description to be loaded + * @param { callback: Callback } callback - the callback of model + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromFd( + model: number, callback: Callback): void; + + /** + * Create a Model instance from file description + * @param { number } model - model indicates model file description to be loaded + * @param { Context } [context] - context indicates model context information + * @param { callback: Callback } callback - the callback of model + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromFd( + model: number, + context: Context, callback: Callback): void; + + /** + * Creates a Model instance file description + * @param { number } model - model indicates model file description to be loaded + * @param { Context } context - context indicates model context information + * @return { Promise } the promise returned by the function. + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + function loadModelFromFd( + model: number, + context?: Context): Promise; + + /** + * Provides manages model function. Including get inputs, predict ,resize. + * @typedef Model + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + interface Model { + /** + * Get model input tensors. + * @return { MSTensor[] } the MSTensor array of the inputs. + * @syscap SystemCapability.AI.MindSporeLite. + * @stagemodelonly + * @since 10 + */ + getInputs(): MSTensor[]; + + /** + * Infer model + * @param { MSTensor[] } inputs - indicates the MSTensor array of the inputs. + * @param { callback: Callback } callback - the callback of model. + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + predict(inputs: MSTensor[], callback: Callback): void; + + /** + * Infer model + * @param { MSTensor[] } inputs - indicates the MSTensor array of the inputs. + * @return { Promise } the promise returned by the function. + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + predict(inputs: MSTensor[]): Promise; + + /** + * resize model input + * @param { MSTensor[] } inputs - indicates the MSTensor array of the inputs. + * @param { Array> } dims - indicates the target new shape array + * @return { boolean } the boolen result if the resize operation is successful + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + resize(inputs: MSTensor[], dims: Array>): boolean; + } + + /** + * Provides the device configurations + * @typedef Context + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + interface Context { + /** + * The target device,optional device names: "cpu", "nnrt".If not set, default is "cpu". + * @type {string[]} + * @since 10 + */ + target?: string[]; + /** + * The cpu device infomation + * @type {CpuDevice} + * @since 10 + */ + cpu?: CpuDevice; + /** + * The NNRT device infomation + * @type {NNRTDevice} + * @since 10 + */ + nnrt?: NNRTDevice; + } + + /** + * Provides the CPU device info + * @typedef CpuDevice + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + interface CpuDevice { + /** + * The number of threads used in model prediction. + * @type {number} + * @since 10 + */ + threadNum?: number; + /** + * The thread affinity mode + * @type {ThreadAffinityMode} + * @since 10 + */ + threadAffinityMode?: ThreadAffinityMode; + /** + * The thread affinity core list + * @type {number[]} + * @since 10 + */ + threadAffinityCoreList?: number[]; + /** + * The precision mode + * @type {string} + * @since 10 + */ + precisionMode?: string; + } + + /** + * Provides the NNRT device info + * @typedef NNRTDevice + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + interface NNRTDevice { + } + + /** + * Enum for provide CPU thread affinity mode + * @enum {number} + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + export enum ThreadAffinityMode { + /** + * Thread affinity mode is no bind. + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NO_AFFINITIES = 0, + + /** + * Thread affinity mode is big cores first + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + BIG_CORES_FIRST = 1, + + /** + * Thread affinity mode is little cores first + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + LITTLE_CORES_FIRST = 2, + } + + /** + * Provides MSTensor defination + * @typedef MSTensor + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + interface MSTensor { + /** + * The name of the tensor. + * @type {string} + * @since 10 + */ + name: string; + /** + * The shape of the tensor. + * @type {number[]} + * @since 10 + */ + shape: number[]; + /** + * The number of elements in the tensor. + * @type {number} + * @since 10 + */ + elementNum: number; + /** + * The data size of the tensor. + * @type {number} + * @since 10 + */ + dataSize: number; + /** + * The data type of the tensor. + * @type {DataType} + * @since 10 + */ + dtype: DataType; + /** + * The format of the tensor. + * @type {DataType} + * @since 10 + */ + format: Format; + + /** + * Get MSTensor data + * @return { ArrayBuffer } the data of tensor + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + getData(): ArrayBuffer; + + /** + * Set MSTensor data + * @param { ArrayBuffer } inputArray - indicates the buffer of tensor + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + setData(inputArray: ArrayBuffer): void; + } + + /** + * Enum for provide MSTensor data type + * @enum {number} + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + export enum DataType { + /** + * data type is unknown + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + TYPE_UNKNOWN = 0, + /** + * data type is int8 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_INT8 = 32, + /** + * data type is int16 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_INT16 = 33, + /** + * data type is int32 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_INT32 = 34, + /** + * data type is int64 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_INT64 = 35, + /** + * data type is uint8 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_UINT8 = 37, + /** + * data type is uint16 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_UINT16 = 38, + /** + * data type is uint32 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_UINT32 = 39, + /** + * data type is uint64 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_UINT64 = 40, + /** + * data type is float16 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_FLOAT16 = 42, + /** + * data type is float32 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_FLOAT32 = 43, + /** + * data type is float64 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NUMBER_TYPE_FLOAT64 = 44, + } + + /** + * Enum for provide MSTensor format + * @enum {number} + * @syscap SystemCapability.AI.MindSporeLite + * @stagemodelonly + * @since 10 + */ + export enum Format { + /** + * data format is default + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + DEFAULT_FORMAT = -1, + /** + * data format is NCHW + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NCHW = 0, + /** + * data format is NHWC + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NHWC = 1, + /** + * data format is NHWC4 + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + NHWC4 = 2, + /** + * data format is HWKC + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + HWKC = 3, + /** + * data format is HWCK + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + HWCK = 4, + /** + * data format is HWCK + * @syscap SystemCapability.AI.MindSporeLite + * @since 10 + */ + KCHW = 5, + } +} +export default mindSporeLite; diff --git a/include/js_api/@ohos.ai.mindspore.d.ts b/include/js_api/@ohos.ai.mindspore.d.ts deleted file mode 100644 index ce59f029..00000000 --- a/include/js_api/@ohos.ai.mindspore.d.ts +++ /dev/null @@ -1,222 +0,0 @@ -/* -* Copyright (C) 2023 Huawei Device Co., Ltd. -* 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. -*/ - -import { ErrorCallback, AsyncCallback, Callback } from './basic'; - -/** - * @name mslite - * @since 9 - * @import import mslite from '@ohos.mslite' - */ -declare namespace mslite { - /** - * Creates an MSLiteModel instance. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - * @import import mslite from '@ohos.mslite' - * @param model The path to the model (string) - * @param options Options related to model inference. - * @throws { BusinessError } 401 - invaild path. Return by callback. - * @return A Promise instance used to return MSLiteModel instance if the operation is successful; returns null otherwise. - */ - function loadModelFromFile( - model: string, - options?: Context): Promise; - - /** - * Creates an MSLiteModel instance. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - * @import import mslite from '@ohos.mslite' - * @param model The model content in memory(ArrayBuffer). - * @param options Options related to model inference. - * @throws { BusinessError } 401 - No memory. Return by callback. - * @return A Promise instance used to return MSLiteModel instance if the operation is successful; returns null otherwise. - */ - function loadModelFromBuffer( - model: ArrayBuffer, - options?: Context): Promise; - - /** - * Creates an MSLiteModel instance. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - * @import import mslite from '@ohos.mslite' - * @param model The memory fd to the model (number). - * @param options Options related to model inference. - * @throws { BusinessError } 401 - invaild fd. Return by callback. - * @return A Promise instance used to return MSLiteModel instance if the operation is successful; returns null otherwise. - */ - function loadModelFromFd( - model: number, - options?: Context): Promise; - - /** - * Manages model. Before calling an MSLiteModel method, you must use loadMSLiteModel() - * to create an MSLiteModel instance. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - */ - interface MSLiteModel { - /** - * Get model input tensors. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - * @return MSTensor Array - */ - getInputs(): MSTensor[]; - - /** - * Infer model. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - * @inputs inputs tensor - * @return A Promise instance used to return MSTensor array if the operation is successful; returns null otherwise. - */ - predict(inputs: MSTensor[]): Promise; - - /** - * resize model input. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - * @inputs inputs tensor - * @dims resize shape,the order is same with inputs - * @return true if the operation is successful; returns false otherwise. - */ - resize(inputs: MSTensor[], dims: Array>): boolean; - } - - /** - * Provides the device configurations. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - */ - interface Context { - target?: string[]; - cpu?:CpuDevice; - nnrt?:NnrtDevice; - } - - /** - * Provides the CPU device info. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - */ - interface CpuDevice { - thread_num?: number - thread_affinity_mode?: ThreadAffinityMode; - thread_affinity_core_list?: number[]; - precision_mode?: string; - } - - /** - * Provides the NNRT device info. - * @since 9 - * @syscap SystemCapability.MsLite.MsLiteModel - */ - interface NnrtDevice { - } - - /** - * Provides CPU thread affinity mode. - * @since 9 - * @syscap SystemCapability.MsLite.Context - */ - enum ThreadAffinityMode { - /** - * NO_BIND. - * @since 9 - * @syscap SystemCapability.MsLite.Context - */ - NO_AFFINITIES = 0, - - /** - * BIG_CORES_FIRST. - * @since 9 - * @syscap SystemCapability.MsLite.Context - */ - BIG_CORES_FIRST = 1, - - /** - * LITTLE_CORES_FIRST. - * @since 9 - * @syscap SystemCapability.MsLite.Context - */ - LITTLE_CORES_FIRST = 2, - } - - /** - * Provides MSTensor defination. - * @since 9 - * @syscap SystemCapability.MsLite.MsTensor - */ - interface MSTensor { - /** The name of the tensor. */ - 'name': string; - /** The shape of the tensor. */ - 'shape': number[]; - /** Number of elements in the tensor. */ - 'element_num': number; - /** Number of elements in the tensor. */ - 'data_size': number; - /** The data type for the array. */ - 'dtype': number; - /** The format type of the tensor. */ - 'format': number; - - /** - * Get MSTensor data. - * @since 9 - * @syscap SystemCapability.MsLite.MsTensor - * @return ArrayBuffer. - */ - data(): ArrayBuffer; - - /** - * Set MSTensor data. - * @since 9 - * @syscap SystemCapability.MsLite.MsTensor - * @param inputArray - */ - setData(inputArray: ArrayBuffer): void; - } - - enum DataType { - kTypeUnknown = 0, - kNumberTypeInt8 = 32, - kNumberTypeInt16 = 33, - kNumberTypeInt32 = 34, - kNumberTypeInt64 = 35, - kNumberTypeUInt8 = 37, - kNumberTypeUInt16 = 38, - kNumberTypeUInt32 = 39, - kNumberTypeUInt64 = 40, - kNumberTypeFloat16 = 42, - kNumberTypeFloat32 = 43, - kNumberTypeFloat64 = 44, - kNumberTypeEnd = 46, - } - - enum Format { - DEFAULT_FORMAT = -1, - NCHW = 0, - NHWC = 1, - NHWC4 = 2, - HWKC = 3, - HWCK = 4, - KCHW = 5, - } -} -export default mslite; \ No newline at end of file diff --git a/mindspore/lite/BUILD.gn b/mindspore/lite/BUILD.gn index 7032b028..9ad0caf7 100644 --- a/mindspore/lite/BUILD.gn +++ b/mindspore/lite/BUILD.gn @@ -70,7 +70,7 @@ ohos_group("mindspore") { ":mindspore_lib", ":mindspore_train_lib", "mindir:mindir_lib", - "src/runtime/js_api:mslite" + "src/runtime/js_api:mindspore_lite_napi" ] } diff --git a/mindspore/lite/src/runtime/js_api/BUILD.gn b/mindspore/lite/src/runtime/js_api/BUILD.gn index 44669c26..04031370 100644 --- a/mindspore/lite/src/runtime/js_api/BUILD.gn +++ b/mindspore/lite/src/runtime/js_api/BUILD.gn @@ -14,7 +14,7 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") -ohos_shared_library("mslite") { +ohos_shared_library("mindspore_lite_napi") { include_dirs = [ "//third_party/mindspore/mindspore-src/source/", "//third_party/mindspore/mindspore-src/source/include/api", diff --git a/mindspore/lite/src/runtime/js_api/common_napi.cc b/mindspore/lite/src/runtime/js_api/common_napi.cc index 6fa2501e..5054a317 100644 --- a/mindspore/lite/src/runtime/js_api/common_napi.cc +++ b/mindspore/lite/src/runtime/js_api/common_napi.cc @@ -64,17 +64,17 @@ int32_t CommonNapi::GetPropertyInt32(napi_env env, napi_value config_obj, const napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist); if (status != napi_ok || !exist) { - MS_LOG(ERROR) << "can not find " << type.c_str() << " property"; + MS_LOG(WARNING) << "can not find " << type.c_str() << " property"; return ERR_NOT_EXISTED_PARAM; } if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) { - MS_LOG(ERROR) << "get " << type.c_str() << " property fail"; + MS_LOG(WARNING) << "get " << type.c_str() << " property fail"; return ERR_INVALID_PARAM; } if (napi_get_value_int32(env, item, &result) != napi_ok) { - MS_LOG(ERROR) << "get " << type.c_str() << " property value fail"; + MS_LOG(WARNING) << "get " << type.c_str() << " property value fail"; return ERR_INVALID_PARAM; } return SUCCESS; @@ -88,23 +88,19 @@ int32_t CommonNapi::GetPropertyString(napi_env env, napi_value config_obj, const size_t length = 0; napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist); - if (status != napi_ok || !exist) { - MS_LOG(ERROR) << "can not find target property"; - return ERR_NOT_EXISTED_PARAM; - } if (status != napi_ok || !exist) { - MS_LOG(ERROR) << "can not find " << type.c_str() << " property"; + MS_LOG(WARNING) << "can not find " << type.c_str() << " property"; return ERR_NOT_EXISTED_PARAM; } if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) { - MS_LOG(ERROR) << "get " << type.c_str() << " property fail"; + MS_LOG(WARNING) << "get " << type.c_str() << " property fail"; return ERR_INVALID_PARAM; } if (napi_get_value_string_utf8(env, item, buffer, SIZE, &length) != napi_ok) { - MS_LOG(ERROR) << "get " << type.c_str() << " property value fail"; + MS_LOG(WARNING) << "get " << type.c_str() << " property value fail"; return ERR_INVALID_PARAM; } result = std::string(buffer); @@ -117,34 +113,34 @@ int32_t CommonNapi::GetPropertyInt32Array(napi_env env, napi_value config_obj, c bool exist = false; napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist); if (status != napi_ok || !exist) { - MS_LOG(ERROR) << "can not find " << type.c_str() << " property"; + MS_LOG(WARNING) << "can not find " << type.c_str() << " property"; return ERR_NOT_EXISTED_PARAM; } if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) { - MS_LOG(ERROR) << "get " << type.c_str() << " property fail"; + MS_LOG(WARNING) << "get " << type.c_str() << " property fail"; return ERR_INVALID_PARAM; } uint32_t array_length = 0; status = napi_get_array_length(env, item, &array_length); if (status != napi_ok || array_length <= 0) { - MS_LOG(ERROR) << "can not get array length"; + MS_LOG(WARNING) << "can not get array length"; return ERR_INVALID_PARAM; } MS_LOG(DEBUG) << "GetPropertyInt32Array array_length: " << array_length; for (size_t i = 0; i < array_length; i++) { - int32_t int_value = 0; + int32_t int_value = {0}; napi_value element = nullptr; status = napi_get_element(env, item, i, &element); if (status != napi_ok) { - MS_LOG(ERROR) << "can not get element"; + MS_LOG(WARNING) << "can not get element"; return ERR_INVALID_PARAM; } if (napi_get_value_int32(env, element, &int_value) != napi_ok) { - MS_LOG(ERROR) << "get " << type.c_str() << " property value fail"; + MS_LOG(WARNING) << "get " << type.c_str() << " property value fail"; return ERR_INVALID_PARAM; } result.push_back(int_value); @@ -160,19 +156,19 @@ int32_t CommonNapi::GetPropertyStringArray(napi_env env, napi_value config_obj, napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist); if (status != napi_ok || !exist) { - MS_LOG(ERROR) << "can not find " << type.c_str() << " property"; + MS_LOG(WARNING) << "can not find " << type.c_str() << " property"; return ERR_NOT_EXISTED_PARAM; } if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) { - MS_LOG(ERROR) << "get " << type.c_str() << " property fail"; + MS_LOG(WARNING) << "get " << type.c_str() << " property fail"; return ERR_INVALID_PARAM; } uint32_t array_length = 0; status = napi_get_array_length(env, item, &array_length); if (status != napi_ok || array_length <= 0) { - MS_LOG(ERROR) << "can not get array length"; + MS_LOG(WARNING) << "can not get array length"; return ERR_INVALID_PARAM; } @@ -183,12 +179,12 @@ int32_t CommonNapi::GetPropertyStringArray(napi_env env, napi_value config_obj, napi_value element = nullptr; status = napi_get_element(env, item, i, &element); if (status != napi_ok) { - MS_LOG(ERROR) << "can not get element"; + MS_LOG(WARNING) << "can not get element"; return ERR_INVALID_PARAM; } if (napi_get_value_string_utf8(env, element, buffer, SIZE, &length) != napi_ok) { - MS_LOG(ERROR) << "get " << type.c_str() << " property value fail"; + MS_LOG(WARNING) << "get " << type.c_str() << " property value fail"; return ERR_INVALID_PARAM; } result.push_back(std::string(buffer)); diff --git a/mindspore/lite/src/runtime/js_api/mslite_model_napi.cc b/mindspore/lite/src/runtime/js_api/mslite_model_napi.cc index 31f7fdc3..61ed5d28 100644 --- a/mindspore/lite/src/runtime/js_api/mslite_model_napi.cc +++ b/mindspore/lite/src/runtime/js_api/mslite_model_napi.cc @@ -23,8 +23,8 @@ #include #include #include -#include #include +#include #include "include/js_api/mstensor_napi.h" #include "include/js_api/common_napi.h" #include "include/js_api/ms_parameters_napi.h" @@ -48,12 +48,15 @@ std::mutex MSLiteModelNapi::create_mutex_; namespace { const int ARGS_ONE = 1; const int ARGS_TWO = 2; +const int ARGS_THREE = 3; const int PARAM0 = 0; const int PARAM1 = 1; +const int PARAM2 = 2; const int SIZE = 100; -const std::string CLASS_NAME = "MSLiteModel"; + +const std::string CLASS_NAME = "Model"; const std::unordered_map kDeviceTypes{ {"cpu", kCPU}, @@ -185,6 +188,7 @@ std::shared_ptr MSLiteModelNapi::CreateModel(ModelInfo *model_ } auto ret = model_ptr->Build(model_info_ptr->model_path, mindspore::kMindIR, context); if (ret == mindspore::kSuccess) { + MS_LOG(INFO) << "Build model from path success."; return model_ptr; } return nullptr; @@ -199,8 +203,9 @@ std::shared_ptr MSLiteModelNapi::CreateModel(ModelInfo *model_ } auto ret = model_ptr->Build(model_info_ptr->model_buffer_data, model_info_ptr->model_buffer_total, mindspore::kMindIR, context); + if (ret == mindspore::kSuccess) { - MS_LOG(INFO) << "Build model from buffer success."; + MS_LOG(INFO) << "Build model from fd success."; return model_ptr; } (void)munmap(model_info_ptr->model_buffer_data, model_info_ptr->model_buffer_total); @@ -291,7 +296,7 @@ int32_t MSLiteModelNapi::ParseModelInfo(napi_env env, napi_value root, ModelInfo return ERR_INVALID_PARAM; } if ((valueType != napi_object) && (valueType != napi_string) && (valueType != napi_number)) { - MS_LOG(ERROR) << "napi_type not support."; + MS_LOG(ERROR) << "model is invaild."; return ERR_INVALID_PARAM; } @@ -318,18 +323,18 @@ int32_t MSLiteModelNapi::ParseModelInfo(napi_env env, napi_value root, ModelInfo MS_LOG(ERROR) << "Parse model FD failed."; return ERR_INVALID_PARAM; } + int size = lseek(fd, 0, SEEK_END); (void)lseek(fd, 0, SEEK_SET); auto mmap_buffers = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); if (mmap_buffers == NULL) { MS_LOG(ERROR) << "mmap_buffers is NULL."; return ERR_INVALID_PARAM; - } + } model_info.model_fd = fd; model_info.model_buffer_data = static_cast(mmap_buffers); model_info.model_buffer_total = size; model_info.mode = kFD; - close(fd); } else { char char_buf[SIZE]; size_t buf_length = 0; @@ -349,20 +354,20 @@ int32_t MSLiteModelNapi::ParseContextInfo(napi_env env, napi_value args, Context napi_valuetype valueType; napi_status status = napi_typeof(env, args, &valueType); if ((status != napi_ok) || (valueType != napi_object)) { - MS_LOG(ERROR) << "napi_typeof check failed."; + MS_LOG(ERROR) << "model is invaild."; return ERR_NOT_EXISTED_PARAM; } std::vector str_values; auto ret = CommonNapi::GetPropertyStringArray(env, args, "target", str_values); - if (ret != SUCCESS && ret != ERR_NOT_EXISTED_PARAM) { + if (ret != SUCCESS) { MS_LOG(ERROR) << "Get context target failed."; return ret; } context.target.assign(str_values.begin(), str_values.end()); ret = GetCpuDeviceInfo(env, args, context); - if (ret != SUCCESS && ret != ERR_NOT_EXISTED_PARAM) { + if (ret != ERR_NOT_EXISTED_PARAM && ret != SUCCESS) { MS_LOG(ERROR) << "Get context CpuDeviceInfo failed."; return ret; } @@ -407,12 +412,12 @@ void MSLiteModelNapi::GetMSLiteModelAsyncCallbackComplete(napi_env env, napi_sta void MSLiteModelNapi::CommonCallbackRoutine(napi_env env, MSLiteModelAsyncContext *&asyncContext, const napi_value &valueParam) { - napi_value result[ARGS_TWO] = {0}; + napi_value result[ARGS_ONE] = {0}; napi_value retVal; + napi_value error = nullptr; - if (!asyncContext->status) { - napi_get_undefined(env, &result[PARAM0]); - result[PARAM1] = valueParam; + if (!asyncContext->status) { + result[PARAM0] = valueParam; } else { napi_value message = nullptr; std::string messageValue = CommonNapi::getMessageByCode(asyncContext->status); @@ -421,20 +426,20 @@ void MSLiteModelNapi::CommonCallbackRoutine(napi_env env, MSLiteModelAsyncContex napi_value code = nullptr; napi_create_string_utf8(env, (std::to_string(asyncContext->status)).c_str(), NAPI_AUTO_LENGTH, &code); - napi_create_error(env, code, message, &result[PARAM0]); - napi_get_undefined(env, &result[PARAM1]); + napi_create_error(env, code, message, &error); + napi_get_undefined(env, &result[PARAM0]); } - if (asyncContext->deferred) { + if (asyncContext->deferred != nullptr) { if (!asyncContext->status) { - napi_resolve_deferred(env, asyncContext->deferred, result[PARAM1]); + napi_resolve_deferred(env, asyncContext->deferred, result[PARAM0]); } else { - napi_reject_deferred(env, asyncContext->deferred, result[PARAM0]); + napi_reject_deferred(env, asyncContext->deferred, error); } } else { napi_value callback = nullptr; napi_get_reference_value(env, asyncContext->callbackRef, &callback); - napi_call_function(env, nullptr, callback, ARGS_TWO, result, &retVal); + napi_call_function(env, nullptr, callback, ARGS_ONE, result, &retVal); napi_delete_reference(env, asyncContext->callbackRef); } napi_delete_async_work(env, asyncContext->work); @@ -446,34 +451,50 @@ void MSLiteModelNapi::CommonCallbackRoutine(napi_env env, MSLiteModelAsyncContex napi_value MSLiteModelNapi::LoadMSLiteModelFromFile(napi_env env, napi_callback_info info) { napi_status status; napi_value result = nullptr; - - GET_PARAMS(env, info, ARGS_TWO); + const int32_t refCount = 1; + GET_PARAMS(env, info, ARGS_THREE); std::unique_ptr asyncContext = std::make_unique(); int32_t ret; for (size_t i = PARAM0; i < argc; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); if (i == PARAM0) { ret = ParseModelInfo(env, argv[i], asyncContext->model_info); if (ret != SUCCESS) { - MS_LOG(ERROR) << "Parsing model info failed."; + MS_LOG(ERROR) << "Parsing model failed."; return result; } } else if (i == PARAM1) { ret = ParseContextInfo(env, argv[i], asyncContext->context); - if (ret != SUCCESS && ret != ERR_NOT_EXISTED_PARAM) { - MS_LOG(ERROR) << "Parsing context info failed."; + if (ret != SUCCESS) { + MS_LOG(ERROR) << "Parsing context failed."; return result; } + } else if (i == PARAM2) { + if (valueType == napi_function) { + napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef); + } + break; } else { MS_LOG(ERROR) << "Invalid input params."; return result; } } - status = napi_create_promise(env, &asyncContext->deferred, &result); - if (status != napi_ok) { - MS_LOG(ERROR) << "create promise failed."; - return result; + + if (asyncContext->callbackRef == nullptr) { + status = napi_create_promise(env, &asyncContext->deferred, &result); + if (status != napi_ok) { + MS_LOG(ERROR) << "create promise failed."; + return result; + } + } else { + status = napi_get_undefined(env, &result); + if (status != napi_ok) { + MS_LOG(ERROR) << "create callback failed."; + return result; + } } napi_value resource = nullptr; @@ -501,34 +522,50 @@ napi_value MSLiteModelNapi::LoadMSLiteModelFromFile(napi_env env, napi_callback_ napi_value MSLiteModelNapi::LoadMSLiteModelFromBuffer(napi_env env, napi_callback_info info) { napi_status status; napi_value result = nullptr; - - GET_PARAMS(env, info, ARGS_TWO); + const int32_t refCount = 1; + GET_PARAMS(env, info, ARGS_THREE); std::unique_ptr asyncContext = std::make_unique(); int32_t ret; for (size_t i = PARAM0; i < argc; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); if (i == PARAM0) { ret = ParseModelInfo(env, argv[i], asyncContext->model_info); if (ret != SUCCESS) { - MS_LOG(ERROR) << "Parsing model info failed."; + MS_LOG(ERROR) << "Parsing model failed."; return result; } } else if (i == PARAM1) { ret = ParseContextInfo(env, argv[i], asyncContext->context); - if (ret != SUCCESS && ret != ERR_NOT_EXISTED_PARAM) { - MS_LOG(ERROR) << "Parsing context info failed."; + if (ret != SUCCESS) { + MS_LOG(ERROR) << "Parsing context failed."; return result; } + } else if (i == PARAM2) { + if (valueType == napi_function) { + napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef); + } + break; } else { MS_LOG(ERROR) << "Invalid input params."; return result; } } - status = napi_create_promise(env, &asyncContext->deferred, &result); - if (status != napi_ok) { - MS_LOG(ERROR) << "create promise failed."; - return result; + + if (asyncContext->callbackRef == nullptr) { + status = napi_create_promise(env, &asyncContext->deferred, &result); + if (status != napi_ok) { + MS_LOG(ERROR) << "create promise failed."; + return result; + } + } else { + status = napi_get_undefined(env, &result); + if (status != napi_ok) { + MS_LOG(ERROR) << "create callback failed."; + return result; + } } napi_value resource = nullptr; @@ -556,34 +593,50 @@ napi_value MSLiteModelNapi::LoadMSLiteModelFromBuffer(napi_env env, napi_callbac napi_value MSLiteModelNapi::LoadMSLiteModelFromFd(napi_env env, napi_callback_info info) { napi_status status; napi_value result = nullptr; - - GET_PARAMS(env, info, ARGS_TWO); + const int32_t refCount = 1; + GET_PARAMS(env, info, ARGS_THREE); std::unique_ptr asyncContext = std::make_unique(); int32_t ret; for (size_t i = PARAM0; i < argc; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); if (i == PARAM0) { ret = ParseModelInfo(env, argv[i], asyncContext->model_info); if (ret != SUCCESS) { - MS_LOG(ERROR) << "Parsing model info failed."; + MS_LOG(ERROR) << "Parsing model failed."; return result; } } else if (i == PARAM1) { ret = ParseContextInfo(env, argv[i], asyncContext->context); - if (ret != SUCCESS && ret != ERR_NOT_EXISTED_PARAM) { - MS_LOG(ERROR) << "Parsing context info failed."; + if (ret != SUCCESS) { + MS_LOG(ERROR) << "Parsing context failed."; return result; } + } else if (i == PARAM2) { + if (valueType == napi_function) { + napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef); + } + break; } else { MS_LOG(ERROR) << "Invalid input params."; return result; } } - status = napi_create_promise(env, &asyncContext->deferred, &result); - if (status != napi_ok) { - MS_LOG(ERROR) << "create promise failed."; - return result; + + if (asyncContext->callbackRef == nullptr) { + status = napi_create_promise(env, &asyncContext->deferred, &result); + if (status != napi_ok) { + MS_LOG(ERROR) << "create promise failed."; + return result; + } + } else { + status = napi_get_undefined(env, &result); + if (status != napi_ok) { + MS_LOG(ERROR) << "create callback failed."; + return result; + } } napi_value resource = nullptr; @@ -630,24 +683,32 @@ int32_t MSLiteModelNapi::GetCpuDeviceInfo(napi_env env, napi_value args, Context std::string str_value = ""; std::vector affinity_cores; - if (CommonNapi::GetPropertyInt32(env, config_item, "thread_num", int_value) == SUCCESS) { - MS_LOG(DEBUG) << "thread_num: " << int_value; + if (CommonNapi::GetPropertyInt32(env, config_item, "threadNum", int_value) == SUCCESS) { + MS_LOG(DEBUG) << "threadNum: " << int_value; context.cpu_device.thread_num = int_value; + } else { + context.cpu_device.thread_num = PARAM2; } - if (CommonNapi::GetPropertyInt32(env, config_item, "thread_affinity_mode", int_value) == SUCCESS) { - MS_LOG(DEBUG) << "thread_affinity_mode: " << int_value; - context.cpu_device.thread_num = int_value; + if (CommonNapi::GetPropertyInt32(env, config_item, "threadAffinityMode", int_value) == SUCCESS) { + MS_LOG(DEBUG) << "threadAffinityMode: " << int_value; + context.cpu_device.thread_affinity_mode = int_value; + } else { + context.cpu_device.thread_affinity_mode = PARAM0; } - if (CommonNapi::GetPropertyInt32Array(env, config_item, "thread_affinity_core_list", affinity_cores) == SUCCESS) { - MS_LOG(DEBUG) << "affinity_cores size: " << affinity_cores.size(); + if (CommonNapi::GetPropertyInt32Array(env, config_item, "threadAffinityCoreList", affinity_cores) == SUCCESS) { + MS_LOG(DEBUG) << "affinityCores size: " << affinity_cores.size(); context.cpu_device.thread_affinity_cores.assign(affinity_cores.begin(), affinity_cores.end()); + } else { + context.cpu_device.thread_affinity_cores = {}; } - if (CommonNapi::GetPropertyString(env, config_item, "precision_mode", str_value) == SUCCESS) { - MS_LOG(DEBUG) << "precision_mode: " << str_value.c_str(); + if (CommonNapi::GetPropertyString(env, config_item, "precisionMode", str_value) == SUCCESS) { + MS_LOG(DEBUG) << "precisionMode: " << str_value.c_str(); context.cpu_device.precision_mode = str_value; + } else { + context.cpu_device.precision_mode = "enforce_fp32"; } return SUCCESS; } @@ -694,13 +755,12 @@ napi_value MSLiteModelNapi::GetInputs(napi_env env, napi_callback_info info) { size_t size = inputs.size(); MS_LOG(INFO) << "inputs size: " << size; - napi_create_array_with_length(env, size, &jsResult); for (size_t i = 0; i < size; i++) { status = napi_set_element(env, jsResult, i, MSTensorNapi::NewInstance(env, tensor_inputs[i])); if (status != napi_ok) { MS_LOG(ERROR) << "napi_set_element failed! code: " << status; - } + } } MS_LOG(INFO) << "get model inputs success: " << inputs[0].Name().c_str(); return jsResult; @@ -710,18 +770,17 @@ napi_value MSLiteModelNapi::Resize(napi_env env, napi_callback_info info) { napi_value undefinedResult = nullptr; bool result = false; napi_get_undefined(env, &undefinedResult); - napi_value argv[ARGS_TWO] = {0}; - size_t argCount = 2; + napi_value jsThis = nullptr; napi_value jsResult = nullptr; MSLiteModelNapi *modelNapi = nullptr; - + napi_value argv[ARGS_TWO] = {0}; + size_t argCount = PARAM2; napi_status status = napi_get_cb_info(env, info, &argCount, argv, &jsThis, nullptr); if (status != napi_ok || jsThis == nullptr) { MS_LOG(ERROR) << "Failed to retrieve details about the callback"; return undefinedResult; } - status = napi_unwrap(env, jsThis, reinterpret_cast(&modelNapi)); if (status != napi_ok || modelNapi == nullptr) { MS_LOG(ERROR) << "get model napi error"; @@ -755,7 +814,7 @@ napi_value MSLiteModelNapi::Resize(napi_env env, napi_callback_info info) { return undefinedResult; } - std::string property_name = "data"; + std::string property_name = "getData"; bool exist = false; napi_value data_func = nullptr; @@ -766,7 +825,7 @@ napi_value MSLiteModelNapi::Resize(napi_env env, napi_callback_info info) { } if (status != napi_ok || !exist) { - MS_LOG(INFO) << "can not find " << property_name.c_str() << " property."; + MS_LOG(ERROR) << "can not find " << property_name.c_str() << " property."; return undefinedResult; } @@ -834,6 +893,7 @@ napi_value MSLiteModelNapi::Resize(napi_env env, napi_callback_info info) { } status = napi_get_array_length(env, dim_element, &dim_size); + MS_LOG(ERROR) << "DIM SIZE IS:" << dim_size; if (status != napi_ok) { MS_LOG(ERROR) << "get new dim size error"; return undefinedResult; @@ -890,24 +950,48 @@ napi_value MSLiteModelNapi::PredictAsync(napi_env env, napi_callback_info info) napi_status status = napi_ok; napi_value undefinedResult = nullptr; napi_value result = nullptr; - + const int32_t refCount = 1; + napi_valuetype valueType; + std::unique_ptr asyncContext = std::make_unique(); if (asyncContext == nullptr) { MS_LOG(ERROR) << "MSLiteModelAsyncContext object create failed."; return undefinedResult; } - GET_PARAMS(env, info, ARGS_ONE); + GET_PARAMS(env, info, ARGS_TWO); + for (size_t i = PARAM0; i < argc; i++) { + if (i == PARAM1) { + status = napi_typeof(env, argv[i], &valueType); + if ((status != napi_ok) || (valueType != napi_function)) { + MS_LOG(ERROR) << "napi_typeof check callback failed."; + return result; + } + status = napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef); + if (status != napi_ok) { + MS_LOG(ERROR) << "Failed to create reference of callback"; + return result; + } + } + } if (SetTensorData(env, thisVar, argv[PARAM0], asyncContext.get()) != SUCCESS) { MS_LOG(ERROR) << "Set tensor data failed."; return undefinedResult; } - napi_create_promise(env, &asyncContext->deferred, &result); - if (status != napi_ok) { - MS_LOG(ERROR) << "create promise failed."; - return result; + if (asyncContext->callbackRef == nullptr) { + status = napi_create_promise(env, &asyncContext->deferred, &result); + if (status != napi_ok) { + MS_LOG(ERROR) << "create promise failed."; + return result; + } + } else { + status = napi_get_undefined(env, &result); + if (status != napi_ok) { + MS_LOG(ERROR) << "create callback failed."; + return result; + } } napi_value resource = nullptr; @@ -966,18 +1050,14 @@ int32_t MSLiteModelNapi::SetTensorData(napi_env env, napi_value thisVar, napi_va return ERROR; } - std::string property_name = "data"; + std::string property_name = "getData"; bool exist = false; napi_value data_func = nullptr; napi_status status = napi_has_named_property(env, element, property_name.c_str(), &exist); - if (status != napi_ok || !exist) { - MS_LOG(ERROR) << "can not find target property"; - return ERROR; - } if (status != napi_ok || !exist) { - MS_LOG(INFO) << "can not find " << property_name.c_str() << " property."; + MS_LOG(ERROR) << "can not find " << property_name.c_str() << " property."; return ERROR; } @@ -994,7 +1074,6 @@ int32_t MSLiteModelNapi::SetTensorData(napi_env env, napi_value thisVar, napi_va MS_LOG(ERROR) << "napi call function error."; return ERROR; } - status = napi_get_arraybuffer_info(env, return_val, &js_data, &length); if (status != napi_ok || js_data == nullptr) { MS_LOG(ERROR) << "Get js data error."; diff --git a/mindspore/lite/src/runtime/js_api/mstensor_napi.cc b/mindspore/lite/src/runtime/js_api/mstensor_napi.cc index a03bd484..cd8044e9 100644 --- a/mindspore/lite/src/runtime/js_api/mstensor_napi.cc +++ b/mindspore/lite/src/runtime/js_api/mstensor_napi.cc @@ -128,12 +128,12 @@ napi_value MSTensorNapi::GetConstructor(napi_env env) { napi_property_descriptor properties[] = { DECLARE_NAPI_GETTER("name", GetName), DECLARE_NAPI_GETTER("shape", GetShape), - DECLARE_NAPI_GETTER("element_num", GetElementNum), + DECLARE_NAPI_GETTER("elementNum", GetElementNum), DECLARE_NAPI_GETTER("dtype", GetDtype), DECLARE_NAPI_GETTER("format", GetFormat), - DECLARE_NAPI_GETTER("data_size", GetDataSize), + DECLARE_NAPI_GETTER("dataSize", GetDataSize), - DECLARE_NAPI_FUNCTION("data", GetDataBuffer), + DECLARE_NAPI_FUNCTION("getData", GetDataBuffer), DECLARE_NAPI_FUNCTION("setData", SetData), }; @@ -391,12 +391,6 @@ napi_value MSTensorNapi::SetData(napi_env env, napi_callback_info info) { return undefinedResult; } - if (tensor->nativeMSTensor_->DataType() != mindspore::DataType::kNumberTypeFloat32) { - MS_LOG(ERROR) << "tensor data type must be Float32(43), but got " - << static_cast(tensor->nativeMSTensor_->DataType()); - return undefinedResult; - } - // convert napi_value to c++ type data void *js_data = nullptr; size_t length = 0; -- 2.17.1