• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "server_executor/include/engine_manager.h"
17 
18 #include <cstring>
19 
20 #include "platform/lock/include/rw_lock.h"
21 #include "plugin/i_plugin.h"
22 #include "plugin_manager/include/aie_plugin_info.h"
23 #include "plugin_manager/include/i_plugin_manager.h"
24 #include "server_executor/include/engine.h"
25 #include "utils/constants/constants.h"
26 #include "utils/log/aie_log.h"
27 
28 namespace OHOS {
29 namespace AI {
30 namespace {
31     const int PLUGIN_NUM_FOR_UNLOAD = 1;
32 }
33 EngineManager::EngineManager() = default;
34 
~EngineManager()35 EngineManager::~EngineManager()
36 {
37     Uninitialize();
38 }
39 
Initialize()40 int EngineManager::Initialize()
41 {
42     return RETCODE_SUCCESS;
43 }
44 
Uninitialize()45 void EngineManager::Uninitialize()
46 {
47     HILOGI("[EngineManager]Begin to release engine manager.");
48     engines_.clear();
49     clientEngines_.clear();
50 
51     IPluginManager *pluginManager = IPluginManager::GetPluginManager();
52     if (pluginManager != nullptr) {
53         pluginManager->Destroy();
54     }
55 }
56 
StartEngine(long long transactionId,const AlgorithmInfo & algoInfo,const DataInfo & inputInfo,DataInfo & outputInfo)57 int EngineManager::StartEngine(long long transactionId, const AlgorithmInfo &algoInfo, const DataInfo &inputInfo,
58     DataInfo &outputInfo)
59 {
60     std::string aid = GetAlgorithmIdByType(algoInfo.algorithmType);
61     if (aid == ALGORITHM_ID_INVALID) {
62         HILOGE("[EngineManager]Start engine failed, aid is invalid.");
63         return RETCODE_ALGORITHM_ID_INVALID;
64     }
65     EngineKey engineKey(aid, algoInfo.algorithmVersion);
66     std::shared_ptr<Engine> engine = FindEngine(engineKey);
67     if (engine == nullptr) {
68         int retCode = CreateEngineWithCheck(engineKey, engine);
69         if (retCode != RETCODE_SUCCESS) {
70             HILOGE("[EngineManager][transactionId:%lld]Create engine failed, retCode=[%d].",
71                 transactionId, retCode);
72             return retCode;
73         }
74     }
75     std::shared_ptr<Plugin> plugin = engine->GetPlugin();
76     if (plugin == nullptr) {
77         HILOGE("[EngineManager]Plugin is nullptr.");
78         return RETCODE_FAILURE;
79     }
80     int retCode = plugin->GetPluginAlgorithm()->Prepare(transactionId, inputInfo, outputInfo);
81     if (retCode != RETCODE_SUCCESS) {
82         HILOGE("[EngineManager]Start engine failed, failed to prepare.");
83         return retCode;
84     }
85     engine->AddEngineReference();
86     RecordClient(transactionId, engine);
87     return RETCODE_SUCCESS;
88 }
89 
StopEngine(long long transactionId,const DataInfo & inputInfo)90 int EngineManager::StopEngine(long long transactionId, const DataInfo &inputInfo)
91 {
92     std::shared_ptr<Engine> engine = FindEngine(transactionId);
93     if (engine == nullptr) {
94         HILOGE("[EngineManager]No corresponding engine was found.");
95         return RETCODE_SA_SERVICE_EXCEPTION;
96     }
97 
98     std::shared_ptr<Plugin> plugin = engine->GetPlugin();
99     if (plugin == nullptr) {
100         HILOGE("[EngineManager]The plugin is null.");
101         return RETCODE_SA_SERVICE_EXCEPTION;
102     }
103 
104     // only one engine remains, fully unload this plugin
105     bool isFullUnload = engine->GetEngineReference() == PLUGIN_NUM_FOR_UNLOAD;
106     int retCode = plugin->GetPluginAlgorithm()->Release(isFullUnload, transactionId, inputInfo);
107     if (retCode != RETCODE_SUCCESS) {
108         HILOGE("[EngineManager]Failed to release plugin.");
109         return retCode;
110     }
111 
112     engine->DelEngineReference();
113     if (engine->GetEngineReference() == 0) {
114         HILOGI("[EngineManager]The current engine is not in use.");
115         IPluginManager *pluginManager = IPluginManager::GetPluginManager();
116         if (pluginManager == nullptr) {
117             HILOGE("[EngineManager]The pluginManager is null.");
118             return RETCODE_NULL_PARAM;
119         }
120 
121         const std::string aid = plugin->GetAid();
122         long long version = plugin->GetVersion();
123         pluginManager->UnloadPlugin(aid, version);
124         EngineKey engineKey(aid, version);
125         DelEngine(engineKey);
126     }
127     UnRecordClient(transactionId);
128     return RETCODE_SUCCESS;
129 }
130 
SetOption(long long transactionId,int optionType,const DataInfo & inputInfo)131 int EngineManager::SetOption(long long transactionId, int optionType, const DataInfo &inputInfo)
132 {
133     std::shared_ptr<Engine> engine = FindEngine(transactionId);
134     if (engine == nullptr) {
135         HILOGE("[EngineManager]No corresponding engine was found.");
136         return RETCODE_SA_SERVICE_EXCEPTION;
137     }
138     std::shared_ptr<Plugin> plugin = engine->GetPlugin();
139     if (plugin == nullptr) {
140         HILOGE("[EngineManager]The plugin is null.");
141         return RETCODE_SA_SERVICE_EXCEPTION;
142     }
143     return plugin->GetPluginAlgorithm()->SetOption(optionType, inputInfo);
144 }
145 
GetOption(long long transactionId,int optionType,const DataInfo & inputInfo,DataInfo & outputInfo)146 int EngineManager::GetOption(long long transactionId, int optionType, const DataInfo &inputInfo,
147     DataInfo &outputInfo)
148 {
149     std::shared_ptr<Engine> engine = FindEngine(transactionId);
150     if (engine == nullptr) {
151         HILOGE("[EngineManager]No corresponding engine was found.");
152         return RETCODE_SA_SERVICE_EXCEPTION;
153     }
154     std::shared_ptr<Plugin> plugin = engine->GetPlugin();
155     if (plugin == nullptr) {
156         HILOGE("[EngineManager]The plugin is null.");
157         return RETCODE_SA_SERVICE_EXCEPTION;
158     }
159     return plugin->GetPluginAlgorithm()->GetOption(optionType, inputInfo, outputInfo);
160 }
161 
FindEngine(long long transactionId)162 std::shared_ptr<Engine> EngineManager::FindEngine(long long transactionId)
163 {
164     ReadGuard<RwLock> guard(rwLock_);
165     auto iter = clientEngines_.find(transactionId);
166     if (iter == clientEngines_.end()) {
167         HILOGE("[EngineManager]No corresponding engine was found.");
168         return nullptr;
169     }
170     return iter->second;
171 }
172 
RecordClient(long long transactionId,const std::shared_ptr<Engine> & engine)173 void EngineManager::RecordClient(long long transactionId, const std::shared_ptr<Engine> &engine)
174 {
175     WriteGuard<RwLock> guard(rwLock_);
176     clientEngines_[transactionId] = engine;
177 }
178 
UnRecordClient(long long transactionId)179 void EngineManager::UnRecordClient(long long transactionId)
180 {
181     WriteGuard<RwLock> guard(rwLock_);
182     clientEngines_.erase(transactionId);
183 }
184 
CreateEngine(const EngineKey & engineKey,std::shared_ptr<Engine> & engine)185 int EngineManager::CreateEngine(const EngineKey &engineKey, std::shared_ptr<Engine> &engine)
186 {
187     IPluginManager *pluginManager = IPluginManager::GetPluginManager();
188     if (pluginManager == nullptr) {
189         HILOGE("[EngineManager]The pluginManager is null.");
190         return RETCODE_NULL_PARAM;
191     }
192 
193     std::shared_ptr<Plugin> plugin = nullptr;
194     int retCode = pluginManager->GetPlugin(engineKey.aid, engineKey.version, plugin);
195     if (retCode != RETCODE_SUCCESS) {
196         HILOGE("[EngineManager]The plugin(aid=%s, version=%lld) is not existed.",
197             engineKey.aid.c_str(), engineKey.version);
198         return retCode;
199     }
200 
201     ThreadPool *threadPool = ThreadPool::GetInstance();
202     CHK_RET(threadPool == nullptr, RETCODE_OUT_OF_MEMORY);
203     std::shared_ptr<Thread> thread = threadPool->Pop();
204     if (thread == nullptr) {
205         HILOGE("[EngineManager]Failed to get thread.");
206         return RETCODE_OUT_OF_MEMORY;
207     }
208 
209     QueuePool<Task> *queuePool = QueuePool<Task>::GetInstance(MAX_SYNC_MSG_NUM);
210     CHK_RET(queuePool == nullptr, RETCODE_OUT_OF_MEMORY);
211     std::shared_ptr<Queue<Task>> queue = queuePool->Pop();
212     if (queue == nullptr) {
213         HILOGE("[EngineManager]Failed to get queue.");
214         threadPool->Push(thread);
215         return RETCODE_OUT_OF_MEMORY;
216     }
217 
218     Engine *newEngine = nullptr;
219     AIE_NEW(newEngine, Engine(plugin, thread, queue));
220     if (newEngine == nullptr) {
221         HILOGE("[EngineManager]Failed to create engine.");
222         queuePool->Push(queue);
223         threadPool->Push(thread);
224         return RETCODE_ENGINE_NOT_EXIST;
225     }
226 
227     engine.reset(newEngine);
228     retCode = engine->Initialize();
229     if (retCode != RETCODE_SUCCESS) {
230         HILOGE("[EngineManager]Initialize engine failed.");
231         queuePool->Push(queue);
232         threadPool->Push(thread);
233         return retCode;
234     }
235     return RETCODE_SUCCESS;
236 }
237 
CreateEngineWithCheck(const EngineKey & engineKey,std::shared_ptr<Engine> & engine)238 int EngineManager::CreateEngineWithCheck(const EngineKey &engineKey, std::shared_ptr<Engine> &engine)
239 {
240     HILOGI("[EngineManager]Begin to create corresponding engine.");
241     WriteGuard<RwLock> guard(rwLock_);
242     Engines::iterator iter = engines_.find(engineKey);
243     if (iter != engines_.end()) {
244         HILOGI("[EngineManager]Success to find engine.");
245         engine = iter->second;
246         return RETCODE_SUCCESS;
247     }
248 
249     int retCode = CreateEngine(engineKey, engine);
250     if (retCode != RETCODE_SUCCESS) {
251         HILOGE("[EngineManager]Failed to create engine.");
252         return retCode;
253     }
254 
255     engines_[engineKey] = engine;
256     return RETCODE_SUCCESS;
257 }
258 
FindEngine(const EngineKey & engineKey)259 std::shared_ptr<Engine> EngineManager::FindEngine(const EngineKey &engineKey)
260 {
261     ReadGuard<RwLock> guard(rwLock_);
262     Engines::iterator iter = engines_.find(engineKey);
263     if (iter == engines_.end()) {
264         HILOGI("[EngineManager]No corresponding engine was found.");
265         return nullptr;
266     }
267     return iter->second;
268 }
269 
DelEngine(const EngineKey & engineKey)270 void EngineManager::DelEngine(const EngineKey &engineKey)
271 {
272     WriteGuard<RwLock> guard(rwLock_);
273     engines_.erase(engineKey);
274 }
275 } // namespace AI
276 } // namespace OHOS