1*89c4ff92SAndroid Build Coastguard Worker // 2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2017 Arm Ltd and Contributors. All rights reserved. 3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT 4*89c4ff92SAndroid Build Coastguard Worker // 5*89c4ff92SAndroid Build Coastguard Worker 6*89c4ff92SAndroid Build Coastguard Worker #pragma once 7*89c4ff92SAndroid Build Coastguard Worker 8*89c4ff92SAndroid Build Coastguard Worker #include <armnn/backends/DynamicBackend.hpp> 9*89c4ff92SAndroid Build Coastguard Worker #include <armnn/backends/IBackendInternal.hpp> 10*89c4ff92SAndroid Build Coastguard Worker 11*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Exceptions.hpp> 12*89c4ff92SAndroid Build Coastguard Worker 13*89c4ff92SAndroid Build Coastguard Worker #include <fmt/format.h> 14*89c4ff92SAndroid Build Coastguard Worker 15*89c4ff92SAndroid Build Coastguard Worker #include <string> 16*89c4ff92SAndroid Build Coastguard Worker #include <vector> 17*89c4ff92SAndroid Build Coastguard Worker #if defined(__unix__) || defined(__APPLE__) 18*89c4ff92SAndroid Build Coastguard Worker #include <dlfcn.h> 19*89c4ff92SAndroid Build Coastguard Worker #endif 20*89c4ff92SAndroid Build Coastguard Worker 21*89c4ff92SAndroid Build Coastguard Worker #if !defined(DYNAMIC_BACKEND_PATHS) 22*89c4ff92SAndroid Build Coastguard Worker #define DYNAMIC_BACKEND_PATHS "" 23*89c4ff92SAndroid Build Coastguard Worker #endif 24*89c4ff92SAndroid Build Coastguard Worker 25*89c4ff92SAndroid Build Coastguard Worker namespace armnn 26*89c4ff92SAndroid Build Coastguard Worker { 27*89c4ff92SAndroid Build Coastguard Worker 28*89c4ff92SAndroid Build Coastguard Worker class DynamicBackendUtils 29*89c4ff92SAndroid Build Coastguard Worker { 30*89c4ff92SAndroid Build Coastguard Worker public: 31*89c4ff92SAndroid Build Coastguard Worker static void* OpenHandle(const std::string& sharedObjectPath); 32*89c4ff92SAndroid Build Coastguard Worker static void CloseHandle(const void* sharedObjectHandle); 33*89c4ff92SAndroid Build Coastguard Worker 34*89c4ff92SAndroid Build Coastguard Worker template<typename EntryPointType> 35*89c4ff92SAndroid Build Coastguard Worker static EntryPointType GetEntryPoint(const void* sharedObjectHandle, const char* symbolName); 36*89c4ff92SAndroid Build Coastguard Worker 37*89c4ff92SAndroid Build Coastguard Worker static bool IsBackendCompatible(const BackendVersion& backendVersion); 38*89c4ff92SAndroid Build Coastguard Worker 39*89c4ff92SAndroid Build Coastguard Worker static std::vector<std::string> GetBackendPaths(const std::string& overrideBackendPath = ""); 40*89c4ff92SAndroid Build Coastguard Worker static bool IsPathValid(const std::string& path); 41*89c4ff92SAndroid Build Coastguard Worker static std::vector<std::string> GetSharedObjects(const std::vector<std::string>& backendPaths); 42*89c4ff92SAndroid Build Coastguard Worker 43*89c4ff92SAndroid Build Coastguard Worker static std::vector<DynamicBackendPtr> CreateDynamicBackends(const std::vector<std::string>& sharedObjects); 44*89c4ff92SAndroid Build Coastguard Worker static BackendIdSet RegisterDynamicBackends(const std::vector<DynamicBackendPtr>& dynamicBackends); 45*89c4ff92SAndroid Build Coastguard Worker static void DeregisterDynamicBackends(const BackendIdSet& dynamicBackends); 46*89c4ff92SAndroid Build Coastguard Worker 47*89c4ff92SAndroid Build Coastguard Worker protected: 48*89c4ff92SAndroid Build Coastguard Worker /// Protected methods for testing purposes 49*89c4ff92SAndroid Build Coastguard Worker static bool IsBackendCompatibleImpl(const BackendVersion& backendApiVersion, const BackendVersion& backendVersion); 50*89c4ff92SAndroid Build Coastguard Worker static std::vector<std::string> GetBackendPathsImpl(const std::string& backendPaths); 51*89c4ff92SAndroid Build Coastguard Worker static BackendIdSet RegisterDynamicBackendsImpl(BackendRegistry& backendRegistry, 52*89c4ff92SAndroid Build Coastguard Worker const std::vector<DynamicBackendPtr>& dynamicBackends); 53*89c4ff92SAndroid Build Coastguard Worker 54*89c4ff92SAndroid Build Coastguard Worker private: 55*89c4ff92SAndroid Build Coastguard Worker static std::string GetDlError(); 56*89c4ff92SAndroid Build Coastguard Worker 57*89c4ff92SAndroid Build Coastguard Worker /// This class is to hold utility functions only 58*89c4ff92SAndroid Build Coastguard Worker DynamicBackendUtils() = delete; 59*89c4ff92SAndroid Build Coastguard Worker }; 60*89c4ff92SAndroid Build Coastguard Worker 61*89c4ff92SAndroid Build Coastguard Worker template<typename EntryPointType> GetEntryPoint(const void * sharedObjectHandle,const char * symbolName)62*89c4ff92SAndroid Build Coastguard WorkerEntryPointType DynamicBackendUtils::GetEntryPoint(const void* sharedObjectHandle, const char* symbolName) 63*89c4ff92SAndroid Build Coastguard Worker { 64*89c4ff92SAndroid Build Coastguard Worker #if defined(__unix__) || defined(__APPLE__) 65*89c4ff92SAndroid Build Coastguard Worker if (sharedObjectHandle == nullptr) 66*89c4ff92SAndroid Build Coastguard Worker { 67*89c4ff92SAndroid Build Coastguard Worker throw RuntimeException("GetEntryPoint error: invalid handle"); 68*89c4ff92SAndroid Build Coastguard Worker } 69*89c4ff92SAndroid Build Coastguard Worker 70*89c4ff92SAndroid Build Coastguard Worker if (symbolName == nullptr) 71*89c4ff92SAndroid Build Coastguard Worker { 72*89c4ff92SAndroid Build Coastguard Worker throw RuntimeException("GetEntryPoint error: invalid symbol"); 73*89c4ff92SAndroid Build Coastguard Worker } 74*89c4ff92SAndroid Build Coastguard Worker 75*89c4ff92SAndroid Build Coastguard Worker auto entryPoint = reinterpret_cast<EntryPointType>(dlsym(const_cast<void*>(sharedObjectHandle), symbolName)); 76*89c4ff92SAndroid Build Coastguard Worker if (!entryPoint) 77*89c4ff92SAndroid Build Coastguard Worker { 78*89c4ff92SAndroid Build Coastguard Worker throw RuntimeException(fmt::format("GetEntryPoint error: {}", GetDlError())); 79*89c4ff92SAndroid Build Coastguard Worker } 80*89c4ff92SAndroid Build Coastguard Worker 81*89c4ff92SAndroid Build Coastguard Worker return entryPoint; 82*89c4ff92SAndroid Build Coastguard Worker #else 83*89c4ff92SAndroid Build Coastguard Worker armnn::IgnoreUnused(sharedObjectHandle); 84*89c4ff92SAndroid Build Coastguard Worker armnn::IgnoreUnused(symbolName); 85*89c4ff92SAndroid Build Coastguard Worker throw RuntimeException("Dynamic backends not supported on this platform"); 86*89c4ff92SAndroid Build Coastguard Worker #endif 87*89c4ff92SAndroid Build Coastguard Worker } 88*89c4ff92SAndroid Build Coastguard Worker 89*89c4ff92SAndroid Build Coastguard Worker } // namespace armnn 90