eb86fc30b8da3f1d703a26d9704bcc1a3e32f93f
[platform/core/api/webapi-plugins.git] / src / ml / ml_instance.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include "ml_instance.h"
18 #include "ml_utils.h"
19
20 #include "common/converter.h"
21 #include "common/logger.h"
22 #include "common/picojson.h"
23 #include "common/platform_result.h"
24 #include "common/tools.h"
25
26 static_assert(ML_TENSOR_RANK_LIMIT == 4,
27               "This implementation requires different ML_TENSOR_RANK_LIMIT. Please fix the code.");
28
29 namespace extension {
30 namespace ml {
31
32 namespace {
33 const int kCustomFilterSuccess = 0;
34 const int kNoId = -1;
35 const std::string kAsync = "async";
36 const std::string kBOOLEAN = "BOOLEAN";
37 const std::string kBuffer = "buffer";
38 const std::string kCallbackId = "callbackId";
39 const std::string kDataId = "dataId";
40 const std::string kDefinition = "definition";
41 const std::string kDimensions = "dimensions";
42 const std::string kFwType = "fwType";
43 const std::string kGetInputMode = "getInputMode";
44 const std::string kHw = "hw";
45 const std::string kHwType = "hwType";
46 const std::string kId = "id";
47 const std::string kIndex = "index";
48 const std::string kInputTensorsInfoId = "inputTensorsInfoId";
49 const std::string kInTensorsInfo = "inTensorsInfo";
50 const std::string kIsDynamicMode = "isDynamicMode";
51 const std::string kListenerName = "listenerName";
52 const std::string kLocation = "location";
53 const std::string kModelPath = "modelPath";
54 const std::string kName = "name";
55 const std::string kNnfw = "nnfw";
56 const std::string kCustomRequirement = "customRequirement";
57 const std::string kNodeName = "nodeName";
58 const std::string kOpen = "open";
59 const std::string kOtherId = "otherId";
60 const std::string kOutputTensorsInfoId = "outputTensorsInfoId";
61 const std::string kOutTensorsInfo = "outTensorsInfo";
62 const std::string kPadName = "padName";
63 const std::string kPipelineStateChangeListenerName = "listenerName";
64 const std::string kProperty = "property";
65 const std::string kRequestId = "requestId";
66 const std::string kShape = "shape";
67 const std::string kSize = "size";
68 const std::string kStatus = "status";
69 const std::string kSTRING = "STRING";
70 const std::string kTensorsDataId = "tensorsDataId";
71 const std::string kTensorsInfoId = "tensorsInfoId";
72 const std::string kTimeout = "timeout";
73 const std::string kType = "type";
74 const std::string kValue = "value";
75
76 // TODO: sort const
77 const std::string kTrain = "train";
78 const std::string kValid = "valid";
79 const std::string kTest = "test";
80 const std::string kOptions = "options";
81 }  //  namespace
82
83 using namespace common;
84
85 #define CHECK_EXIST(args, name, out)                                            \
86   if (!args.contains(name)) {                                                   \
87     std::string msg = std::string(name) + " is required argument";              \
88     LogAndReportError(PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, msg), &out); \
89     return;                                                                     \
90   }
91
92 // CHECK_TYPE will throw AbortError by default, but it can be changed by providing
93 // additional parameter to the macro, i.e.:
94 // CHECK_TYPE(args, "name", std::string, out, ErrorCode::TYPE_MISMATCH_ERR)
95 #define CHECK_TYPE(...) CHECK_TYPE_X(__VA_ARGS__, CHECK_TYPE_5, CHECK_TYPE_4)(__VA_ARGS__)
96 #define CHECK_TYPE_X(_1, _2, _3, _4, _5, EXC_TYPE, ...) EXC_TYPE
97 #define CHECK_TYPE_5(args, name, type, out, error_type)        \
98   if (!args.get(name).is<type>()) {                            \
99     std::string msg = std::string(name) + " has invalid type"; \
100     LogAndReportError(PlatformResult(error_type, msg), &out);  \
101     return;                                                    \
102   }
103 #define CHECK_TYPE_4(args, name, type, out) \
104   CHECK_TYPE_5(args, name, type, out, ErrorCode::ABORT_ERR)
105
106 #define CHECK_ARGS(args, name, type, out) \
107   CHECK_EXIST(args, name, out)            \
108   CHECK_TYPE(args, name, type, out)
109
110 MlInstance::MlInstance()
111     : tensors_info_manager_{&tensors_data_manager_},
112       single_manager_{&tensors_info_manager_},
113       pipeline_manager_{this, &tensors_info_manager_, &tensors_data_manager_} {
114   ScopeLogger();
115   using namespace std::placeholders;
116
117 #define REGISTER_METHOD(M) RegisterSyncHandler(#M, std::bind(&MlInstance::M, this, _1, _2))
118 #define REGISTER_BINARY_METHOD(M) RegisterBinaryHandler(std::bind(&MlInstance::M, this, _1, _2, _3))
119 #define REGISTER_METHOD_WITH_BINARY_ANWSER(M) \
120   RegisterSyncHandlerWithBinaryAnswer(#M, std::bind(&MlInstance::M, this, _1, _2))
121
122   REGISTER_METHOD(MLCheckNNFWAvailability);
123   REGISTER_METHOD(MLTensorsInfoCountGetter);
124   REGISTER_METHOD(MLTensorsInfoAddTensorInfo);
125   REGISTER_METHOD(MLTensorsInfoCreate);
126   REGISTER_METHOD(MLTensorsInfoGetDimensions);
127   REGISTER_METHOD(MLTensorsInfoSetDimensions);
128   REGISTER_METHOD(MLTensorsInfoGetTensorName);
129   REGISTER_METHOD(MLTensorsInfoSetTensorName);
130   REGISTER_METHOD(MLTensorsInfoGetTensorSize);
131   REGISTER_METHOD(MLTensorsInfoGetTensorType);
132   REGISTER_METHOD(MLTensorsInfoSetTensorType);
133   REGISTER_METHOD(MLTensorsInfoGetTensorsData);
134   REGISTER_METHOD(MLTensorsInfoClone);
135   REGISTER_METHOD(MLTensorsInfoEquals);
136   REGISTER_METHOD(MLTensorsInfoDispose);
137   REGISTER_METHOD(MLPipelineValveSetOpen);
138   REGISTER_METHOD(MLPipelineValveIsOpen);
139
140   REGISTER_METHOD(MLTensorsDataDispose);
141   REGISTER_METHOD(MLTensorsDataGetTensorRawData);
142   REGISTER_METHOD_WITH_BINARY_ANWSER(MLTensorsDataGetTensorRawDataBinary);
143   REGISTER_METHOD(MLTensorsDataGetTensorType);
144   REGISTER_METHOD(MLTensorsDataSetTensorRawData);
145   REGISTER_BINARY_METHOD(MLTensorsDataSetTensorRawDataBinary);
146
147   REGISTER_METHOD(MLSingleManagerOpenModel);
148   REGISTER_METHOD(MLSingleShotGetTensorsInfo);
149   REGISTER_METHOD(MLSingleShotSetInputInfo);
150   REGISTER_METHOD(MLSingleShotInvoke);
151   REGISTER_METHOD(MLSingleShotGetValue);
152   REGISTER_METHOD(MLSingleShotSetValue);
153   REGISTER_METHOD(MLSingleShotSetTimeout);
154   REGISTER_METHOD(MLSingleShotClose);
155
156   REGISTER_METHOD(MLPipelineManagerCreatePipeline);
157   REGISTER_METHOD(MLPipelineGetState);
158   REGISTER_METHOD(MLPipelineDispose);
159   REGISTER_METHOD(MLPipelineStart);
160   REGISTER_METHOD(MLPipelineStop);
161   REGISTER_METHOD(MLPipelineGetNodeInfo);
162   REGISTER_METHOD(MLPipelineGetSwitch);
163   REGISTER_METHOD(MLPipelineSwitchGetPadList);
164   REGISTER_METHOD(MLPipelineSwitchSelect);
165   REGISTER_METHOD(MLPipelineGetValve);
166   REGISTER_METHOD(MLPipelineNodeInfoGetProperty);
167   REGISTER_METHOD(MLPipelineNodeInfoSetProperty);
168   REGISTER_METHOD(MLPipelineGetSource);
169   REGISTER_METHOD(MLPipelineGetInputTensorsInfo);
170   REGISTER_METHOD(MLPipelineSourceInputData);
171   REGISTER_METHOD(MLPipelineRegisterSinkListener);
172   REGISTER_METHOD(MLPipelineUnregisterSinkListener);
173   REGISTER_METHOD(MLPipelineManagerRegisterCustomFilter);
174   REGISTER_METHOD(MLPipelineManagerCustomFilterOutput);
175   REGISTER_METHOD(MLPipelineManagerUnregisterCustomFilter);
176
177   REGISTER_METHOD(MLTrainerLayerSetProperty);
178   REGISTER_METHOD(MLTrainerLayerCreate);
179   REGISTER_METHOD(MLTrainerOptimizerSetProperty);
180   REGISTER_METHOD(MLTrainerOptimizerCreate);
181   REGISTER_METHOD(MLTrainerModelCreate);
182   REGISTER_METHOD(MLTrainerModelCompile);
183   REGISTER_METHOD(MLTrainerModelAddLayer);
184   REGISTER_METHOD(MLTrainerModelRun);
185   REGISTER_METHOD(MLTrainerModelSummarize);
186   REGISTER_METHOD(MLTrainerModelSetDataset);
187   REGISTER_METHOD(MLTrainerModelSetOptimizer);
188   REGISTER_METHOD(MLTrainerDatasetCreateGenerator);
189   REGISTER_METHOD(MLTrainerDatasetCreateFromFile);
190   REGISTER_METHOD(MLTrainerDatasetSetProperty);
191
192 #undef REGISTER_METHOD
193 }
194
195 MlInstance::~MlInstance() {
196   ScopeLogger();
197   worker_.stop();
198 }
199
200 TensorsInfoManager& MlInstance::GetTensorsInfoManager() {
201   return tensors_info_manager_;
202 }
203
204 TensorsDataManager& MlInstance::GetTensorsDataManager() {
205   return tensors_data_manager_;
206 }
207
208 void MlInstance::MLCheckNNFWAvailability(const picojson::value& args, picojson::object& out) {
209   ScopeLogger("args: %s", args.serialize().c_str());
210   CHECK_EXIST(args, kNnfw, out)
211   CHECK_EXIST(args, kHw, out)
212   CHECK_EXIST(args, kCustomRequirement, out)
213
214   std::string nnfw = args.get(kNnfw).get<std::string>();
215   std::string hw = args.get(kHw).get<std::string>();
216   optional<std::string> customRequirement;
217   if (args.get(kCustomRequirement).is<std::string>()) {
218     customRequirement = args.get(kCustomRequirement).get<std::string>();
219   }
220   bool availability_val = util::CheckNNFWAvailability(nnfw, hw, customRequirement);
221
222   picojson::value available = picojson::value{availability_val};
223   ReportSuccess(available, out);
224 }
225
226 void MlInstance::MLTensorsInfoCreate(const picojson::value& args, picojson::object& out) {
227   ScopeLogger("args: %s", args.serialize().c_str());
228
229   TensorsInfo* tensorsInfo = GetTensorsInfoManager().CreateTensorsInfo();
230   if (nullptr == tensorsInfo) {
231     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
232                       ("Could not create new TensorsInfo handle"));
233     return;
234   }
235   out[kId] = picojson::value(static_cast<double>(tensorsInfo->Id()));
236   ReportSuccess(out);
237 }
238
239 void MlInstance::MLTensorsInfoCountGetter(const picojson::value& args, picojson::object& out) {
240   ScopeLogger("args: %s", args.serialize().c_str());
241   CHECK_ARGS(args, kTensorsInfoId, double, out);
242
243   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
244   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
245   if (nullptr == tensorsInfo) {
246     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
247                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
248     return;
249   }
250   unsigned int count = 0;
251   PlatformResult result = tensorsInfo->NativeGetCount(&count);
252   if (!result) {
253     ReportError(result, &out);
254     return;
255   }
256   picojson::value val = picojson::value{static_cast<double>(count)};
257   ReportSuccess(val, out);
258 }
259
260 void MlInstance::MLTensorsInfoAddTensorInfo(const picojson::value& args, picojson::object& out) {
261   ScopeLogger("args: %s", args.serialize().c_str());
262   CHECK_ARGS(args, kTensorsInfoId, double, out);
263   CHECK_ARGS(args, kType, std::string, out);
264   // kName is nullable
265   CHECK_EXIST(args, kName, out);
266   CHECK_ARGS(args, kDimensions, picojson::array, out);
267
268   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
269   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
270   if (nullptr == tensorsInfo) {
271     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
272                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
273     return;
274   }
275
276   const std::string& tensorType = args.get(kType).get<std::string>();
277   ml_tensor_type_e tensorTypeEnum = ML_TENSOR_TYPE_UNKNOWN;
278   PlatformResult result = types::TensorTypeEnum.getValue(tensorType, &tensorTypeEnum);
279   if (!result) {
280     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Error getting value of TensorType"),
281                       &out,
282                       ("TensorTypeEnum.getValue() failed, error: %s", result.message().c_str()));
283     return;
284   }
285
286   std::string name;
287   if (args.get(kName).is<std::string>()) {
288     name = args.get(kName).get<std::string>();
289     LoggerD("name: %s", name.c_str());
290   }
291
292   unsigned int dimensions[ML_TENSOR_RANK_LIMIT] = {};
293   auto dim = args.get(kDimensions).get<picojson::array>();
294   result = util::GetDimensionsFromJsonArray(dim, dimensions);
295   if (!result) {
296     LogAndReportError(result, &out);
297     return;
298   }
299
300   result = tensorsInfo->AddTensorInfo(name, tensorTypeEnum, dimensions);
301   if (!result) {
302     LogAndReportError(result, &out);
303     return;
304   }
305
306   int count = tensorsInfo->Count() - 1;
307
308   picojson::value val = picojson::value{static_cast<double>(count)};
309   ReportSuccess(val, out);
310 }
311
312 void MlInstance::MLTensorsInfoGetDimensions(const picojson::value& args, picojson::object& out) {
313   ScopeLogger("args: %s", args.serialize().c_str());
314   CHECK_ARGS(args, kTensorsInfoId, double, out);
315   CHECK_ARGS(args, kIndex, double, out);
316
317   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
318   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
319   if (nullptr == tensorsInfo) {
320     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
321                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
322     return;
323   }
324   int index = static_cast<int>(args.get(kIndex).get<double>());
325   unsigned int dim[ML_TENSOR_RANK_LIMIT];
326   PlatformResult result = tensorsInfo->NativeGetTensorDimensions(index, dim);
327   if (!result) {
328     LogAndReportError(result, &out);
329     return;
330   }
331   picojson::array array = picojson::array{};
332   for (int i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
333     if (0 == dim[i]) {
334       break;
335     }
336     array.push_back(picojson::value{static_cast<double>(dim[i])});
337   }
338   picojson::value val = picojson::value{array};
339   ReportSuccess(val, out);
340 }
341
342 void MlInstance::MLTensorsInfoSetDimensions(const picojson::value& args, picojson::object& out) {
343   ScopeLogger("args: %s", args.serialize().c_str());
344   CHECK_ARGS(args, kTensorsInfoId, double, out);
345   CHECK_ARGS(args, kIndex, double, out);
346   CHECK_ARGS(args, kDimensions, picojson::array, out);
347
348   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
349   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
350   if (nullptr == tensorsInfo) {
351     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
352                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
353     return;
354   }
355
356   unsigned int dimensions[ML_TENSOR_RANK_LIMIT] = {};
357   auto dim = args.get(kDimensions).get<picojson::array>();
358   PlatformResult result = util::GetDimensionsFromJsonArray(dim, dimensions);
359   if (!result) {
360     LogAndReportError(result, &out);
361     return;
362   }
363
364   int index = static_cast<int>(args.get(kIndex).get<double>());
365   result = tensorsInfo->NativeSetTensorDimensions(index, dimensions);
366   if (!result) {
367     LogAndReportError(result, &out);
368     return;
369   }
370   ReportSuccess(out);
371 }
372
373 void MlInstance::MLTensorsInfoGetTensorName(const picojson::value& args, picojson::object& out) {
374   ScopeLogger("args: %s", args.serialize().c_str());
375   CHECK_ARGS(args, kTensorsInfoId, double, out);
376   CHECK_ARGS(args, kIndex, double, out);
377
378   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
379   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
380   if (nullptr == tensorsInfo) {
381     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
382                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
383     return;
384   }
385   int index = static_cast<int>(args.get(kIndex).get<double>());
386   std::string name;
387   PlatformResult result = tensorsInfo->NativeGetTensorName(index, &name);
388   if (!result) {
389     LogAndReportError(result, &out);
390     return;
391   }
392   picojson::value val = picojson::value{name};
393   ReportSuccess(val, out);
394 }
395
396 void MlInstance::MLTensorsInfoSetTensorName(const picojson::value& args, picojson::object& out) {
397   ScopeLogger("args: %s", args.serialize().c_str());
398   CHECK_ARGS(args, kTensorsInfoId, double, out);
399   CHECK_ARGS(args, kIndex, double, out);
400   CHECK_ARGS(args, kName, std::string, out);
401
402   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
403   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
404   if (nullptr == tensorsInfo) {
405     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
406                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
407     return;
408   }
409
410   int index = static_cast<int>(args.get(kIndex).get<double>());
411   const std::string& name = args.get(kName).get<std::string>();
412   PlatformResult result = tensorsInfo->NativeSetTensorName(index, name);
413   if (!result) {
414     LogAndReportError(result, &out);
415     return;
416   }
417   ReportSuccess(out);
418 }
419
420 void MlInstance::MLTensorsInfoGetTensorSize(const picojson::value& args, picojson::object& out) {
421   ScopeLogger("args: %s", args.serialize().c_str());
422   CHECK_ARGS(args, kTensorsInfoId, double, out);
423   CHECK_ARGS(args, kIndex, double, out);
424
425   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
426   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
427   if (nullptr == tensorsInfo) {
428     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
429                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
430     return;
431   }
432   int index = static_cast<int>(args.get(kIndex).get<double>());
433   size_t size;
434   PlatformResult result = tensorsInfo->NativeGetTensorSize(index, &size);
435   if (!result) {
436     LogAndReportError(result, &out);
437     return;
438   }
439
440   picojson::value val = picojson::value{static_cast<double>(size)};
441   ReportSuccess(val, out);
442 }
443
444 void MlInstance::MLTensorsInfoGetTensorType(const picojson::value& args, picojson::object& out) {
445   ScopeLogger("args: %s", args.serialize().c_str());
446   CHECK_ARGS(args, kTensorsInfoId, double, out);
447   CHECK_ARGS(args, kIndex, double, out);
448
449   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
450   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
451   if (nullptr == tensorsInfo) {
452     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
453                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
454     return;
455   }
456
457   int index = static_cast<int>(args.get(kIndex).get<double>());
458   ml_tensor_type_e tensorTypeEnum = ML_TENSOR_TYPE_UNKNOWN;
459   PlatformResult result = tensorsInfo->NativeGetTensorType(index, &tensorTypeEnum);
460   if (!result) {
461     LogAndReportError(result, &out);
462     return;
463   }
464   std::string tensorTypeString;
465   result = types::TensorTypeEnum.getName(tensorTypeEnum, &tensorTypeString);
466   if (!result) {
467     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Error getting name of TensorType"),
468                       &out,
469                       ("TensorTypeEnum.getName() failed, error: %s", result.message().c_str()));
470     return;
471   }
472
473   picojson::value val = picojson::value{tensorTypeString};
474   ReportSuccess(val, out);
475 }
476
477 void MlInstance::MLTensorsInfoSetTensorType(const picojson::value& args, picojson::object& out) {
478   ScopeLogger("args: %s", args.serialize().c_str());
479   CHECK_ARGS(args, kTensorsInfoId, double, out);
480   CHECK_ARGS(args, kIndex, double, out);
481   CHECK_ARGS(args, kType, std::string, out);
482
483   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
484   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
485   if (nullptr == tensorsInfo) {
486     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
487                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
488     return;
489   }
490
491   const std::string& tensorType = args.get(kType).get<std::string>();
492   ml_tensor_type_e tensorTypeEnum = ML_TENSOR_TYPE_UNKNOWN;
493   PlatformResult result = types::TensorTypeEnum.getValue(tensorType, &tensorTypeEnum);
494   if (!result) {
495     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Error getting value of TensorType"),
496                       &out,
497                       ("TensorTypeEnum.getValue() failed, error: %s", result.message().c_str()));
498     return;
499   }
500
501   int index = static_cast<int>(args.get(kIndex).get<double>());
502   result = tensorsInfo->NativeSetTensorType(index, tensorTypeEnum);
503   if (!result) {
504     LogAndReportError(result, &out);
505     return;
506   }
507   ReportSuccess(out);
508 }
509
510 void MlInstance::MLTensorsInfoGetTensorsData(const picojson::value& args, picojson::object& out) {
511   ScopeLogger("args: %s", args.serialize().c_str());
512   CHECK_ARGS(args, kTensorsInfoId, double, out);
513
514   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
515   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
516   if (nullptr == tensorsInfo) {
517     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
518                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
519     return;
520   }
521
522   TensorsData* tensorsData = GetTensorsInfoManager().CreateTensorsData(tensorsInfo);
523   if (!tensorsData) {
524     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
525                       ("Could not create TensorsData"));
526     return;
527   }
528
529   out[kTensorsDataId] = picojson::value(static_cast<double>(tensorsData->Id()));
530   out[kTensorsInfoId] = picojson::value(static_cast<double>(tensorsData->TensorsInfoId()));
531   ReportSuccess(out);
532 }
533
534 void MlInstance::MLTensorsInfoClone(const picojson::value& args, picojson::object& out) {
535   ScopeLogger("args: %s", args.serialize().c_str());
536   CHECK_ARGS(args, kTensorsInfoId, double, out);
537
538   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
539   TensorsInfo* tensorsInfo = GetTensorsInfoManager().GetTensorsInfo(tensorsInfoId);
540   if (nullptr == tensorsInfo) {
541     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
542                       ("Could not find TensorsInfo handle with given id: %d", tensorsInfoId));
543     return;
544   }
545
546   TensorsInfo* cloned = GetTensorsInfoManager().CloneTensorsInfo(tensorsInfo);
547   if (nullptr == cloned) {
548     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
549                       ("Could not clone TensorsInfo with given id: %d", tensorsInfoId));
550     return;
551   }
552
553   out["id"] = picojson::value(static_cast<double>(cloned->Id()));
554   ReportSuccess(out);
555 }
556
557 void MlInstance::MLTensorsInfoEquals(const picojson::value& args, picojson::object& out) {
558   ScopeLogger("args: %s", args.serialize().c_str());
559   CHECK_ARGS(args, kTensorsInfoId, double, out);
560   CHECK_ARGS(args, kOtherId, double, out);
561
562   int firstId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
563   int secondId = static_cast<int>(args.get(kOtherId).get<double>());
564
565   TensorsInfo* first = GetTensorsInfoManager().GetTensorsInfo(firstId);
566   if (nullptr == first) {
567     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
568                       ("Could not find TensorsInfo handle with given id: %d", firstId));
569     return;
570   }
571
572   TensorsInfo* second = GetTensorsInfoManager().GetTensorsInfo(secondId);
573   if (nullptr == second) {
574     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
575                       ("Could not find TensorsInfo handle with given id: %d", secondId));
576     return;
577   }
578
579   bool equals = first->Equals(second);
580   picojson::value val = picojson::value{equals};
581   ReportSuccess(val, out);
582 }
583
584 void MlInstance::MLTensorsInfoDispose(const picojson::value& args, picojson::object& out) {
585   ScopeLogger("args: %s", args.serialize().c_str());
586   CHECK_ARGS(args, kTensorsInfoId, double, out);
587   int tensorsInfoId = static_cast<int>(args.get(kTensorsInfoId).get<double>());
588
589   PlatformResult result = GetTensorsInfoManager().DisposeTensorsInfo(tensorsInfoId);
590   if (!result) {
591     LogAndReportError(result, &out);
592   }
593   ReportSuccess(out);
594 }
595
596 void MlInstance::MLTensorsDataDispose(const picojson::value& args, picojson::object& out) {
597   ScopeLogger("args: %s", args.serialize().c_str());
598   CHECK_ARGS(args, kTensorsDataId, double, out);
599   int tensors_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
600
601   TensorsData* tensors_data = GetTensorsDataManager().GetTensorsData(tensors_data_id);
602   if (nullptr == tensors_data) {
603     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsData error"), &out,
604                       ("Could not find TensorsData handle with given id: %d", tensors_data_id));
605     return;
606   }
607
608   if (!tensors_data->DisposableFromJS()) {
609     ReportSuccess(out);
610     return;
611   }
612
613   // Dispose underlying tensorsInfo
614   PlatformResult result = GetTensorsInfoManager().DisposeTensorsInfo(tensors_data->TensorsInfoId());
615   if (!result) {
616     LogAndReportError(result, &out);
617     return;
618   }
619
620   result = GetTensorsDataManager().DisposeTensorsData(tensors_data_id);
621   if (!result) {
622     LogAndReportError(result, &out);
623     return;
624   }
625   ReportSuccess(out);
626 }
627
628 void MlInstance::MLTensorsDataGetTensorRawData(const picojson::value& args, picojson::object& out) {
629   ScopeLogger("args: %s", args.serialize().c_str());
630   CHECK_ARGS(args, kTensorsDataId, double, out);
631   CHECK_ARGS(args, kIndex, double, out);
632   CHECK_ARGS(args, kLocation, picojson::array, out);
633   CHECK_ARGS(args, kSize, picojson::array, out);
634
635   int tensor_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
636   int index = static_cast<int>(args.get(kIndex).get<double>());
637
638   TensorsData* tensors_data = GetTensorsDataManager().GetTensorsData(tensor_data_id);
639   if (nullptr == tensors_data) {
640     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsData error"), &out,
641                       ("Could not find TensorsData handle with given id: %d", tensor_data_id));
642     return;
643   }
644
645   unsigned int location[ML_TENSOR_RANK_LIMIT] = {};
646   PlatformResult result =
647       util::GetLocationFromJsonArray(args.get(kLocation).get<picojson::array>(), location);
648   if (!result) {
649     LogAndReportError(result, &out);
650     return;
651   }
652
653   unsigned int dimensions[ML_TENSOR_RANK_LIMIT] = {};
654   result = tensors_data->GetTensorsInfo()->NativeGetTensorDimensions(index, dimensions);
655   if (!result) {
656     LogAndReportError(result, &out);
657     return;
658   }
659
660   unsigned int size[ML_TENSOR_RANK_LIMIT] = {};
661   result = util::GetSizeFromJsonArray(args.get(kSize).get<picojson::array>(), location, dimensions,
662                                       size);
663   if (!result) {
664     LogAndReportError(result, &out);
665     return;
666   }
667
668   TensorRawData raw_data;
669   result = tensors_data->GetTensorRawData(index, location, size, &raw_data);
670   if (!result) {
671     LogAndReportError(result, &out);
672     return;
673   }
674
675   std::vector<std::uint8_t> out_data{raw_data.data, raw_data.data + raw_data.size_in_bytes};
676   out[kBuffer] = picojson::value(picojson::string_type, true);
677   common::encode_binary_in_string(out_data, out[kBuffer].get<std::string>());
678
679   out[kType] = picojson::value(raw_data.type_str);
680   picojson::array shape = picojson::array{};
681   for (int i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
682     shape.push_back(picojson::value{static_cast<double>(raw_data.shape[i])});
683   }
684   out[kShape] = picojson::value{shape};
685
686   ReportSuccess(out);
687 }
688
689 void MlInstance::MLTensorsDataGetTensorRawDataBinary(const picojson::value& args,
690                                                      std::vector<uint8_t>* out) {
691   ScopeLogger("args: %s", args.serialize().c_str());
692   // TODO handle errors to out
693   // CHECK_ARGS(args, kTensorsDataId, double, out);
694   // CHECK_ARGS(args, kIndex, double, out);
695   // CHECK_ARGS(args, kLocation, picojson::array, out);
696   // CHECK_ARGS(args, kSize, picojson::array, out);
697
698   int tensor_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
699   int index = static_cast<int>(args.get(kIndex).get<double>());
700
701   TensorsData* tensors_data = GetTensorsDataManager().GetTensorsData(tensor_data_id);
702   if (nullptr == tensors_data) {
703     LoggerE("Could not find TensorsData handle with given id: %d", tensor_data_id);
704     tools::ReportErrorToBinary(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsData error"),
705                                out);
706     return;
707   }
708
709   unsigned int location[ML_TENSOR_RANK_LIMIT] = {};
710   PlatformResult result =
711       util::GetLocationFromJsonArray(args.get(kLocation).get<picojson::array>(), location);
712   if (!result) {
713     LoggerE("Reporting error.");
714     tools::ReportErrorToBinary(result, out);
715     return;
716   }
717
718   unsigned int dimensions[ML_TENSOR_RANK_LIMIT] = {};
719   result = tensors_data->GetTensorsInfo()->NativeGetTensorDimensions(index, dimensions);
720   if (!result) {
721     LoggerE("Reporting error.");
722     tools::ReportErrorToBinary(result, out);
723     return;
724   }
725
726   unsigned int size[ML_TENSOR_RANK_LIMIT] = {};
727   result = util::GetSizeFromJsonArray(args.get(kSize).get<picojson::array>(), location, dimensions,
728                                       size);
729   if (!result) {
730     LoggerE("Reporting error.");
731     tools::ReportErrorToBinary(result, out);
732     return;
733   }
734
735   TensorRawData raw_data;
736   result = tensors_data->GetTensorRawData(index, location, size, &raw_data);
737   if (!result) {
738     LoggerE("Reporting error.");
739     tools::ReportErrorToBinary(result, out);
740     return;
741   }
742
743   picojson::value result_json = picojson::value(picojson::object());
744   auto& out_json = result_json.get<picojson::object>();
745
746   out_json[kType] = picojson::value(raw_data.type_str);
747   picojson::array shape = picojson::array{};
748   for (int i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
749     shape.push_back(picojson::value{static_cast<double>(raw_data.shape[i])});
750   }
751   out_json[kShape] = picojson::value{shape};
752
753   std::vector<std::uint8_t> out_data{raw_data.data, raw_data.data + raw_data.size_in_bytes};
754
755   // FORMAT:
756   // 4 byte    === JSON lenght (N)
757   // N bytest  === JSON data
758   tools::ReportSuccessToBinary(result_json, out);
759   // 4 byte    === buffer length (M)
760   // M bytes   === buffer data
761   tools::ReportDataToBinary(out_data, out);
762 }
763
764 void MlInstance::MLTensorsDataGetTensorType(const picojson::value& args, picojson::object& out) {
765   ScopeLogger("args: %s", args.serialize().c_str());
766   CHECK_ARGS(args, kTensorsDataId, double, out);
767   CHECK_ARGS(args, kIndex, double, out);
768
769   int tensors_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
770   int index = static_cast<int>(args.get(kIndex).get<double>());
771
772   TensorsData* tensors_data = GetTensorsDataManager().GetTensorsData(tensors_data_id);
773   if (nullptr == tensors_data) {
774     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsData error"), &out,
775                       ("Could not find TensorsData handle with given id: %d", tensors_data_id));
776     return;
777   }
778
779   std::string tensor_type_string;
780   PlatformResult result =
781       types::TensorTypeEnum.getName(tensors_data->GetTensorType(index), &tensor_type_string);
782   if (!result) {
783     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Error getting name of TensorType"),
784                       &out,
785                       ("TensorTypeEnum.getName() failed, error: %s", result.message().c_str()));
786     return;
787   }
788
789   picojson::value val = picojson::value{tensor_type_string};
790   ReportSuccess(val, out);
791 }
792
793 void MlInstance::MLTensorsDataSetTensorRawData(const picojson::value& args, picojson::object& out) {
794   ScopeLogger();
795   CHECK_ARGS(args, kTensorsDataId, double, out);
796   CHECK_ARGS(args, kIndex, double, out);
797   CHECK_ARGS(args, kBuffer, std::string, out);
798   CHECK_ARGS(args, kLocation, picojson::array, out);
799   CHECK_ARGS(args, kSize, picojson::array, out);
800   LoggerD("%s, %s", kTensorsDataId.c_str(), args.get(kTensorsDataId).serialize().c_str());
801   LoggerD("%s, %s", kIndex.c_str(), args.get(kIndex).serialize().c_str());
802   LoggerD("%s, %s", kLocation.c_str(), args.get(kLocation).serialize().c_str());
803   LoggerD("%s, %s", kSize.c_str(), args.get(kSize).serialize().c_str());
804
805   int tensors_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
806   int index = static_cast<int>(args.get(kIndex).get<double>());
807
808   TensorsData* tensors_data = GetTensorsDataManager().GetTensorsData(tensors_data_id);
809   if (nullptr == tensors_data) {
810     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsData error"), &out,
811                       ("Could not find TensorsData handle with given id: %d", tensors_data_id));
812     return;
813   }
814
815   unsigned int location[ML_TENSOR_RANK_LIMIT] = {};
816   PlatformResult result =
817       util::GetLocationFromJsonArray(args.get(kLocation).get<picojson::array>(), location);
818   if (!result) {
819     LogAndReportError(result, &out);
820     return;
821   }
822
823   unsigned int dimensions[ML_TENSOR_RANK_LIMIT] = {};
824   result = tensors_data->GetTensorsInfo()->NativeGetTensorDimensions(index, dimensions);
825   if (!result) {
826     LogAndReportError(result, &out);
827     return;
828   }
829
830   unsigned int size[ML_TENSOR_RANK_LIMIT] = {};
831   result = util::GetSizeFromJsonArray(args.get(kSize).get<picojson::array>(), location, dimensions,
832                                       size);
833   if (!result) {
834     LogAndReportError(result, &out);
835     return;
836   }
837   const std::string& str_buffer = args.get(kBuffer).get<std::string>();
838   std::vector<std::uint8_t> buffer;
839   common::decode_binary_from_string(str_buffer, buffer);
840
841   TensorRawData raw_data{buffer.data(), buffer.size()};
842   result = tensors_data->SetTensorRawData(index, location, size, raw_data);
843   if (!result) {
844     LogAndReportError(result, &out);
845     return;
846   }
847
848   ReportSuccess(out);
849 }
850
851 void MlInstance::MLTensorsDataSetTensorRawDataBinary(const char* data, size_t data_size,
852                                                      picojson::object& out) {
853   ScopeLogger();
854   /*
855   METHOD_ID WAS ALREADY REMOVED during message handling
856   other data packed with following format:
857     // FORMAT:
858     // 1 byte    === methodIndex   /// already parsed
859     // 4 byte    === JSON lenght (N)
860     // 4 byte    === buffer length (M)
861     // N bytest  === JSON data
862     // M bytes   === buffer data
863   */
864   unsigned int call_args_len_begin = 0;
865   unsigned int call_args_len = static_cast<unsigned int>(
866       (data[call_args_len_begin] << 24) + (data[call_args_len_begin + 1] << 16) +
867       (data[call_args_len_begin + 2] << 8) + (data[call_args_len_begin + 3]));
868
869   unsigned int buffer_len_begin = call_args_len_begin + 4;
870   unsigned int buffer_len = static_cast<unsigned int>(
871       (data[buffer_len_begin] << 24) + (data[buffer_len_begin + 1] << 16) +
872       (data[buffer_len_begin + 2] << 8) + (data[buffer_len_begin + 3]));
873
874   unsigned int call_args_begin = buffer_len_begin + 4;
875   std::string call_args(data + call_args_begin, call_args_len);
876
877   picojson::value args;
878   picojson::parse(args, call_args);
879
880   unsigned int buffer_begin = call_args_begin + call_args_len;
881
882   CHECK_ARGS(args, kTensorsDataId, double, out);
883   CHECK_ARGS(args, kIndex, double, out);
884   CHECK_ARGS(args, kLocation, picojson::array, out);
885   CHECK_ARGS(args, kSize, picojson::array, out);
886   LoggerD("%s, %s", kTensorsDataId.c_str(), args.get(kTensorsDataId).serialize().c_str());
887   LoggerD("%s, %s", kIndex.c_str(), args.get(kIndex).serialize().c_str());
888   LoggerD("%s, %s", kLocation.c_str(), args.get(kLocation).serialize().c_str());
889   LoggerD("%s, %s", kSize.c_str(), args.get(kSize).serialize().c_str());
890
891   int tensors_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
892   int index = static_cast<int>(args.get(kIndex).get<double>());
893
894   TensorsData* tensors_data = GetTensorsDataManager().GetTensorsData(tensors_data_id);
895   if (nullptr == tensors_data) {
896     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsData error"), &out,
897                       ("Could not find TensorsData handle with given id: %d", tensors_data_id));
898     return;
899   }
900
901   unsigned int location[ML_TENSOR_RANK_LIMIT] = {};
902   PlatformResult result =
903       util::GetLocationFromJsonArray(args.get(kLocation).get<picojson::array>(), location);
904   if (!result) {
905     LogAndReportError(result, &out);
906     return;
907   }
908
909   unsigned int dimensions[ML_TENSOR_RANK_LIMIT] = {};
910   result = tensors_data->GetTensorsInfo()->NativeGetTensorDimensions(index, dimensions);
911   if (!result) {
912     LogAndReportError(result, &out);
913     return;
914   }
915
916   unsigned int size[ML_TENSOR_RANK_LIMIT] = {};
917   result = util::GetSizeFromJsonArray(args.get(kSize).get<picojson::array>(), location, dimensions,
918                                       size);
919   if (!result) {
920     LogAndReportError(result, &out);
921     return;
922   }
923
924   TensorRawData raw_data{reinterpret_cast<uint8_t*>(const_cast<char*>(data + buffer_begin)),
925                          buffer_len};
926   result = tensors_data->SetTensorRawData(index, location, size, raw_data);
927   if (!result) {
928     LogAndReportError(result, &out);
929     return;
930   }
931
932   ReportSuccess(out);
933 }
934
935 void MlInstance::MLSingleManagerOpenModel(const picojson::value& args, picojson::object& out) {
936   ScopeLogger("args: %s", args.serialize().c_str());
937   CHECK_ARGS(args, kModelPath, std::string, out);
938   CHECK_ARGS(args, kInTensorsInfo, double, out);
939   CHECK_ARGS(args, kOutTensorsInfo, double, out);
940   CHECK_ARGS(args, kFwType, std::string, out);
941   CHECK_ARGS(args, kHwType, std::string, out);
942   CHECK_ARGS(args, kIsDynamicMode, bool, out);
943
944   const auto& model_path = common::tools::ConvertUriToPath(args.get(kModelPath).get<std::string>());
945   CHECK_STORAGE_ACCESS(model_path, &out);
946
947   TensorsInfo* in_tensors_info = nullptr;
948   auto inTensorId = static_cast<int>(args.get(kInTensorsInfo).get<double>());
949   if (kNoId != inTensorId) {
950     in_tensors_info = GetTensorsInfoManager().GetTensorsInfo(inTensorId);
951     if (nullptr == in_tensors_info) {
952       LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
953                         ("Could not find TensorsInfo handle with given id: %d", inTensorId));
954       return;
955     }
956   }
957
958   TensorsInfo* out_tensors_info = nullptr;
959   auto outTensorId = static_cast<int>(args.get(kOutTensorsInfo).get<double>());
960   if (kNoId != outTensorId) {
961     out_tensors_info = GetTensorsInfoManager().GetTensorsInfo(outTensorId);
962     if (nullptr == out_tensors_info) {
963       LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
964                         ("Could not find TensorsInfo handle with given id: %d", outTensorId));
965       return;
966     }
967   }
968
969   ml_nnfw_type_e nnfw_e = ML_NNFW_TYPE_ANY;
970   PlatformResult result =
971       types::NNFWTypeEnum.getValue(args.get(kFwType).get<std::string>(), &nnfw_e);
972   if (!result) {
973     LogAndReportError(result, &out);
974     return;
975   }
976
977   ml_nnfw_hw_e hw_e = ML_NNFW_HW_ANY;
978   result = types::HWTypeEnum.getValue(args.get(kHwType).get<std::string>(), &hw_e);
979   if (!result) {
980     LogAndReportError(result, &out);
981     return;
982   }
983
984   auto is_dynamic_mode = args.get(kIsDynamicMode).get<bool>();
985
986   auto logic = [this, model_path, in_tensors_info, out_tensors_info, nnfw_e, hw_e,
987                 is_dynamic_mode](decltype(out) out) {
988     PlatformResult result = common::tools::CheckFileAvailability(model_path);
989     if (!result) {
990       LogAndReportError(
991           PlatformResult(ErrorCode::NOT_FOUND_ERR, "File does not exist or is not accessible"),
992           &out, ("File does not exist or is not accessible: %s", model_path.c_str()));
993       return;
994     }
995
996     int res_id = -1;
997     result = single_manager_.OpenModel(model_path, in_tensors_info, out_tensors_info, nnfw_e, hw_e,
998                                        is_dynamic_mode, &res_id);
999     if (!result) {
1000       ReportError(result, &out);
1001       return;
1002     }
1003
1004     out[kId] = picojson::value(static_cast<double>(res_id));
1005     ReportSuccess(out);
1006   };
1007
1008   bool async =
1009       (args.contains(kAsync) && args.get(kAsync).is<bool>()) ? args.get(kAsync).get<bool>() : false;
1010
1011   if (!async) {
1012     logic(out);
1013   } else {
1014     // Async logic
1015     CHECK_ARGS(args, kCallbackId, double, out);
1016     double callback_id = args.get(kCallbackId).get<double>();
1017     this->worker_.add_job([this, callback_id, logic] {
1018       picojson::value response = picojson::value(picojson::object());
1019       picojson::object& async_out = response.get<picojson::object>();
1020       async_out[kCallbackId] = picojson::value(callback_id);
1021       logic(async_out);
1022       this->PostMessage(response.serialize().c_str());
1023     });
1024
1025     // Sync return
1026     ReportSuccess(out);
1027   }
1028 }
1029
1030 void MlInstance::MLSingleShotGetTensorsInfo(const picojson::value& args, picojson::object& out) {
1031   ScopeLogger("args: %s", args.serialize().c_str());
1032   CHECK_ARGS(args, kId, double, out);
1033   CHECK_ARGS(args, kGetInputMode, bool, out);
1034
1035   auto id = static_cast<int>(args.get(kId).get<double>());
1036   // true means gathering input data; false means gathering output data
1037   auto get_input_mode = static_cast<int>(args.get(kGetInputMode).get<bool>());
1038
1039   int res_id = -1;
1040   auto ret = single_manager_.GetNativeTensorsInfo(id, get_input_mode, &res_id);
1041   if (!ret) {
1042     ReportError(ret, &out);
1043     return;
1044   }
1045
1046   out[kId] = picojson::value(static_cast<double>(res_id));
1047   ReportSuccess(out);
1048 }
1049
1050 void MlInstance::MLSingleShotSetInputInfo(const picojson::value& args, picojson::object& out) {
1051   ScopeLogger("args: %s", args.serialize().c_str());
1052   CHECK_ARGS(args, kId, double, out);
1053   CHECK_ARGS(args, kInTensorsInfo, double, out);
1054
1055   auto id = static_cast<int>(args.get(kId).get<double>());
1056   auto inTensorId = static_cast<int>(args.get(kInTensorsInfo).get<double>());
1057
1058   TensorsInfo* in_tensors_info = GetTensorsInfoManager().GetTensorsInfo(inTensorId);
1059   if (nullptr == in_tensors_info) {
1060     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
1061                       ("Could not find TensorsInfo handle with given id: %d", inTensorId));
1062     return;
1063   }
1064
1065   TensorsInfo* clone = GetTensorsInfoManager().CloneTensorsInfo(in_tensors_info);
1066
1067   auto ret = single_manager_.SetNativeInputInfo(id, in_tensors_info);
1068   if (!ret) {
1069     ReportError(ret, &out);
1070     return;
1071   }
1072
1073   out[kId] = picojson::value(static_cast<double>(clone->Id()));
1074   ReportSuccess(out);
1075 }
1076
1077 void MlInstance::MLSingleShotInvoke(const picojson::value& args, picojson::object& out) {
1078   ScopeLogger("args: %s", args.serialize().c_str());
1079   CHECK_ARGS(args, kId, double, out);
1080   CHECK_ARGS(args, kTensorsDataId, double, out);
1081
1082   int id = static_cast<int>(args.get(kId).get<double>());
1083   int tensors_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
1084   bool async =
1085       (args.contains(kAsync) && args.get(kAsync).is<bool>()) ? args.get(kAsync).get<bool>() : false;
1086
1087   TensorsData* in_tensors_data = GetTensorsDataManager().GetTensorsData(tensors_data_id);
1088   if (async && in_tensors_data) {
1089     // in case of async flow need to prevent destroying entry data during invoke
1090     // from JS, creation of a copy
1091     in_tensors_data = GetTensorsInfoManager().CloneNativeTensorWithData(
1092         in_tensors_data->GetTensorsInfo()->Handle(), in_tensors_data->Handle());
1093   }
1094   if (nullptr == in_tensors_data) {
1095     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsData error"), &out,
1096                       ("Could not find TensorsData handle with given id: %d", tensors_data_id));
1097     return;
1098   }
1099
1100   auto logic = [this, id, tensors_data_id, in_tensors_data, async](decltype(out) out) {
1101     TensorsData* out_tensors_data = nullptr;
1102     auto ret = single_manager_.Invoke(id, in_tensors_data, &out_tensors_data);
1103     if (async) {
1104       // in case of async flow, the in_tensor_data with underlying TensorsInfo
1105       // was copied, thus need to be released here
1106       GetTensorsInfoManager().DisposeTensorsInfo(in_tensors_data->GetTensorsInfo());
1107       GetTensorsDataManager().DisposeTensorsData(in_tensors_data);
1108     }
1109     if (!ret) {
1110       ReportError(ret, &out);
1111       return;
1112     }
1113
1114     out[kTensorsDataId] = picojson::value(static_cast<double>(out_tensors_data->Id()));
1115     out[kTensorsInfoId] = picojson::value(static_cast<double>(out_tensors_data->TensorsInfoId()));
1116     ReportSuccess(out);
1117   };
1118
1119   if (!async) {
1120     logic(out);
1121   } else {
1122     CHECK_ARGS(args, kCallbackId, double, out);
1123     double callback_id = args.get(kCallbackId).get<double>();
1124     this->worker_.add_job([this, callback_id, logic] {
1125       picojson::value response = picojson::value(picojson::object());
1126       picojson::object& async_out = response.get<picojson::object>();
1127       async_out[kCallbackId] = picojson::value(callback_id);
1128       logic(async_out);
1129       this->PostMessage(response.serialize().c_str());
1130     });
1131
1132     // Sync return
1133     ReportSuccess(out);
1134   }
1135 }
1136
1137 void MlInstance::MLSingleShotGetValue(const picojson::value& args, picojson::object& out) {
1138   ScopeLogger("args: %s", args.serialize().c_str());
1139   CHECK_ARGS(args, kId, double, out);
1140   CHECK_ARGS(args, kName, std::string, out);
1141
1142   auto id = static_cast<int>(args.get(kId).get<double>());
1143   const auto& name = args.get(kName).get<std::string>();
1144   std::string value;
1145   auto ret = single_manager_.GetValue(id, name, value);
1146   if (!ret) {
1147     ReportError(ret, &out);
1148     return;
1149   }
1150
1151   picojson::value val = picojson::value{value};
1152   ReportSuccess(val, out);
1153 }
1154
1155 void MlInstance::MLSingleShotSetValue(const picojson::value& args, picojson::object& out) {
1156   ScopeLogger("args: %s", args.serialize().c_str());
1157   CHECK_ARGS(args, kId, double, out);
1158   CHECK_ARGS(args, kName, std::string, out);
1159   CHECK_ARGS(args, kValue, std::string, out);
1160
1161   auto id = static_cast<int>(args.get(kId).get<double>());
1162   const auto& name = args.get(kName).get<std::string>();
1163   const auto& value = args.get(kValue).get<std::string>();
1164
1165   auto ret = single_manager_.SetValue(id, name, value);
1166   if (!ret) {
1167     ReportError(ret, &out);
1168     return;
1169   }
1170
1171   ReportSuccess(out);
1172 }
1173
1174 void MlInstance::MLSingleShotSetTimeout(const picojson::value& args, picojson::object& out) {
1175   ScopeLogger("args: %s", args.serialize().c_str());
1176   CHECK_ARGS(args, kId, double, out);
1177   CHECK_ARGS(args, kTimeout, double, out);
1178
1179   auto id = static_cast<int>(args.get(kId).get<double>());
1180   auto timeout = static_cast<unsigned long>(args.get(kTimeout).get<double>());
1181
1182   auto ret = single_manager_.SetTimeout(id, timeout);
1183   if (!ret) {
1184     ReportError(ret, &out);
1185     return;
1186   }
1187
1188   ReportSuccess(out);
1189 }
1190
1191 void MlInstance::MLSingleShotClose(const picojson::value& args, picojson::object& out) {
1192   ScopeLogger("args: %s", args.serialize().c_str());
1193   CHECK_ARGS(args, kId, double, out);
1194
1195   auto id = static_cast<int>(args.get(kId).get<double>());
1196
1197   auto ret = single_manager_.Close(id);
1198   if (!ret) {
1199     ReportError(ret, &out);
1200     return;
1201   }
1202
1203   ReportSuccess(out);
1204 }
1205
1206 namespace {
1207
1208 bool CreatePipelineArgumentsAreInvalid(const picojson::value& args) {
1209   ScopeLogger();
1210
1211   auto arguments_valid = args.get(kId).is<double>();
1212   arguments_valid &= args.get(kDefinition).is<std::string>();
1213   arguments_valid &= (args.get(kPipelineStateChangeListenerName).is<std::string>() ||
1214                       args.get(kPipelineStateChangeListenerName).is<picojson::null>());
1215   LoggerD("CreatePipeline arguments are %s", arguments_valid ? "valid" : "invalid");
1216
1217   return !arguments_valid;
1218 }
1219
1220 };  // namespace
1221
1222 void MlInstance::MLPipelineManagerCreatePipeline(const picojson::value& args,
1223                                                  picojson::object& out) {
1224   ScopeLogger("args: %s", args.serialize().c_str());
1225
1226   if (CreatePipelineArgumentsAreInvalid(args)) {
1227     ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Could not create pipeline"}, &out);
1228     return;
1229   }
1230
1231   auto id = static_cast<int>(args.get(kId).get<double>());
1232   auto definition = args.get(kDefinition).get<std::string>();
1233   auto state_change_listener_name =
1234       args.get(kPipelineStateChangeListenerName).is<std::string>()
1235           ? args.get(kPipelineStateChangeListenerName).get<std::string>()
1236           : "";
1237
1238   auto ret = pipeline_manager_.CreatePipeline(id, definition, state_change_listener_name);
1239
1240   if (!ret) {
1241     ReportError(ret, &out);
1242     return;
1243   }
1244
1245   ReportSuccess(out);
1246 }
1247
1248 void MlInstance::MLPipelineGetState(const picojson::value& args, picojson::object& out) {
1249   ScopeLogger("args: %s", args.serialize().c_str());
1250
1251   if (!args.get(kId).is<double>()) {
1252     LoggerD("id is not a number");
1253     ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Invalid pipeline"}, &out);
1254     return;
1255   }
1256   auto id = static_cast<int>(args.get(kId).get<double>());
1257
1258   picojson::value state_value{std::string{}};
1259   std::string* state_ptr = &state_value.get<std::string>();
1260   auto ret = pipeline_manager_.GetPipelineState(id, state_ptr);
1261   if (!ret) {
1262     ReportError(ret, &out);
1263     return;
1264   }
1265
1266   ReportSuccess(state_value, out);
1267 }
1268
1269 void MlInstance::MLPipelineStart(const picojson::value& args, picojson::object& out) {
1270   ScopeLogger("args: %s", args.serialize().c_str());
1271
1272   CHECK_ARGS(args, kId, double, out);
1273
1274   auto id = static_cast<int>(args.get(kId).get<double>());
1275
1276   PlatformResult result = pipeline_manager_.Start(id);
1277
1278   if (!result) {
1279     ReportError(result, &out);
1280     return;
1281   }
1282
1283   ReportSuccess(out);
1284 }
1285
1286 void MlInstance::MLPipelineStop(const picojson::value& args, picojson::object& out) {
1287   ScopeLogger("args: %s", args.serialize().c_str());
1288
1289   CHECK_ARGS(args, kId, double, out);
1290
1291   auto id = static_cast<int>(args.get(kId).get<double>());
1292
1293   PlatformResult result = pipeline_manager_.Stop(id);
1294
1295   if (!result) {
1296     LogAndReportError(result, &out);
1297     return;
1298   }
1299
1300   ReportSuccess(out);
1301 }
1302
1303 void MlInstance::MLPipelineDispose(const picojson::value& args, picojson::object& out) {
1304   ScopeLogger("args: %s", args.serialize().c_str());
1305
1306   if (!args.get(kId).is<double>()) {
1307     LoggerD("id is not a number");
1308     ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Invalid pipeline"}, &out);
1309     return;
1310   }
1311
1312   auto id = static_cast<int>(args.get(kId).get<double>());
1313   auto ret = pipeline_manager_.DisposePipeline(id);
1314
1315   if (!ret) {
1316     ReportError(ret, &out);
1317     return;
1318   }
1319
1320   ReportSuccess(out);
1321 }
1322
1323 void MlInstance::MLPipelineGetNodeInfo(const picojson::value& args, picojson::object& out) {
1324   ScopeLogger("args: %s", args.serialize().c_str());
1325
1326   CHECK_ARGS(args, kId, double, out);
1327   CHECK_ARGS(args, kName, std::string, out);
1328
1329   auto name = args.get(kName).get<std::string>();
1330   auto id = static_cast<int>(args.get(kId).get<double>());
1331
1332   PlatformResult result = pipeline_manager_.GetNodeInfo(id, name);
1333
1334   if (!result) {
1335     LogAndReportError(result, &out);
1336     return;
1337   }
1338
1339   ReportSuccess(out);
1340 }
1341
1342 void MlInstance::MLPipelineGetSource(const picojson::value& args, picojson::object& out) {
1343   ScopeLogger("args: %s", args.serialize().c_str());
1344
1345   CHECK_ARGS(args, kId, double, out);
1346   CHECK_ARGS(args, kName, std::string, out);
1347
1348   auto name = args.get(kName).get<std::string>();
1349   auto id = static_cast<int>(args.get(kId).get<double>());
1350
1351   PlatformResult result = pipeline_manager_.GetSource(id, name);
1352
1353   if (!result) {
1354     LogAndReportError(result, &out);
1355     return;
1356   }
1357
1358   ReportSuccess(out);
1359 }
1360
1361 void MlInstance::MLPipelineGetSwitch(const picojson::value& args, picojson::object& out) {
1362   ScopeLogger("args: %s", args.serialize().c_str());
1363
1364   if (!args.get(kId).is<double>()) {
1365     LoggerD("id is not a number");
1366     ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Invalid pipeline"}, &out);
1367     return;
1368   }
1369
1370   if (!args.get(kName).is<std::string>()) {
1371     LoggerD("name is not a string");
1372     ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Invalid name"}, &out);
1373     return;
1374   }
1375
1376   auto name = args.get(kName).get<std::string>();
1377   auto pipeline_id = static_cast<int>(args.get(kId).get<double>());
1378   std::string type;
1379
1380   auto ret = pipeline_manager_.GetSwitch(name, pipeline_id, &type);
1381   if (!ret) {
1382     LogAndReportError(ret, &out);
1383     return;
1384   }
1385
1386   out["type"] = picojson::value{type};
1387   ReportSuccess(out);
1388 }
1389
1390 void MlInstance::MLPipelineGetValve(const picojson::value& args, picojson::object& out) {
1391   ScopeLogger("args: %s", args.serialize().c_str());
1392
1393   CHECK_ARGS(args, kId, double, out);
1394   CHECK_ARGS(args, kName, std::string, out);
1395
1396   auto name = args.get(kName).get<std::string>();
1397   auto pipeline_id = args.get(kId).get<double>();
1398
1399   auto ret = pipeline_manager_.GetValve(name, pipeline_id);
1400   if (!ret) {
1401     LogAndReportError(ret, &out);
1402     return;
1403   }
1404
1405   ReportSuccess(out);
1406 }
1407
1408 void MlInstance::MLPipelineRegisterSinkListener(const picojson::value& args,
1409                                                 picojson::object& out) {
1410   ScopeLogger("args: %s", args.serialize().c_str());
1411
1412   CHECK_ARGS(args, kId, double, out);
1413   CHECK_ARGS(args, kName, std::string, out);
1414   CHECK_ARGS(args, kListenerName, std::string, out);
1415
1416   auto pipeline_id = static_cast<int>(args.get(kId).get<double>());
1417   auto sink_name = args.get(kName).get<std::string>();
1418   auto listener_name = args.get(kListenerName).get<std::string>();
1419
1420   auto ret = pipeline_manager_.RegisterSinkListener(sink_name, pipeline_id, listener_name);
1421   if (!ret) {
1422     LogAndReportError(ret, &out);
1423     return;
1424   }
1425
1426   ReportSuccess(out);
1427 }
1428
1429 void MlInstance::MLPipelineUnregisterSinkListener(const picojson::value& args,
1430                                                   picojson::object& out) {
1431   ScopeLogger("args: %s", args.serialize().c_str());
1432
1433   CHECK_ARGS(args, kId, double, out);
1434   CHECK_ARGS(args, kName, std::string, out);
1435
1436   auto pipeline_id = static_cast<int>(args.get(kId).get<double>());
1437   auto sink_name = args.get(kName).get<std::string>();
1438
1439   auto ret = pipeline_manager_.UnregisterSinkListener(sink_name, pipeline_id);
1440   if (!ret) {
1441     LogAndReportError(ret, &out);
1442     return;
1443   }
1444
1445   ReportSuccess(out);
1446 }
1447
1448 void MlInstance::MLPipelineManagerRegisterCustomFilter(const picojson::value& args,
1449                                                        picojson::object& out) {
1450   ScopeLogger("args: %s", args.serialize().c_str());
1451
1452   CHECK_ARGS(args, kName, std::string, out);
1453   CHECK_ARGS(args, kListenerName, std::string, out);
1454   CHECK_ARGS(args, kInputTensorsInfoId, double, out);
1455   CHECK_ARGS(args, kOutputTensorsInfoId, double, out);
1456
1457   const auto& custom_filter_name = args.get(kName).get<std::string>();
1458   const auto& listener_name = args.get(kListenerName).get<std::string>();
1459   auto input_tensors_info_id = static_cast<int>(args.get(kInputTensorsInfoId).get<double>());
1460   auto output_tensors_info_id = static_cast<int>(args.get(kOutputTensorsInfoId).get<double>());
1461
1462   TensorsInfo* input_tensors_info_ptr =
1463       GetTensorsInfoManager().GetTensorsInfo(input_tensors_info_id);
1464   if (!input_tensors_info_ptr) {
1465     LogAndReportError(
1466         PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
1467         ("Could not find TensorsInfo handle with given id: %d", input_tensors_info_id));
1468     return;
1469   }
1470
1471   TensorsInfo* output_tensors_info_ptr =
1472       GetTensorsInfoManager().GetTensorsInfo(output_tensors_info_id);
1473   if (!output_tensors_info_ptr) {
1474     LogAndReportError(
1475         PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsInfo error"), &out,
1476         ("Could not find TensorsInfo handle with given id: %d", output_tensors_info_id));
1477     return;
1478   }
1479
1480   auto ret = pipeline_manager_.RegisterCustomFilter(
1481       custom_filter_name, listener_name, input_tensors_info_ptr, output_tensors_info_ptr);
1482   if (!ret) {
1483     LogAndReportError(ret, &out);
1484     return;
1485   }
1486
1487   ReportSuccess(out);
1488 }
1489
1490 void MlInstance::MLPipelineManagerCustomFilterOutput(const picojson::value& args,
1491                                                      picojson::object& out) {
1492   ScopeLogger("args: %s", args.serialize().c_str());
1493
1494   CHECK_ARGS(args, kName, std::string, out);
1495   CHECK_ARGS(args, kStatus, double, out);
1496   CHECK_ARGS(args, kRequestId, double, out);
1497
1498   const auto& custom_filter_name = args.get(kName).get<std::string>();
1499   auto status = static_cast<int>(args.get(kStatus).get<double>());
1500   auto request_id = static_cast<int>(args.get(kRequestId).get<double>());
1501
1502   auto ret = pipeline_manager_.CustomFilterOutput(custom_filter_name, request_id, status);
1503   if (!ret) {
1504     LogAndReportError(ret, &out);
1505     return;
1506   }
1507
1508   ReportSuccess(out);
1509 }
1510
1511 void MlInstance::MLPipelineManagerUnregisterCustomFilter(const picojson::value& args,
1512                                                          picojson::object& out) {
1513   ScopeLogger("args: %s", args.serialize().c_str());
1514
1515   CHECK_ARGS(args, kName, std::string, out);
1516
1517   const auto& custom_filter_name = args.get(kName).get<std::string>();
1518
1519   auto ret = pipeline_manager_.UnregisterCustomFilter(custom_filter_name);
1520   if (!ret) {
1521     LogAndReportError(ret, &out);
1522     return;
1523   }
1524
1525   ReportSuccess(out);
1526 }
1527
1528 void MlInstance::MLPipelineNodeInfoGetProperty(const picojson::value& args, picojson::object& out) {
1529   ScopeLogger("args: %s", args.serialize().c_str());
1530
1531   CHECK_ARGS(args, kId, double, out);
1532   CHECK_ARGS(args, kNodeName, std::string, out);
1533   CHECK_ARGS(args, kName, std::string, out);
1534   CHECK_ARGS(args, kType, std::string, out);
1535
1536   auto id = static_cast<int>(args.get(kId).get<double>());
1537   const auto& name = args.get(kName).get<std::string>();
1538   const auto& node_name = args.get(kNodeName).get<std::string>();
1539   const auto& type = args.get(kType).get<std::string>();
1540
1541   PlatformResult result = pipeline_manager_.getProperty(id, node_name, name, type, &out);
1542
1543   if (!result) {
1544     LogAndReportError(result, &out);
1545     return;
1546   }
1547
1548   ReportSuccess(out);
1549 }
1550
1551 void MlInstance::MLPipelineNodeInfoSetProperty(const picojson::value& args, picojson::object& out) {
1552   ScopeLogger("args: %s", args.serialize().c_str());
1553
1554   CHECK_ARGS(args, kId, double, out);
1555   CHECK_ARGS(args, kNodeName, std::string, out);
1556   CHECK_ARGS(args, kName, std::string, out);
1557   CHECK_ARGS(args, kType, std::string, out);
1558
1559   auto id = static_cast<int>(args.get(kId).get<double>());
1560   const auto& name = args.get(kName).get<std::string>();
1561   const auto& node_name = args.get(kNodeName).get<std::string>();
1562   const auto& type = args.get(kType).get<std::string>();
1563
1564   CHECK_EXIST(args, kProperty, out);
1565   if (kBOOLEAN == type) {
1566     CHECK_TYPE(args, kProperty, bool, out, ErrorCode::TYPE_MISMATCH_ERR);
1567   } else if (kSTRING == type) {
1568     CHECK_TYPE(args, kProperty, std::string, out, ErrorCode::TYPE_MISMATCH_ERR);
1569   } else {
1570     CHECK_TYPE(args, kProperty, double, out, ErrorCode::TYPE_MISMATCH_ERR);
1571   }
1572   const picojson::value& property = args.get(kProperty);
1573
1574   PlatformResult result = pipeline_manager_.setProperty(id, node_name, name, type, property);
1575   if (!result) {
1576     LogAndReportError(result, &out);
1577     return;
1578   }
1579
1580   ReportSuccess(out);
1581 }
1582
1583 void MlInstance::MLPipelineGetInputTensorsInfo(const picojson::value& args, picojson::object& out) {
1584   ScopeLogger("args: [%s]", args.serialize().c_str());
1585
1586   CHECK_ARGS(args, kId, double, out);
1587   CHECK_ARGS(args, kName, std::string, out);
1588
1589   auto id = static_cast<int>(args.get(kId).get<double>());
1590   const auto& name = args.get(kName).get<std::string>();
1591
1592   int res_id = -1;
1593   PlatformResult result = pipeline_manager_.getInputTensorsInfo(id, name, &res_id);
1594   if (!result) {
1595     LogAndReportError(result, &out);
1596     return;
1597   }
1598
1599   ReportSuccess(out);
1600 }
1601
1602 void MlInstance::MLPipelineSourceInputData(const picojson::value& args, picojson::object& out) {
1603   ScopeLogger("args: [%s]", args.serialize().c_str());
1604
1605   CHECK_ARGS(args, kId, double, out);
1606   CHECK_ARGS(args, kName, std::string, out);
1607   CHECK_ARGS(args, kTensorsDataId, double, out);
1608
1609   auto pipeline_id = static_cast<int>(args.get(kId).get<double>());
1610   auto& source_name = args.get(kName).get<std::string>();
1611   auto tensor_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
1612
1613   TensorsData* tensors_data = GetTensorsDataManager().GetTensorsData(tensor_data_id);
1614
1615   if (nullptr == tensors_data) {
1616     LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal Source error"), &out,
1617                       ("Could not get TensorData handle with given id: %d", tensor_data_id));
1618     return;
1619   }
1620
1621   auto ret = pipeline_manager_.SourceInputData(pipeline_id, source_name, tensors_data);
1622   if (!ret) {
1623     LogAndReportError(ret, &out);
1624     return;
1625   }
1626
1627   ReportSuccess(out);
1628 }
1629
1630 void MlInstance::MLPipelineSwitchGetPadList(const picojson::value& args, picojson::object& out) {
1631   ScopeLogger("args: [%s]", args.serialize().c_str());
1632
1633   CHECK_ARGS(args, kId, double, out);
1634   CHECK_ARGS(args, kName, std::string, out);
1635
1636   auto pipeline_id = static_cast<int>(args.get(kId).get<double>());
1637   auto& switch_name = args.get(kName).get<std::string>();
1638
1639   picojson::array pad_list;
1640   auto ret = pipeline_manager_.SwitchGetPadList(pipeline_id, switch_name, &pad_list);
1641   if (!ret) {
1642     LogAndReportError(ret, &out);
1643     return;
1644   }
1645
1646   ReportSuccess(picojson::value{std::move(pad_list)}, out);
1647 }
1648
1649 void MlInstance::MLPipelineSwitchSelect(const picojson::value& args, picojson::object& out) {
1650   ScopeLogger("args: [%s]", args.serialize().c_str());
1651
1652   CHECK_ARGS(args, kId, double, out);
1653   CHECK_ARGS(args, kName, std::string, out);
1654   CHECK_ARGS(args, kPadName, std::string, out);
1655
1656   auto pipeline_id = args.get(kId).get<double>();
1657   auto& switch_name = args.get(kName).get<std::string>();
1658   auto& pad_name = args.get(kPadName).get<std::string>();
1659
1660   auto ret = pipeline_manager_.SwitchSelect(pipeline_id, switch_name, pad_name);
1661   if (!ret) {
1662     LogAndReportError(ret, &out);
1663     return;
1664   }
1665
1666   ReportSuccess(out);
1667 }
1668
1669 void MlInstance::MLPipelineValveSetOpen(const picojson::value& args, picojson::object& out) {
1670   ScopeLogger("args: %s", args.serialize().c_str());
1671
1672   CHECK_ARGS(args, kId, double, out);
1673   CHECK_ARGS(args, kName, std::string, out);
1674   CHECK_ARGS(args, kOpen, bool, out);
1675
1676   auto name = args.get(kName).get<std::string>();
1677   auto pipeline_id = args.get(kId).get<double>();
1678   auto open = args.get(kOpen).get<bool>();
1679
1680   auto ret = pipeline_manager_.ValveSetOpen(pipeline_id, name, open);
1681   if (!ret) {
1682     LogAndReportError(ret, &out);
1683     return;
1684   }
1685
1686   ReportSuccess(out);
1687 }
1688
1689 void MlInstance::MLPipelineValveIsOpen(const picojson::value& args, picojson::object& out) {
1690   ScopeLogger("args: %s", args.serialize().c_str());
1691
1692   CHECK_ARGS(args, kId, double, out);
1693   CHECK_ARGS(args, kName, std::string, out);
1694
1695   auto name = args.get(kName).get<std::string>();
1696   auto pipeline_id = args.get(kId).get<double>();
1697   auto open = true;
1698
1699   auto ret = pipeline_manager_.ValveIsOpen(pipeline_id, name, &open);
1700   if (!ret) {
1701     LogAndReportError(ret, &out);
1702     return;
1703   }
1704
1705   ReportSuccess(picojson::value{open}, out);
1706 }
1707
1708 void MlInstance::MLTrainerLayerSetProperty(const picojson::value& args, picojson::object& out) {
1709   ScopeLogger("args: %s", args.serialize().c_str());
1710   CHECK_ARGS(args, kId, double, out);
1711   CHECK_ARGS(args, kName, std::string, out);
1712   CHECK_ARGS(args, kValue, std::string, out);
1713
1714   auto id = static_cast<int>(args.get(kId).get<double>());
1715   auto name = args.get(kName).get<std::string>();
1716   auto value = args.get(kValue).get<std::string>();
1717
1718   PlatformResult result = trainer_manager_.LayerSetProperty(id, name, value);
1719   if (!result) {
1720     ReportError(result, &out);
1721     return;
1722   }
1723   ReportSuccess(out);
1724 }
1725
1726 void MlInstance::MLTrainerLayerCreate(const picojson::value& args, picojson::object& out) {
1727   ScopeLogger("args: %s", args.serialize().c_str());
1728   CHECK_ARGS(args, kType, std::string, out);
1729   int id = -1;
1730
1731   LayerType layer_type = LayerType::LAYER_UNKNOWN;
1732   PlatformResult result =
1733       types::LayerTypeEnum.getValue(args.get(kType).get<std::string>(), &layer_type);
1734   if (!result) {
1735     LogAndReportError(result, &out);
1736     return;
1737   }
1738
1739   result = trainer_manager_.CreateLayer(id, layer_type);
1740   if (!result) {
1741     ReportError(result, &out);
1742     return;
1743   }
1744   out[kId] = picojson::value(static_cast<double>(id));
1745   ReportSuccess(out);
1746 }
1747
1748 void MlInstance::MLTrainerOptimizerSetProperty(const picojson::value& args, picojson::object& out) {
1749   ScopeLogger("args: %s", args.serialize().c_str());
1750   CHECK_ARGS(args, kId, double, out);
1751   CHECK_ARGS(args, kName, std::string, out);
1752   CHECK_ARGS(args, kValue, std::string, out);
1753
1754   auto id = static_cast<int>(args.get(kId).get<double>());
1755   auto name = args.get(kName).get<std::string>();
1756   auto value = args.get(kValue).get<std::string>();
1757
1758   PlatformResult result = trainer_manager_.OptimizerSetProperty(id, name, value);
1759   if (!result) {
1760     ReportError(result, &out);
1761     return;
1762   }
1763   ReportSuccess(out);
1764 }
1765
1766 void MlInstance::MLTrainerOptimizerCreate(const picojson::value& args, picojson::object& out) {
1767   ScopeLogger("args: %s", args.serialize().c_str());
1768   CHECK_ARGS(args, kType, std::string, out);
1769   int id = -1;
1770
1771   OptimizerType optimizer_type = OptimizerType::UNKNOWN;
1772   PlatformResult result =
1773       types::OptimizerTypeEnum.getValue(args.get(kType).get<std::string>(), &optimizer_type);
1774   if (!result) {
1775     LogAndReportError(result, &out);
1776     return;
1777   }
1778
1779   result = trainer_manager_.CreateOptimizer(id, optimizer_type);
1780   if (!result) {
1781     ReportError(result, &out);
1782     return;
1783   }
1784   out[kId] = picojson::value(static_cast<double>(id));
1785   ReportSuccess(out);
1786 }
1787
1788 void MlInstance::MLTrainerModelCreate(const picojson::value& args, picojson::object& out) {
1789   ScopeLogger("args: %s", args.serialize().c_str());
1790   int id = -1;
1791   PlatformResult result;
1792   if (args.contains(kModelPath)) {
1793     // create model with config file
1794     CHECK_ARGS(args, kModelPath, std::string, out);
1795     const auto& config_path =
1796         common::tools::ConvertUriToPath(args.get(kModelPath).get<std::string>());
1797     CHECK_STORAGE_ACCESS(config_path, &out);
1798
1799     result = trainer_manager_.CreateModel(id, config_path);
1800   } else {
1801     result = trainer_manager_.CreateModel(id);
1802   }
1803   if (!result) {
1804     ReportError(result, &out);
1805     return;
1806   }
1807   out[kId] = picojson::value(static_cast<double>(id));
1808   ReportSuccess(out);
1809 }
1810
1811 void MlInstance::MLTrainerModelCompile(const picojson::value& args, picojson::object& out) {
1812   ScopeLogger("args: %s", args.serialize().c_str());
1813   CHECK_ARGS(args, kId, double, out);
1814   CHECK_ARGS(args, kOptions, picojson::object, out);
1815
1816   auto options = args.get(kOptions).get<picojson::object>();
1817   auto id = static_cast<int>(args.get(kId).get<double>());
1818
1819   PlatformResult result = trainer_manager_.ModelCompile(id, options);
1820
1821   if (!result) {
1822     ReportError(result, &out);
1823     return;
1824   }
1825   ReportSuccess(out);
1826 }
1827
1828 void MlInstance::MLTrainerModelAddLayer(const picojson::value& args, picojson::object& out) {
1829   ScopeLogger();
1830 }
1831
1832 void MlInstance::MLTrainerModelRun(const picojson::value& args, picojson::object& out) {
1833   ScopeLogger();
1834 }
1835
1836 void MlInstance::MLTrainerModelSummarize(const picojson::value& args, picojson::object& out) {
1837   ScopeLogger();
1838 }
1839
1840 void MlInstance::MLTrainerModelSetDataset(const picojson::value& args, picojson::object& out) {
1841   ScopeLogger();
1842 }
1843
1844 void MlInstance::MLTrainerModelSetOptimizer(const picojson::value& args, picojson::object& out) {
1845   ScopeLogger();
1846 }
1847
1848 void MlInstance::MLTrainerDatasetCreateGenerator(const picojson::value& args,
1849                                                  picojson::object& out) {
1850   ScopeLogger();
1851 }
1852
1853 void MlInstance::MLTrainerDatasetCreateFromFile(const picojson::value& args,
1854                                                 picojson::object& out) {
1855   ScopeLogger("args: %s", args.serialize().c_str());
1856   CHECK_ARGS(args, kTrain, std::string, out);
1857   CHECK_ARGS(args, kValid, std::string, out);
1858   CHECK_ARGS(args, kTest, std::string, out);
1859   int id = -1;
1860
1861   const std::string& train_file_path = args.get(kTrain).get<std::string>();
1862   const std::string& valid_file_path = args.get(kValid).get<std::string>();
1863   const std::string& test_file_path = args.get(kTest).get<std::string>();
1864
1865   PlatformResult result =
1866       trainer_manager_.CreateFileDataset(id, train_file_path, valid_file_path, test_file_path);
1867   if (!result) {
1868     ReportError(result, &out);
1869     return;
1870   }
1871   out[kId] = picojson::value(static_cast<double>(id));
1872   ReportSuccess(out);
1873 }
1874
1875 void MlInstance::MLTrainerDatasetSetProperty(const picojson::value& args, picojson::object& out) {
1876   ScopeLogger("args: %s", args.serialize().c_str());
1877   CHECK_ARGS(args, kId, double, out);
1878   CHECK_ARGS(args, kName, std::string, out);
1879   CHECK_ARGS(args, kValue, std::string, out);
1880
1881   auto id = static_cast<int>(args.get(kId).get<double>());
1882   auto name = args.get(kName).get<std::string>();
1883   auto value = args.get(kValue).get<std::string>();
1884
1885   PlatformResult result = trainer_manager_.DatasetSetProperty(id, name, value);
1886   if (!result) {
1887     ReportError(result, &out);
1888     return;
1889   }
1890   ReportSuccess(out);
1891 }
1892
1893 #undef CHECK_EXIST
1894 #undef CHECK_TYPE
1895 #undef CHECK_TYPE_X
1896 #undef CHECK_TYPE_4
1897 #undef CHECK_TYPE_5
1898 #undef CHECK_ARGS
1899
1900 }  // namespace ml
1901 }  // namespace extension