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