1 /* 2 * Copyright (C) 2017 The Android Open Source Project 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 #define LOG_TAG "Manager" 18 19 #include "Manager.h" 20 #include "HalInterfaces.h" 21 #include "Utils.h" 22 23 #include <android/hidl/manager/1.0/IServiceManager.h> 24 #include <hidl/HidlTransportSupport.h> 25 #include <hidl/ServiceManagement.h> 26 27 #include <algorithm> 28 #include <functional> 29 30 namespace android { 31 namespace nn { 32 33 Device::Device(std::string name, const sp<V1_0::IDevice>& device) : 34 mName(std::move(name)), mInterface(device) {} 35 36 // TODO: handle errors from initialize correctly 37 bool Device::initialize() { 38 #ifdef NN_DEBUGGABLE 39 static const char samplePrefix[] = "sample"; 40 41 mSupported = 42 (mName.substr(0, sizeof(samplePrefix) - 1) == samplePrefix) 43 ? getProp("debug.nn.sample.supported") : 0; 44 #endif // NN_DEBUGGABLE 45 46 ErrorStatus status = ErrorStatus::GENERAL_FAILURE; 47 Capabilities capabilities; 48 std::tie(status, capabilities) = mInterface.getCapabilities(); 49 50 if (status != ErrorStatus::NONE) { 51 LOG(ERROR) << "IDevice::getCapabilities returned the error " << toString(status); 52 } else { 53 VLOG(MANAGER) << "Capab " << capabilities.float32Performance.execTime; 54 VLOG(MANAGER) << "Capab " << capabilities.quantized8Performance.execTime; 55 VLOG(MANAGER) << "Capab " << capabilities.relaxedFloat32toFloat16Performance.execTime; 56 mFloat32Performance = capabilities.float32Performance; 57 mQuantized8Performance = capabilities.quantized8Performance; 58 mRelaxedFloat32toFloat16Performance = capabilities.relaxedFloat32toFloat16Performance; 59 } 60 61 return status == ErrorStatus::NONE; 62 } 63 64 void Device::getSupportedOperations(const Model& hidlModel, 65 hidl_vec<bool>* outSupportedOperations) { 66 // Query the driver for what it can do. 67 ErrorStatus status = ErrorStatus::GENERAL_FAILURE; 68 hidl_vec<bool> supportedOperations; 69 std::tie(status, supportedOperations) = mInterface.getSupportedOperations(hidlModel); 70 71 if (status != ErrorStatus::NONE) { 72 LOG(ERROR) << "IDevice::getSupportedOperations returned the error " << toString(status); 73 // Set the supported operation vectors to all false, so we won't use this driver. 74 outSupportedOperations->resize(hidlModel.operations.size()); 75 std::fill(outSupportedOperations->begin(), outSupportedOperations->end(), false); 76 return; 77 } 78 if (supportedOperations.size() != hidlModel.operations.size()) { 79 LOG(ERROR) << "IDevice::getSupportedOperations returned a vector of length " 80 << supportedOperations.size() << " when expecting " 81 << hidlModel.operations.size(); 82 // Set the supported operation vectors to all false, so we won't use this driver. 83 outSupportedOperations->resize(hidlModel.operations.size()); 84 std::fill(outSupportedOperations->begin(), outSupportedOperations->end(), false); 85 return; 86 } 87 88 *outSupportedOperations = supportedOperations; 89 90 #ifdef NN_DEBUGGABLE 91 if (mSupported != 1) { 92 return; 93 } 94 95 const uint32_t baseAccumulator = std::hash<std::string>{}(mName); 96 for (size_t operationIndex = 0; operationIndex < outSupportedOperations->size(); 97 operationIndex++) { 98 if (!(*outSupportedOperations)[operationIndex]) { 99 continue; 100 } 101 102 uint32_t accumulator = baseAccumulator; 103 const Operation &operation = hidlModel.operations[operationIndex]; 104 accumulator ^= static_cast<uint32_t>(operation.type); 105 auto accumulateOperands = [&hidlModel, &accumulator](const hidl_vec<uint32_t>& operands) { 106 for (uint32_t operandIndex : operands) { 107 const Operand& operand = hidlModel.operands[operandIndex]; 108 accumulator ^= static_cast<uint32_t>(operand.type); 109 accumulator ^= operand.dimensions.size(); 110 for (uint32_t dimension : operand.dimensions) { 111 accumulator ^= dimension; 112 if (operand.lifetime == OperandLifeTime::CONSTANT_COPY || 113 operand.lifetime == OperandLifeTime::CONSTANT_REFERENCE) { 114 accumulator ^= 1; 115 } 116 } 117 } 118 }; 119 accumulateOperands(operation.inputs); 120 accumulateOperands(operation.outputs); 121 if (accumulator & 1) { 122 (*outSupportedOperations)[operationIndex] = false; 123 } 124 } 125 #endif // NN_DEBUGGABLE 126 } 127 128 DeviceManager* DeviceManager::get() { 129 static DeviceManager manager; 130 return &manager; 131 } 132 133 void DeviceManager::findAvailableDevices() { 134 using ::android::hidl::manager::V1_0::IServiceManager; 135 VLOG(MANAGER) << "findAvailableDevices"; 136 137 sp<IServiceManager> manager = hardware::defaultServiceManager(); 138 if (manager == nullptr) { 139 LOG(ERROR) << "Unable to open defaultServiceManager"; 140 return; 141 } 142 143 manager->listByInterface(V1_0::IDevice::descriptor, [this](const hidl_vec<hidl_string>& names) { 144 for (const auto& name : names) { 145 VLOG(MANAGER) << "Found interface " << name.c_str(); 146 sp<V1_0::IDevice> device = V1_0::IDevice::getService(name); 147 if (device == nullptr) { 148 LOG(ERROR) << "Got a null IDEVICE for " << name.c_str(); 149 continue; 150 } 151 registerDevice(name.c_str(), device); 152 } 153 }); 154 } 155 156 void DeviceManager::registerDevice(const char* name, const sp<V1_0::IDevice>& device) { 157 auto d = std::make_shared<Device>(name, device); 158 if (d->initialize()) { 159 mDevices.push_back(d); 160 } 161 } 162 163 DeviceManager::DeviceManager() { 164 VLOG(MANAGER) << "DeviceManager::DeviceManager"; 165 findAvailableDevices(); 166 #ifdef NN_DEBUGGABLE 167 mPartitioning = getProp("debug.nn.partition", kPartitioningDefault); 168 mDebugNNCpuOnly = (getProp("debug.nn.cpuonly") != 0); 169 #endif // NN_DEBUGGABLE 170 } 171 172 } // namespace nn 173 } // namespace android 174