1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include <armnn/BackendRegistry.hpp>
7 #include <armnn/Exceptions.hpp>
8 #include <armnn/profiling/ArmNNProfiling.hpp>
9
10 #include <client/include/IProfilingService.hpp>
11
12 namespace armnn
13 {
14
BackendRegistryInstance()15 BackendRegistry& BackendRegistryInstance()
16 {
17 static BackendRegistry instance;
18 return instance;
19 }
20
Register(const BackendId & id,BackendRegistry::FactoryFunction factory)21 void BackendRegistry::Register(const BackendId& id, BackendRegistry::FactoryFunction factory)
22 {
23 if (m_Factories.find(id) != m_Factories.end())
24 {
25 throw InvalidArgumentException(
26 std::string(id) + " already registered as IBackend factory",
27 CHECK_LOCATION());
28 }
29 m_Factories[id] = factory;
30
31 if (m_ProfilingService.has_value())
32 {
33 if (m_ProfilingService.has_value() && m_ProfilingService.value().IsProfilingEnabled())
34 {
35 m_ProfilingService.value().IncrementCounterValue(arm::pipe::REGISTERED_BACKENDS);
36 }
37 }
38
39 }
40
Deregister(const BackendId & id)41 void BackendRegistry::Deregister(const BackendId& id)
42 {
43 m_Factories.erase(id);
44 DeregisterAllocator(id);
45
46 if (m_ProfilingService.has_value() && m_ProfilingService.value().IsProfilingEnabled())
47 {
48 m_ProfilingService.value().IncrementCounterValue(arm::pipe::UNREGISTERED_BACKENDS);
49 }
50 }
51
IsBackendRegistered(const BackendId & id) const52 bool BackendRegistry::IsBackendRegistered(const BackendId& id) const
53 {
54 return (m_Factories.find(id) != m_Factories.end());
55 }
56
GetFactory(const BackendId & id) const57 BackendRegistry::FactoryFunction BackendRegistry::GetFactory(const BackendId& id) const
58 {
59 auto it = m_Factories.find(id);
60 if (it == m_Factories.end())
61 {
62 throw InvalidArgumentException(
63 std::string(id) + " has no IBackend factory registered",
64 CHECK_LOCATION());
65 }
66
67 return it->second;
68 }
69
Size() const70 size_t BackendRegistry::Size() const
71 {
72 return m_Factories.size();
73 }
74
GetBackendIds() const75 BackendIdSet BackendRegistry::GetBackendIds() const
76 {
77 BackendIdSet result;
78 for (const auto& it : m_Factories)
79 {
80 result.insert(it.first);
81 }
82 return result;
83 }
84
GetBackendIdsAsString() const85 std::string BackendRegistry::GetBackendIdsAsString() const
86 {
87 static const std::string delimitator = ", ";
88
89 std::stringstream output;
90 for (auto& backendId : GetBackendIds())
91 {
92 if (output.tellp() != std::streampos(0))
93 {
94 output << delimitator;
95 }
96 output << backendId;
97 }
98
99 return output.str();
100 }
101
Swap(BackendRegistry & instance,BackendRegistry::FactoryStorage & other)102 void BackendRegistry::Swap(BackendRegistry& instance, BackendRegistry::FactoryStorage& other)
103 {
104 std::swap(instance.m_Factories, other);
105 }
106
SetProfilingService(armnn::Optional<arm::pipe::IProfilingService &> profilingService)107 void BackendRegistry::SetProfilingService(armnn::Optional<arm::pipe::IProfilingService&> profilingService)
108 {
109 m_ProfilingService = profilingService;
110 }
111
RegisterAllocator(const BackendId & id,std::shared_ptr<ICustomAllocator> alloc)112 void BackendRegistry::RegisterAllocator(const BackendId& id, std::shared_ptr<ICustomAllocator> alloc)
113 {
114 if (m_CustomMemoryAllocatorMap.find(id) != m_CustomMemoryAllocatorMap.end())
115 {
116 throw InvalidArgumentException(
117 std::string(id) + " already has an allocator associated with it",
118 CHECK_LOCATION());
119 }
120 m_CustomMemoryAllocatorMap[id] = alloc;
121 }
122
DeregisterAllocator(const BackendId & id)123 void BackendRegistry::DeregisterAllocator(const BackendId& id)
124 {
125 m_CustomMemoryAllocatorMap.erase(id);
126 }
127
GetAllocators()128 std::unordered_map<BackendId, std::shared_ptr<ICustomAllocator>> BackendRegistry::GetAllocators()
129 {
130 return m_CustomMemoryAllocatorMap;
131 }
132
RegisterMemoryOptimizerStrategy(const BackendId & id,std::shared_ptr<IMemoryOptimizerStrategy> strategy)133 void BackendRegistry::RegisterMemoryOptimizerStrategy(const BackendId& id,
134 std::shared_ptr<IMemoryOptimizerStrategy> strategy)
135 {
136 if (m_MemoryOptimizerStrategyMap.find(id) != m_MemoryOptimizerStrategyMap.end())
137 {
138 throw InvalidArgumentException(
139 std::string(id) + " already has an memory optimizer strategy associated with it",
140 CHECK_LOCATION());
141 }
142 m_MemoryOptimizerStrategyMap[id] = strategy;
143 }
144
DeregisterMemoryOptimizerStrategy(const BackendId & id)145 void BackendRegistry::DeregisterMemoryOptimizerStrategy(const BackendId &id)
146 {
147 m_MemoryOptimizerStrategyMap.erase(id);
148 }
149
GetMemoryOptimizerStrategies()150 MemoryOptimizerStrategiesMapRef BackendRegistry::GetMemoryOptimizerStrategies()
151 {
152 return m_MemoryOptimizerStrategyMap;
153 }
154
155 } // namespace armnn
156