1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "include/js_api/common_napi.h"
17 #include <climits>
18 #include "src/common/log.h"
19
20 namespace mindspore {
21
22 namespace {
23 const int SIZE = 100;
24 }
25
getMessageByCode(int32_t & code)26 std::string CommonNapi::getMessageByCode(int32_t &code) {
27 std::string err_message;
28 switch (code) {
29 case NAPI_ERR_INVALID_PARAM:
30 err_message = NAPI_ERR_INVALID_PARAM_INFO;
31 break;
32 case NAPI_ERR_NO_MEMORY:
33 err_message = NAPI_ERR_NO_MEMORY_INFO;
34 break;
35 case NAPI_ERR_ILLEGAL_STATE:
36 err_message = NAPI_ERR_ILLEGAL_STATE_INFO;
37 break;
38 case NAPI_ERR_UNSUPPORTED:
39 err_message = NAPI_ERR_UNSUPPORTED_INFO;
40 break;
41 case NAPI_ERR_TIMEOUT:
42 err_message = NAPI_ERR_TIMEOUT_INFO;
43 break;
44 case NAPI_ERR_STREAM_LIMIT:
45 err_message = NAPI_ERR_STREAM_LIMIT_INFO;
46 break;
47 case NAPI_ERR_SYSTEM:
48 err_message = NAPI_ERR_SYSTEM_INFO;
49 break;
50 case NAPI_ERR_INPUT_INVALID:
51 err_message = NAPI_ERR_INPUT_INVALID_INFO;
52 break;
53 default:
54 err_message = NAPI_ERR_SYSTEM_INFO;
55 code = NAPI_ERR_SYSTEM;
56 break;
57 }
58 return err_message;
59 }
60
GetPropertyInt32(napi_env env,napi_value config_obj,const std::string & type,int32_t & result)61 int32_t CommonNapi::GetPropertyInt32(napi_env env, napi_value config_obj, const std::string &type, int32_t &result) {
62 napi_value item = nullptr;
63 bool exist = false;
64 napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist);
65
66 if (status != napi_ok || !exist) {
67 MS_LOG(WARNING) << "can not find " << type.c_str() << " will set default value";
68 return ERR_NOT_EXISTED_PARAM;
69 }
70
71 if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) {
72 MS_LOG(WARNING) << "fail to get property: " << type.c_str();
73 return ERR_INVALID_PARAM;
74 }
75
76 if (napi_get_value_int32(env, item, &result) != napi_ok) {
77 MS_LOG(WARNING) << "fail to get property value " << type.c_str();
78 return ERR_INVALID_PARAM;
79 }
80 return SUCCESS;
81 }
82
GetPropertyString(napi_env env,napi_value config_obj,const std::string & type,std::string & result)83 int32_t CommonNapi::GetPropertyString(napi_env env, napi_value config_obj, const std::string &type,
84 std::string &result) {
85 napi_value item = nullptr;
86 bool exist = false;
87 char buffer[SIZE];
88 size_t length = 0;
89
90 napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist);
91
92 if (status != napi_ok || !exist) {
93 MS_LOG(WARNING) << "can not find " << type.c_str() << "will set default value";
94 return ERR_NOT_EXISTED_PARAM;
95 }
96
97 if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) {
98 MS_LOG(WARNING) << "fail to get property: " << type.c_str();
99 return ERR_INVALID_PARAM;
100 }
101
102 if (napi_get_value_string_utf8(env, item, buffer, SIZE, &length) != napi_ok) {
103 MS_LOG(WARNING) << "fail to get property value " << type.c_str();
104 return ERR_INVALID_PARAM;
105 }
106 result = std::string(buffer);
107 return SUCCESS;
108 }
109
GetPropertyBigIntUint64(napi_env env,napi_value config_obj,const std::string & type,uint64_t & result)110 int32_t CommonNapi::GetPropertyBigIntUint64(napi_env env, napi_value config_obj, const std::string &type,
111 uint64_t &result) {
112 napi_value item = nullptr;
113 bool exist = false;
114 napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist);
115
116 if (status != napi_ok || !exist) {
117 MS_LOG(WARNING) << "can not find " << type.c_str() << " will set default value";
118 return ERR_NOT_EXISTED_PARAM;
119 }
120
121 if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) {
122 MS_LOG(WARNING) << "fail to get property: " << type.c_str();
123 return ERR_INVALID_PARAM;
124 }
125
126 bool lossless = false;
127 if (napi_get_value_bigint_uint64(env, item, &result, &lossless) != napi_ok) {
128 MS_LOG(WARNING) << "fail to get property value " << type.c_str();
129 return ERR_INVALID_PARAM;
130 }
131
132 if (!lossless) {
133 MS_LOG(WARNING) << "get uint64_t loss precision !";
134 return ERR_INVALID_PARAM;
135 }
136 return SUCCESS;
137 }
138
GetPropertyInt32Array(napi_env env,napi_value config_obj,const std::string & type,std::vector<int32_t> & result)139 int32_t CommonNapi::GetPropertyInt32Array(napi_env env, napi_value config_obj, const std::string &type,
140 std::vector<int32_t> &result) {
141 napi_value item = nullptr;
142 bool exist = false;
143 napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist);
144 if (status != napi_ok || !exist) {
145 MS_LOG(WARNING) << "can not find " << type.c_str() << "will set default value";
146 return ERR_NOT_EXISTED_PARAM;
147 }
148
149 if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) {
150 MS_LOG(WARNING) << "fail to get property: " << type.c_str();
151 return ERR_INVALID_PARAM;
152 }
153
154 uint32_t array_length = 0;
155 status = napi_get_array_length(env, item, &array_length);
156 if (status != napi_ok || array_length < 0) {
157 MS_LOG(WARNING) << "can not get array length.";
158 return ERR_INVALID_PARAM;
159 }
160
161 if (array_length == 0) {
162 return SUCCESS;
163 }
164
165 for (size_t i = 0; i < array_length; i++) {
166 int32_t int_value = {0};
167 napi_value element = nullptr;
168 status = napi_get_element(env, item, i, &element);
169 if (status != napi_ok) {
170 MS_LOG(WARNING) << "can not get element";
171 return ERR_INVALID_PARAM;
172 }
173
174 if (napi_get_value_int32(env, element, &int_value) != napi_ok) {
175 MS_LOG(WARNING) << "get " << type.c_str() << " property value fail";
176 return ERR_INVALID_PARAM;
177 }
178 result.push_back(int_value);
179 }
180
181 return SUCCESS;
182 }
183
GetPropertyStringArray(napi_env env,napi_value config_obj,const std::string & type,std::vector<std::string> & result)184 int32_t CommonNapi::GetPropertyStringArray(napi_env env, napi_value config_obj, const std::string &type,
185 std::vector<std::string> &result) {
186 napi_value item = nullptr;
187 bool exist = false;
188 napi_status status = napi_has_named_property(env, config_obj, type.c_str(), &exist);
189
190 if (status != napi_ok || !exist) {
191 MS_LOG(WARNING) << "can not find " << type.c_str() << "will set default value";
192 return ERR_NOT_EXISTED_PARAM;
193 }
194
195 if (napi_get_named_property(env, config_obj, type.c_str(), &item) != napi_ok) {
196 MS_LOG(WARNING) << "fail to get property: " << type.c_str();
197 return ERR_INVALID_PARAM;
198 }
199
200 uint32_t array_length = 0;
201 status = napi_get_array_length(env, item, &array_length);
202 if (status != napi_ok || array_length <= 0) {
203 MS_LOG(WARNING) << "can not get array length";
204 return ERR_INVALID_PARAM;
205 }
206
207 for (size_t i = 0; i < array_length; i++) {
208 char buffer[SIZE];
209 size_t length = 0;
210
211 napi_value element = nullptr;
212 status = napi_get_element(env, item, i, &element);
213 if (status != napi_ok) {
214 MS_LOG(WARNING) << "can not get element";
215 return ERR_INVALID_PARAM;
216 }
217
218 if (napi_get_value_string_utf8(env, element, buffer, SIZE, &length) != napi_ok) {
219 MS_LOG(WARNING) << "fail to get property value " << type.c_str();
220 return ERR_INVALID_PARAM;
221 }
222 result.push_back(std::string(buffer));
223 }
224
225 return SUCCESS;
226 }
227
GetStringArray(napi_env env,napi_value value,std::vector<std::string> & result)228 int32_t CommonNapi::GetStringArray(napi_env env, napi_value value, std::vector<std::string> &result) {
229 uint32_t array_length = 0;
230 auto status = napi_get_array_length(env, value, &array_length);
231 if (status != napi_ok || array_length <= 0) {
232 MS_LOG(WARNING) << "can not get array length";
233 return ERR_INVALID_PARAM;
234 }
235
236 for (size_t i = 0; i < array_length; i++) {
237 char buffer[SIZE];
238 size_t length = 0;
239
240 napi_value element = nullptr;
241 status = napi_get_element(env, value, i, &element);
242 if (status != napi_ok) {
243 MS_LOG(WARNING) << "can not get element";
244 return ERR_INVALID_PARAM;
245 }
246
247 if (napi_get_value_string_utf8(env, element, buffer, SIZE, &length) != napi_ok) {
248 MS_LOG(WARNING) << "fail to get string_utf8 value";
249 return ERR_INVALID_PARAM;
250 }
251 result.push_back(std::string(buffer));
252 }
253
254 return SUCCESS;
255 }
256
WriteTensorData(MSTensor tensor,std::string file_path)257 void CommonNapi::WriteTensorData(MSTensor tensor, std::string file_path) {
258 std::ofstream out_file;
259 out_file.open(file_path, std::ios::out | std::ios::app);
260 if (!out_file.is_open()) {
261 MS_LOG(ERROR) << "output file open failed";
262 return;
263 }
264 auto out_data = reinterpret_cast<const float *>(tensor.Data().get());
265 out_file << tensor.Name() << " ";
266 for (auto dim : tensor.Shape()) {
267 out_file << dim << " ";
268 }
269 out_file << std::endl;
270 for (int i = 0; i < tensor.ElementNum(); i++) {
271 out_file << out_data[i] << " ";
272 }
273 out_file << std::endl;
274 out_file.close();
275 }
276
WriteOutputsData(const std::vector<MSTensor> outputs,std::string file_path)277 void CommonNapi::WriteOutputsData(const std::vector<MSTensor> outputs, std::string file_path) {
278 std::ofstream out_file;
279 out_file.open(file_path, std::ios::out | std::ios::app);
280 if (!out_file.is_open()) {
281 MS_LOG(ERROR) << "output file open failed";
282 return;
283 }
284 for (auto tensor : outputs) {
285 MS_LOG(INFO) << "tensor name is: " << tensor.Name().c_str()
286 << "tensor size is: " << static_cast<int>(tensor.DataSize())
287 << "tensor elements num is: " << static_cast<int>(tensor.ElementNum());
288 // dtype float
289 auto out_data = reinterpret_cast<const float *>(tensor.Data().get());
290 out_file << tensor.Name() << " ";
291 for (auto dim : tensor.Shape()) {
292 out_file << dim << " ";
293 }
294 out_file << std::endl;
295 for (int i = 0; i < tensor.ElementNum(); i++) {
296 out_file << out_data[i] << " ";
297 }
298 out_file << std::endl;
299 }
300 out_file.close();
301 }
302
303 } // namespace mindspore