| // |
| // Copyright © 2017 Arm Ltd and Contributors. All rights reserved. |
| // SPDX-License-Identifier: MIT |
| // |
| |
| #pragma once |
| |
| #include <armnn/backends/DynamicBackend.hpp> |
| #include <armnn/backends/IBackendInternal.hpp> |
| |
| #include <armnn/Exceptions.hpp> |
| |
| #include <fmt/format.h> |
| |
| #include <string> |
| #include <vector> |
| #if defined(__unix__) || defined(__APPLE__) |
| #include <dlfcn.h> |
| #endif |
| |
| #if !defined(DYNAMIC_BACKEND_PATHS) |
| #define DYNAMIC_BACKEND_PATHS "" |
| #endif |
| |
| namespace armnn |
| { |
| |
| class DynamicBackendUtils |
| { |
| public: |
| static void* OpenHandle(const std::string& sharedObjectPath); |
| static void CloseHandle(const void* sharedObjectHandle); |
| |
| template<typename EntryPointType> |
| static EntryPointType GetEntryPoint(const void* sharedObjectHandle, const char* symbolName); |
| |
| static bool IsBackendCompatible(const BackendVersion& backendVersion); |
| |
| static std::vector<std::string> GetBackendPaths(const std::string& overrideBackendPath = ""); |
| static bool IsPathValid(const std::string& path); |
| static std::vector<std::string> GetSharedObjects(const std::vector<std::string>& backendPaths); |
| |
| static std::vector<DynamicBackendPtr> CreateDynamicBackends(const std::vector<std::string>& sharedObjects); |
| static BackendIdSet RegisterDynamicBackends(const std::vector<DynamicBackendPtr>& dynamicBackends); |
| static void DeregisterDynamicBackends(const BackendIdSet& dynamicBackends); |
| |
| protected: |
| /// Protected methods for testing purposes |
| static bool IsBackendCompatibleImpl(const BackendVersion& backendApiVersion, const BackendVersion& backendVersion); |
| static std::vector<std::string> GetBackendPathsImpl(const std::string& backendPaths); |
| static BackendIdSet RegisterDynamicBackendsImpl(BackendRegistry& backendRegistry, |
| const std::vector<DynamicBackendPtr>& dynamicBackends); |
| |
| private: |
| static std::string GetDlError(); |
| |
| /// This class is to hold utility functions only |
| DynamicBackendUtils() = delete; |
| }; |
| |
| template<typename EntryPointType> |
| EntryPointType DynamicBackendUtils::GetEntryPoint(const void* sharedObjectHandle, const char* symbolName) |
| { |
| #if defined(__unix__) || defined(__APPLE__) |
| if (sharedObjectHandle == nullptr) |
| { |
| throw RuntimeException("GetEntryPoint error: invalid handle"); |
| } |
| |
| if (symbolName == nullptr) |
| { |
| throw RuntimeException("GetEntryPoint error: invalid symbol"); |
| } |
| |
| auto entryPoint = reinterpret_cast<EntryPointType>(dlsym(const_cast<void*>(sharedObjectHandle), symbolName)); |
| if (!entryPoint) |
| { |
| throw RuntimeException(fmt::format("GetEntryPoint error: {}", GetDlError())); |
| } |
| |
| return entryPoint; |
| #else |
| armnn::IgnoreUnused(sharedObjectHandle); |
| armnn::IgnoreUnused(symbolName); |
| throw RuntimeException("Dynamic backends not supported on this platform"); |
| #endif |
| } |
| |
| } // namespace armnn |