ArmNN
 21.02
BackendRegistryTests.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include <armnn/Types.hpp>
8 
10 #include <reference/RefBackend.hpp>
11 
12 #include <boost/test/unit_test.hpp>
13 
14 namespace
15 {
16 
17 class SwapRegistryStorage : public armnn::BackendRegistry
18 {
19 public:
20  SwapRegistryStorage() : armnn::BackendRegistry()
21  {
22  Swap(armnn::BackendRegistryInstance(), m_TempStorage);
23  }
24 
25  ~SwapRegistryStorage()
26  {
27  Swap(armnn::BackendRegistryInstance(),m_TempStorage);
28  }
29 
30 private:
31  FactoryStorage m_TempStorage;
32 };
33 
34 }
35 
36 BOOST_AUTO_TEST_SUITE(BackendRegistryTests)
37 
38 BOOST_AUTO_TEST_CASE(SwapRegistry)
39 {
40  using namespace armnn;
41  auto nFactories = BackendRegistryInstance().Size();
42  {
43  SwapRegistryStorage helper;
44  BOOST_TEST(BackendRegistryInstance().Size() == 0);
45  }
46  BOOST_TEST(BackendRegistryInstance().Size() == nFactories);
47 }
48 
49 BOOST_AUTO_TEST_CASE(TestRegistryHelper)
50 {
51  using namespace armnn;
52  SwapRegistryStorage helper;
53 
54  bool called = false;
55 
58  "HelloWorld",
59  [&called]()
60  {
61  called = true;
62  return armnn::IBackendInternalUniquePtr(nullptr);
63  }
64  );
65 
66  // sanity check: the factory has not been called yet
67  BOOST_TEST(called == false);
68 
69  auto factoryFunction = BackendRegistryInstance().GetFactory("HelloWorld");
70 
71  // sanity check: the factory still not called
72  BOOST_TEST(called == false);
73 
74  factoryFunction();
75  BOOST_TEST(called == true);
76  BackendRegistryInstance().Deregister("HelloWorld");
77 }
78 
79 BOOST_AUTO_TEST_CASE(TestDirectCallToRegistry)
80 {
81  using namespace armnn;
82  SwapRegistryStorage helper;
83 
84  bool called = false;
86  "HelloWorld",
87  [&called]()
88  {
89  called = true;
90  return armnn::IBackendInternalUniquePtr(nullptr);
91  }
92  );
93 
94  // sanity check: the factory has not been called yet
95  BOOST_TEST(called == false);
96 
97  auto factoryFunction = BackendRegistryInstance().GetFactory("HelloWorld");
98 
99  // sanity check: the factory still not called
100  BOOST_TEST(called == false);
101 
102  factoryFunction();
103  BOOST_TEST(called == true);
104  BackendRegistryInstance().Deregister("HelloWorld");
105 }
106 
107 // Test that backends can throw exceptions during their factory function to prevent loading in an unsuitable
108 // environment. For example Neon Backend loading on armhf device without neon support.
109 // In reality the dynamic backend is loaded in during the LoadDynamicBackends(options.m_DynamicBackendsPath)
110 // step of runtime constructor, then the factory function is called to check if supported, in case
111 // of Neon not being detected the exception is raised and so the backend is not added to the supportedBackends
112 // list
113 
114 BOOST_AUTO_TEST_CASE(ThrowBackendUnavailableException)
115 {
116  using namespace armnn;
117 
118  const BackendId mockBackendId("MockDynamicBackend");
119 
120  const std::string exceptionMessage("Neon support not found on device, could not register CpuAcc Backend.\n");
121 
122  // Register the mock backend with a factory function lambda equivalent to NeonRegisterInitializer
123  BackendRegistryInstance().Register(mockBackendId,
124  [exceptionMessage]()
125  {
126  if (false)
127  {
129  }
130  ARMNN_LOG(info) << "Neon support not found on device, could not register CpuAcc Backend.";
131  throw armnn::BackendUnavailableException(exceptionMessage);
132  });
133 
134  // Get the factory function of the mock backend
135  auto factoryFunc = BackendRegistryInstance().GetFactory(mockBackendId);
136 
137  try
138  {
139  // Call the factory function as done during runtime backend registering
140  auto backend = factoryFunc();
141  }
142  catch (const BackendUnavailableException& e)
143  {
144  // Caught
145  BOOST_CHECK_EQUAL(e.what(), exceptionMessage);
146  BOOST_TEST_MESSAGE("ThrowBackendUnavailableExceptionImpl: BackendUnavailableException caught.");
147  }
148 }
149 
BOOST_AUTO_TEST_SUITE(TensorflowLiteParser)
FactoryFunction GetFactory(const BackendId &id) const
void Register(const BackendId &id, FactoryFunction factory)
static void Swap(BackendRegistry &instance, FactoryStorage &other)
For testing only.
virtual const char * what() const noexcept override
Definition: Exceptions.cpp:32
#define ARMNN_LOG(severity)
Definition: Logging.hpp:202
BackendRegistry & BackendRegistryInstance()
Copyright (c) 2021 ARM Limited and Contributors.
BOOST_AUTO_TEST_CASE(SwapRegistry)
BOOST_AUTO_TEST_SUITE_END()
void Deregister(const BackendId &id)
std::unique_ptr< IBackendInternal > IBackendInternalUniquePtr
Class for non-fatal exceptions raised while initialising a backend.
Definition: Exceptions.hpp:68