1 /*
2 * Copyright (c) 2022 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 "device_manager.h"
17
18 #include "hdi_interfaces.h"
19 #include "hdi_device.h"
20 #include "common/log.h"
21 #include "common/utils.h"
22
23 namespace OHOS {
24 namespace NeuralNetworkRuntime {
GetAllDeviceId()25 const std::vector<size_t>& DeviceManager::GetAllDeviceId()
26 {
27 m_tmpDeviceIds.clear();
28 std::shared_ptr<Device> device {nullptr};
29 for (auto iter = m_devices.begin(); iter != m_devices.end(); ++iter) {
30 device = iter->second;
31 if (!IsValidDevice(device)) {
32 continue;
33 }
34 m_tmpDeviceIds.emplace_back(iter->first);
35 }
36 return m_tmpDeviceIds;
37 }
38
GetDevice(size_t deviceId) const39 std::shared_ptr<Device> DeviceManager::GetDevice(size_t deviceId) const
40 {
41 auto iter = m_devices.find(deviceId);
42 if (iter == m_devices.end()) {
43 LOGE("DeviceId is not found, deviceId=%zu", deviceId);
44 return nullptr;
45 }
46
47 return iter->second;
48 }
49
GetDeviceName(size_t deviceId)50 const std::string& DeviceManager::GetDeviceName(size_t deviceId)
51 {
52 m_tmpDeviceName.clear();
53 auto iter = m_devices.find(deviceId);
54 if (iter == m_devices.end()) {
55 LOGE("DeviceId is not found, deviceId=%zu", deviceId);
56 return m_tmpDeviceName;
57 }
58
59 std::string deviceName;
60 auto ret = iter->second->GetDeviceName(deviceName);
61 if (ret != OH_NN_SUCCESS) {
62 LOGE("Get device name failed.");
63 return m_tmpDeviceName;
64 }
65
66 std::string vendorName;
67 ret = iter->second->GetVendorName(vendorName);
68 if (ret != OH_NN_SUCCESS) {
69 LOGE("Get vendor name failed.");
70 return m_tmpDeviceName;
71 }
72
73 m_tmpDeviceName = GenUniqueName(deviceName, vendorName);
74 return m_tmpDeviceName;
75 }
76
GenUniqueName(const std::string & deviceName,const std::string & vendorName) const77 std::string DeviceManager::GenUniqueName(const std::string& deviceName, const std::string& vendorName) const
78 {
79 return deviceName + "_" + vendorName;
80 }
81
RegisterDevice(std::function<std::shared_ptr<Device> ()> creator)82 OH_NN_ReturnCode DeviceManager::RegisterDevice(std::function<std::shared_ptr<Device>()> creator)
83 {
84 auto regDevice = creator();
85 if (regDevice == nullptr) {
86 LOGE("Cannot create device, register device failed.");
87 return OH_NN_INVALID_PARAMETER;
88 }
89
90 if (!IsValidDevice(regDevice)) {
91 LOGE("Device is not avaliable.");
92 return OH_NN_UNAVALIDABLE_DEVICE;
93 }
94
95 std::string deviceName;
96 auto ret = regDevice->GetDeviceName(deviceName);
97 if (ret != OH_NN_SUCCESS) {
98 LOGE("Get device name failed.");
99 return ret;
100 }
101
102 std::string vendorName;
103 ret = regDevice->GetVendorName(vendorName);
104 if (ret != OH_NN_SUCCESS) {
105 LOGE("Get vendor name failed.");
106 return ret;
107 }
108
109 const std::lock_guard<std::mutex> lock(m_mtx);
110 std::string uniqueName = GenUniqueName(deviceName, vendorName);
111 auto setResult = m_uniqueName.emplace(uniqueName);
112 if (!setResult.second) {
113 LOGE("Device already exists, cannot register again. deviceName=%s, vendorName=%s",
114 deviceName.c_str(), vendorName.c_str());
115 return OH_NN_FAILED;
116 }
117
118 m_devices.emplace(std::hash<std::string>{}(uniqueName), regDevice);
119 return OH_NN_SUCCESS;
120 }
121
DiscoverHDIDevices()122 void DeviceManager::DiscoverHDIDevices()
123 {
124 // only one device from HDI now.
125 OHOS::sptr<V1_0::INnrtDevice> iDevice = V1_0::INnrtDevice::Get();
126 if (iDevice == nullptr) {
127 LOGW("Get HDI device failed.");
128 return;
129 }
130
131 std::string deviceName;
132 std::string vendorName;
133 auto hdiRet = iDevice->GetDeviceName(deviceName);
134 if (hdiRet != HDF_SUCCESS) {
135 LOGW("Get device name failed. ErrorCode=%d", hdiRet);
136 return;
137 }
138 hdiRet = iDevice->GetVendorName(vendorName);
139 if (hdiRet != HDF_SUCCESS) {
140 LOGW("Get vendor name failed. ErrorCode=%d", hdiRet);
141 return;
142 }
143
144 std::string uniqueName = GenUniqueName(deviceName, vendorName);
145 const std::lock_guard<std::mutex> lock(m_mtx);
146 auto setResult = m_uniqueName.emplace(uniqueName);
147 if (!setResult.second) {
148 LOGW("Device already exists, cannot register again. deviceName=%s, vendorName=%s",
149 deviceName.c_str(), vendorName.c_str());
150 return;
151 }
152
153 std::shared_ptr<Device> device = CreateSharedPtr<HDIDevice>(iDevice);
154 if (device == nullptr) {
155 LOGW("Failed to register device, because fail to create device instance.");
156 return;
157 }
158 m_devices.emplace(std::hash<std::string>{}(uniqueName), device);
159 }
160
IsValidDevice(std::shared_ptr<Device> device) const161 bool DeviceManager::IsValidDevice(std::shared_ptr<Device> device) const
162 {
163 DeviceStatus status {DeviceStatus::UNKNOWN};
164 auto ret = device->GetDeviceStatus(status);
165 if (ret != OH_NN_SUCCESS || status == DeviceStatus::UNKNOWN || status == DeviceStatus::OFFLINE) {
166 return false;
167 }
168 return true;
169 }
170 } // NeuralNetworkRuntime
171 } // OHOS