blob: ce8acbbf2a30d745c4d39d74111d1f840ae9aefa [file] [log] [blame]
David Beck32cbb0c2018-10-09 15:46:08 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
David Beck32cbb0c2018-10-09 15:46:08 +01005
David Beck32cbb0c2018-10-09 15:46:08 +01006#include <armnn/Types.hpp>
Matteo Martincighc601aa62019-10-29 15:03:22 +00007#include <armnn/BackendRegistry.hpp>
David Beck32cbb0c2018-10-09 15:46:08 +01008
Matteo Martincighe5b8eb92019-11-28 15:45:42 +00009#include <armnn/backends/IBackendInternal.hpp>
Francis Murtagh5dc64fe2021-01-25 10:18:10 +000010#include <reference/RefBackend.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000011
12#include <boost/test/unit_test.hpp>
13
David Beck32cbb0c2018-10-09 15:46:08 +010014namespace
15{
16
17class SwapRegistryStorage : public armnn::BackendRegistry
18{
19public:
20 SwapRegistryStorage() : armnn::BackendRegistry()
21 {
David Beck3e9e1152018-10-17 14:17:50 +010022 Swap(armnn::BackendRegistryInstance(), m_TempStorage);
David Beck32cbb0c2018-10-09 15:46:08 +010023 }
24
25 ~SwapRegistryStorage()
26 {
David Beck3e9e1152018-10-17 14:17:50 +010027 Swap(armnn::BackendRegistryInstance(),m_TempStorage);
David Beck32cbb0c2018-10-09 15:46:08 +010028 }
29
30private:
David Beck3e9e1152018-10-17 14:17:50 +010031 FactoryStorage m_TempStorage;
David Beck32cbb0c2018-10-09 15:46:08 +010032};
33
34}
35
36BOOST_AUTO_TEST_SUITE(BackendRegistryTests)
37
38BOOST_AUTO_TEST_CASE(SwapRegistry)
39{
David Beck3e9e1152018-10-17 14:17:50 +010040 using namespace armnn;
41 auto nFactories = BackendRegistryInstance().Size();
David Beck32cbb0c2018-10-09 15:46:08 +010042 {
43 SwapRegistryStorage helper;
David Beck3e9e1152018-10-17 14:17:50 +010044 BOOST_TEST(BackendRegistryInstance().Size() == 0);
David Beck32cbb0c2018-10-09 15:46:08 +010045 }
David Beck3e9e1152018-10-17 14:17:50 +010046 BOOST_TEST(BackendRegistryInstance().Size() == nFactories);
David Beck32cbb0c2018-10-09 15:46:08 +010047}
48
49BOOST_AUTO_TEST_CASE(TestRegistryHelper)
50{
David Beck3e9e1152018-10-17 14:17:50 +010051 using namespace armnn;
David Beck32cbb0c2018-10-09 15:46:08 +010052 SwapRegistryStorage helper;
53
54 bool called = false;
David Beck3e9e1152018-10-17 14:17:50 +010055
David Beck111b5d92018-11-12 14:59:37 +000056 BackendRegistry::StaticRegistryInitializer factoryHelper(
David Beck3e9e1152018-10-17 14:17:50 +010057 BackendRegistryInstance(),
58 "HelloWorld",
David Beck9efb57d2018-11-05 13:40:33 +000059 [&called]()
David Beck3e9e1152018-10-17 14:17:50 +010060 {
61 called = true;
David Beck29c75de2018-10-23 13:35:58 +010062 return armnn::IBackendInternalUniquePtr(nullptr);
David Beck3e9e1152018-10-17 14:17:50 +010063 }
64 );
David Beck32cbb0c2018-10-09 15:46:08 +010065
66 // sanity check: the factory has not been called yet
67 BOOST_TEST(called == false);
68
David Beck3e9e1152018-10-17 14:17:50 +010069 auto factoryFunction = BackendRegistryInstance().GetFactory("HelloWorld");
David Beck32cbb0c2018-10-09 15:46:08 +010070
71 // sanity check: the factory still not called
72 BOOST_TEST(called == false);
73
David Beck9efb57d2018-11-05 13:40:33 +000074 factoryFunction();
David Beck32cbb0c2018-10-09 15:46:08 +010075 BOOST_TEST(called == true);
David Monahanc1536d62020-02-12 15:52:35 +000076 BackendRegistryInstance().Deregister("HelloWorld");
David Beck32cbb0c2018-10-09 15:46:08 +010077}
78
79BOOST_AUTO_TEST_CASE(TestDirectCallToRegistry)
80{
David Beck3e9e1152018-10-17 14:17:50 +010081 using namespace armnn;
David Beck32cbb0c2018-10-09 15:46:08 +010082 SwapRegistryStorage helper;
83
84 bool called = false;
David Beck3e9e1152018-10-17 14:17:50 +010085 BackendRegistryInstance().Register(
86 "HelloWorld",
David Beck9efb57d2018-11-05 13:40:33 +000087 [&called]()
David Beck3e9e1152018-10-17 14:17:50 +010088 {
89 called = true;
David Beck29c75de2018-10-23 13:35:58 +010090 return armnn::IBackendInternalUniquePtr(nullptr);
David Beck3e9e1152018-10-17 14:17:50 +010091 }
92 );
David Beck32cbb0c2018-10-09 15:46:08 +010093
94 // sanity check: the factory has not been called yet
95 BOOST_TEST(called == false);
96
David Beck3e9e1152018-10-17 14:17:50 +010097 auto factoryFunction = BackendRegistryInstance().GetFactory("HelloWorld");
David Beck32cbb0c2018-10-09 15:46:08 +010098
99 // sanity check: the factory still not called
100 BOOST_TEST(called == false);
101
David Beck9efb57d2018-11-05 13:40:33 +0000102 factoryFunction();
David Beck32cbb0c2018-10-09 15:46:08 +0100103 BOOST_TEST(called == true);
David Monahanc1536d62020-02-12 15:52:35 +0000104 BackendRegistryInstance().Deregister("HelloWorld");
David Beck32cbb0c2018-10-09 15:46:08 +0100105}
106
Francis Murtagh5dc64fe2021-01-25 10:18:10 +0000107// 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
114BOOST_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 {
128 return IBackendInternalUniquePtr(new RefBackend);
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
David Beck32cbb0c2018-10-09 15:46:08 +0100150BOOST_AUTO_TEST_SUITE_END()