From 05509cba30e095d20da47ff5e614d54ce25c6ab5 Mon Sep 17 00:00:00 2001 From: Kevin May Date: Mon, 9 Jan 2023 16:06:45 +0000 Subject: IVGCVSW-7402 Fix for Native crashes in Arm NNAPI SL * Instead of extending ArmnnDevice with ArmnnDriver make it a member * This will allow us to construct the ArmnnDriver and return a DEVICE_UNAVAILABLE NN_ERROR instead of segfaulting with the armnn::InvalidArgumentException if we cannot create a device Signed-off-by: Kevin May Change-Id: Ibbcdbeb33dfd170dd1fb393204620e5b9e6342b8 --- shim/sl/canonical/ArmnnDevice.hpp | 8 ++-- shim/sl/canonical/ArmnnDriver.hpp | 84 ++++++++++++++++++++++++--------------- 2 files changed, 56 insertions(+), 36 deletions(-) diff --git a/shim/sl/canonical/ArmnnDevice.hpp b/shim/sl/canonical/ArmnnDevice.hpp index 9597bfc013..93109696f7 100644 --- a/shim/sl/canonical/ArmnnDevice.hpp +++ b/shim/sl/canonical/ArmnnDevice.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2022 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -14,11 +14,11 @@ namespace armnn_driver class ArmnnDevice { +friend class ArmnnDriver; -protected: +public: ArmnnDevice(DriverOptions options); - virtual ~ArmnnDevice() {} - + ~ArmnnDevice() {} protected: armnn::IRuntimePtr m_Runtime; armnn::IGpuAccTunedParametersPtr m_ClTunedParameters; diff --git a/shim/sl/canonical/ArmnnDriver.hpp b/shim/sl/canonical/ArmnnDriver.hpp index bf5565a219..6cb06604d2 100644 --- a/shim/sl/canonical/ArmnnDriver.hpp +++ b/shim/sl/canonical/ArmnnDriver.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2022 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -28,18 +28,26 @@ namespace armnn_driver //using namespace android::nn; -class ArmnnDriver : public ArmnnDevice, public IDevice +class ArmnnDriver : public IDevice { +private: + std::unique_ptr m_Device; public: - ArmnnDriver(DriverOptions options) - : ArmnnDevice(std::move(options)) - { - VLOG(DRIVER) << "ArmnnDriver::ArmnnDriver()"; - } - ~ArmnnDriver() { - VLOG(DRIVER) << "ArmnnDriver::~ArmnnDriver()"; + try + { + VLOG(DRIVER) << "ArmnnDriver::ArmnnDriver()"; + m_Device = std::unique_ptr(new ArmnnDevice(std::move(options))); + } + catch (armnn::InvalidArgumentException& ex) + { + VLOG(DRIVER) << "ArmnnDevice failed to initialise: " << ex.what(); + } + catch (...) + { + VLOG(DRIVER) << "ArmnnDevice failed to initialise with an unknown error"; + } } public: @@ -80,17 +88,18 @@ public: const Capabilities& getCapabilities() const override { VLOG(DRIVER) << "ArmnnDriver::GetCapabilities()"; - return ArmnnDriverImpl::GetCapabilities(m_Runtime); + return ArmnnDriverImpl::GetCapabilities(m_Device->m_Runtime); } std::pair getNumberOfCacheFilesNeeded() const override { VLOG(DRIVER) << "ArmnnDriver::getNumberOfCacheFilesNeeded()"; unsigned int numberOfCachedModelFiles = 0; - for (auto& backend : m_Options.GetBackends()) + for (auto& backend : m_Device->m_Options.GetBackends()) { numberOfCachedModelFiles += GetNumberOfCacheFiles(backend); - VLOG(DRIVER) << "ArmnnDriver::getNumberOfCacheFilesNeeded() = " << std::to_string(numberOfCachedModelFiles); + VLOG(DRIVER) << "ArmnnDriver::getNumberOfCacheFilesNeeded() = " + << std::to_string(numberOfCachedModelFiles); } return std::make_pair(numberOfCachedModelFiles, 1ul); } @@ -104,22 +113,26 @@ public: GeneralResult> getSupportedOperations(const Model& model) const override { VLOG(DRIVER) << "ArmnnDriver::getSupportedOperations()"; + if (m_Device.get() == nullptr) + { + return NN_ERROR(ErrorStatus::DEVICE_UNAVAILABLE) << "Device Unavailable!"; + } std::stringstream ss; ss << "ArmnnDriverImpl::getSupportedOperations()"; std::string fileName; std::string timestamp; - if (!m_Options.GetRequestInputsAndOutputsDumpDir().empty()) + if (!m_Device->m_Options.GetRequestInputsAndOutputsDumpDir().empty()) { ss << " : " - << m_Options.GetRequestInputsAndOutputsDumpDir() + << m_Device->m_Options.GetRequestInputsAndOutputsDumpDir() << "/" // << GetFileTimestamp() << "_getSupportedOperations.txt"; } VLOG(DRIVER) << ss.str().c_str(); - if (!m_Options.GetRequestInputsAndOutputsDumpDir().empty()) + if (!m_Device->m_Options.GetRequestInputsAndOutputsDumpDir().empty()) { //dump the marker file std::ofstream fileStream; @@ -133,7 +146,7 @@ public: } std::vector result; - if (!m_Runtime) + if (!m_Device->m_Runtime) { return NN_ERROR(ErrorStatus::DEVICE_UNAVAILABLE) << "Device Unavailable!"; } @@ -145,9 +158,9 @@ public: } // Attempt to convert the model to an ArmNN input network (INetwork). - ModelToINetworkTransformer modelConverter(m_Options.GetBackends(), + ModelToINetworkTransformer modelConverter(m_Device->m_Options.GetBackends(), model, - m_Options.GetForcedUnsupportedOperations()); + m_Device->m_Options.GetForcedUnsupportedOperations()); if (modelConverter.GetConversionResult() != ConversionResult::Success && modelConverter.GetConversionResult() != ConversionResult::UnsupportedFeature) @@ -179,6 +192,10 @@ public: { VLOG(DRIVER) << "ArmnnDriver::prepareModel()"; + if (m_Device.get() == nullptr) + { + return NN_ERROR(ErrorStatus::DEVICE_UNAVAILABLE) << "Device Unavailable!"; + } // Validate arguments. if (const auto result = validate(model); !result.ok()) { return NN_ERROR(ErrorStatus::INVALID_ARGUMENT) << "Invalid Model: " << result.error(); @@ -196,15 +213,15 @@ public: return NN_ERROR(ErrorStatus::MISSED_DEADLINE_PERSISTENT); } - return ArmnnDriverImpl::PrepareArmnnModel(m_Runtime, - m_ClTunedParameters, - m_Options, - model, - modelCache, - dataCache, - token, - model.relaxComputationFloat32toFloat16 && m_Options.GetFp16Enabled(), - priority); + return ArmnnDriverImpl::PrepareArmnnModel(m_Device->m_Runtime, + m_Device->m_ClTunedParameters, + m_Device->m_Options, + model, + modelCache, + dataCache, + token, + model.relaxComputationFloat32toFloat16 && m_Device->m_Options.GetFp16Enabled(), + priority); } GeneralResult prepareModelFromCache(OptionalTimePoint deadline, @@ -213,20 +230,23 @@ public: const CacheToken& token) const override { VLOG(DRIVER) << "ArmnnDriver::prepareModelFromCache()"; - + if (m_Device.get() == nullptr) + { + return NN_ERROR(ErrorStatus::DEVICE_UNAVAILABLE) << "Device Unavailable!"; + } // Check if deadline has passed. if (hasDeadlinePassed(deadline)) { return NN_ERROR(ErrorStatus::MISSED_DEADLINE_PERSISTENT); } return ArmnnDriverImpl::PrepareArmnnModelFromCache( - m_Runtime, - m_ClTunedParameters, - m_Options, + m_Device->m_Runtime, + m_Device->m_ClTunedParameters, + m_Device->m_Options, modelCache, dataCache, token, - m_Options.GetFp16Enabled()); + m_Device->m_Options.GetFp16Enabled()); } GeneralResult allocate(const BufferDesc&, -- cgit v1.2.1