blob: a4f1613a587bdbc59885e67dc0d0ee89af18efa4 [file] [log] [blame]
Matteo Martincighac60d282019-07-25 15:25:44 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Matteo Martincighe5b8eb92019-11-28 15:45:42 +00008#include <armnn/BackendRegistry.hpp>
Matteo Martincighe5b8eb92019-11-28 15:45:42 +00009#include <armnn/backends/DynamicBackend.hpp>
Francis Murtaghcae45682021-04-26 10:07:49 +010010#include <armnn/backends/ILayerSupport.hpp>
Jan Eilersbb446e52020-04-02 13:56:54 +010011#include <armnn/utility/PolymorphicDowncast.hpp>
Jan Eilersbb446e52020-04-02 13:56:54 +010012#include <backendsCommon/DynamicBackendUtils.hpp>
James Conroy1f58f032021-04-27 17:13:27 +010013#include <backendsCommon/TensorHandle.hpp>
Francis Murtagh532a29d2020-06-29 11:50:01 +010014#include <Filesystem.hpp>
Matteo Martincigh4e73b422019-08-08 13:46:32 +010015#include <reference/workloads/RefConvolution2dWorkload.hpp>
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +010016#include <Runtime.hpp>
17
Matteo Martincighbc2e2102019-07-24 14:56:13 +010018#include <string>
19#include <memory>
Matteo Martincigh986c1862019-07-26 15:12:47 +010020
Matteo Martincighac60d282019-07-25 15:25:44 +010021#include <boost/test/unit_test.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010022
Colm Donelanaa93d982020-06-28 08:16:46 +010023#if !defined(DYNAMIC_BACKEND_BUILD_DIR)
24#define DYNAMIC_BACKEND_BUILD_DIR fs::path("./")
25#endif
26
27static std::string g_TestDirCLI = "--dynamic-backend-build-dir";
Matteo Martincighd0dc7702019-08-01 17:09:03 +010028static std::string g_TestBaseDir = "src/backends/backendsCommon/test/";
Matteo Martincigh986c1862019-07-26 15:12:47 +010029
Matteo Martincighd0dc7702019-08-01 17:09:03 +010030static std::string g_TestSharedObjectSubDir = "testSharedObject/";
31static std::string g_TestDynamicBackendSubDir = "testDynamicBackend/";
32
33static std::string g_TestSharedObjectFileName = "libTestSharedObject.so";
34static std::string g_TestNoSharedObjectFileName = "libNoSharedObject.txt";
35
36static std::string g_TestValidTestDynamicBackendFileName = "libValidTestDynamicBackend.so";
37static std::string g_TestInvalidTestDynamicBackend1FileName = "libInvalidTestDynamicBackend1.so";
38static std::string g_TestInvalidTestDynamicBackend2FileName = "libInvalidTestDynamicBackend2.so";
39static std::string g_TestInvalidTestDynamicBackend3FileName = "libInvalidTestDynamicBackend3.so";
40static std::string g_TestInvalidTestDynamicBackend4FileName = "libInvalidTestDynamicBackend4.so";
41static std::string g_TestInvalidTestDynamicBackend5FileName = "libInvalidTestDynamicBackend5.so";
42static std::string g_TestInvalidTestDynamicBackend6FileName = "libInvalidTestDynamicBackend6.so";
43static std::string g_TestInvalidTestDynamicBackend7FileName = "libInvalidTestDynamicBackend7.so";
44
Matteo Martincighe54aa062019-08-05 14:12:11 +010045static std::string g_TestValidBackend2FileName = "Arm_TestValid2_backend.so";
46static std::string g_TestValidBackend3FileName = "Arm_TestValid3_backend.so";
47static std::string g_TestValidBackend4FileName = "Arm_TestValid4_backend.so";
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010048static std::string g_TestValidBackend5FileName = "Arm_TestValid5_backend.so";
Matteo Martincighe54aa062019-08-05 14:12:11 +010049static std::string g_TestInvalidBackend8FileName = "Arm_TestInvalid8_backend.so";
50static std::string g_TestInvalidBackend9FileName = "Arm_TestInvalid9_backend.so";
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010051static std::string g_TestInvalidBackend10FileName = "Arm_TestInvalid10_backend.so";
52static std::string g_TestInvalidBackend11FileName = "Arm_TestInvalid11_backend.so";
Matteo Martincighe54aa062019-08-05 14:12:11 +010053
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010054static std::string g_TestDynamicBackendsSubDir1 = "backendsTestPath1/";
55static std::string g_TestDynamicBackendsSubDir2 = "backendsTestPath2/";
56static std::string g_TestDynamicBackendsSubDir3 = "backendsTestPath3/";
57static std::string g_TestDynamicBackendsSubDir4 = "backendsTestPath4/";
58static std::string g_TestDynamicBackendsSubDir5 = "backendsTestPath5/";
59static std::string g_TestDynamicBackendsSubDir6 = "backendsTestPath6/";
60static std::string g_TestDynamicBackendsSubDir7 = "backendsTestPath7/";
61static std::string g_TestDynamicBackendsSubDir8 = "backendsTestPath8/";
62static std::string g_TestDynamicBackendsSubDir9 = "backendsTestPath9/";
63
Matteo Martincigh4e73b422019-08-08 13:46:32 +010064static std::string g_DynamicBackendsBaseDir = "src/backends/dynamic";
65static std::string g_ReferenceDynamicBackendSubDir = "reference/";
66static std::string g_ReferenceBackendFileName = "Arm_CpuRef_backend.so";
67
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +010068// DynamicBackendUtils wrapper class used for testing (allows to directly invoke the protected methods)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010069class TestDynamicBackendUtils : public armnn::DynamicBackendUtils
70{
71public:
72 static bool IsBackendCompatibleTest(const armnn::BackendVersion& backendApiVersion,
73 const armnn::BackendVersion& backendVersion)
74 {
75 return IsBackendCompatibleImpl(backendApiVersion, backendVersion);
76 }
77
78 static std::vector<std::string> GetBackendPathsImplTest(const std::string& path)
79 {
80 return GetBackendPathsImpl(path);
81 }
82
Matteo Martincigh89533902019-08-15 12:08:06 +010083 static armnn::BackendIdSet RegisterDynamicBackendsImplTest(
84 armnn::BackendRegistry& backendRegistry,
85 const std::vector<armnn::DynamicBackendPtr>& dynamicBackends)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010086 {
Matteo Martincigh89533902019-08-15 12:08:06 +010087 return RegisterDynamicBackendsImpl(backendRegistry, dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010088 }
89};
Matteo Martincighe7d44982019-08-05 12:16:47 +010090
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +010091// BackendRegistry wrapper class used for testing (swaps the underlying factory storage)
92class TestBackendRegistry : public armnn::BackendRegistry
93{
94public:
95 TestBackendRegistry() : armnn::BackendRegistry()
96 {
97 Swap(armnn::BackendRegistryInstance(), m_TempStorage);
98 }
99
100 ~TestBackendRegistry()
101 {
102 Swap(armnn::BackendRegistryInstance(), m_TempStorage);
103 }
104
105private:
106 FactoryStorage m_TempStorage;
107};
108
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100109std::string GetBasePath(const std::string& basePath)
Matteo Martincigh986c1862019-07-26 15:12:47 +0100110{
Francis Murtagh532a29d2020-06-29 11:50:01 +0100111 using namespace fs;
Colm Donelanaa93d982020-06-28 08:16:46 +0100112 // What we're looking for here is the location of the UnitTests executable.
113 // In the normal build environment there are a series of files and
114 // directories created by cmake. If the executable has been relocated they
115 // may not be there. The search hierarchy is:
116 // * User specified --dynamic-backend-build-dir
117 // * Compile time value of DYNAMIC_BACKEND_BUILD_DIR.
118 // * Arg0 location.
119 // * Fall back value of current directory.
120 path programLocation = DYNAMIC_BACKEND_BUILD_DIR;
121 // Look for the specific argument --dynamic-backend-build-dir?
122 if (boost::unit_test::framework::master_test_suite().argc == 3)
123 {
124 // Boost custom arguments begin after a '--' on the command line.
125 if (g_TestDirCLI.compare(boost::unit_test::framework::master_test_suite().argv[1]) == 0)
126 {
127 // Then the next argument is the path.
128 programLocation = boost::unit_test::framework::master_test_suite().argv[2];
129 }
130 }
131 else
132 {
133 // Start by checking if DYNAMIC_BACKEND_BUILD_DIR value exist.
134 if (!exists(programLocation))
135 {
136 // That doesn't exist try looking at arg[0].
137 path arg0Path(boost::unit_test::framework::master_test_suite().argv[0]);
138 arg0Path.remove_filename();
139 path arg0SharedObjectPath(arg0Path);
140 arg0SharedObjectPath.append(basePath);
141 if (exists(arg0SharedObjectPath))
142 {
143 // Yeah arg0 worked.
144 programLocation = arg0Path;
145 }
146 }
147 }
148 // This is the base path from the build where the test libraries were built.
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100149 path sharedObjectPath = programLocation.append(basePath);
Colm Donelanaa93d982020-06-28 08:16:46 +0100150 BOOST_REQUIRE_MESSAGE(exists(sharedObjectPath), "Base path for shared objects does not exist: " +
151 sharedObjectPath.string() + "\nTo specify the root of this base path on the " +
152 "command line add: \'-- --dynamic-backend-build-dir <path>\'");
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100153 return sharedObjectPath.string();
154}
155
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100156std::string GetTestDirectoryBasePath()
157{
158 return GetBasePath(g_TestBaseDir);
159}
160
161std::string GetDynamicBackendsBasePath()
162{
163 return GetBasePath(g_DynamicBackendsBaseDir);
164}
165
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100166std::string GetTestSubDirectory(const std::string& subdir)
167{
Francis Murtagh532a29d2020-06-29 11:50:01 +0100168 using namespace fs;
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100169
170 std::string testDynamicBackendsBaseDir = GetTestDirectoryBasePath();
171 path testDynamicBackendsBasePath(testDynamicBackendsBaseDir);
172 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
173 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
174
175 return testDynamicBackendsSubDir.string();
176}
177
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100178std::string GetTestSubDirectory(const std::string& basePath, const std::string& subdir)
179{
Francis Murtagh532a29d2020-06-29 11:50:01 +0100180 using namespace fs;
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100181
182 path testDynamicBackendsBasePath(basePath);
183 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
184 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
185
186 return testDynamicBackendsSubDir.string();
187}
188
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100189std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
190{
Francis Murtagh532a29d2020-06-29 11:50:01 +0100191 using namespace fs;
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100192
193 path directoryPath(directory);
194 path fileNamePath = directoryPath.append(fileName);
195 BOOST_CHECK(exists(fileNamePath));
196
197 return fileNamePath.string();
Matteo Martincigh986c1862019-07-26 15:12:47 +0100198}
199
200void OpenCloseHandleTestImpl()
201{
202 using namespace armnn;
203
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100204 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
205 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100206
207 void* sharedObjectHandle = nullptr;
208 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
209 BOOST_TEST((sharedObjectHandle != nullptr));
210
211 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
212}
213
214void CloseInvalidHandleTestImpl()
215{
216 using namespace armnn;
217
218 // This calls must silently handle invalid handles and complete successfully (no segfaults, etc.)
219 DynamicBackendUtils::CloseHandle(nullptr);
220}
221
222void OpenEmptyFileNameTestImpl()
223{
224 using namespace armnn;
225
226 void* sharedObjectHandle = nullptr;
227 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(""), RuntimeException);
228 BOOST_TEST((sharedObjectHandle == nullptr));
229}
230
231void OpenNotExistingFileTestImpl()
232{
233 using namespace armnn;
234
235 void* sharedObjectHandle = nullptr;
236 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle("NotExistingFileName"), RuntimeException);
237 BOOST_TEST((sharedObjectHandle == nullptr));
238}
239
240void OpenNotSharedObjectTestImpl()
241{
242 using namespace armnn;
243
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100244 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
245 std::string notSharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestNoSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100246
247 void* sharedObjectHandle = nullptr;
248 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(notSharedObjectFilePath), RuntimeException);
249 BOOST_TEST((sharedObjectHandle == nullptr));
250}
251
252void GetValidEntryPointTestImpl()
253{
254 using namespace armnn;
255
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100256 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
257 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100258
259 void* sharedObjectHandle = nullptr;
260 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
261 BOOST_TEST((sharedObjectHandle != nullptr));
262
263 using TestFunctionType = int(*)(int);
264 TestFunctionType testFunctionPointer = nullptr;
265 BOOST_CHECK_NO_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
266 "TestFunction1"));
267 BOOST_TEST((testFunctionPointer != nullptr));
268 BOOST_TEST(testFunctionPointer(7) == 7);
269
270 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
271}
272
273void GetNameMangledEntryPointTestImpl()
274{
275 using namespace armnn;
276
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100277 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
278 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100279
280 void* sharedObjectHandle = nullptr;
281 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
282 BOOST_TEST((sharedObjectHandle != nullptr));
283
284 using TestFunctionType = int(*)(int);
285 TestFunctionType testFunctionPointer = nullptr;
286 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
287 "TestFunction2"),
288 RuntimeException);
289 BOOST_TEST((testFunctionPointer == nullptr));
290
291 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
292}
293
294void GetNoExternEntryPointTestImpl()
295{
296 using namespace armnn;
297
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100298 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
299 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100300
301 void* sharedObjectHandle = nullptr;
302 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
303 BOOST_TEST((sharedObjectHandle != nullptr));
304
305 using TestFunctionType = int(*)(int);
306 TestFunctionType testFunctionPointer = nullptr;
307 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
308 "TestFunction3"),
309 RuntimeException);
310 BOOST_TEST((testFunctionPointer == nullptr));
311
312 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
313}
314
315void GetNotExistingEntryPointTestImpl()
316{
317 using namespace armnn;
318
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100319 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
320 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100321
322 void* sharedObjectHandle = nullptr;
323 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
324 BOOST_TEST((sharedObjectHandle != nullptr));
325
326 using TestFunctionType = int(*)(int);
327 TestFunctionType testFunctionPointer = nullptr;
328 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
329 "TestFunction4"),
330 RuntimeException);
331 BOOST_TEST((testFunctionPointer == nullptr));
332
333 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
334}
Matteo Martincighac60d282019-07-25 15:25:44 +0100335
336void BackendVersioningTestImpl()
337{
Matteo Martincigh986c1862019-07-26 15:12:47 +0100338 using namespace armnn;
339
Matteo Martincighac60d282019-07-25 15:25:44 +0100340 // The backend API version used for the tests
Matteo Martincigh986c1862019-07-26 15:12:47 +0100341 BackendVersion backendApiVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100342
343 // Same backend and backend API versions are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100344 BackendVersion sameBackendVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100345 BOOST_TEST(sameBackendVersion == backendApiVersion);
346 BOOST_TEST(sameBackendVersion <= backendApiVersion);
347 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true);
348
349 // Backend versions that differ from the backend API version by major revision are not compatible
350 // with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100351 BackendVersion laterMajorBackendVersion{ 3, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100352 BOOST_TEST(!(laterMajorBackendVersion == backendApiVersion));
353 BOOST_TEST(!(laterMajorBackendVersion <= backendApiVersion));
354 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false);
355
Matteo Martincigh986c1862019-07-26 15:12:47 +0100356 BackendVersion earlierMajorBackendVersion{ 1, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100357 BOOST_TEST(!(earlierMajorBackendVersion == backendApiVersion));
358 BOOST_TEST(earlierMajorBackendVersion <= backendApiVersion);
359 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion,
360 earlierMajorBackendVersion) == false);
361
362 // Backend versions with the same major revision but later minor revision than
363 // the backend API version are not compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100364 BackendVersion laterMinorBackendVersion{ 2, 5 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100365 BOOST_TEST(!(laterMinorBackendVersion == backendApiVersion));
366 BOOST_TEST(!(laterMinorBackendVersion <= backendApiVersion));
367 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false);
368
369 // Backend versions with the same major revision but earlier minor revision than
370 // the backend API version are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100371 BackendVersion earlierMinorBackendVersion{ 2, 3 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100372 BOOST_TEST(!(earlierMinorBackendVersion == backendApiVersion));
373 BOOST_TEST(earlierMinorBackendVersion <= backendApiVersion);
374 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
375}
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100376
David Monahan9e9c7f52020-09-03 09:02:52 +0100377#if defined(ARMNNREF_ENABLED)
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100378void CreateValidDynamicBackendObjectTestImpl()
379{
380 // Valid shared object handle
381 // Correct name mangling
382 // Correct interface
383 // Correct backend implementation
384
385 using namespace armnn;
386
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100387 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
Colm Donelanf060b2e2020-06-16 17:14:51 +0100388
389 // We expect this path to exists so we can load a valid dynamic backend.
Francis Murtagh532a29d2020-06-29 11:50:01 +0100390 BOOST_CHECK_MESSAGE(fs::exists(testSubDirectory),
Colm Donelanf060b2e2020-06-16 17:14:51 +0100391 "Base path for shared objects does not exist: " + testSubDirectory);
392
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100393 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestValidTestDynamicBackendFileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100394
395 void* sharedObjectHandle = nullptr;
396 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
397 BOOST_TEST((sharedObjectHandle != nullptr));
398
Matteo Martincighe54aa062019-08-05 14:12:11 +0100399 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100400 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
401 BOOST_TEST((dynamicBackend != nullptr));
402
403 BackendId dynamicBackendId;
404 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
405 BOOST_TEST((dynamicBackendId == "ValidTestDynamicBackend"));
406
407 BackendVersion dynamicBackendVersion;
408 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100409 BOOST_TEST((dynamicBackendVersion == IBackendInternal::GetApiVersion()));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100410
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100411 IBackendInternalUniquePtr dynamicBackendInstance1;
412 BOOST_CHECK_NO_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend());
413 BOOST_TEST((dynamicBackendInstance1 != nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100414
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100415 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
416 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
417 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
418
419 IBackendInternalUniquePtr dynamicBackendInstance2;
420 BOOST_CHECK_NO_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction());
421 BOOST_TEST((dynamicBackendInstance2 != nullptr));
422
423 BOOST_TEST((dynamicBackendInstance1->GetId() == "ValidTestDynamicBackend"));
424 BOOST_TEST((dynamicBackendInstance2->GetId() == "ValidTestDynamicBackend"));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100425}
David Monahan9e9c7f52020-09-03 09:02:52 +0100426#endif
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100427
428void CreateDynamicBackendObjectInvalidHandleTestImpl()
429{
430 // Invalid (null) shared object handle
431
432 using namespace armnn;
433
434 void* sharedObjectHandle = nullptr;
Matteo Martincighe54aa062019-08-05 14:12:11 +0100435 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100436 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
437 BOOST_TEST((dynamicBackend == nullptr));
438}
439
440void CreateDynamicBackendObjectInvalidInterface1TestImpl()
441{
442 // Valid shared object handle
443 // Wrong (not C-style) name mangling
444
445 using namespace armnn;
446
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100447 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
448 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend1FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100449
450 void* sharedObjectHandle = nullptr;
451 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
452 BOOST_TEST((sharedObjectHandle != nullptr));
453
Matteo Martincighe54aa062019-08-05 14:12:11 +0100454 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100455 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
456 BOOST_TEST((dynamicBackend == nullptr));
457}
458
459void CreateDynamicBackendObjectInvalidInterface2TestImpl()
460{
461 // Valid shared object handle
462 // Correct name mangling
463 // Wrong interface (missing GetBackendId())
464
465 using namespace armnn;
466
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100467 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
468 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend2FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100469
470 void* sharedObjectHandle = nullptr;
471 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
472 BOOST_TEST((sharedObjectHandle != nullptr));
473
Matteo Martincighe54aa062019-08-05 14:12:11 +0100474 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100475 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
476 BOOST_TEST((dynamicBackend == nullptr));
477}
478
479void CreateDynamicBackendObjectInvalidInterface3TestImpl()
480{
481 // Valid shared object handle
482 // Correct name mangling
483 // Wrong interface (missing GetVersion())
484
485 using namespace armnn;
486
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100487 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
488 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend3FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100489
490 void* sharedObjectHandle = nullptr;
491 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
492 BOOST_TEST((sharedObjectHandle != nullptr));
493
Matteo Martincighe54aa062019-08-05 14:12:11 +0100494 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100495 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
496 BOOST_TEST((dynamicBackend == nullptr));
497}
498
499void CreateDynamicBackendObjectInvalidInterface4TestImpl()
500{
501 // Valid shared object handle
502 // Correct name mangling
503 // Wrong interface (missing BackendFactory())
504
505 using namespace armnn;
506
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100507 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
508 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend4FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100509
510 void* sharedObjectHandle = nullptr;
511 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
512 BOOST_TEST((sharedObjectHandle != nullptr));
513
Matteo Martincighe54aa062019-08-05 14:12:11 +0100514 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100515 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
516 BOOST_TEST((dynamicBackend == nullptr));
517}
518
519void CreateDynamicBackendObjectInvalidInterface5TestImpl()
520{
521 // Valid shared object handle
522 // Correct name mangling
523 // Correct interface
524 // Invalid (null) backend id returned by GetBackendId()
525
526 using namespace armnn;
527
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100528 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
529 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend5FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100530
531 void* sharedObjectHandle = nullptr;
532 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
533 BOOST_TEST((sharedObjectHandle != nullptr));
534
Matteo Martincighe54aa062019-08-05 14:12:11 +0100535 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100536 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
537 BOOST_TEST((dynamicBackend == nullptr));
538}
539
540void CreateDynamicBackendObjectInvalidInterface6TestImpl()
541{
542 // Valid shared object handle
543 // Correct name mangling
544 // Correct interface
545 // Invalid (null) backend instance returned by BackendFactory()
546
547 using namespace armnn;
548
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100549 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
550 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend6FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100551
552 void* sharedObjectHandle = nullptr;
553 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
554 BOOST_TEST((sharedObjectHandle != nullptr));
555
Matteo Martincighe54aa062019-08-05 14:12:11 +0100556 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100557 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
558 BOOST_TEST((dynamicBackend != nullptr));
559
560 BackendId dynamicBackendId;
561 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
562 BOOST_TEST((dynamicBackendId == "InvalidTestDynamicBackend"));
563
564 BackendVersion dynamicBackendVersion;
565 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
566 BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
567
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100568 IBackendInternalUniquePtr dynamicBackendInstance1;
569 BOOST_CHECK_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException);
570 BOOST_TEST((dynamicBackendInstance1 == nullptr));
571
572 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
573 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
574 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
575
576 IBackendInternalUniquePtr dynamicBackendInstance2;
577 BOOST_CHECK_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction(), RuntimeException);
578 BOOST_TEST((dynamicBackendInstance2 == nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100579}
580
581void CreateDynamicBackendObjectInvalidInterface7TestImpl()
582{
583 // Valid shared object handle
584 // Correct name mangling
585 // Correct interface
586 // Invalid (incompatible backend API version) backend instance returned by BackendFactory()
587
588 using namespace armnn;
589
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100590 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
591 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend7FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100592
593 void* sharedObjectHandle = nullptr;
594 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
595 BOOST_TEST((sharedObjectHandle != nullptr));
596
Matteo Martincighe54aa062019-08-05 14:12:11 +0100597 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100598 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
599 BOOST_TEST((dynamicBackend == nullptr));
600}
Matteo Martincighe7d44982019-08-05 12:16:47 +0100601
602void GetBackendPathsTestImpl()
603{
604 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +0100605 using namespace fs;
Matteo Martincighe7d44982019-08-05 12:16:47 +0100606
607 // The test covers four directories:
608 // <unit test path>/src/backends/backendsCommon/test/
Matteo Martincighe54aa062019-08-05 14:12:11 +0100609 // ├─ backendsTestPath1/ -> exists, contains files
610 // ├─ backendsTestPath2/ -> exists, contains files
611 // ├─ backendsTestPath3/ -> exists, but empty
612 // └─ backendsTestPath4/ -> does not exist
Matteo Martincighe7d44982019-08-05 12:16:47 +0100613
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100614 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
615 std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
616 std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
617 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100618
619 BOOST_CHECK(exists(subDir1));
620 BOOST_CHECK(exists(subDir2));
621 BOOST_CHECK(exists(subDir3));
622 BOOST_CHECK(!exists(subDir4));
623
Matteo Martincighe7d44982019-08-05 12:16:47 +0100624 // No path
625 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());
626
627 // Malformed path
628 std::string malformedDir(subDir1 + "/" + subDir1);
629 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(malformedDir).size()==0);
630
631 // Single valid path
632 std::vector<std::string> DynamicBackendPaths2 = TestDynamicBackendUtils::GetBackendPathsImplTest(subDir1);
633 BOOST_TEST(DynamicBackendPaths2.size() == 1);
634 BOOST_TEST(DynamicBackendPaths2[0] == subDir1);
635
636 // Multiple equal and valid paths
637 std::string multipleEqualDirs(subDir1 + ":" + subDir1);
638 std::vector<std::string> DynamicBackendPaths3 = TestDynamicBackendUtils::GetBackendPathsImplTest(multipleEqualDirs);
639 BOOST_TEST(DynamicBackendPaths3.size() == 1);
640 BOOST_TEST(DynamicBackendPaths3[0] == subDir1);
641
642 // Multiple empty paths
643 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(":::").empty());
644
645 // Multiple valid paths
646 std::string multipleValidPaths(subDir1 + ":" + subDir2 + ":" + subDir3);
647 std::vector<std::string> DynamicBackendPaths5 =
648 TestDynamicBackendUtils::GetBackendPathsImplTest(multipleValidPaths);
649 BOOST_TEST(DynamicBackendPaths5.size() == 3);
650 BOOST_TEST(DynamicBackendPaths5[0] == subDir1);
651 BOOST_TEST(DynamicBackendPaths5[1] == subDir2);
652 BOOST_TEST(DynamicBackendPaths5[2] == subDir3);
653
654 // Valid among empty paths
655 std::string validAmongEmptyDirs("::" + subDir1 + ":");
656 std::vector<std::string> DynamicBackendPaths6 =
657 TestDynamicBackendUtils::GetBackendPathsImplTest(validAmongEmptyDirs);
658 BOOST_TEST(DynamicBackendPaths6.size() == 1);
659 BOOST_TEST(DynamicBackendPaths6[0] == subDir1);
660
661 // Invalid among empty paths
662 std::string invalidAmongEmptyDirs(":" + subDir4 + "::");
663 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(invalidAmongEmptyDirs).empty());
664
665 // Valid, invalid and empty paths
666 std::string validInvalidEmptyDirs(subDir1 + ":" + subDir4 + ":");
667 std::vector<std::string> DynamicBackendPaths8 =
668 TestDynamicBackendUtils::GetBackendPathsImplTest(validInvalidEmptyDirs);
669 BOOST_TEST(DynamicBackendPaths8.size() == 1);
670 BOOST_TEST(DynamicBackendPaths8[0] == subDir1);
671
672 // Mix of duplicates of valid, invalid and empty paths
673 std::string duplicateValidInvalidEmptyDirs(validInvalidEmptyDirs + ":" + validInvalidEmptyDirs + ":" +
674 subDir2 + ":" + subDir2);
675 std::vector<std::string> DynamicBackendPaths9 =
676 TestDynamicBackendUtils::GetBackendPathsImplTest(duplicateValidInvalidEmptyDirs);
677 BOOST_TEST(DynamicBackendPaths9.size() == 2);
678 BOOST_TEST(DynamicBackendPaths9[0] == subDir1);
679 BOOST_TEST(DynamicBackendPaths9[1] == subDir2);
680}
681
682void GetBackendPathsOverrideTestImpl()
683{
684 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +0100685 using namespace fs;
Matteo Martincighe7d44982019-08-05 12:16:47 +0100686
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100687 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
688 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100689
690 BOOST_CHECK(exists(subDir1));
691 BOOST_CHECK(!exists(subDir4));
692
693 // Override with valid path
694 std::vector<std::string> validResult = DynamicBackendUtils::GetBackendPaths(subDir1);
695 BOOST_TEST(validResult.size() == 1);
696 BOOST_TEST(validResult[0] == subDir1);
697
698 // Override with invalid path
699 std::vector<std::string> invalidResult = DynamicBackendUtils::GetBackendPaths(subDir4);
700 BOOST_TEST(invalidResult.empty());
701}
Jan Eilers4a539fc2019-07-25 17:08:37 +0100702
703void GetSharedObjectsTestImpl()
704{
705 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +0100706 using namespace fs;
Jan Eilers4a539fc2019-07-25 17:08:37 +0100707
Matteo Martincighe54aa062019-08-05 14:12:11 +0100708 // The test covers four directories:
709 // <unit test path>/src/backends/backendsCommon/test/
710 // ├─ backendsTestPath1/ -> exists, contains files
711 // ├─ backendsTestPath2/ -> exists, contains files
712 // ├─ backendsTestPath3/ -> exists, but empty
713 // └─ backendsTestPath4/ -> does not exist
Jan Eilers4a539fc2019-07-25 17:08:37 +0100714 //
715 // The test sub-directory backendsTestPath1/ contains the following test files:
716 //
717 // Arm_GpuAcc_backend.so -> valid (basic backend name)
718 // Arm_GpuAcc_backend.so.1 -> valid (single field version number)
719 // Arm_GpuAcc_backend.so.1.2 -> valid (multiple field version number)
720 // Arm_GpuAcc_backend.so.1.2.3 -> valid (multiple field version number)
721 // Arm_GpuAcc_backend.so.10.1.27 -> valid (Multiple digit version)
722 // Arm_GpuAcc_backend.so.10.1.33. -> not valid (dot not followed by version number)
723 // Arm_GpuAcc_backend.so.3.4..5 -> not valid (dot not followed by version number)
724 // Arm_GpuAcc_backend.so.1,1.1 -> not valid (comma instead of dot in the version)
725 //
726 // Arm123_GpuAcc_backend.so -> valid (digits in vendor name are allowed)
727 // Arm_GpuAcc456_backend.so -> valid (digits in backend id are allowed)
728 // Arm%Co_GpuAcc_backend.so -> not valid (invalid character in vendor name)
729 // Arm_Gpu.Acc_backend.so -> not valid (invalid character in backend id)
730 //
731 // GpuAcc_backend.so -> not valid (missing vendor name)
732 // _GpuAcc_backend.so -> not valid (missing vendor name)
733 // Arm__backend.so -> not valid (missing backend id)
734 // Arm_GpuAcc.so -> not valid (missing "backend" at the end)
735 // __backend.so -> not valid (missing vendor name and backend id)
736 // __.so -> not valid (missing all fields)
737 //
738 // Arm_GpuAcc_backend -> not valid (missing at least ".so" at the end)
739 // Arm_GpuAcc_backend_v1.2.so -> not valid (extra version info at the end)
740 //
741 // The test sub-directory backendsTestPath1/ contains the following test files:
742 //
743 // Arm_CpuAcc_backend.so -> valid (basic backend name)
744 // Arm_CpuAcc_backend.so.1 -> Arm_CpuAcc_backend.so -> valid (symlink to valid backend file)
745 // Arm_CpuAcc_backend.so.1.2 -> Arm_CpuAcc_backend.so.1 -> valid (symlink to valid symlink)
746 // Arm_CpuAcc_backend.so.1.2.3 -> Arm_CpuAcc_backend.so.1.2 -> valid (symlink to valid symlink)
747 //
748 // Arm_no_backend.so -> nothing -> not valid (symlink resolves to non-existent file)
749 //
750 // Arm_GpuAcc_backend.so -> valid (but duplicated from backendsTestPath1/)
751
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100752 std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
753 std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
754 std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
755 std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Jan Eilers4a539fc2019-07-25 17:08:37 +0100756 BOOST_CHECK(exists(testDynamicBackendsSubDir1));
757 BOOST_CHECK(exists(testDynamicBackendsSubDir2));
758 BOOST_CHECK(exists(testDynamicBackendsSubDir3));
759 BOOST_CHECK(!exists(testDynamicBackendsSubDir4));
760
761 std::vector<std::string> backendPaths
762 {
763 testDynamicBackendsSubDir1,
764 testDynamicBackendsSubDir2,
765 testDynamicBackendsSubDir3,
766 testDynamicBackendsSubDir4
767 };
768 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
Colm Donelanaa93d982020-06-28 08:16:46 +0100769 std::vector<fs::path> expectedSharedObjects
Jan Eilers4a539fc2019-07-25 17:08:37 +0100770 {
Colm Donelanaa93d982020-06-28 08:16:46 +0100771 path(testDynamicBackendsSubDir1 + "Arm123_GpuAcc_backend.so"), // Digits in vendor name are allowed
772 path(testDynamicBackendsSubDir1 + "Arm_GpuAcc456_backend.so"), // Digits in backend id are allowed
773 path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so"), // Basic backend name
774 path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1"), // Single field version number
775 path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2"), // Multiple field version number
776 path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2.3"), // Multiple field version number
777 path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.10.1.27"), // Multiple digit version
778 path(testDynamicBackendsSubDir2 + "Arm_CpuAcc_backend.so"), // Duplicate symlinks removed
779 path(testDynamicBackendsSubDir2 + "Arm_GpuAcc_backend.so") // Duplicates on different paths are allowed
Jan Eilers4a539fc2019-07-25 17:08:37 +0100780 };
781
782 BOOST_TEST(sharedObjects.size() == expectedSharedObjects.size());
Colm Donelanaa93d982020-06-28 08:16:46 +0100783 BOOST_TEST(fs::equivalent(path(sharedObjects[0]), expectedSharedObjects[0]));
784 BOOST_TEST(fs::equivalent(path(sharedObjects[1]), expectedSharedObjects[1]));
785 BOOST_TEST(fs::equivalent(path(sharedObjects[2]), expectedSharedObjects[2]));
786 BOOST_TEST(fs::equivalent(path(sharedObjects[3]), expectedSharedObjects[3]));
787 BOOST_TEST(fs::equivalent(path(sharedObjects[4]), expectedSharedObjects[4]));
788 BOOST_TEST(fs::equivalent(path(sharedObjects[5]), expectedSharedObjects[5]));
789 BOOST_TEST(fs::equivalent(path(sharedObjects[6]), expectedSharedObjects[6]));
790 BOOST_TEST(fs::equivalent(path(sharedObjects[7]), expectedSharedObjects[7]));
791 BOOST_TEST(fs::equivalent(path(sharedObjects[8]), expectedSharedObjects[8]));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100792}
793
794void CreateDynamicBackendsTestImpl()
795{
796 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +0100797 using namespace fs;
Matteo Martincighe54aa062019-08-05 14:12:11 +0100798
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100799 // The test covers four directories:
Matteo Martincighe54aa062019-08-05 14:12:11 +0100800 // <unit test path>/src/backends/backendsCommon/test/
801 // ├─ backendsTestPath5/ -> exists, contains files
802 // ├─ backendsTestPath6/ -> exists, contains files
803 // ├─ backendsTestPath7/ -> exists, but empty
804 // └─ backendsTestPath8/ -> does not exist
805 //
806 // The test sub-directory backendsTestPath5/ contains the following test files:
807 //
808 // Arm_TestValid2_backend.so -> valid (basic backend name)
809 // Arm_TestValid3_backend.so -> valid (basic backend name)
810 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
811 //
812 // The test sub-directory backendsTestPath6/ contains the following test files:
813 //
814 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
815 // Arm_TestValid4_backend.so -> valid (it has a different filename,
816 // but it has the same backend id of Arm_TestValid2_backend.so
817 // and the same version)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100818 // Arm_TestValid5_backend.so -> valid (basic backend name)
Matteo Martincighe54aa062019-08-05 14:12:11 +0100819 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
820 // but it has the same backend id of Arm_TestValid2_backend.so
821 // and a version incompatible with the Backend API)
822
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100823 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
824 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
825 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
826 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100827 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
828 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
829 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
830 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
831
832 std::vector<std::string> backendPaths
Jan Eilers4a539fc2019-07-25 17:08:37 +0100833 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100834 testDynamicBackendsSubDir5,
835 testDynamicBackendsSubDir6,
836 testDynamicBackendsSubDir7,
837 testDynamicBackendsSubDir8
838 };
839 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
840 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
841
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100842 BOOST_TEST(dynamicBackends.size() == 5);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100843 BOOST_TEST((dynamicBackends[0] != nullptr));
844 BOOST_TEST((dynamicBackends[1] != nullptr));
845 BOOST_TEST((dynamicBackends[2] != nullptr));
846 BOOST_TEST((dynamicBackends[3] != nullptr));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100847 BOOST_TEST((dynamicBackends[4] != nullptr));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100848
849 // Duplicates are allowed here, they will be skipped later during the backend registration
850 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
851 BOOST_TEST((dynamicBackends[1]->GetBackendId() == "TestValid3"));
852 BOOST_TEST((dynamicBackends[2]->GetBackendId() == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
853 BOOST_TEST((dynamicBackends[3]->GetBackendId() == "TestValid2")); // From Arm_TestValid4_backend.so
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100854 BOOST_TEST((dynamicBackends[4]->GetBackendId() == "TestValid5"));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100855}
856
857void CreateDynamicBackendsNoPathsTestImpl()
858{
859 using namespace armnn;
860
861 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends({});
862
863 BOOST_TEST(dynamicBackends.empty());
864}
865
866void CreateDynamicBackendsAllInvalidTestImpl()
867{
868 using namespace armnn;
869
870 std::vector<std::string> sharedObjects
871 {
872 "InvalidSharedObject1",
873 "InvalidSharedObject2",
874 "InvalidSharedObject3",
875 };
876 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
877
878 BOOST_TEST(dynamicBackends.empty());
879}
880
881void CreateDynamicBackendsMixedTypesTestImpl()
882{
883 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +0100884 using namespace fs;
Matteo Martincighe54aa062019-08-05 14:12:11 +0100885
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100886 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
887 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100888 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
889 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
890
891 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
892 g_TestValidBackend2FileName);
893 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
894 g_TestInvalidBackend8FileName);
895 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
896 g_TestInvalidBackend9FileName);
897 BOOST_CHECK(exists(testValidBackend2FilePath));
898 BOOST_CHECK(exists(testInvalidBackend8FilePath));
899 BOOST_CHECK(exists(testInvalidBackend9FilePath));
900
901 std::vector<std::string> sharedObjects
902 {
903 testValidBackend2FilePath, // Arm_TestValid2_backend.so -> valid (basic backend name)
904 testInvalidBackend8FilePath, // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
905 testInvalidBackend9FilePath, // Arm_TestInvalid9_backend.so -> not valid (incompatible version)
906 "InvalidSharedObject", // The file does not exist
907 };
908 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
909
910 BOOST_TEST(dynamicBackends.size() == 1);
911 BOOST_TEST((dynamicBackends[0] != nullptr));
912 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
Jan Eilers4a539fc2019-07-25 17:08:37 +0100913}
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100914
David Monahan9e9c7f52020-09-03 09:02:52 +0100915#if defined(ARMNNREF_ENABLED)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100916void RegisterSingleDynamicBackendTestImpl()
917{
918 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +0100919 using namespace fs;
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100920
921 // Register one valid dynamic backend
922
923 // Dummy registry used for testing
924 BackendRegistry backendRegistry;
925 BOOST_TEST(backendRegistry.Size() == 0);
926
927 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
928 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
929
930 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
931 BOOST_CHECK(exists(testValidBackend2FilePath));
932
933 std::vector<std::string> sharedObjects{ testValidBackend2FilePath };
934 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
935
936 BOOST_TEST(dynamicBackends.size() == 1);
937 BOOST_TEST((dynamicBackends[0] != nullptr));
938
939 BackendId dynamicBackendId = dynamicBackends[0]->GetBackendId();
940 BOOST_TEST((dynamicBackendId == "TestValid2"));
941
942 BackendVersion dynamicBackendVersion = dynamicBackends[0]->GetBackendVersion();
943 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
944
Matteo Martincigh89533902019-08-15 12:08:06 +0100945 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
946 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100947 BOOST_TEST(backendRegistry.Size() == 1);
Matteo Martincigh89533902019-08-15 12:08:06 +0100948 BOOST_TEST(registeredBackendIds.size() == 1);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100949
950 BackendIdSet backendIds = backendRegistry.GetBackendIds();
951 BOOST_TEST(backendIds.size() == 1);
952 BOOST_TEST((backendIds.find(dynamicBackendId) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +0100953 BOOST_TEST((registeredBackendIds.find(dynamicBackendId) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100954
955 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
956 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
957
958 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
959 BOOST_TEST((dynamicBackend != nullptr));
960 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
961}
962
963void RegisterMultipleDynamicBackendsTestImpl()
964{
965 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +0100966 using namespace fs;
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100967
968 // Register many valid dynamic backends
969
970 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
971 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
972 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
973 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
974
975 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
976 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
977 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
978 BOOST_CHECK(exists(testValidBackend2FilePath));
979 BOOST_CHECK(exists(testValidBackend3FilePath));
980 BOOST_CHECK(exists(testValidBackend5FilePath));
981
982 std::vector<std::string> sharedObjects
983 {
984 testValidBackend2FilePath,
985 testValidBackend3FilePath,
986 testValidBackend5FilePath
987 };
988 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
989
990 BOOST_TEST(dynamicBackends.size() == 3);
991 BOOST_TEST((dynamicBackends[0] != nullptr));
992 BOOST_TEST((dynamicBackends[1] != nullptr));
993 BOOST_TEST((dynamicBackends[2] != nullptr));
994
995 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
996 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
997 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
998 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
999 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
1000 BOOST_TEST((dynamicBackendId3 == "TestValid5"));
1001
1002 for (size_t i = 0; i < dynamicBackends.size(); i++)
1003 {
1004 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1005 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1006 }
1007
1008 // Dummy registry used for testing
1009 BackendRegistry backendRegistry;
1010 BOOST_TEST(backendRegistry.Size() == 0);
1011
Matteo Martincigh89533902019-08-15 12:08:06 +01001012 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1013 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001014 BOOST_TEST(backendRegistry.Size() == 3);
Matteo Martincigh89533902019-08-15 12:08:06 +01001015 BOOST_TEST(registeredBackendIds.size() == 3);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001016
1017 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1018 BOOST_TEST(backendIds.size() == 3);
1019 BOOST_TEST((backendIds.find(dynamicBackendId1) != backendIds.end()));
1020 BOOST_TEST((backendIds.find(dynamicBackendId2) != backendIds.end()));
1021 BOOST_TEST((backendIds.find(dynamicBackendId3) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +01001022 BOOST_TEST((registeredBackendIds.find(dynamicBackendId1) != registeredBackendIds.end()));
1023 BOOST_TEST((registeredBackendIds.find(dynamicBackendId2) != registeredBackendIds.end()));
1024 BOOST_TEST((registeredBackendIds.find(dynamicBackendId3) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001025
1026 for (size_t i = 0; i < dynamicBackends.size(); i++)
1027 {
1028 BackendId dynamicBackendId = dynamicBackends[i]->GetBackendId();
1029
1030 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
1031 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
1032
1033 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
1034 BOOST_TEST((dynamicBackend != nullptr));
1035 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
1036 }
1037}
1038
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001039void RegisterMixedDynamicBackendsTestImpl()
1040{
1041 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +01001042 using namespace fs;
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001043
1044 // The test covers five directories:
1045 // <unit test path>/src/backends/backendsCommon/test/
1046 // ├─ backendsTestPath5/ -> exists, contains files
1047 // ├─ backendsTestPath6/ -> exists, contains files
1048 // ├─ backendsTestPath7/ -> exists, but empty
1049 // ├─ backendsTestPath8/ -> does not exist
1050 // └─ backendsTestPath9/ -> exists, contains files
1051 //
1052 // The test sub-directory backendsTestPath5/ contains the following test files:
1053 //
1054 // Arm_TestValid2_backend.so -> valid (basic backend name)
1055 // Arm_TestValid3_backend.so -> valid (basic backend name)
1056 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
1057 //
1058 // The test sub-directory backendsTestPath6/ contains the following test files:
1059 //
1060 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
1061 // Arm_TestValid4_backend.so -> valid (it has a different filename,
1062 // but it has the same backend id of Arm_TestValid2_backend.so
1063 // and the same version)
1064 // Arm_TestValid5_backend.so -> valid (basic backend name)
1065 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
1066 // but it has the same backend id of Arm_TestValid2_backend.so
1067 // and a version incompatible with the Backend API)
1068 //
1069 // The test sub-directory backendsTestPath9/ contains the following test files:
1070 //
1071 // Arm_TestInvalid10_backend.so -> not valid (empty backend id)
1072 // Arm_TestInvalid11_backend.so -> not valid ("Unknown" backend id)
1073
1074 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1075 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1076 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
1077 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
1078 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1079 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1080 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1081 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
1082 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
1083 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1084
1085 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
1086 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
1087 std::string testValidBackend2DupFilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend2FileName);
1088 std::string testValidBackend4FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend4FileName);
1089 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
1090 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
1091 g_TestInvalidBackend8FileName);
1092 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
1093 g_TestInvalidBackend9FileName);
1094 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1095 g_TestInvalidBackend10FileName);
1096 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1097 g_TestInvalidBackend11FileName);
1098 BOOST_CHECK(exists(testValidBackend2FilePath));
1099 BOOST_CHECK(exists(testValidBackend3FilePath));
1100 BOOST_CHECK(exists(testValidBackend2DupFilePath));
1101 BOOST_CHECK(exists(testValidBackend4FilePath));
1102 BOOST_CHECK(exists(testValidBackend5FilePath));
1103 BOOST_CHECK(exists(testInvalidBackend8FilePath));
1104 BOOST_CHECK(exists(testInvalidBackend9FilePath));
1105 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1106 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1107
1108 std::vector<std::string> sharedObjects
1109 {
1110 testValidBackend2FilePath,
1111 testValidBackend3FilePath,
1112 testValidBackend2DupFilePath,
1113 testValidBackend4FilePath,
1114 testValidBackend5FilePath,
1115 testInvalidBackend8FilePath,
1116 testInvalidBackend9FilePath,
1117 testInvalidBackend10FilePath,
1118 testInvalidBackend11FilePath,
1119 "InvalidSharedObject"
1120 };
1121 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1122
1123 BOOST_TEST(dynamicBackends.size() == 7);
1124 BOOST_TEST((dynamicBackends[0] != nullptr));
1125 BOOST_TEST((dynamicBackends[1] != nullptr));
1126 BOOST_TEST((dynamicBackends[2] != nullptr));
1127 BOOST_TEST((dynamicBackends[3] != nullptr));
1128 BOOST_TEST((dynamicBackends[4] != nullptr));
1129 BOOST_TEST((dynamicBackends[5] != nullptr));
1130 BOOST_TEST((dynamicBackends[6] != nullptr));
1131
1132 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1133 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1134 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
1135 BackendId dynamicBackendId4 = dynamicBackends[3]->GetBackendId();
1136 BackendId dynamicBackendId5 = dynamicBackends[4]->GetBackendId();
1137 BackendId dynamicBackendId6 = dynamicBackends[5]->GetBackendId();
1138 BackendId dynamicBackendId7 = dynamicBackends[6]->GetBackendId();
1139 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
1140 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
1141 BOOST_TEST((dynamicBackendId3 == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
1142 BOOST_TEST((dynamicBackendId4 == "TestValid2")); // From Arm_TestValid4_backend.so
1143 BOOST_TEST((dynamicBackendId5 == "TestValid5"));
1144 BOOST_TEST((dynamicBackendId6 == ""));
1145 BOOST_TEST((dynamicBackendId7 == "Unknown"));
1146
1147 for (size_t i = 0; i < dynamicBackends.size(); i++)
1148 {
1149 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1150 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1151 }
1152
1153 // Dummy registry used for testing
1154 BackendRegistry backendRegistry;
1155 BOOST_TEST(backendRegistry.Size() == 0);
1156
1157 std::vector<BackendId> expectedRegisteredbackendIds
1158 {
1159 "TestValid2",
1160 "TestValid3",
1161 "TestValid5"
1162 };
1163
Matteo Martincigh89533902019-08-15 12:08:06 +01001164 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1165 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001166 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
Matteo Martincigh89533902019-08-15 12:08:06 +01001167 BOOST_TEST(registeredBackendIds.size() == expectedRegisteredbackendIds.size());
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001168
1169 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1170 BOOST_TEST(backendIds.size() == expectedRegisteredbackendIds.size());
1171 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1172 {
1173 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +01001174 BOOST_TEST((registeredBackendIds.find(expectedRegisteredbackendId) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001175
1176 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(expectedRegisteredbackendId);
1177 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
1178
1179 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
1180 BOOST_TEST((dynamicBackend != nullptr));
1181 BOOST_TEST((dynamicBackend->GetId() == expectedRegisteredbackendId));
1182 }
1183}
David Monahan9e9c7f52020-09-03 09:02:52 +01001184#endif
1185
1186void RegisterMultipleInvalidDynamicBackendsTestImpl()
1187{
1188 using namespace armnn;
1189 using namespace fs;
1190
1191 // Try to register many invalid dynamic backends
1192
1193 // The test covers one directory:
1194 // <unit test path>/src/backends/backendsCommon/test/
1195 // └─ backendsTestPath9/ -> exists, contains files
1196 //
1197 // The test sub-directory backendsTestPath9/ contains the following test files:
1198 //
1199 // Arm_TestInvalid10_backend.so -> not valid (invalid backend id)
1200 // Arm_TestInvalid11_backend.so -> not valid (invalid backend id)
1201
1202 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1203 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1204
1205 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1206 g_TestInvalidBackend10FileName);
1207 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1208 g_TestInvalidBackend11FileName);
1209 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1210 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1211
1212 std::vector<std::string> sharedObjects
1213 {
1214 testInvalidBackend10FilePath,
1215 testInvalidBackend11FilePath,
1216 "InvalidSharedObject"
1217 };
1218 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1219
1220 BOOST_TEST(dynamicBackends.size() == 2);
1221 BOOST_TEST((dynamicBackends[0] != nullptr));
1222 BOOST_TEST((dynamicBackends[1] != nullptr));
1223
1224 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1225 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1226 BOOST_TEST((dynamicBackendId1 == ""));
1227 BOOST_TEST((dynamicBackendId2 == "Unknown"));
1228
1229 for (size_t i = 0; i < dynamicBackends.size(); i++)
1230 {
1231 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1232 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1233 }
1234
1235 // Dummy registry used for testing
1236 BackendRegistry backendRegistry;
1237 BOOST_TEST(backendRegistry.Size() == 0);
1238
1239 // Check that no dynamic backend got registered
1240 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1241 dynamicBackends);
1242 BOOST_TEST(backendRegistry.Size() == 0);
1243 BOOST_TEST(registeredBackendIds.empty());
1244}
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001245
Narumol Prangnawarat60a20fb2019-12-09 17:24:41 +00001246#if !defined(ARMNN_DYNAMIC_BACKEND_ENABLED)
1247
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001248void RuntimeEmptyTestImpl()
1249{
1250 using namespace armnn;
1251
1252 // Swapping the backend registry storage for testing
1253 TestBackendRegistry testBackendRegistry;
1254
Matteo Martincigh89533902019-08-15 12:08:06 +01001255 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1256 BOOST_TEST(backendRegistry.Size() == 0);
1257
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001258 IRuntime::CreationOptions creationOptions;
1259 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1260
Jan Eilersbb446e52020-04-02 13:56:54 +01001261 const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
Matteo Martincigh89533902019-08-15 12:08:06 +01001262 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1263 BOOST_TEST(supportedBackendIds.empty());
1264
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001265 BOOST_TEST(backendRegistry.Size() == 0);
1266}
1267
Narumol Prangnawarat60a20fb2019-12-09 17:24:41 +00001268#endif
1269
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001270void RuntimeDynamicBackendsTestImpl()
1271{
1272 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +01001273 using namespace fs;
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001274
1275 // Swapping the backend registry storage for testing
1276 TestBackendRegistry testBackendRegistry;
1277
1278 // This directory contains valid and invalid backends
1279 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1280 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1281
1282 // Using the path override in CreationOptions to load some test dynamic backends
1283 IRuntime::CreationOptions creationOptions;
1284 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir5;
1285 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1286
1287 std::vector<BackendId> expectedRegisteredbackendIds
1288 {
1289 "TestValid2",
1290 "TestValid3"
1291 };
1292
1293 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1294 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1295
1296 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1297 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1298 {
1299 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1300 }
Matteo Martincigh89533902019-08-15 12:08:06 +01001301
Jan Eilersbb446e52020-04-02 13:56:54 +01001302 const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
Matteo Martincigh89533902019-08-15 12:08:06 +01001303 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1304 BOOST_TEST(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
1305 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1306 {
1307 BOOST_TEST((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
1308 }
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001309}
1310
1311void RuntimeDuplicateDynamicBackendsTestImpl()
1312{
1313 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +01001314 using namespace fs;
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001315
1316 // Swapping the backend registry storage for testing
1317 TestBackendRegistry testBackendRegistry;
1318
1319 // This directory contains valid, invalid and duplicate backends
1320 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1321 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1322
1323 // Using the path override in CreationOptions to load some test dynamic backends
1324 IRuntime::CreationOptions creationOptions;
1325 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir6;
1326 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1327
1328 std::vector<BackendId> expectedRegisteredbackendIds
1329 {
1330 "TestValid2",
1331 "TestValid5"
1332 };
1333
1334 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1335 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1336
1337 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1338 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1339 {
1340 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1341 }
Matteo Martincigh89533902019-08-15 12:08:06 +01001342
Jan Eilersbb446e52020-04-02 13:56:54 +01001343 const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
Matteo Martincigh89533902019-08-15 12:08:06 +01001344 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1345 BOOST_TEST(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
1346 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1347 {
1348 BOOST_TEST((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
1349 }
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001350}
1351
1352void RuntimeInvalidDynamicBackendsTestImpl()
1353{
1354 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +01001355 using namespace fs;
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001356
1357 // Swapping the backend registry storage for testing
1358 TestBackendRegistry testBackendRegistry;
1359
1360 // This directory contains only invalid backends
1361 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1362 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1363
1364 // Using the path override in CreationOptions to load some test dynamic backends
1365 IRuntime::CreationOptions creationOptions;
1366 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir9;
1367 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1368
1369 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1370 BOOST_TEST(backendRegistry.Size() == 0);
Matteo Martincigh89533902019-08-15 12:08:06 +01001371
Jan Eilersbb446e52020-04-02 13:56:54 +01001372 const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
Matteo Martincigh89533902019-08-15 12:08:06 +01001373 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1374 BOOST_TEST(supportedBackendIds.empty());
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001375}
1376
1377void RuntimeInvalidOverridePathTestImpl()
1378{
1379 using namespace armnn;
1380
1381 // Swapping the backend registry storage for testing
1382 TestBackendRegistry testBackendRegistry;
1383
1384 // Using the path override in CreationOptions to load some test dynamic backends
1385 IRuntime::CreationOptions creationOptions;
1386 creationOptions.m_DynamicBackendsPath = "InvalidPath";
1387 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1388
1389 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1390 BOOST_TEST(backendRegistry.Size() == 0);
Matteo Martincigh89533902019-08-15 12:08:06 +01001391
Jan Eilersbb446e52020-04-02 13:56:54 +01001392 const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
Matteo Martincigh89533902019-08-15 12:08:06 +01001393 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1394 BOOST_TEST(supportedBackendIds.empty());
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001395}
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001396
Matteo Martincighdb16dd32019-08-27 16:41:11 +01001397#if defined(ARMNNREF_ENABLED)
Matteo Martincighe67edb22019-08-14 14:05:46 +01001398
1399// This test unit needs the reference backend, it's not available if the reference backend is not built
1400
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001401void CreateReferenceDynamicBackendTestImpl()
1402{
1403 using namespace armnn;
Francis Murtagh532a29d2020-06-29 11:50:01 +01001404 using namespace fs;
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001405
1406 // Swapping the backend registry storage for testing
1407 TestBackendRegistry testBackendRegistry;
1408
1409 // This directory contains the reference dynamic backend
1410 std::string dynamicBackendsBaseDir = GetDynamicBackendsBasePath();
1411 std::string referenceDynamicBackendSubDir = GetTestSubDirectory(dynamicBackendsBaseDir,
1412 g_ReferenceDynamicBackendSubDir);
1413 BOOST_CHECK(exists(referenceDynamicBackendSubDir));
1414
1415 // Check that the reference dynamic backend file exists
1416 std::string referenceBackendFilePath = GetTestFilePath(referenceDynamicBackendSubDir,
1417 g_ReferenceBackendFileName);
1418 BOOST_CHECK(exists(referenceBackendFilePath));
1419
1420 // Using the path override in CreationOptions to load the reference dynamic backend
1421 IRuntime::CreationOptions creationOptions;
1422 creationOptions.m_DynamicBackendsPath = referenceDynamicBackendSubDir;
1423 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1424
1425 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1426 BOOST_TEST(backendRegistry.Size() == 1);
1427
1428 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1429 BOOST_TEST((backendIds.find("CpuRef") != backendIds.end()));
1430
Jan Eilersbb446e52020-04-02 13:56:54 +01001431 const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
Matteo Martincigh89533902019-08-15 12:08:06 +01001432 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1433 BOOST_TEST(supportedBackendIds.size() == 1);
1434 BOOST_TEST((supportedBackendIds.find("CpuRef") != supportedBackendIds.end()));
1435
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001436 // Get the factory function
1437 auto referenceDynamicBackendFactoryFunction = backendRegistry.GetFactory("CpuRef");
1438 BOOST_TEST((referenceDynamicBackendFactoryFunction != nullptr));
1439
1440 // Use the factory function to create an instance of the reference backend
1441 IBackendInternalUniquePtr referenceDynamicBackend = referenceDynamicBackendFactoryFunction();
1442 BOOST_TEST((referenceDynamicBackend != nullptr));
1443 BOOST_TEST((referenceDynamicBackend->GetId() == "CpuRef"));
1444
1445 // Test the backend instance by querying the layer support
1446 IBackendInternal::ILayerSupportSharedPtr referenceLayerSupport = referenceDynamicBackend->GetLayerSupport();
1447 BOOST_TEST((referenceLayerSupport != nullptr));
1448
1449 TensorShape inputShape { 1, 16, 16, 16 };
1450 TensorShape outputShape{ 1, 16, 16, 16 };
1451 TensorShape weightShape{ 16, 1, 1, 16 };
1452 TensorInfo inputInfo (inputShape, DataType::Float32);
1453 TensorInfo outputInfo(outputShape, DataType::Float32);
1454 TensorInfo weightInfo(weightShape, DataType::Float32);
1455 Convolution2dDescriptor convolution2dDescriptor;
1456 bool referenceConvolution2dSupported =
1457 referenceLayerSupport->IsConvolution2dSupported(inputInfo,
1458 outputInfo,
1459 convolution2dDescriptor,
1460 weightInfo,
1461 EmptyOptional());
1462 BOOST_TEST(referenceConvolution2dSupported);
1463
1464 // Test the backend instance by creating a workload
1465 IBackendInternal::IWorkloadFactoryPtr referenceWorkloadFactory = referenceDynamicBackend->CreateWorkloadFactory();
1466 BOOST_TEST((referenceWorkloadFactory != nullptr));
1467
1468 // Create dummy settings for the workload
1469 Convolution2dQueueDescriptor convolution2dQueueDescriptor;
1470 WorkloadInfo workloadInfo
1471 {
1472 { inputInfo },
1473 { outputInfo }
1474 };
1475 convolution2dQueueDescriptor.m_Inputs.push_back(nullptr);
James Conroy1f58f032021-04-27 17:13:27 +01001476 auto weights = std::make_unique<ScopedTensorHandle>(weightInfo);
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001477 convolution2dQueueDescriptor.m_Weight = weights.get();
1478
1479 // Create a convolution workload with the dummy settings
1480 auto workload = referenceWorkloadFactory->CreateConvolution2d(convolution2dQueueDescriptor, workloadInfo);
1481 BOOST_TEST((workload != nullptr));
Jan Eilersbb446e52020-04-02 13:56:54 +01001482 BOOST_TEST(workload.get() == PolymorphicDowncast<RefConvolution2dWorkload*>(workload.get()));
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001483}
Matteo Martincighe67edb22019-08-14 14:05:46 +01001484
1485#endif
Narumol Prangnawarat867eba52020-02-03 12:29:56 +00001486
1487#if defined(SAMPLE_DYNAMIC_BACKEND_ENABLED)
Colm Donelanfa0d8382020-06-04 12:30:16 +01001488
1489void CheckSampleDynamicBackendLoaded()
1490{
1491 using namespace armnn;
1492 // At this point we expect DYNAMIC_BACKEND_PATHS to include a path to where libArm_SampleDynamic_backend.so is.
1493 // If it hasn't been loaded there's no point continuing with the rest of the tests.
1494 BackendIdSet backendIds = BackendRegistryInstance().GetBackendIds();
1495 if (backendIds.find("SampleDynamic") == backendIds.end())
1496 {
1497 std::string message = "The SampleDynamic backend has not been loaded. This may be a build configuration error. "
1498 "Ensure a DYNAMIC_BACKEND_PATHS was set at compile time to the location of "
1499 "libArm_SampleDynamic_backend.so. "
1500 "To disable this test recompile with: -DSAMPLE_DYNAMIC_BACKEND_ENABLED=0";
1501 BOOST_FAIL(message);
1502 }
1503}
1504
Narumol Prangnawarat867eba52020-02-03 12:29:56 +00001505void CreateSampleDynamicBackendTestImpl()
1506{
1507 using namespace armnn;
Narumol Prangnawarat867eba52020-02-03 12:29:56 +00001508 // Using the path override in CreationOptions to load the reference dynamic backend
1509 IRuntime::CreationOptions creationOptions;
Colm Donelan0dbe00a2020-06-03 08:00:28 +01001510 IRuntimePtr runtime = IRuntime::Create(creationOptions);
Narumol Prangnawarat867eba52020-02-03 12:29:56 +00001511 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1512 BOOST_TEST(backendRegistry.Size() >= 1);
Colm Donelanfa0d8382020-06-04 12:30:16 +01001513 CheckSampleDynamicBackendLoaded();
Jan Eilersbb446e52020-04-02 13:56:54 +01001514 const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
Narumol Prangnawarat867eba52020-02-03 12:29:56 +00001515 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1516 BOOST_TEST(supportedBackendIds.size()>= 1);
1517 BOOST_TEST((supportedBackendIds.find("SampleDynamic") != supportedBackendIds.end()));
1518
1519 // Get the factory function
1520 auto sampleDynamicBackendFactoryFunction = backendRegistry.GetFactory("SampleDynamic");
1521 BOOST_TEST((sampleDynamicBackendFactoryFunction != nullptr));
1522
1523 // Use the factory function to create an instance of the dynamic backend
1524 IBackendInternalUniquePtr sampleDynamicBackend = sampleDynamicBackendFactoryFunction();
1525 BOOST_TEST((sampleDynamicBackend != nullptr));
1526 BOOST_TEST((sampleDynamicBackend->GetId() == "SampleDynamic"));
1527
1528 // Test the backend instance by querying the layer support
1529 IBackendInternal::ILayerSupportSharedPtr sampleLayerSupport = sampleDynamicBackend->GetLayerSupport();
1530 BOOST_TEST((sampleLayerSupport != nullptr));
1531
1532 TensorShape inputShape { 1, 16, 16, 16 };
1533 TensorShape outputShape{ 1, 16, 16, 16 };
1534 TensorShape weightShape{ 16, 1, 1, 16 };
1535 TensorInfo inputInfo (inputShape, DataType::Float32);
1536 TensorInfo outputInfo(outputShape, DataType::Float32);
1537 TensorInfo weightInfo(weightShape, DataType::Float32);
1538 Convolution2dDescriptor convolution2dDescriptor;
1539 bool sampleConvolution2dSupported =
1540 sampleLayerSupport->IsConvolution2dSupported(inputInfo,
1541 outputInfo,
1542 convolution2dDescriptor,
1543 weightInfo,
1544 EmptyOptional());
1545 BOOST_TEST(!sampleConvolution2dSupported);
1546
1547 // Test the backend instance by creating a workload
1548 IBackendInternal::IWorkloadFactoryPtr sampleWorkloadFactory = sampleDynamicBackend->CreateWorkloadFactory();
1549 BOOST_TEST((sampleWorkloadFactory != nullptr));
1550
1551 // Create dummy settings for the workload
1552 AdditionQueueDescriptor additionQueueDescriptor;
1553 WorkloadInfo workloadInfo
1554 {
1555 { inputInfo, inputInfo },
1556 { outputInfo }
1557 };
1558
1559 // Create a addition workload
1560 auto workload = sampleWorkloadFactory->CreateAddition(additionQueueDescriptor, workloadInfo);
1561 BOOST_TEST((workload != nullptr));
1562}
1563
1564void SampleDynamicBackendEndToEndTestImpl()
1565{
1566 using namespace armnn;
Narumol Prangnawarat867eba52020-02-03 12:29:56 +00001567 // Create runtime in which test will run
1568 IRuntime::CreationOptions options;
1569 IRuntimePtr runtime(IRuntime::Create(options));
Colm Donelanfa0d8382020-06-04 12:30:16 +01001570 CheckSampleDynamicBackendLoaded();
Narumol Prangnawarat867eba52020-02-03 12:29:56 +00001571 // Builds up the structure of the network.
1572 INetworkPtr net(INetwork::Create());
1573
1574 IConnectableLayer* input0 = net->AddInputLayer(0);
1575 IConnectableLayer* input1 = net->AddInputLayer(1);
1576 IConnectableLayer* add = net->AddAdditionLayer();
1577 IConnectableLayer* output = net->AddOutputLayer(0);
1578
1579 input0->GetOutputSlot(0).Connect(add->GetInputSlot(0));
1580 input1->GetOutputSlot(0).Connect(add->GetInputSlot(1));
1581 add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
1582
1583 TensorInfo tensorInfo(TensorShape({2, 1}), DataType::Float32);
1584 input0->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1585 input1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1586 add->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1587
1588 // optimize the network
1589 IOptimizedNetworkPtr optNet = Optimize(*net, {"SampleDynamic"}, runtime->GetDeviceSpec());
1590
1591 // Loads it into the runtime.
1592 NetworkId netId;
1593 runtime->LoadNetwork(netId, std::move(optNet));
1594
1595 std::vector<float> input0Data{ 5.0f, 3.0f };
1596 std::vector<float> input1Data{ 10.0f, 8.0f };
1597 std::vector<float> expectedOutputData{ 15.0f, 11.0f };
1598 std::vector<float> outputData(2);
1599
1600 InputTensors inputTensors
1601 {
1602 {0,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), input0Data.data())},
1603 {1,armnn::ConstTensor(runtime->GetInputTensorInfo(netId, 0), input1Data.data())}
1604 };
1605 OutputTensors outputTensors
1606 {
1607 {0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
1608 };
1609
1610 // Does the inference.
1611 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
1612
1613 // Checks the results.
1614 BOOST_TEST(outputData == expectedOutputData);
1615}
1616#endif