[ML][Pipeline] Implement {register, unregister}CustomFilter
[platform/core/api/webapi-plugins.git] / src / ml / ml_pipeline_manager.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 <algorithm>
18 #include <regex>
19
20 #include "common/tools.h"
21 #include "ml_pipeline_manager.h"
22 #include "ml_pipeline_switch.h"
23
24 using common::PlatformResult;
25 using common::ErrorCode;
26 using common::tools::ReportError;
27 using common::tools::ReportSuccess;
28
29 namespace extension {
30 namespace ml {
31
32 PipelineManager::PipelineManager(common::Instance* instance_ptr,
33                                  TensorsInfoManager* tensors_info_manager,
34                                  TensorsDataManager* tensors_data_manager)
35     : instance_ptr_{instance_ptr},
36       tensors_info_manager_{tensors_info_manager},
37       tensors_data_manager_{tensors_data_manager} {
38   ScopeLogger();
39 }
40
41 PipelineManager::~PipelineManager() {
42   ScopeLogger();
43 }
44
45 // PipelineManager::createPipeline() begin
46 PlatformResult PipelineManager::CreatePipeline(int id, const std::string& definition,
47                                                const std::string& state_change_listener_name) {
48   ScopeLogger("id: [%d], definition: [%s], state_change_listener_name: [%s]", id,
49               definition.c_str(), state_change_listener_name.c_str());
50
51   if (pipelines_.count(id)) {
52     LoggerD("The pipeline already exists: [%d]", id);
53     return PlatformResult{ErrorCode::ABORT_ERR, "Could not create pipeline"};
54   }
55
56   std::unique_ptr<Pipeline> pipeline_ptr;
57   auto ret = Pipeline::CreatePipeline(id, definition, state_change_listener_name, instance_ptr_,
58                                       tensors_info_manager_, &pipeline_ptr);
59   if (!ret) {
60     return ret;
61   }
62
63   pipelines_.insert({id, std::move(pipeline_ptr)});
64
65   return PlatformResult{};
66 }
67 // PipelineManager::createPipeline() end
68
69 // Pipeline::state begin
70 PlatformResult PipelineManager::GetPipelineState(int id, std::string* out) {
71   ScopeLogger("id: [%d]", id);
72
73   auto pipeline_it = pipelines_.find(id);
74   if (pipelines_.end() == pipeline_it) {
75     LoggerD("Pipeline not found: [%d]", id);
76     *out = "NULL";
77     return PlatformResult{};
78   }
79
80   auto ret = pipeline_it->second->GetState(out);
81   return ret;
82 }
83 // Pipeline::state end
84
85 // Pipeline::start() begin
86 PlatformResult PipelineManager::Start(int id) {
87   ScopeLogger("id: [%d]", id);
88
89   auto pipeline_it = pipelines_.find(id);
90   if (pipelines_.end() == pipeline_it) {
91     LoggerD("Pipeline not found: [%d]", id);
92     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
93   }
94
95   auto ret = pipeline_it->second->Start();
96   return ret;
97 }
98 // Pipeline::start() end
99
100 // Pipeline::stop() begin
101 PlatformResult PipelineManager::Stop(int id) {
102   ScopeLogger("id: [%d]", id);
103
104   auto pipeline_it = pipelines_.find(id);
105   if (pipelines_.end() == pipeline_it) {
106     LoggerD("Pipeline not found: [%d]", id);
107     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
108   }
109
110   auto ret = pipeline_it->second->Stop();
111   return ret;
112 }
113 // Pipeline::stop() end
114
115 // Pipeline::dispose() begin
116 PlatformResult PipelineManager::DisposePipeline(int id) {
117   ScopeLogger("id: [%d]", id);
118
119   auto pipeline_it = pipelines_.find(id);
120   if (pipelines_.end() == pipeline_it) {
121     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
122   }
123
124   /*
125    * Native ml_pipeline_destroy() may fail (I've checked its implementation),
126    * so we shouldn't just call pipelines_.erase(id) and let the ~Pipeline()
127    * destroy the pipeline, but only call pipelines_.erase(id) when
128    * pipeline->Dispose() succeeds.
129    */
130   auto ret = pipeline_it->second->Dispose();
131   if (ret) {
132     pipelines_.erase(id);
133   }
134
135   return ret;
136 }
137 // Pipeline::dispose() end
138
139 // Pipeline::getNodeInfo() begin
140 PlatformResult PipelineManager::GetNodeInfo(int id, std::string& name) {
141   ScopeLogger("id: [%d], name [%s]", id, name.c_str());
142
143   auto pipeline_it = pipelines_.find(id);
144   if (pipelines_.end() == pipeline_it) {
145     LoggerD("Pipeline not found: [%d]", id);
146     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
147   }
148
149   auto ret = pipeline_it->second->GetNodeInfo(name);
150   return ret;
151 }
152 // Pipeline::getNodeInfo() end
153
154 // Pipeline::getSource() begin
155 PlatformResult PipelineManager::GetSource(int pipeline_id, const std::string& name) {
156   ScopeLogger("name: [%s], pipeline_id: [%d]", name.c_str(), pipeline_id);
157
158   auto pipeline_it = pipelines_.find(pipeline_id);
159   if (pipelines_.end() == pipeline_it) {
160     LoggerD("Pipeline not found: [%d]", pipeline_id);
161     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
162   }
163
164   return pipeline_it->second->GetSource(name);
165 }
166 // Pipeline::getSource() end
167
168 // Pipeline::getSwitch() begin
169 PlatformResult PipelineManager::GetSwitch(const std::string& name, int pipeline_id,
170                                           std::string* type) {
171   ScopeLogger("name: [%s], pipeline_id: [%d]", name.c_str(), pipeline_id);
172
173   auto pipeline_it = pipelines_.find(pipeline_id);
174   if (pipelines_.end() == pipeline_it) {
175     LoggerD("Pipeline not found: [%d]", pipeline_id);
176     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
177   }
178
179   return pipeline_it->second->GetSwitch(name, type);
180 }
181 // Pipeline::getSwitch() end
182
183 // Pipeline::getValve() begin
184 PlatformResult PipelineManager::GetValve(const std::string& name, int pipeline_id) {
185   ScopeLogger("name: [%s], pipeline_id: [%d]", name.c_str(), pipeline_id);
186
187   auto pipeline_it = pipelines_.find(pipeline_id);
188   if (pipelines_.end() == pipeline_it) {
189     LoggerD("Pipeline not found: [%d]", pipeline_id);
190     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
191   }
192
193   return pipeline_it->second->GetValve(name);
194 }
195 // Pipeline::getValve() end
196
197 // Pipeline::registerSinkCallback() begin
198 PlatformResult PipelineManager::RegisterSinkListener(const std::string& sink_name, int pipeline_id,
199                                                      const std::string& listener_name) {
200   ScopeLogger("sink_name: [%s], pipeline_id: [%d], listener_name: [%s]", sink_name.c_str(),
201               pipeline_id, listener_name.c_str());
202
203   auto pipeline_it = pipelines_.find(pipeline_id);
204   if (pipelines_.end() == pipeline_it) {
205     LoggerD("Pipeline not found: [%d]", pipeline_id);
206     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
207   }
208
209   return pipeline_it->second->RegisterSinkListener(sink_name, listener_name);
210 }
211 // Pipeline::registerSinkCallback() end
212
213 // Pipeline::unregisterSinkCallback() begin
214 PlatformResult PipelineManager::UnregisterSinkListener(const std::string& sink_name,
215                                                        int pipeline_id) {
216   ScopeLogger("sink_name: [%s], pipeline_id: [%d]", sink_name.c_str(), pipeline_id);
217
218   auto pipeline_it = pipelines_.find(pipeline_id);
219   if (pipelines_.end() == pipeline_it) {
220     LoggerD("Pipeline not found: [%d]", pipeline_id);
221     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
222   }
223
224   return pipeline_it->second->UnregisterSinkListener(sink_name);
225 }
226 // Pipeline::unregisterSinkCallback() end
227
228 // Pipeline::registerCustomFilter() begin
229 PlatformResult PipelineManager::RegisterCustomFilter(const std::string& custom_filter_name,
230                                                      const std::string& listener_name,
231                                                      TensorsInfo* input_tensors_info_ptr,
232                                                      TensorsInfo* output_tensors_info_ptr) {
233   ScopeLogger(
234       "custom_filter_name: [%s], listener_name: [%s], input_tensors_info::id: [%d], "
235       "output_tensors_info::id: [%d]",
236       custom_filter_name.c_str(), listener_name.c_str(), input_tensors_info_ptr->Id(),
237       output_tensors_info_ptr->Id());
238
239   if (custom_filters_.count(custom_filter_name)) {
240     LoggerE("Listener for [%s] custom_filter is already registered", custom_filter_name.c_str());
241     return PlatformResult{ErrorCode::ABORT_ERR, "Internal CustomFilter error"};
242   }
243
244   std::unique_ptr<CustomFilter> custom_filter_ptr;
245   auto ret = CustomFilter::CreateAndRegisterCustomFilter(
246       custom_filter_name, listener_name, input_tensors_info_ptr, output_tensors_info_ptr,
247       instance_ptr_, tensors_info_manager_, tensors_data_manager_, &custom_filter_ptr);
248
249   if (!ret) {
250     return ret;
251   }
252
253   custom_filters_.insert({custom_filter_name, std::move(custom_filter_ptr)});
254
255   return PlatformResult{};
256 }
257 // Pipeline::registerCustomFilter() end
258
259 // Pipeline::unregisterCustomFilter() begin
260 PlatformResult PipelineManager::UnregisterCustomFilter(const std::string& custom_filter_name) {
261   ScopeLogger("custom_filter_name: [%s]", custom_filter_name.c_str());
262
263   auto custom_filter_it = custom_filters_.find(custom_filter_name);
264   if (custom_filters_.end() == custom_filter_it) {
265     LoggerD("custom_filter [%s] not found", custom_filter_name.c_str());
266     return PlatformResult{ErrorCode::INVALID_VALUES_ERR,
267                           "\"" + custom_filter_name + "\" CustomFilter not found"};
268   }
269
270   auto ret = custom_filter_it->second->Unregister();
271   if (ret) {
272     custom_filters_.erase(custom_filter_it);
273   }
274   return ret;
275 }
276 // Pipeline::unregisterCustomFilter() end
277
278 // NodeInfo::getProperty() begin
279 PlatformResult PipelineManager::getProperty(int id, const std::string& node_name,
280                                             const std::string& name, const std::string& type,
281                                             picojson::object* property) {
282   ScopeLogger("id: [%d], name [%s], nodeName [%s], type [%s] ", id, name.c_str(), node_name.c_str(),
283               type.c_str());
284
285   auto pipeline_it = pipelines_.find(id);
286   if (pipelines_.end() == pipeline_it) {
287     LoggerD("Pipeline not found: [%d]", id);
288     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
289   }
290
291   return pipeline_it->second->getProperty(node_name, name, type, property);
292 }
293 // NodeInfo::getProperty() end
294
295 // NodeInfo::setProperty() begin
296 PlatformResult PipelineManager::setProperty(int id, const std::string& node_name,
297                                             const std::string& name, const std::string& type,
298                                             const picojson::value& property) {
299   ScopeLogger("id: [%d], name [%s], nodeName [%s], type [%s] ", id, name.c_str(), node_name.c_str(),
300               type.c_str());
301
302   auto pipeline_it = pipelines_.find(id);
303   if (pipelines_.end() == pipeline_it) {
304     LoggerD("Pipeline not found: [%d]", id);
305     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
306   }
307
308   return pipeline_it->second->setProperty(node_name, name, type, property);
309 }
310 // NodeInfo::setProperty() end
311
312 // Source::inputTensorsInfo begin
313 PlatformResult PipelineManager::getInputTensorsInfo(int id, const std::string& name, int* res_id) {
314   ScopeLogger();
315
316   auto pipeline_it = pipelines_.find(id);
317   if (pipelines_.end() == pipeline_it) {
318     LoggerD("Pipeline not found: [%d]", id);
319     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
320   }
321   ml_tensors_info_h in_info = nullptr;
322   PlatformResult ret = pipeline_it->second->getInputTensorsInfo(name, &in_info);
323   if (!ret) {
324     return ret;
325   }
326
327   auto tensor_info = tensors_info_manager_->CreateTensorsInfo(in_info);
328   *res_id = tensor_info->Id();
329   return PlatformResult{};
330 }
331 // Source::inputTensorsInfo end
332
333 // Source::inputData() begin
334 PlatformResult PipelineManager::SourceInputData(int id, const std::string& name,
335                                                 TensorsData* tensors_data) {
336   ScopeLogger();
337
338   auto pipeline_it = pipelines_.find(id);
339   if (pipelines_.end() == pipeline_it) {
340     LoggerD("Pipeline not found: [%d]", id);
341     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
342   }
343
344   return pipeline_it->second->SourceInputData(name, tensors_data);
345 }
346 // Source::inputData() end
347
348 // Switch::getPadList() begin
349 PlatformResult PipelineManager::SwitchGetPadList(int pipeline_id, const std::string& switch_name,
350                                                  picojson::array* out) {
351   ScopeLogger("pipeline_id: [%d], switch_name: [%s]", pipeline_id, switch_name.c_str());
352
353   auto pipeline_it = pipelines_.find(pipeline_id);
354   if (pipelines_.end() == pipeline_it) {
355     LoggerD("Pipeline not found: [%d]", pipeline_id);
356     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
357   }
358
359   Switch* switch_ptr = nullptr;
360   auto ret = pipeline_it->second->GetSwitch(switch_name, &switch_ptr);
361   if (!ret) {
362     return ret;
363   }
364
365   return switch_ptr->GetPadList(out);
366 }
367 // Switch::getPadList() end
368
369 // Switch::select() begin
370 PlatformResult PipelineManager::SwitchSelect(int pipeline_id, const std::string& switch_name,
371                                              const std::string& pad_name) {
372   ScopeLogger("pipeline_id: [%d], switch_name: [%s], pad_name: [%s]", pipeline_id,
373               switch_name.c_str(), pad_name.c_str());
374
375   auto pipeline_it = pipelines_.find(pipeline_id);
376   if (pipelines_.end() == pipeline_it) {
377     LoggerD("Pipeline not found: [%d]", pipeline_id);
378     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
379   }
380
381   Switch* switch_ptr = nullptr;
382   auto ret = pipeline_it->second->GetSwitch(switch_name, &switch_ptr);
383   if (!ret) {
384     return ret;
385   }
386
387   return switch_ptr->Select(pad_name);
388 }
389 // Switch::select() end
390
391 // Valve::setOpen() begin
392 PlatformResult PipelineManager::ValveSetOpen(int pipeline_id, const std::string& valve_name,
393                                              bool open) {
394   ScopeLogger("pipeline_id: [%d], valve_name: [%s], open: [%s]", pipeline_id, valve_name.c_str(),
395               open ? "true" : "false");
396
397   auto pipeline_it = pipelines_.find(pipeline_id);
398   if (pipelines_.end() == pipeline_it) {
399     LoggerD("Pipeline not found: [%d]", pipeline_id);
400     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
401   }
402
403   Valve* valve_ptr = nullptr;
404   auto ret = pipeline_it->second->GetValve(valve_name, &valve_ptr);
405   if (!ret) {
406     return ret;
407   }
408
409   return valve_ptr->SetOpen(open);
410 }
411 // Valve::setOpen() end
412
413 // Valve::isOpen() begin
414 PlatformResult PipelineManager::ValveIsOpen(int pipeline_id, const std::string& valve_name,
415                                             bool* open) {
416   ScopeLogger("pipeline_id: [%d], valve_name: [%s]", pipeline_id, valve_name.c_str());
417
418   auto pipeline_it = pipelines_.find(pipeline_id);
419   if (pipelines_.end() == pipeline_it) {
420     LoggerD("Pipeline not found: [%d]", pipeline_id);
421     return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
422   }
423
424   Valve* valve_ptr = nullptr;
425   auto ret = pipeline_it->second->GetValve(valve_name, &valve_ptr);
426   if (!ret) {
427     return ret;
428   }
429
430   return valve_ptr->IsOpen(open);
431 }
432 // Valve::isOpen() end
433
434 }  // namespace ml
435 }  // namespace extension