blob: 561578e8417f63112d52b957073a4b5d9926de43 [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>
9#include <armnn/ILayerSupport.hpp>
10
11#include <armnn/backends/DynamicBackend.hpp>
12
Matteo Martincighac60d282019-07-25 15:25:44 +010013#include <backendsCommon/DynamicBackendUtils.hpp>
Matteo Martincigh4e73b422019-08-08 13:46:32 +010014#include <backendsCommon/CpuTensorHandle.hpp>
15
Matteo Martincigh4e73b422019-08-08 13:46:32 +010016#include <reference/workloads/RefConvolution2dWorkload.hpp>
Matteo Martincighac60d282019-07-25 15:25:44 +010017
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +010018#include <Runtime.hpp>
19
Matteo Martincighbc2e2102019-07-24 14:56:13 +010020#include <string>
21#include <memory>
Matteo Martincigh986c1862019-07-26 15:12:47 +010022#include <string>
23
Matteo Martincighac60d282019-07-25 15:25:44 +010024#include <boost/test/unit_test.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010025#include <boost/filesystem.hpp>
Matteo Martincigha77d80e2019-07-31 11:05:16 +010026#include <boost/dll.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010027
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{
111 using namespace boost::filesystem;
112
Matteo Martincigha77d80e2019-07-31 11:05:16 +0100113 path programLocation = boost::dll::program_location().parent_path();
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100114 path sharedObjectPath = programLocation.append(basePath);
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100115 BOOST_CHECK(exists(sharedObjectPath));
Matteo Martincigh986c1862019-07-26 15:12:47 +0100116
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100117 return sharedObjectPath.string();
118}
119
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100120std::string GetTestDirectoryBasePath()
121{
122 return GetBasePath(g_TestBaseDir);
123}
124
125std::string GetDynamicBackendsBasePath()
126{
127 return GetBasePath(g_DynamicBackendsBaseDir);
128}
129
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100130std::string GetTestSubDirectory(const std::string& subdir)
131{
132 using namespace boost::filesystem;
133
134 std::string testDynamicBackendsBaseDir = GetTestDirectoryBasePath();
135 path testDynamicBackendsBasePath(testDynamicBackendsBaseDir);
136 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
137 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
138
139 return testDynamicBackendsSubDir.string();
140}
141
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100142std::string GetTestSubDirectory(const std::string& basePath, const std::string& subdir)
143{
144 using namespace boost::filesystem;
145
146 path testDynamicBackendsBasePath(basePath);
147 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
148 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
149
150 return testDynamicBackendsSubDir.string();
151}
152
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100153std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
154{
155 using namespace boost::filesystem;
156
157 path directoryPath(directory);
158 path fileNamePath = directoryPath.append(fileName);
159 BOOST_CHECK(exists(fileNamePath));
160
161 return fileNamePath.string();
Matteo Martincigh986c1862019-07-26 15:12:47 +0100162}
163
164void OpenCloseHandleTestImpl()
165{
166 using namespace armnn;
167
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100168 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
169 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100170
171 void* sharedObjectHandle = nullptr;
172 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
173 BOOST_TEST((sharedObjectHandle != nullptr));
174
175 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
176}
177
178void CloseInvalidHandleTestImpl()
179{
180 using namespace armnn;
181
182 // This calls must silently handle invalid handles and complete successfully (no segfaults, etc.)
183 DynamicBackendUtils::CloseHandle(nullptr);
184}
185
186void OpenEmptyFileNameTestImpl()
187{
188 using namespace armnn;
189
190 void* sharedObjectHandle = nullptr;
191 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(""), RuntimeException);
192 BOOST_TEST((sharedObjectHandle == nullptr));
193}
194
195void OpenNotExistingFileTestImpl()
196{
197 using namespace armnn;
198
199 void* sharedObjectHandle = nullptr;
200 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle("NotExistingFileName"), RuntimeException);
201 BOOST_TEST((sharedObjectHandle == nullptr));
202}
203
204void OpenNotSharedObjectTestImpl()
205{
206 using namespace armnn;
207
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100208 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
209 std::string notSharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestNoSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100210
211 void* sharedObjectHandle = nullptr;
212 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(notSharedObjectFilePath), RuntimeException);
213 BOOST_TEST((sharedObjectHandle == nullptr));
214}
215
216void GetValidEntryPointTestImpl()
217{
218 using namespace armnn;
219
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100220 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
221 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100222
223 void* sharedObjectHandle = nullptr;
224 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
225 BOOST_TEST((sharedObjectHandle != nullptr));
226
227 using TestFunctionType = int(*)(int);
228 TestFunctionType testFunctionPointer = nullptr;
229 BOOST_CHECK_NO_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
230 "TestFunction1"));
231 BOOST_TEST((testFunctionPointer != nullptr));
232 BOOST_TEST(testFunctionPointer(7) == 7);
233
234 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
235}
236
237void GetNameMangledEntryPointTestImpl()
238{
239 using namespace armnn;
240
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100241 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
242 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100243
244 void* sharedObjectHandle = nullptr;
245 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
246 BOOST_TEST((sharedObjectHandle != nullptr));
247
248 using TestFunctionType = int(*)(int);
249 TestFunctionType testFunctionPointer = nullptr;
250 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
251 "TestFunction2"),
252 RuntimeException);
253 BOOST_TEST((testFunctionPointer == nullptr));
254
255 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
256}
257
258void GetNoExternEntryPointTestImpl()
259{
260 using namespace armnn;
261
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100262 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
263 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100264
265 void* sharedObjectHandle = nullptr;
266 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
267 BOOST_TEST((sharedObjectHandle != nullptr));
268
269 using TestFunctionType = int(*)(int);
270 TestFunctionType testFunctionPointer = nullptr;
271 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
272 "TestFunction3"),
273 RuntimeException);
274 BOOST_TEST((testFunctionPointer == nullptr));
275
276 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
277}
278
279void GetNotExistingEntryPointTestImpl()
280{
281 using namespace armnn;
282
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100283 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
284 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100285
286 void* sharedObjectHandle = nullptr;
287 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
288 BOOST_TEST((sharedObjectHandle != nullptr));
289
290 using TestFunctionType = int(*)(int);
291 TestFunctionType testFunctionPointer = nullptr;
292 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
293 "TestFunction4"),
294 RuntimeException);
295 BOOST_TEST((testFunctionPointer == nullptr));
296
297 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
298}
Matteo Martincighac60d282019-07-25 15:25:44 +0100299
300void BackendVersioningTestImpl()
301{
Matteo Martincigh986c1862019-07-26 15:12:47 +0100302 using namespace armnn;
303
Matteo Martincighac60d282019-07-25 15:25:44 +0100304 // The backend API version used for the tests
Matteo Martincigh986c1862019-07-26 15:12:47 +0100305 BackendVersion backendApiVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100306
307 // Same backend and backend API versions are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100308 BackendVersion sameBackendVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100309 BOOST_TEST(sameBackendVersion == backendApiVersion);
310 BOOST_TEST(sameBackendVersion <= backendApiVersion);
311 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true);
312
313 // Backend versions that differ from the backend API version by major revision are not compatible
314 // with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100315 BackendVersion laterMajorBackendVersion{ 3, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100316 BOOST_TEST(!(laterMajorBackendVersion == backendApiVersion));
317 BOOST_TEST(!(laterMajorBackendVersion <= backendApiVersion));
318 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false);
319
Matteo Martincigh986c1862019-07-26 15:12:47 +0100320 BackendVersion earlierMajorBackendVersion{ 1, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100321 BOOST_TEST(!(earlierMajorBackendVersion == backendApiVersion));
322 BOOST_TEST(earlierMajorBackendVersion <= backendApiVersion);
323 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion,
324 earlierMajorBackendVersion) == false);
325
326 // Backend versions with the same major revision but later minor revision than
327 // the backend API version are not compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100328 BackendVersion laterMinorBackendVersion{ 2, 5 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100329 BOOST_TEST(!(laterMinorBackendVersion == backendApiVersion));
330 BOOST_TEST(!(laterMinorBackendVersion <= backendApiVersion));
331 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false);
332
333 // Backend versions with the same major revision but earlier minor revision than
334 // the backend API version are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100335 BackendVersion earlierMinorBackendVersion{ 2, 3 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100336 BOOST_TEST(!(earlierMinorBackendVersion == backendApiVersion));
337 BOOST_TEST(earlierMinorBackendVersion <= backendApiVersion);
338 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
339}
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100340
341void CreateValidDynamicBackendObjectTestImpl()
342{
343 // Valid shared object handle
344 // Correct name mangling
345 // Correct interface
346 // Correct backend implementation
347
348 using namespace armnn;
349
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100350 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
351 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestValidTestDynamicBackendFileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100352
353 void* sharedObjectHandle = nullptr;
354 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
355 BOOST_TEST((sharedObjectHandle != nullptr));
356
Matteo Martincighe54aa062019-08-05 14:12:11 +0100357 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100358 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
359 BOOST_TEST((dynamicBackend != nullptr));
360
361 BackendId dynamicBackendId;
362 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
363 BOOST_TEST((dynamicBackendId == "ValidTestDynamicBackend"));
364
365 BackendVersion dynamicBackendVersion;
366 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100367 BOOST_TEST((dynamicBackendVersion == IBackendInternal::GetApiVersion()));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100368
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100369 IBackendInternalUniquePtr dynamicBackendInstance1;
370 BOOST_CHECK_NO_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend());
371 BOOST_TEST((dynamicBackendInstance1 != nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100372
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100373 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
374 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
375 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
376
377 IBackendInternalUniquePtr dynamicBackendInstance2;
378 BOOST_CHECK_NO_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction());
379 BOOST_TEST((dynamicBackendInstance2 != nullptr));
380
381 BOOST_TEST((dynamicBackendInstance1->GetId() == "ValidTestDynamicBackend"));
382 BOOST_TEST((dynamicBackendInstance2->GetId() == "ValidTestDynamicBackend"));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100383}
384
385void CreateDynamicBackendObjectInvalidHandleTestImpl()
386{
387 // Invalid (null) shared object handle
388
389 using namespace armnn;
390
391 void* sharedObjectHandle = nullptr;
Matteo Martincighe54aa062019-08-05 14:12:11 +0100392 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100393 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
394 BOOST_TEST((dynamicBackend == nullptr));
395}
396
397void CreateDynamicBackendObjectInvalidInterface1TestImpl()
398{
399 // Valid shared object handle
400 // Wrong (not C-style) name mangling
401
402 using namespace armnn;
403
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100404 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
405 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend1FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100406
407 void* sharedObjectHandle = nullptr;
408 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
409 BOOST_TEST((sharedObjectHandle != nullptr));
410
Matteo Martincighe54aa062019-08-05 14:12:11 +0100411 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100412 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
413 BOOST_TEST((dynamicBackend == nullptr));
414}
415
416void CreateDynamicBackendObjectInvalidInterface2TestImpl()
417{
418 // Valid shared object handle
419 // Correct name mangling
420 // Wrong interface (missing GetBackendId())
421
422 using namespace armnn;
423
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100424 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
425 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend2FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100426
427 void* sharedObjectHandle = nullptr;
428 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
429 BOOST_TEST((sharedObjectHandle != nullptr));
430
Matteo Martincighe54aa062019-08-05 14:12:11 +0100431 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100432 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
433 BOOST_TEST((dynamicBackend == nullptr));
434}
435
436void CreateDynamicBackendObjectInvalidInterface3TestImpl()
437{
438 // Valid shared object handle
439 // Correct name mangling
440 // Wrong interface (missing GetVersion())
441
442 using namespace armnn;
443
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100444 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
445 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend3FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100446
447 void* sharedObjectHandle = nullptr;
448 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
449 BOOST_TEST((sharedObjectHandle != nullptr));
450
Matteo Martincighe54aa062019-08-05 14:12:11 +0100451 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100452 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
453 BOOST_TEST((dynamicBackend == nullptr));
454}
455
456void CreateDynamicBackendObjectInvalidInterface4TestImpl()
457{
458 // Valid shared object handle
459 // Correct name mangling
460 // Wrong interface (missing BackendFactory())
461
462 using namespace armnn;
463
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100464 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
465 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend4FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100466
467 void* sharedObjectHandle = nullptr;
468 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
469 BOOST_TEST((sharedObjectHandle != nullptr));
470
Matteo Martincighe54aa062019-08-05 14:12:11 +0100471 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100472 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
473 BOOST_TEST((dynamicBackend == nullptr));
474}
475
476void CreateDynamicBackendObjectInvalidInterface5TestImpl()
477{
478 // Valid shared object handle
479 // Correct name mangling
480 // Correct interface
481 // Invalid (null) backend id returned by GetBackendId()
482
483 using namespace armnn;
484
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100485 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
486 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend5FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100487
488 void* sharedObjectHandle = nullptr;
489 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
490 BOOST_TEST((sharedObjectHandle != nullptr));
491
Matteo Martincighe54aa062019-08-05 14:12:11 +0100492 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100493 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
494 BOOST_TEST((dynamicBackend == nullptr));
495}
496
497void CreateDynamicBackendObjectInvalidInterface6TestImpl()
498{
499 // Valid shared object handle
500 // Correct name mangling
501 // Correct interface
502 // Invalid (null) backend instance returned by BackendFactory()
503
504 using namespace armnn;
505
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100506 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
507 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend6FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100508
509 void* sharedObjectHandle = nullptr;
510 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
511 BOOST_TEST((sharedObjectHandle != nullptr));
512
Matteo Martincighe54aa062019-08-05 14:12:11 +0100513 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100514 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
515 BOOST_TEST((dynamicBackend != nullptr));
516
517 BackendId dynamicBackendId;
518 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
519 BOOST_TEST((dynamicBackendId == "InvalidTestDynamicBackend"));
520
521 BackendVersion dynamicBackendVersion;
522 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
523 BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
524
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100525 IBackendInternalUniquePtr dynamicBackendInstance1;
526 BOOST_CHECK_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException);
527 BOOST_TEST((dynamicBackendInstance1 == nullptr));
528
529 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
530 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
531 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
532
533 IBackendInternalUniquePtr dynamicBackendInstance2;
534 BOOST_CHECK_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction(), RuntimeException);
535 BOOST_TEST((dynamicBackendInstance2 == nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100536}
537
538void CreateDynamicBackendObjectInvalidInterface7TestImpl()
539{
540 // Valid shared object handle
541 // Correct name mangling
542 // Correct interface
543 // Invalid (incompatible backend API version) backend instance returned by BackendFactory()
544
545 using namespace armnn;
546
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100547 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
548 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend7FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100549
550 void* sharedObjectHandle = nullptr;
551 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
552 BOOST_TEST((sharedObjectHandle != nullptr));
553
Matteo Martincighe54aa062019-08-05 14:12:11 +0100554 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100555 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
556 BOOST_TEST((dynamicBackend == nullptr));
557}
Matteo Martincighe7d44982019-08-05 12:16:47 +0100558
559void GetBackendPathsTestImpl()
560{
561 using namespace armnn;
562 using namespace boost::filesystem;
563
564 // The test covers four directories:
565 // <unit test path>/src/backends/backendsCommon/test/
Matteo Martincighe54aa062019-08-05 14:12:11 +0100566 // ├─ backendsTestPath1/ -> exists, contains files
567 // ├─ backendsTestPath2/ -> exists, contains files
568 // ├─ backendsTestPath3/ -> exists, but empty
569 // └─ backendsTestPath4/ -> does not exist
Matteo Martincighe7d44982019-08-05 12:16:47 +0100570
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100571 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
572 std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
573 std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
574 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100575
576 BOOST_CHECK(exists(subDir1));
577 BOOST_CHECK(exists(subDir2));
578 BOOST_CHECK(exists(subDir3));
579 BOOST_CHECK(!exists(subDir4));
580
Matteo Martincighe7d44982019-08-05 12:16:47 +0100581 // No path
582 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());
583
584 // Malformed path
585 std::string malformedDir(subDir1 + "/" + subDir1);
586 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(malformedDir).size()==0);
587
588 // Single valid path
589 std::vector<std::string> DynamicBackendPaths2 = TestDynamicBackendUtils::GetBackendPathsImplTest(subDir1);
590 BOOST_TEST(DynamicBackendPaths2.size() == 1);
591 BOOST_TEST(DynamicBackendPaths2[0] == subDir1);
592
593 // Multiple equal and valid paths
594 std::string multipleEqualDirs(subDir1 + ":" + subDir1);
595 std::vector<std::string> DynamicBackendPaths3 = TestDynamicBackendUtils::GetBackendPathsImplTest(multipleEqualDirs);
596 BOOST_TEST(DynamicBackendPaths3.size() == 1);
597 BOOST_TEST(DynamicBackendPaths3[0] == subDir1);
598
599 // Multiple empty paths
600 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(":::").empty());
601
602 // Multiple valid paths
603 std::string multipleValidPaths(subDir1 + ":" + subDir2 + ":" + subDir3);
604 std::vector<std::string> DynamicBackendPaths5 =
605 TestDynamicBackendUtils::GetBackendPathsImplTest(multipleValidPaths);
606 BOOST_TEST(DynamicBackendPaths5.size() == 3);
607 BOOST_TEST(DynamicBackendPaths5[0] == subDir1);
608 BOOST_TEST(DynamicBackendPaths5[1] == subDir2);
609 BOOST_TEST(DynamicBackendPaths5[2] == subDir3);
610
611 // Valid among empty paths
612 std::string validAmongEmptyDirs("::" + subDir1 + ":");
613 std::vector<std::string> DynamicBackendPaths6 =
614 TestDynamicBackendUtils::GetBackendPathsImplTest(validAmongEmptyDirs);
615 BOOST_TEST(DynamicBackendPaths6.size() == 1);
616 BOOST_TEST(DynamicBackendPaths6[0] == subDir1);
617
618 // Invalid among empty paths
619 std::string invalidAmongEmptyDirs(":" + subDir4 + "::");
620 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(invalidAmongEmptyDirs).empty());
621
622 // Valid, invalid and empty paths
623 std::string validInvalidEmptyDirs(subDir1 + ":" + subDir4 + ":");
624 std::vector<std::string> DynamicBackendPaths8 =
625 TestDynamicBackendUtils::GetBackendPathsImplTest(validInvalidEmptyDirs);
626 BOOST_TEST(DynamicBackendPaths8.size() == 1);
627 BOOST_TEST(DynamicBackendPaths8[0] == subDir1);
628
629 // Mix of duplicates of valid, invalid and empty paths
630 std::string duplicateValidInvalidEmptyDirs(validInvalidEmptyDirs + ":" + validInvalidEmptyDirs + ":" +
631 subDir2 + ":" + subDir2);
632 std::vector<std::string> DynamicBackendPaths9 =
633 TestDynamicBackendUtils::GetBackendPathsImplTest(duplicateValidInvalidEmptyDirs);
634 BOOST_TEST(DynamicBackendPaths9.size() == 2);
635 BOOST_TEST(DynamicBackendPaths9[0] == subDir1);
636 BOOST_TEST(DynamicBackendPaths9[1] == subDir2);
637}
638
639void GetBackendPathsOverrideTestImpl()
640{
641 using namespace armnn;
642 using namespace boost::filesystem;
643
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100644 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
645 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100646
647 BOOST_CHECK(exists(subDir1));
648 BOOST_CHECK(!exists(subDir4));
649
650 // Override with valid path
651 std::vector<std::string> validResult = DynamicBackendUtils::GetBackendPaths(subDir1);
652 BOOST_TEST(validResult.size() == 1);
653 BOOST_TEST(validResult[0] == subDir1);
654
655 // Override with invalid path
656 std::vector<std::string> invalidResult = DynamicBackendUtils::GetBackendPaths(subDir4);
657 BOOST_TEST(invalidResult.empty());
658}
Jan Eilers4a539fc2019-07-25 17:08:37 +0100659
660void GetSharedObjectsTestImpl()
661{
662 using namespace armnn;
663 using namespace boost::filesystem;
664
Matteo Martincighe54aa062019-08-05 14:12:11 +0100665 // The test covers four directories:
666 // <unit test path>/src/backends/backendsCommon/test/
667 // ├─ backendsTestPath1/ -> exists, contains files
668 // ├─ backendsTestPath2/ -> exists, contains files
669 // ├─ backendsTestPath3/ -> exists, but empty
670 // └─ backendsTestPath4/ -> does not exist
Jan Eilers4a539fc2019-07-25 17:08:37 +0100671 //
672 // The test sub-directory backendsTestPath1/ contains the following test files:
673 //
674 // Arm_GpuAcc_backend.so -> valid (basic backend name)
675 // Arm_GpuAcc_backend.so.1 -> valid (single field version number)
676 // Arm_GpuAcc_backend.so.1.2 -> valid (multiple field version number)
677 // Arm_GpuAcc_backend.so.1.2.3 -> valid (multiple field version number)
678 // Arm_GpuAcc_backend.so.10.1.27 -> valid (Multiple digit version)
679 // Arm_GpuAcc_backend.so.10.1.33. -> not valid (dot not followed by version number)
680 // Arm_GpuAcc_backend.so.3.4..5 -> not valid (dot not followed by version number)
681 // Arm_GpuAcc_backend.so.1,1.1 -> not valid (comma instead of dot in the version)
682 //
683 // Arm123_GpuAcc_backend.so -> valid (digits in vendor name are allowed)
684 // Arm_GpuAcc456_backend.so -> valid (digits in backend id are allowed)
685 // Arm%Co_GpuAcc_backend.so -> not valid (invalid character in vendor name)
686 // Arm_Gpu.Acc_backend.so -> not valid (invalid character in backend id)
687 //
688 // GpuAcc_backend.so -> not valid (missing vendor name)
689 // _GpuAcc_backend.so -> not valid (missing vendor name)
690 // Arm__backend.so -> not valid (missing backend id)
691 // Arm_GpuAcc.so -> not valid (missing "backend" at the end)
692 // __backend.so -> not valid (missing vendor name and backend id)
693 // __.so -> not valid (missing all fields)
694 //
695 // Arm_GpuAcc_backend -> not valid (missing at least ".so" at the end)
696 // Arm_GpuAcc_backend_v1.2.so -> not valid (extra version info at the end)
697 //
698 // The test sub-directory backendsTestPath1/ contains the following test files:
699 //
700 // Arm_CpuAcc_backend.so -> valid (basic backend name)
701 // Arm_CpuAcc_backend.so.1 -> Arm_CpuAcc_backend.so -> valid (symlink to valid backend file)
702 // Arm_CpuAcc_backend.so.1.2 -> Arm_CpuAcc_backend.so.1 -> valid (symlink to valid symlink)
703 // Arm_CpuAcc_backend.so.1.2.3 -> Arm_CpuAcc_backend.so.1.2 -> valid (symlink to valid symlink)
704 //
705 // Arm_no_backend.so -> nothing -> not valid (symlink resolves to non-existent file)
706 //
707 // Arm_GpuAcc_backend.so -> valid (but duplicated from backendsTestPath1/)
708
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100709 std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
710 std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
711 std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
712 std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Jan Eilers4a539fc2019-07-25 17:08:37 +0100713 BOOST_CHECK(exists(testDynamicBackendsSubDir1));
714 BOOST_CHECK(exists(testDynamicBackendsSubDir2));
715 BOOST_CHECK(exists(testDynamicBackendsSubDir3));
716 BOOST_CHECK(!exists(testDynamicBackendsSubDir4));
717
718 std::vector<std::string> backendPaths
719 {
720 testDynamicBackendsSubDir1,
721 testDynamicBackendsSubDir2,
722 testDynamicBackendsSubDir3,
723 testDynamicBackendsSubDir4
724 };
725 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100726 std::vector<std::string> expectedSharedObjects
Jan Eilers4a539fc2019-07-25 17:08:37 +0100727 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100728 testDynamicBackendsSubDir1 + "Arm123_GpuAcc_backend.so", // Digits in vendor name are allowed
729 testDynamicBackendsSubDir1 + "Arm_GpuAcc456_backend.so", // Digits in backend id are allowed
Jan Eilers4a539fc2019-07-25 17:08:37 +0100730 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so", // Basic backend name
731 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1", // Single field version number
732 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2", // Multiple field version number
733 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2.3", // Multiple field version number
734 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.10.1.27", // Multiple digit version
Jan Eilers4a539fc2019-07-25 17:08:37 +0100735 testDynamicBackendsSubDir2 + "Arm_CpuAcc_backend.so", // Duplicate symlinks removed
736 testDynamicBackendsSubDir2 + "Arm_GpuAcc_backend.so" // Duplicates on different paths are allowed
737 };
738
739 BOOST_TEST(sharedObjects.size() == expectedSharedObjects.size());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100740 BOOST_TEST(sharedObjects[0] == expectedSharedObjects[0]);
741 BOOST_TEST(sharedObjects[1] == expectedSharedObjects[1]);
742 BOOST_TEST(sharedObjects[2] == expectedSharedObjects[2]);
743 BOOST_TEST(sharedObjects[3] == expectedSharedObjects[3]);
744 BOOST_TEST(sharedObjects[4] == expectedSharedObjects[4]);
745 BOOST_TEST(sharedObjects[5] == expectedSharedObjects[5]);
746 BOOST_TEST(sharedObjects[6] == expectedSharedObjects[6]);
747 BOOST_TEST(sharedObjects[7] == expectedSharedObjects[7]);
748 BOOST_TEST(sharedObjects[8] == expectedSharedObjects[8]);
749}
750
751void CreateDynamicBackendsTestImpl()
752{
753 using namespace armnn;
754 using namespace boost::filesystem;
755
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100756 // The test covers four directories:
Matteo Martincighe54aa062019-08-05 14:12:11 +0100757 // <unit test path>/src/backends/backendsCommon/test/
758 // ├─ backendsTestPath5/ -> exists, contains files
759 // ├─ backendsTestPath6/ -> exists, contains files
760 // ├─ backendsTestPath7/ -> exists, but empty
761 // └─ backendsTestPath8/ -> does not exist
762 //
763 // The test sub-directory backendsTestPath5/ contains the following test files:
764 //
765 // Arm_TestValid2_backend.so -> valid (basic backend name)
766 // Arm_TestValid3_backend.so -> valid (basic backend name)
767 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
768 //
769 // The test sub-directory backendsTestPath6/ contains the following test files:
770 //
771 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
772 // Arm_TestValid4_backend.so -> valid (it has a different filename,
773 // but it has the same backend id of Arm_TestValid2_backend.so
774 // and the same version)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100775 // Arm_TestValid5_backend.so -> valid (basic backend name)
Matteo Martincighe54aa062019-08-05 14:12:11 +0100776 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
777 // but it has the same backend id of Arm_TestValid2_backend.so
778 // and a version incompatible with the Backend API)
779
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100780 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
781 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
782 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
783 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100784 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
785 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
786 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
787 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
788
789 std::vector<std::string> backendPaths
Jan Eilers4a539fc2019-07-25 17:08:37 +0100790 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100791 testDynamicBackendsSubDir5,
792 testDynamicBackendsSubDir6,
793 testDynamicBackendsSubDir7,
794 testDynamicBackendsSubDir8
795 };
796 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
797 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
798
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100799 BOOST_TEST(dynamicBackends.size() == 5);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100800 BOOST_TEST((dynamicBackends[0] != nullptr));
801 BOOST_TEST((dynamicBackends[1] != nullptr));
802 BOOST_TEST((dynamicBackends[2] != nullptr));
803 BOOST_TEST((dynamicBackends[3] != nullptr));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100804 BOOST_TEST((dynamicBackends[4] != nullptr));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100805
806 // Duplicates are allowed here, they will be skipped later during the backend registration
807 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
808 BOOST_TEST((dynamicBackends[1]->GetBackendId() == "TestValid3"));
809 BOOST_TEST((dynamicBackends[2]->GetBackendId() == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
810 BOOST_TEST((dynamicBackends[3]->GetBackendId() == "TestValid2")); // From Arm_TestValid4_backend.so
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100811 BOOST_TEST((dynamicBackends[4]->GetBackendId() == "TestValid5"));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100812}
813
814void CreateDynamicBackendsNoPathsTestImpl()
815{
816 using namespace armnn;
817
818 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends({});
819
820 BOOST_TEST(dynamicBackends.empty());
821}
822
823void CreateDynamicBackendsAllInvalidTestImpl()
824{
825 using namespace armnn;
826
827 std::vector<std::string> sharedObjects
828 {
829 "InvalidSharedObject1",
830 "InvalidSharedObject2",
831 "InvalidSharedObject3",
832 };
833 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
834
835 BOOST_TEST(dynamicBackends.empty());
836}
837
838void CreateDynamicBackendsMixedTypesTestImpl()
839{
840 using namespace armnn;
841 using namespace boost::filesystem;
842
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100843 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
844 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100845 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
846 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
847
848 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
849 g_TestValidBackend2FileName);
850 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
851 g_TestInvalidBackend8FileName);
852 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
853 g_TestInvalidBackend9FileName);
854 BOOST_CHECK(exists(testValidBackend2FilePath));
855 BOOST_CHECK(exists(testInvalidBackend8FilePath));
856 BOOST_CHECK(exists(testInvalidBackend9FilePath));
857
858 std::vector<std::string> sharedObjects
859 {
860 testValidBackend2FilePath, // Arm_TestValid2_backend.so -> valid (basic backend name)
861 testInvalidBackend8FilePath, // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
862 testInvalidBackend9FilePath, // Arm_TestInvalid9_backend.so -> not valid (incompatible version)
863 "InvalidSharedObject", // The file does not exist
864 };
865 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
866
867 BOOST_TEST(dynamicBackends.size() == 1);
868 BOOST_TEST((dynamicBackends[0] != nullptr));
869 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
Jan Eilers4a539fc2019-07-25 17:08:37 +0100870}
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100871
872void RegisterSingleDynamicBackendTestImpl()
873{
874 using namespace armnn;
875 using namespace boost::filesystem;
876
877 // Register one valid dynamic backend
878
879 // Dummy registry used for testing
880 BackendRegistry backendRegistry;
881 BOOST_TEST(backendRegistry.Size() == 0);
882
883 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
884 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
885
886 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
887 BOOST_CHECK(exists(testValidBackend2FilePath));
888
889 std::vector<std::string> sharedObjects{ testValidBackend2FilePath };
890 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
891
892 BOOST_TEST(dynamicBackends.size() == 1);
893 BOOST_TEST((dynamicBackends[0] != nullptr));
894
895 BackendId dynamicBackendId = dynamicBackends[0]->GetBackendId();
896 BOOST_TEST((dynamicBackendId == "TestValid2"));
897
898 BackendVersion dynamicBackendVersion = dynamicBackends[0]->GetBackendVersion();
899 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
900
Matteo Martincigh89533902019-08-15 12:08:06 +0100901 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
902 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100903 BOOST_TEST(backendRegistry.Size() == 1);
Matteo Martincigh89533902019-08-15 12:08:06 +0100904 BOOST_TEST(registeredBackendIds.size() == 1);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100905
906 BackendIdSet backendIds = backendRegistry.GetBackendIds();
907 BOOST_TEST(backendIds.size() == 1);
908 BOOST_TEST((backendIds.find(dynamicBackendId) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +0100909 BOOST_TEST((registeredBackendIds.find(dynamicBackendId) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100910
911 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
912 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
913
914 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
915 BOOST_TEST((dynamicBackend != nullptr));
916 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
917}
918
919void RegisterMultipleDynamicBackendsTestImpl()
920{
921 using namespace armnn;
922 using namespace boost::filesystem;
923
924 // Register many valid dynamic backends
925
926 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
927 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
928 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
929 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
930
931 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
932 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
933 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
934 BOOST_CHECK(exists(testValidBackend2FilePath));
935 BOOST_CHECK(exists(testValidBackend3FilePath));
936 BOOST_CHECK(exists(testValidBackend5FilePath));
937
938 std::vector<std::string> sharedObjects
939 {
940 testValidBackend2FilePath,
941 testValidBackend3FilePath,
942 testValidBackend5FilePath
943 };
944 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
945
946 BOOST_TEST(dynamicBackends.size() == 3);
947 BOOST_TEST((dynamicBackends[0] != nullptr));
948 BOOST_TEST((dynamicBackends[1] != nullptr));
949 BOOST_TEST((dynamicBackends[2] != nullptr));
950
951 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
952 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
953 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
954 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
955 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
956 BOOST_TEST((dynamicBackendId3 == "TestValid5"));
957
958 for (size_t i = 0; i < dynamicBackends.size(); i++)
959 {
960 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
961 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
962 }
963
964 // Dummy registry used for testing
965 BackendRegistry backendRegistry;
966 BOOST_TEST(backendRegistry.Size() == 0);
967
Matteo Martincigh89533902019-08-15 12:08:06 +0100968 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
969 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100970 BOOST_TEST(backendRegistry.Size() == 3);
Matteo Martincigh89533902019-08-15 12:08:06 +0100971 BOOST_TEST(registeredBackendIds.size() == 3);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100972
973 BackendIdSet backendIds = backendRegistry.GetBackendIds();
974 BOOST_TEST(backendIds.size() == 3);
975 BOOST_TEST((backendIds.find(dynamicBackendId1) != backendIds.end()));
976 BOOST_TEST((backendIds.find(dynamicBackendId2) != backendIds.end()));
977 BOOST_TEST((backendIds.find(dynamicBackendId3) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +0100978 BOOST_TEST((registeredBackendIds.find(dynamicBackendId1) != registeredBackendIds.end()));
979 BOOST_TEST((registeredBackendIds.find(dynamicBackendId2) != registeredBackendIds.end()));
980 BOOST_TEST((registeredBackendIds.find(dynamicBackendId3) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100981
982 for (size_t i = 0; i < dynamicBackends.size(); i++)
983 {
984 BackendId dynamicBackendId = dynamicBackends[i]->GetBackendId();
985
986 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
987 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
988
989 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
990 BOOST_TEST((dynamicBackend != nullptr));
991 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
992 }
993}
994
995void RegisterMultipleInvalidDynamicBackendsTestImpl()
996{
997 using namespace armnn;
998 using namespace boost::filesystem;
999
1000 // Try to register many invalid dynamic backends
1001
1002 // The test covers one directory:
1003 // <unit test path>/src/backends/backendsCommon/test/
1004 // └─ backendsTestPath9/ -> exists, contains files
1005 //
1006 // The test sub-directory backendsTestPath9/ contains the following test files:
1007 //
1008 // Arm_TestInvalid10_backend.so -> not valid (invalid backend id)
1009 // Arm_TestInvalid11_backend.so -> not valid (invalid backend id)
1010
1011 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1012 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1013
1014 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1015 g_TestInvalidBackend10FileName);
1016 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1017 g_TestInvalidBackend11FileName);
1018 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1019 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1020
1021 std::vector<std::string> sharedObjects
1022 {
1023 testInvalidBackend10FilePath,
1024 testInvalidBackend11FilePath,
1025 "InvalidSharedObject"
1026 };
1027 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1028
1029 BOOST_TEST(dynamicBackends.size() == 2);
1030 BOOST_TEST((dynamicBackends[0] != nullptr));
1031 BOOST_TEST((dynamicBackends[1] != nullptr));
1032
1033 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1034 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1035 BOOST_TEST((dynamicBackendId1 == ""));
1036 BOOST_TEST((dynamicBackendId2 == "Unknown"));
1037
1038 for (size_t i = 0; i < dynamicBackends.size(); i++)
1039 {
1040 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1041 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1042 }
1043
1044 // Dummy registry used for testing
1045 BackendRegistry backendRegistry;
1046 BOOST_TEST(backendRegistry.Size() == 0);
1047
1048 // Check that no dynamic backend got registered
Matteo Martincigh89533902019-08-15 12:08:06 +01001049 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1050 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001051 BOOST_TEST(backendRegistry.Size() == 0);
Matteo Martincigh89533902019-08-15 12:08:06 +01001052 BOOST_TEST(registeredBackendIds.empty());
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001053}
1054
1055void RegisterMixedDynamicBackendsTestImpl()
1056{
1057 using namespace armnn;
1058 using namespace boost::filesystem;
1059
1060 // The test covers five directories:
1061 // <unit test path>/src/backends/backendsCommon/test/
1062 // ├─ backendsTestPath5/ -> exists, contains files
1063 // ├─ backendsTestPath6/ -> exists, contains files
1064 // ├─ backendsTestPath7/ -> exists, but empty
1065 // ├─ backendsTestPath8/ -> does not exist
1066 // └─ backendsTestPath9/ -> exists, contains files
1067 //
1068 // The test sub-directory backendsTestPath5/ contains the following test files:
1069 //
1070 // Arm_TestValid2_backend.so -> valid (basic backend name)
1071 // Arm_TestValid3_backend.so -> valid (basic backend name)
1072 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
1073 //
1074 // The test sub-directory backendsTestPath6/ contains the following test files:
1075 //
1076 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
1077 // Arm_TestValid4_backend.so -> valid (it has a different filename,
1078 // but it has the same backend id of Arm_TestValid2_backend.so
1079 // and the same version)
1080 // Arm_TestValid5_backend.so -> valid (basic backend name)
1081 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
1082 // but it has the same backend id of Arm_TestValid2_backend.so
1083 // and a version incompatible with the Backend API)
1084 //
1085 // The test sub-directory backendsTestPath9/ contains the following test files:
1086 //
1087 // Arm_TestInvalid10_backend.so -> not valid (empty backend id)
1088 // Arm_TestInvalid11_backend.so -> not valid ("Unknown" backend id)
1089
1090 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1091 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1092 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
1093 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
1094 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1095 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1096 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1097 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
1098 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
1099 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1100
1101 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
1102 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
1103 std::string testValidBackend2DupFilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend2FileName);
1104 std::string testValidBackend4FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend4FileName);
1105 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
1106 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
1107 g_TestInvalidBackend8FileName);
1108 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
1109 g_TestInvalidBackend9FileName);
1110 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1111 g_TestInvalidBackend10FileName);
1112 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1113 g_TestInvalidBackend11FileName);
1114 BOOST_CHECK(exists(testValidBackend2FilePath));
1115 BOOST_CHECK(exists(testValidBackend3FilePath));
1116 BOOST_CHECK(exists(testValidBackend2DupFilePath));
1117 BOOST_CHECK(exists(testValidBackend4FilePath));
1118 BOOST_CHECK(exists(testValidBackend5FilePath));
1119 BOOST_CHECK(exists(testInvalidBackend8FilePath));
1120 BOOST_CHECK(exists(testInvalidBackend9FilePath));
1121 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1122 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1123
1124 std::vector<std::string> sharedObjects
1125 {
1126 testValidBackend2FilePath,
1127 testValidBackend3FilePath,
1128 testValidBackend2DupFilePath,
1129 testValidBackend4FilePath,
1130 testValidBackend5FilePath,
1131 testInvalidBackend8FilePath,
1132 testInvalidBackend9FilePath,
1133 testInvalidBackend10FilePath,
1134 testInvalidBackend11FilePath,
1135 "InvalidSharedObject"
1136 };
1137 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1138
1139 BOOST_TEST(dynamicBackends.size() == 7);
1140 BOOST_TEST((dynamicBackends[0] != nullptr));
1141 BOOST_TEST((dynamicBackends[1] != nullptr));
1142 BOOST_TEST((dynamicBackends[2] != nullptr));
1143 BOOST_TEST((dynamicBackends[3] != nullptr));
1144 BOOST_TEST((dynamicBackends[4] != nullptr));
1145 BOOST_TEST((dynamicBackends[5] != nullptr));
1146 BOOST_TEST((dynamicBackends[6] != nullptr));
1147
1148 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1149 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1150 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
1151 BackendId dynamicBackendId4 = dynamicBackends[3]->GetBackendId();
1152 BackendId dynamicBackendId5 = dynamicBackends[4]->GetBackendId();
1153 BackendId dynamicBackendId6 = dynamicBackends[5]->GetBackendId();
1154 BackendId dynamicBackendId7 = dynamicBackends[6]->GetBackendId();
1155 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
1156 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
1157 BOOST_TEST((dynamicBackendId3 == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
1158 BOOST_TEST((dynamicBackendId4 == "TestValid2")); // From Arm_TestValid4_backend.so
1159 BOOST_TEST((dynamicBackendId5 == "TestValid5"));
1160 BOOST_TEST((dynamicBackendId6 == ""));
1161 BOOST_TEST((dynamicBackendId7 == "Unknown"));
1162
1163 for (size_t i = 0; i < dynamicBackends.size(); i++)
1164 {
1165 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1166 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1167 }
1168
1169 // Dummy registry used for testing
1170 BackendRegistry backendRegistry;
1171 BOOST_TEST(backendRegistry.Size() == 0);
1172
1173 std::vector<BackendId> expectedRegisteredbackendIds
1174 {
1175 "TestValid2",
1176 "TestValid3",
1177 "TestValid5"
1178 };
1179
Matteo Martincigh89533902019-08-15 12:08:06 +01001180 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1181 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001182 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
Matteo Martincigh89533902019-08-15 12:08:06 +01001183 BOOST_TEST(registeredBackendIds.size() == expectedRegisteredbackendIds.size());
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001184
1185 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1186 BOOST_TEST(backendIds.size() == expectedRegisteredbackendIds.size());
1187 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1188 {
1189 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +01001190 BOOST_TEST((registeredBackendIds.find(expectedRegisteredbackendId) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001191
1192 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(expectedRegisteredbackendId);
1193 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
1194
1195 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
1196 BOOST_TEST((dynamicBackend != nullptr));
1197 BOOST_TEST((dynamicBackend->GetId() == expectedRegisteredbackendId));
1198 }
1199}
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001200
1201void RuntimeEmptyTestImpl()
1202{
1203 using namespace armnn;
1204
1205 // Swapping the backend registry storage for testing
1206 TestBackendRegistry testBackendRegistry;
1207
Matteo Martincigh89533902019-08-15 12:08:06 +01001208 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1209 BOOST_TEST(backendRegistry.Size() == 0);
1210
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001211 IRuntime::CreationOptions creationOptions;
1212 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1213
Matteo Martincigh89533902019-08-15 12:08:06 +01001214 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1215 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1216 BOOST_TEST(supportedBackendIds.empty());
1217
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001218 BOOST_TEST(backendRegistry.Size() == 0);
1219}
1220
1221void RuntimeDynamicBackendsTestImpl()
1222{
1223 using namespace armnn;
1224 using namespace boost::filesystem;
1225
1226 // Swapping the backend registry storage for testing
1227 TestBackendRegistry testBackendRegistry;
1228
1229 // This directory contains valid and invalid backends
1230 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1231 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1232
1233 // Using the path override in CreationOptions to load some test dynamic backends
1234 IRuntime::CreationOptions creationOptions;
1235 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir5;
1236 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1237
1238 std::vector<BackendId> expectedRegisteredbackendIds
1239 {
1240 "TestValid2",
1241 "TestValid3"
1242 };
1243
1244 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1245 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1246
1247 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1248 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1249 {
1250 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1251 }
Matteo Martincigh89533902019-08-15 12:08:06 +01001252
1253 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1254 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1255 BOOST_TEST(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
1256 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1257 {
1258 BOOST_TEST((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
1259 }
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001260}
1261
1262void RuntimeDuplicateDynamicBackendsTestImpl()
1263{
1264 using namespace armnn;
1265 using namespace boost::filesystem;
1266
1267 // Swapping the backend registry storage for testing
1268 TestBackendRegistry testBackendRegistry;
1269
1270 // This directory contains valid, invalid and duplicate backends
1271 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1272 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1273
1274 // Using the path override in CreationOptions to load some test dynamic backends
1275 IRuntime::CreationOptions creationOptions;
1276 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir6;
1277 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1278
1279 std::vector<BackendId> expectedRegisteredbackendIds
1280 {
1281 "TestValid2",
1282 "TestValid5"
1283 };
1284
1285 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1286 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1287
1288 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1289 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1290 {
1291 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1292 }
Matteo Martincigh89533902019-08-15 12:08:06 +01001293
1294 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1295 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1296 BOOST_TEST(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
1297 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1298 {
1299 BOOST_TEST((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
1300 }
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001301}
1302
1303void RuntimeInvalidDynamicBackendsTestImpl()
1304{
1305 using namespace armnn;
1306 using namespace boost::filesystem;
1307
1308 // Swapping the backend registry storage for testing
1309 TestBackendRegistry testBackendRegistry;
1310
1311 // This directory contains only invalid backends
1312 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1313 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1314
1315 // Using the path override in CreationOptions to load some test dynamic backends
1316 IRuntime::CreationOptions creationOptions;
1317 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir9;
1318 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1319
1320 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1321 BOOST_TEST(backendRegistry.Size() == 0);
Matteo Martincigh89533902019-08-15 12:08:06 +01001322
1323 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1324 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1325 BOOST_TEST(supportedBackendIds.empty());
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001326}
1327
1328void RuntimeInvalidOverridePathTestImpl()
1329{
1330 using namespace armnn;
1331
1332 // Swapping the backend registry storage for testing
1333 TestBackendRegistry testBackendRegistry;
1334
1335 // Using the path override in CreationOptions to load some test dynamic backends
1336 IRuntime::CreationOptions creationOptions;
1337 creationOptions.m_DynamicBackendsPath = "InvalidPath";
1338 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1339
1340 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1341 BOOST_TEST(backendRegistry.Size() == 0);
Matteo Martincigh89533902019-08-15 12:08:06 +01001342
1343 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1344 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1345 BOOST_TEST(supportedBackendIds.empty());
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001346}
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001347
Matteo Martincighdb16dd32019-08-27 16:41:11 +01001348#if defined(ARMNNREF_ENABLED)
Matteo Martincighe67edb22019-08-14 14:05:46 +01001349
1350// This test unit needs the reference backend, it's not available if the reference backend is not built
1351
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001352void CreateReferenceDynamicBackendTestImpl()
1353{
1354 using namespace armnn;
1355 using namespace boost::filesystem;
1356
1357 // Swapping the backend registry storage for testing
1358 TestBackendRegistry testBackendRegistry;
1359
1360 // This directory contains the reference dynamic backend
1361 std::string dynamicBackendsBaseDir = GetDynamicBackendsBasePath();
1362 std::string referenceDynamicBackendSubDir = GetTestSubDirectory(dynamicBackendsBaseDir,
1363 g_ReferenceDynamicBackendSubDir);
1364 BOOST_CHECK(exists(referenceDynamicBackendSubDir));
1365
1366 // Check that the reference dynamic backend file exists
1367 std::string referenceBackendFilePath = GetTestFilePath(referenceDynamicBackendSubDir,
1368 g_ReferenceBackendFileName);
1369 BOOST_CHECK(exists(referenceBackendFilePath));
1370
1371 // Using the path override in CreationOptions to load the reference dynamic backend
1372 IRuntime::CreationOptions creationOptions;
1373 creationOptions.m_DynamicBackendsPath = referenceDynamicBackendSubDir;
1374 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1375
1376 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1377 BOOST_TEST(backendRegistry.Size() == 1);
1378
1379 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1380 BOOST_TEST((backendIds.find("CpuRef") != backendIds.end()));
1381
Matteo Martincigh89533902019-08-15 12:08:06 +01001382 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1383 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1384 BOOST_TEST(supportedBackendIds.size() == 1);
1385 BOOST_TEST((supportedBackendIds.find("CpuRef") != supportedBackendIds.end()));
1386
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001387 // Get the factory function
1388 auto referenceDynamicBackendFactoryFunction = backendRegistry.GetFactory("CpuRef");
1389 BOOST_TEST((referenceDynamicBackendFactoryFunction != nullptr));
1390
1391 // Use the factory function to create an instance of the reference backend
1392 IBackendInternalUniquePtr referenceDynamicBackend = referenceDynamicBackendFactoryFunction();
1393 BOOST_TEST((referenceDynamicBackend != nullptr));
1394 BOOST_TEST((referenceDynamicBackend->GetId() == "CpuRef"));
1395
1396 // Test the backend instance by querying the layer support
1397 IBackendInternal::ILayerSupportSharedPtr referenceLayerSupport = referenceDynamicBackend->GetLayerSupport();
1398 BOOST_TEST((referenceLayerSupport != nullptr));
1399
1400 TensorShape inputShape { 1, 16, 16, 16 };
1401 TensorShape outputShape{ 1, 16, 16, 16 };
1402 TensorShape weightShape{ 16, 1, 1, 16 };
1403 TensorInfo inputInfo (inputShape, DataType::Float32);
1404 TensorInfo outputInfo(outputShape, DataType::Float32);
1405 TensorInfo weightInfo(weightShape, DataType::Float32);
1406 Convolution2dDescriptor convolution2dDescriptor;
1407 bool referenceConvolution2dSupported =
1408 referenceLayerSupport->IsConvolution2dSupported(inputInfo,
1409 outputInfo,
1410 convolution2dDescriptor,
1411 weightInfo,
1412 EmptyOptional());
1413 BOOST_TEST(referenceConvolution2dSupported);
1414
1415 // Test the backend instance by creating a workload
1416 IBackendInternal::IWorkloadFactoryPtr referenceWorkloadFactory = referenceDynamicBackend->CreateWorkloadFactory();
1417 BOOST_TEST((referenceWorkloadFactory != nullptr));
1418
1419 // Create dummy settings for the workload
1420 Convolution2dQueueDescriptor convolution2dQueueDescriptor;
1421 WorkloadInfo workloadInfo
1422 {
1423 { inputInfo },
1424 { outputInfo }
1425 };
1426 convolution2dQueueDescriptor.m_Inputs.push_back(nullptr);
1427 auto weights = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
1428 convolution2dQueueDescriptor.m_Weight = weights.get();
1429
1430 // Create a convolution workload with the dummy settings
1431 auto workload = referenceWorkloadFactory->CreateConvolution2d(convolution2dQueueDescriptor, workloadInfo);
1432 BOOST_TEST((workload != nullptr));
1433 BOOST_TEST(workload.get() == boost::polymorphic_downcast<RefConvolution2dWorkload*>(workload.get()));
1434}
Matteo Martincighe67edb22019-08-14 14:05:46 +01001435
1436#endif