xref: /aosp_15_r20/external/armnn/src/backends/backendsCommon/DynamicBackendUtils.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
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 Worker EntryPointType 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