diff options
Diffstat (limited to 'nn/runtime/Manager.cpp')
-rw-r--r-- | nn/runtime/Manager.cpp | 216 |
1 files changed, 82 insertions, 134 deletions
diff --git a/nn/runtime/Manager.cpp b/nn/runtime/Manager.cpp index 34378b3fd..1be1bf68b 100644 --- a/nn/runtime/Manager.cpp +++ b/nn/runtime/Manager.cpp @@ -52,28 +52,38 @@ const Timing kNoTiming = {.timeOnDevice = UINT64_MAX, .timeInDriver = UINT64_MAX // A Device with actual underlying driver class DriverDevice : public Device { public: - DriverDevice(std::string name, const sp<V1_0::IDevice>& device); - - // Returns true if succesfully initialized. - bool initialize(); - - const char* getName() const override { return mName.c_str(); } - const char* getVersionString() const override { return mVersionString.c_str(); } - int64_t getFeatureLevel() const override { return mInterface->getFeatureLevel(); } - int32_t getType() const override { return mInterface->getType(); } - hidl_vec<Extension> getSupportedExtensions() const override; - void getSupportedOperations(const MetaModel& metaModel, - hidl_vec<bool>* supportedOperations) const override; - PerformanceInfo getPerformance(OperandType type) const override; + // Create a DriverDevice from a name and an IDevice. + // Returns nullptr on failure. + static std::shared_ptr<DriverDevice> create(std::string name, sp<V1_0::IDevice> device); + + // Prefer using DriverDevice::create + DriverDevice(std::shared_ptr<VersionedIDevice> device); + + const std::string& getName() const override { return kInterface->getName(); } + const std::string& getVersionString() const override { return kInterface->getVersionString(); } + int64_t getFeatureLevel() const override { return kInterface->getFeatureLevel(); } + int32_t getType() const override { return kInterface->getType(); } + const std::vector<Extension>& getSupportedExtensions() const override { + return kInterface->getSupportedExtensions(); + } + std::vector<bool> getSupportedOperations(const MetaModel& metaModel) const override; + PerformanceInfo getPerformance(OperandType type) const override { + const auto& capabilities = kInterface->getCapabilities(); + return lookup(capabilities.operandPerformance, type); + } PerformanceInfo getRelaxedFloat32toFloat16PerformanceScalar() const override { - return mCapabilities.relaxedFloat32toFloat16PerformanceScalar; + const auto& capabilities = kInterface->getCapabilities(); + return capabilities.relaxedFloat32toFloat16PerformanceScalar; } PerformanceInfo getRelaxedFloat32toFloat16PerformanceTensor() const override { - return mCapabilities.relaxedFloat32toFloat16PerformanceTensor; + const auto& capabilities = kInterface->getCapabilities(); + return capabilities.relaxedFloat32toFloat16PerformanceTensor; } bool isCachingSupported() const override { // Caching is supported if either of numModelCache or numDataCache is greater than 0. - return mNumCacheFiles.first > 0 || mNumCacheFiles.second > 0; + const auto [numModelCacheFiles, numDataCacheFiles] = + kInterface->getNumberOfCacheFilesNeeded(); + return numModelCacheFiles > 0 || numDataCacheFiles > 0; } std::pair<int, std::shared_ptr<PreparedModel>> prepareModel( @@ -88,12 +98,7 @@ class DriverDevice : public Device { std::pair<int, std::shared_ptr<PreparedModel>> prepareModelFromCacheInternal( const std::string& cacheDir, const CacheToken& token) const; - std::string mName; - std::string mVersionString; - const std::shared_ptr<VersionedIDevice> mInterface; - Capabilities mCapabilities; - hidl_vec<Extension> mSupportedExtensions; - std::pair<uint32_t, uint32_t> mNumCacheFiles; + const std::shared_ptr<VersionedIDevice> kInterface; #ifdef NN_DEBUGGABLE // For debugging: behavior of IDevice::getSupportedOperations for SampleDriver. @@ -124,104 +129,57 @@ class DriverPreparedModel : public PreparedModel { const std::shared_ptr<VersionedIPreparedModel> mPreparedModel; }; -DriverDevice::DriverDevice(std::string name, const sp<V1_0::IDevice>& device) - : mName(std::move(name)), mInterface(VersionedIDevice::create(mName, device)) {} - -// TODO: handle errors from initialize correctly -bool DriverDevice::initialize() { +DriverDevice::DriverDevice(std::shared_ptr<VersionedIDevice> device) + : kInterface(std::move(device)) { #ifdef NN_DEBUGGABLE static const char samplePrefix[] = "sample"; - - mSupported = (mName.substr(0, sizeof(samplePrefix) - 1) == samplePrefix) - ? getProp("debug.nn.sample.supported") - : 0; -#endif // NN_DEBUGGABLE - - ErrorStatus status = ErrorStatus::GENERAL_FAILURE; - - if (mInterface == nullptr) { - LOG(ERROR) << "DriverDevice contains invalid interface object."; - return false; - } - - std::tie(status, mCapabilities) = mInterface->getCapabilities(); - if (status != ErrorStatus::NONE) { - LOG(ERROR) << "IDevice::getCapabilities returned the error " << toString(status); - return false; - } - VLOG(MANAGER) << "Capab " << toString(mCapabilities); - - std::tie(status, mVersionString) = mInterface->getVersionString(); - // TODO(miaowang): add a validation test case for in case of error. - if (status != ErrorStatus::NONE) { - LOG(ERROR) << "IDevice::getVersionString returned the error " << toString(status); - return false; - } - - std::tie(status, mSupportedExtensions) = mInterface->getSupportedExtensions(); - if (status != ErrorStatus::NONE) { - LOG(ERROR) << "IDevice::getSupportedExtensions returned the error " << toString(status); - return false; + if (getName().substr(0, sizeof(samplePrefix) - 1) == samplePrefix) { + mSupported = getProp("debug.nn.sample.supported"); } +#endif // NN_DEBUGGABLE +} - std::tie(status, mNumCacheFiles.first, mNumCacheFiles.second) = - mInterface->getNumberOfCacheFilesNeeded(); - if (status != ErrorStatus::NONE) { - LOG(WARNING) << "IDevice::getNumberOfCacheFilesNeeded returned the error " - << toString(status); - mNumCacheFiles = {0, 0}; - } - if (mNumCacheFiles.first > static_cast<uint32_t>(Constant::MAX_NUMBER_OF_CACHE_FILES) || - mNumCacheFiles.second > static_cast<uint32_t>(Constant::MAX_NUMBER_OF_CACHE_FILES)) { - LOG(WARNING) - << "IDevice::getNumberOfCacheFilesNeeded returned invalid number of cache files " - "numModelCache = " - << mNumCacheFiles.first << ", numDataCache = " << mNumCacheFiles.second; - mNumCacheFiles = {0, 0}; +std::shared_ptr<DriverDevice> DriverDevice::create(std::string name, sp<V1_0::IDevice> device) { + CHECK(device != nullptr); + std::shared_ptr<VersionedIDevice> versionedDevice = + VersionedIDevice::create(name, std::move(device)); + if (versionedDevice == nullptr) { + LOG(ERROR) << "DriverDevice::create failed to create VersionedIDevice object for service " + << name; + return nullptr; } - return true; -} -hidl_vec<Extension> DriverDevice::getSupportedExtensions() const { - return mSupportedExtensions; + return std::make_shared<DriverDevice>(std::move(versionedDevice)); } -void DriverDevice::getSupportedOperations(const MetaModel& metaModel, - hidl_vec<bool>* outSupportedOperations) const { +std::vector<bool> DriverDevice::getSupportedOperations(const MetaModel& metaModel) const { // Query the driver for what it can do. ErrorStatus status = ErrorStatus::GENERAL_FAILURE; - hidl_vec<bool> supportedOperations; - std::tie(status, supportedOperations) = mInterface->getSupportedOperations(metaModel); + std::vector<bool> supportedOperations; + std::tie(status, supportedOperations) = kInterface->getSupportedOperations(metaModel); const Model& hidlModel = metaModel.getModel(); if (status != ErrorStatus::NONE) { LOG(ERROR) << "IDevice::getSupportedOperations returned the error " << toString(status); // Set the supported operation vectors to all false, so we won't use this driver. - outSupportedOperations->resize(hidlModel.operations.size()); - std::fill(outSupportedOperations->begin(), outSupportedOperations->end(), false); - return; + return std::vector<bool>(hidlModel.operations.size(), false); } if (supportedOperations.size() != hidlModel.operations.size()) { LOG(ERROR) << "IDevice::getSupportedOperations returned a vector of length " << supportedOperations.size() << " when expecting " << hidlModel.operations.size(); // Set the supported operation vectors to all false, so we won't use this driver. - outSupportedOperations->resize(hidlModel.operations.size()); - std::fill(outSupportedOperations->begin(), outSupportedOperations->end(), false); - return; + return std::vector<bool>(hidlModel.operations.size(), false); } - *outSupportedOperations = std::move(supportedOperations); - #ifdef NN_DEBUGGABLE if (mSupported != 1) { - return; + return supportedOperations; } - const uint32_t baseAccumulator = std::hash<std::string>{}(mName); - for (size_t operationIndex = 0; operationIndex < outSupportedOperations->size(); - operationIndex++) { - if (!(*outSupportedOperations)[operationIndex]) { + const uint32_t baseAccumulator = std::hash<std::string>{}(getName()); + for (size_t operationIndex = 0; operationIndex < supportedOperations.size(); operationIndex++) { + if (!supportedOperations[operationIndex]) { continue; } @@ -245,14 +203,12 @@ void DriverDevice::getSupportedOperations(const MetaModel& metaModel, accumulateOperands(operation.inputs); accumulateOperands(operation.outputs); if (accumulator & 1) { - (*outSupportedOperations)[operationIndex] = false; + supportedOperations[operationIndex] = false; } } #endif // NN_DEBUGGABLE -} -PerformanceInfo DriverDevice::getPerformance(OperandType type) const { - return lookup(mCapabilities.operandPerformance, type); + return supportedOperations; } // Opens cache file by filename and sets the handle to the opened fd. Returns false on fail. The @@ -322,7 +278,7 @@ static bool getCacheHandles(const std::string& cacheDir, const CacheToken& token static std::pair<int, std::shared_ptr<PreparedModel>> prepareModelCheck( ErrorStatus status, const std::shared_ptr<VersionedIPreparedModel>& preparedModel, - const char* prepareName, const char* serviceName) { + const char* prepareName, const std::string& serviceName) { if (status != ErrorStatus::NONE) { LOG(ERROR) << prepareName << " on " << serviceName << " failed: " << "prepareReturnStatus=" << toString(status); @@ -344,7 +300,7 @@ std::pair<int, std::shared_ptr<PreparedModel>> DriverDevice::prepareModelInterna hidl_vec<hidl_handle> modelCache, dataCache; if (!maybeToken.has_value() || - !getCacheHandles(cacheDir, *maybeToken, mNumCacheFiles, + !getCacheHandles(cacheDir, *maybeToken, kInterface->getNumberOfCacheFilesNeeded(), /*createIfNotExist=*/true, &modelCache, &dataCache)) { modelCache.resize(0); dataCache.resize(0); @@ -353,7 +309,7 @@ std::pair<int, std::shared_ptr<PreparedModel>> DriverDevice::prepareModelInterna static const CacheToken kNullToken{}; const CacheToken token = maybeToken.value_or(kNullToken); const auto [status, preparedModel] = - mInterface->prepareModel(model, preference, modelCache, dataCache, token); + kInterface->prepareModel(model, preference, modelCache, dataCache, token); return prepareModelCheck(status, preparedModel, "prepareModel", getName()); } @@ -365,13 +321,13 @@ std::pair<int, std::shared_ptr<PreparedModel>> DriverDevice::prepareModelFromCac VLOG(COMPILATION) << "prepareModelFromCache"; hidl_vec<hidl_handle> modelCache, dataCache; - if (!getCacheHandles(cacheDir, token, mNumCacheFiles, + if (!getCacheHandles(cacheDir, token, kInterface->getNumberOfCacheFilesNeeded(), /*createIfNotExist=*/false, &modelCache, &dataCache)) { return {ANEURALNETWORKS_OP_FAILED, nullptr}; } const auto [status, preparedModel] = - mInterface->prepareModelFromCache(modelCache, dataCache, token); + kInterface->prepareModelFromCache(modelCache, dataCache, token); return prepareModelCheck(status, preparedModel, "prepareModelFromCache", getName()); } @@ -571,13 +527,14 @@ class CpuDevice : public Device { return instance; } - const char* getName() const override { return kName.c_str(); } - const char* getVersionString() const override { return kVersionString.c_str(); } + const std::string& getName() const override { return kName; } + const std::string& getVersionString() const override { return kVersionString; } int64_t getFeatureLevel() const override { return kFeatureLevel; } int32_t getType() const override { return ANEURALNETWORKS_DEVICE_CPU; } - hidl_vec<Extension> getSupportedExtensions() const override { return {/* No extensions. */}; } - void getSupportedOperations(const MetaModel& metaModel, - hidl_vec<bool>* supportedOperations) const override; + const std::vector<Extension>& getSupportedExtensions() const override { + return kSupportedExtensions; + } + std::vector<bool> getSupportedOperations(const MetaModel& metaModel) const override; PerformanceInfo getPerformance(OperandType) const override { return kPerformance; } PerformanceInfo getRelaxedFloat32toFloat16PerformanceScalar() const override { return kPerformance; @@ -600,6 +557,7 @@ class CpuDevice : public Device { // Since the performance is a ratio compared to the CPU performance, // by definition the performance of the CPU is 1.0. const PerformanceInfo kPerformance = {.execTime = 1.0f, .powerUsage = 1.0f}; + const std::vector<Extension> kSupportedExtensions{/* No extensions. */}; }; // A special abstracted PreparedModel for the CPU, constructed by CpuDevice. @@ -629,11 +587,10 @@ class CpuPreparedModel : public PreparedModel { const std::vector<RunTimePoolInfo> mModelPoolInfos; }; -void CpuDevice::getSupportedOperations(const MetaModel& metaModel, - hidl_vec<bool>* supportedOperations) const { +std::vector<bool> CpuDevice::getSupportedOperations(const MetaModel& metaModel) const { const Model& hidlModel = metaModel.getModel(); const size_t count = hidlModel.operations.size(); - hidl_vec<bool> result(count); + std::vector<bool> result(count, false); for (size_t i = 0; i < count; i++) { // TODO(b/119870033): Decide whether and how post-P operations would be supported on CPU. // We may want to use the slicer for CpuDevice just as we do for @@ -642,7 +599,7 @@ void CpuDevice::getSupportedOperations(const MetaModel& metaModel, result[i] = !isExtensionOperationType(operationType) && operationType != OperationType::OEM_OPERATION; } - *supportedOperations = std::move(result); + return result; } std::pair<int, std::shared_ptr<PreparedModel>> CpuDevice::prepareModel( @@ -751,42 +708,33 @@ std::shared_ptr<Device> DeviceManager::getCpuDevice() { std::shared_ptr<Device> DeviceManager::forTest_makeDriverDevice(const std::string& name, const sp<V1_0::IDevice>& device) { - auto driverDevice = std::make_shared<DriverDevice>(name, device); - CHECK(driverDevice->initialize()); + const auto driverDevice = DriverDevice::create(name, device); + CHECK(driverDevice != nullptr); return driverDevice; } void DeviceManager::findAvailableDevices() { - using ::android::hidl::manager::V1_2::IServiceManager; VLOG(MANAGER) << "findAvailableDevices"; - sp<IServiceManager> manager = hardware::defaultServiceManager1_2(); - if (manager == nullptr) { - LOG(ERROR) << "Unable to open defaultServiceManager"; - return; + // register driver devices + const auto names = hardware::getAllHalInstanceNames(V1_0::IDevice::descriptor); + for (const auto& name : names) { + VLOG(MANAGER) << "Found interface " << name; + sp<V1_0::IDevice> device = V1_0::IDevice::getService(name); + if (device == nullptr) { + LOG(ERROR) << "Got a null IDEVICE for " << name; + continue; + } + registerDevice(name, device); } - manager->listManifestByInterface( - V1_0::IDevice::descriptor, [this](const hidl_vec<hidl_string>& names) { - for (const auto& name : names) { - VLOG(MANAGER) << "Found interface " << name.c_str(); - sp<V1_0::IDevice> device = V1_0::IDevice::getService(name); - if (device == nullptr) { - LOG(ERROR) << "Got a null IDEVICE for " << name.c_str(); - continue; - } - registerDevice(name.c_str(), device); - } - }); - // register CPU fallback device mDevices.push_back(CpuDevice::get()); mDevicesCpuOnly.push_back(CpuDevice::get()); } -void DeviceManager::registerDevice(const char* name, const sp<V1_0::IDevice>& device) { - auto d = std::make_shared<DriverDevice>(name, device); - if (d->initialize()) { +void DeviceManager::registerDevice(const std::string& name, const sp<V1_0::IDevice>& device) { + if (const auto d = DriverDevice::create(name, device)) { mDevices.push_back(d); } } |