blob: ae922bc26dccaa2d68541d4ab8436401017aaa87 [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 Martincighbc2e2102019-07-24 14:56:13 +01008#include <backendsCommon/DynamicBackend.hpp>
Matteo Martincighac60d282019-07-25 15:25:44 +01009#include <backendsCommon/DynamicBackendUtils.hpp>
10
Matteo Martincighbc2e2102019-07-24 14:56:13 +010011#include <string>
12#include <memory>
Matteo Martincigh986c1862019-07-26 15:12:47 +010013#include <string>
14
Matteo Martincighac60d282019-07-25 15:25:44 +010015#include <boost/test/unit_test.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010016#include <boost/filesystem.hpp>
Matteo Martincigha77d80e2019-07-31 11:05:16 +010017#include <boost/dll.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010018
Matteo Martincighd0dc7702019-08-01 17:09:03 +010019static std::string g_TestBaseDir = "src/backends/backendsCommon/test/";
Matteo Martincigh986c1862019-07-26 15:12:47 +010020
Matteo Martincighd0dc7702019-08-01 17:09:03 +010021static std::string g_TestSharedObjectSubDir = "testSharedObject/";
22static std::string g_TestDynamicBackendSubDir = "testDynamicBackend/";
23
24static std::string g_TestSharedObjectFileName = "libTestSharedObject.so";
25static std::string g_TestNoSharedObjectFileName = "libNoSharedObject.txt";
26
27static std::string g_TestValidTestDynamicBackendFileName = "libValidTestDynamicBackend.so";
28static std::string g_TestInvalidTestDynamicBackend1FileName = "libInvalidTestDynamicBackend1.so";
29static std::string g_TestInvalidTestDynamicBackend2FileName = "libInvalidTestDynamicBackend2.so";
30static std::string g_TestInvalidTestDynamicBackend3FileName = "libInvalidTestDynamicBackend3.so";
31static std::string g_TestInvalidTestDynamicBackend4FileName = "libInvalidTestDynamicBackend4.so";
32static std::string g_TestInvalidTestDynamicBackend5FileName = "libInvalidTestDynamicBackend5.so";
33static std::string g_TestInvalidTestDynamicBackend6FileName = "libInvalidTestDynamicBackend6.so";
34static std::string g_TestInvalidTestDynamicBackend7FileName = "libInvalidTestDynamicBackend7.so";
35
Matteo Martincighe54aa062019-08-05 14:12:11 +010036static std::string g_TestValidBackend2FileName = "Arm_TestValid2_backend.so";
37static std::string g_TestValidBackend3FileName = "Arm_TestValid3_backend.so";
38static std::string g_TestValidBackend4FileName = "Arm_TestValid4_backend.so";
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010039static std::string g_TestValidBackend5FileName = "Arm_TestValid5_backend.so";
Matteo Martincighe54aa062019-08-05 14:12:11 +010040static std::string g_TestInvalidBackend8FileName = "Arm_TestInvalid8_backend.so";
41static std::string g_TestInvalidBackend9FileName = "Arm_TestInvalid9_backend.so";
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010042static std::string g_TestInvalidBackend10FileName = "Arm_TestInvalid10_backend.so";
43static std::string g_TestInvalidBackend11FileName = "Arm_TestInvalid11_backend.so";
Matteo Martincighe54aa062019-08-05 14:12:11 +010044
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010045static std::string g_TestDynamicBackendsSubDir1 = "backendsTestPath1/";
46static std::string g_TestDynamicBackendsSubDir2 = "backendsTestPath2/";
47static std::string g_TestDynamicBackendsSubDir3 = "backendsTestPath3/";
48static std::string g_TestDynamicBackendsSubDir4 = "backendsTestPath4/";
49static std::string g_TestDynamicBackendsSubDir5 = "backendsTestPath5/";
50static std::string g_TestDynamicBackendsSubDir6 = "backendsTestPath6/";
51static std::string g_TestDynamicBackendsSubDir7 = "backendsTestPath7/";
52static std::string g_TestDynamicBackendsSubDir8 = "backendsTestPath8/";
53static std::string g_TestDynamicBackendsSubDir9 = "backendsTestPath9/";
54
55// Wrapper class used for testing
56class TestDynamicBackendUtils : public armnn::DynamicBackendUtils
57{
58public:
59 static bool IsBackendCompatibleTest(const armnn::BackendVersion& backendApiVersion,
60 const armnn::BackendVersion& backendVersion)
61 {
62 return IsBackendCompatibleImpl(backendApiVersion, backendVersion);
63 }
64
65 static std::vector<std::string> GetBackendPathsImplTest(const std::string& path)
66 {
67 return GetBackendPathsImpl(path);
68 }
69
70 static void RegisterDynamicBackendsImplTest(armnn::BackendRegistry& backendRegistry,
71 const std::vector<armnn::DynamicBackendPtr>& dynamicBackends)
72 {
73 RegisterDynamicBackendsImpl(backendRegistry, dynamicBackends);
74 }
75};
Matteo Martincighe7d44982019-08-05 12:16:47 +010076
Matteo Martincighd0dc7702019-08-01 17:09:03 +010077std::string GetTestDirectoryBasePath()
Matteo Martincigh986c1862019-07-26 15:12:47 +010078{
79 using namespace boost::filesystem;
80
Matteo Martincigha77d80e2019-07-31 11:05:16 +010081 path programLocation = boost::dll::program_location().parent_path();
Matteo Martincighd0dc7702019-08-01 17:09:03 +010082 path sharedObjectPath = programLocation.append(g_TestBaseDir);
83 BOOST_CHECK(exists(sharedObjectPath));
Matteo Martincigh986c1862019-07-26 15:12:47 +010084
Matteo Martincighd0dc7702019-08-01 17:09:03 +010085 return sharedObjectPath.string();
86}
87
88std::string GetTestSubDirectory(const std::string& subdir)
89{
90 using namespace boost::filesystem;
91
92 std::string testDynamicBackendsBaseDir = GetTestDirectoryBasePath();
93 path testDynamicBackendsBasePath(testDynamicBackendsBaseDir);
94 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
95 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
96
97 return testDynamicBackendsSubDir.string();
98}
99
100std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
101{
102 using namespace boost::filesystem;
103
104 path directoryPath(directory);
105 path fileNamePath = directoryPath.append(fileName);
106 BOOST_CHECK(exists(fileNamePath));
107
108 return fileNamePath.string();
Matteo Martincigh986c1862019-07-26 15:12:47 +0100109}
110
111void OpenCloseHandleTestImpl()
112{
113 using namespace armnn;
114
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100115 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
116 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100117
118 void* sharedObjectHandle = nullptr;
119 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
120 BOOST_TEST((sharedObjectHandle != nullptr));
121
122 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
123}
124
125void CloseInvalidHandleTestImpl()
126{
127 using namespace armnn;
128
129 // This calls must silently handle invalid handles and complete successfully (no segfaults, etc.)
130 DynamicBackendUtils::CloseHandle(nullptr);
131}
132
133void OpenEmptyFileNameTestImpl()
134{
135 using namespace armnn;
136
137 void* sharedObjectHandle = nullptr;
138 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(""), RuntimeException);
139 BOOST_TEST((sharedObjectHandle == nullptr));
140}
141
142void OpenNotExistingFileTestImpl()
143{
144 using namespace armnn;
145
146 void* sharedObjectHandle = nullptr;
147 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle("NotExistingFileName"), RuntimeException);
148 BOOST_TEST((sharedObjectHandle == nullptr));
149}
150
151void OpenNotSharedObjectTestImpl()
152{
153 using namespace armnn;
154
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100155 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
156 std::string notSharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestNoSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100157
158 void* sharedObjectHandle = nullptr;
159 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(notSharedObjectFilePath), RuntimeException);
160 BOOST_TEST((sharedObjectHandle == nullptr));
161}
162
163void GetValidEntryPointTestImpl()
164{
165 using namespace armnn;
166
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100167 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
168 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100169
170 void* sharedObjectHandle = nullptr;
171 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
172 BOOST_TEST((sharedObjectHandle != nullptr));
173
174 using TestFunctionType = int(*)(int);
175 TestFunctionType testFunctionPointer = nullptr;
176 BOOST_CHECK_NO_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
177 "TestFunction1"));
178 BOOST_TEST((testFunctionPointer != nullptr));
179 BOOST_TEST(testFunctionPointer(7) == 7);
180
181 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
182}
183
184void GetNameMangledEntryPointTestImpl()
185{
186 using namespace armnn;
187
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100188 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
189 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100190
191 void* sharedObjectHandle = nullptr;
192 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
193 BOOST_TEST((sharedObjectHandle != nullptr));
194
195 using TestFunctionType = int(*)(int);
196 TestFunctionType testFunctionPointer = nullptr;
197 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
198 "TestFunction2"),
199 RuntimeException);
200 BOOST_TEST((testFunctionPointer == nullptr));
201
202 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
203}
204
205void GetNoExternEntryPointTestImpl()
206{
207 using namespace armnn;
208
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100209 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
210 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100211
212 void* sharedObjectHandle = nullptr;
213 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
214 BOOST_TEST((sharedObjectHandle != nullptr));
215
216 using TestFunctionType = int(*)(int);
217 TestFunctionType testFunctionPointer = nullptr;
218 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
219 "TestFunction3"),
220 RuntimeException);
221 BOOST_TEST((testFunctionPointer == nullptr));
222
223 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
224}
225
226void GetNotExistingEntryPointTestImpl()
227{
228 using namespace armnn;
229
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100230 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
231 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100232
233 void* sharedObjectHandle = nullptr;
234 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
235 BOOST_TEST((sharedObjectHandle != nullptr));
236
237 using TestFunctionType = int(*)(int);
238 TestFunctionType testFunctionPointer = nullptr;
239 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
240 "TestFunction4"),
241 RuntimeException);
242 BOOST_TEST((testFunctionPointer == nullptr));
243
244 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
245}
Matteo Martincighac60d282019-07-25 15:25:44 +0100246
247void BackendVersioningTestImpl()
248{
Matteo Martincigh986c1862019-07-26 15:12:47 +0100249 using namespace armnn;
250
Matteo Martincighac60d282019-07-25 15:25:44 +0100251 // The backend API version used for the tests
Matteo Martincigh986c1862019-07-26 15:12:47 +0100252 BackendVersion backendApiVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100253
254 // Same backend and backend API versions are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100255 BackendVersion sameBackendVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100256 BOOST_TEST(sameBackendVersion == backendApiVersion);
257 BOOST_TEST(sameBackendVersion <= backendApiVersion);
258 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true);
259
260 // Backend versions that differ from the backend API version by major revision are not compatible
261 // with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100262 BackendVersion laterMajorBackendVersion{ 3, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100263 BOOST_TEST(!(laterMajorBackendVersion == backendApiVersion));
264 BOOST_TEST(!(laterMajorBackendVersion <= backendApiVersion));
265 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false);
266
Matteo Martincigh986c1862019-07-26 15:12:47 +0100267 BackendVersion earlierMajorBackendVersion{ 1, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100268 BOOST_TEST(!(earlierMajorBackendVersion == backendApiVersion));
269 BOOST_TEST(earlierMajorBackendVersion <= backendApiVersion);
270 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion,
271 earlierMajorBackendVersion) == false);
272
273 // Backend versions with the same major revision but later minor revision than
274 // the backend API version are not compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100275 BackendVersion laterMinorBackendVersion{ 2, 5 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100276 BOOST_TEST(!(laterMinorBackendVersion == backendApiVersion));
277 BOOST_TEST(!(laterMinorBackendVersion <= backendApiVersion));
278 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false);
279
280 // Backend versions with the same major revision but earlier minor revision than
281 // the backend API version are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100282 BackendVersion earlierMinorBackendVersion{ 2, 3 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100283 BOOST_TEST(!(earlierMinorBackendVersion == backendApiVersion));
284 BOOST_TEST(earlierMinorBackendVersion <= backendApiVersion);
285 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
286}
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100287
288void CreateValidDynamicBackendObjectTestImpl()
289{
290 // Valid shared object handle
291 // Correct name mangling
292 // Correct interface
293 // Correct backend implementation
294
295 using namespace armnn;
296
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100297 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
298 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestValidTestDynamicBackendFileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100299
300 void* sharedObjectHandle = nullptr;
301 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
302 BOOST_TEST((sharedObjectHandle != nullptr));
303
Matteo Martincighe54aa062019-08-05 14:12:11 +0100304 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100305 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
306 BOOST_TEST((dynamicBackend != nullptr));
307
308 BackendId dynamicBackendId;
309 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
310 BOOST_TEST((dynamicBackendId == "ValidTestDynamicBackend"));
311
312 BackendVersion dynamicBackendVersion;
313 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100314 BOOST_TEST((dynamicBackendVersion == IBackendInternal::GetApiVersion()));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100315
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100316 IBackendInternalUniquePtr dynamicBackendInstance1;
317 BOOST_CHECK_NO_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend());
318 BOOST_TEST((dynamicBackendInstance1 != nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100319
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100320 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
321 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
322 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
323
324 IBackendInternalUniquePtr dynamicBackendInstance2;
325 BOOST_CHECK_NO_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction());
326 BOOST_TEST((dynamicBackendInstance2 != nullptr));
327
328 BOOST_TEST((dynamicBackendInstance1->GetId() == "ValidTestDynamicBackend"));
329 BOOST_TEST((dynamicBackendInstance2->GetId() == "ValidTestDynamicBackend"));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100330}
331
332void CreateDynamicBackendObjectInvalidHandleTestImpl()
333{
334 // Invalid (null) shared object handle
335
336 using namespace armnn;
337
338 void* sharedObjectHandle = nullptr;
Matteo Martincighe54aa062019-08-05 14:12:11 +0100339 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100340 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
341 BOOST_TEST((dynamicBackend == nullptr));
342}
343
344void CreateDynamicBackendObjectInvalidInterface1TestImpl()
345{
346 // Valid shared object handle
347 // Wrong (not C-style) name mangling
348
349 using namespace armnn;
350
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100351 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
352 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend1FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100353
354 void* sharedObjectHandle = nullptr;
355 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
356 BOOST_TEST((sharedObjectHandle != nullptr));
357
Matteo Martincighe54aa062019-08-05 14:12:11 +0100358 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100359 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
360 BOOST_TEST((dynamicBackend == nullptr));
361}
362
363void CreateDynamicBackendObjectInvalidInterface2TestImpl()
364{
365 // Valid shared object handle
366 // Correct name mangling
367 // Wrong interface (missing GetBackendId())
368
369 using namespace armnn;
370
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100371 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
372 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend2FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100373
374 void* sharedObjectHandle = nullptr;
375 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
376 BOOST_TEST((sharedObjectHandle != nullptr));
377
Matteo Martincighe54aa062019-08-05 14:12:11 +0100378 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100379 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
380 BOOST_TEST((dynamicBackend == nullptr));
381}
382
383void CreateDynamicBackendObjectInvalidInterface3TestImpl()
384{
385 // Valid shared object handle
386 // Correct name mangling
387 // Wrong interface (missing GetVersion())
388
389 using namespace armnn;
390
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100391 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
392 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend3FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100393
394 void* sharedObjectHandle = nullptr;
395 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
396 BOOST_TEST((sharedObjectHandle != nullptr));
397
Matteo Martincighe54aa062019-08-05 14:12:11 +0100398 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100399 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
400 BOOST_TEST((dynamicBackend == nullptr));
401}
402
403void CreateDynamicBackendObjectInvalidInterface4TestImpl()
404{
405 // Valid shared object handle
406 // Correct name mangling
407 // Wrong interface (missing BackendFactory())
408
409 using namespace armnn;
410
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100411 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
412 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend4FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100413
414 void* sharedObjectHandle = nullptr;
415 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
416 BOOST_TEST((sharedObjectHandle != nullptr));
417
Matteo Martincighe54aa062019-08-05 14:12:11 +0100418 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100419 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
420 BOOST_TEST((dynamicBackend == nullptr));
421}
422
423void CreateDynamicBackendObjectInvalidInterface5TestImpl()
424{
425 // Valid shared object handle
426 // Correct name mangling
427 // Correct interface
428 // Invalid (null) backend id returned by GetBackendId()
429
430 using namespace armnn;
431
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100432 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
433 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend5FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100434
435 void* sharedObjectHandle = nullptr;
436 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
437 BOOST_TEST((sharedObjectHandle != nullptr));
438
Matteo Martincighe54aa062019-08-05 14:12:11 +0100439 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100440 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
441 BOOST_TEST((dynamicBackend == nullptr));
442}
443
444void CreateDynamicBackendObjectInvalidInterface6TestImpl()
445{
446 // Valid shared object handle
447 // Correct name mangling
448 // Correct interface
449 // Invalid (null) backend instance returned by BackendFactory()
450
451 using namespace armnn;
452
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100453 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
454 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend6FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100455
456 void* sharedObjectHandle = nullptr;
457 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
458 BOOST_TEST((sharedObjectHandle != nullptr));
459
Matteo Martincighe54aa062019-08-05 14:12:11 +0100460 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100461 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
462 BOOST_TEST((dynamicBackend != nullptr));
463
464 BackendId dynamicBackendId;
465 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
466 BOOST_TEST((dynamicBackendId == "InvalidTestDynamicBackend"));
467
468 BackendVersion dynamicBackendVersion;
469 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
470 BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
471
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100472 IBackendInternalUniquePtr dynamicBackendInstance1;
473 BOOST_CHECK_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException);
474 BOOST_TEST((dynamicBackendInstance1 == nullptr));
475
476 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
477 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
478 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
479
480 IBackendInternalUniquePtr dynamicBackendInstance2;
481 BOOST_CHECK_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction(), RuntimeException);
482 BOOST_TEST((dynamicBackendInstance2 == nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100483}
484
485void CreateDynamicBackendObjectInvalidInterface7TestImpl()
486{
487 // Valid shared object handle
488 // Correct name mangling
489 // Correct interface
490 // Invalid (incompatible backend API version) backend instance returned by BackendFactory()
491
492 using namespace armnn;
493
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100494 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
495 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend7FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100496
497 void* sharedObjectHandle = nullptr;
498 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
499 BOOST_TEST((sharedObjectHandle != nullptr));
500
Matteo Martincighe54aa062019-08-05 14:12:11 +0100501 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100502 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
503 BOOST_TEST((dynamicBackend == nullptr));
504}
Matteo Martincighe7d44982019-08-05 12:16:47 +0100505
506void GetBackendPathsTestImpl()
507{
508 using namespace armnn;
509 using namespace boost::filesystem;
510
511 // The test covers four directories:
512 // <unit test path>/src/backends/backendsCommon/test/
Matteo Martincighe54aa062019-08-05 14:12:11 +0100513 // ├─ backendsTestPath1/ -> exists, contains files
514 // ├─ backendsTestPath2/ -> exists, contains files
515 // ├─ backendsTestPath3/ -> exists, but empty
516 // └─ backendsTestPath4/ -> does not exist
Matteo Martincighe7d44982019-08-05 12:16:47 +0100517
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100518 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
519 std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
520 std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
521 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100522
523 BOOST_CHECK(exists(subDir1));
524 BOOST_CHECK(exists(subDir2));
525 BOOST_CHECK(exists(subDir3));
526 BOOST_CHECK(!exists(subDir4));
527
Matteo Martincighe7d44982019-08-05 12:16:47 +0100528 // No path
529 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());
530
531 // Malformed path
532 std::string malformedDir(subDir1 + "/" + subDir1);
533 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(malformedDir).size()==0);
534
535 // Single valid path
536 std::vector<std::string> DynamicBackendPaths2 = TestDynamicBackendUtils::GetBackendPathsImplTest(subDir1);
537 BOOST_TEST(DynamicBackendPaths2.size() == 1);
538 BOOST_TEST(DynamicBackendPaths2[0] == subDir1);
539
540 // Multiple equal and valid paths
541 std::string multipleEqualDirs(subDir1 + ":" + subDir1);
542 std::vector<std::string> DynamicBackendPaths3 = TestDynamicBackendUtils::GetBackendPathsImplTest(multipleEqualDirs);
543 BOOST_TEST(DynamicBackendPaths3.size() == 1);
544 BOOST_TEST(DynamicBackendPaths3[0] == subDir1);
545
546 // Multiple empty paths
547 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(":::").empty());
548
549 // Multiple valid paths
550 std::string multipleValidPaths(subDir1 + ":" + subDir2 + ":" + subDir3);
551 std::vector<std::string> DynamicBackendPaths5 =
552 TestDynamicBackendUtils::GetBackendPathsImplTest(multipleValidPaths);
553 BOOST_TEST(DynamicBackendPaths5.size() == 3);
554 BOOST_TEST(DynamicBackendPaths5[0] == subDir1);
555 BOOST_TEST(DynamicBackendPaths5[1] == subDir2);
556 BOOST_TEST(DynamicBackendPaths5[2] == subDir3);
557
558 // Valid among empty paths
559 std::string validAmongEmptyDirs("::" + subDir1 + ":");
560 std::vector<std::string> DynamicBackendPaths6 =
561 TestDynamicBackendUtils::GetBackendPathsImplTest(validAmongEmptyDirs);
562 BOOST_TEST(DynamicBackendPaths6.size() == 1);
563 BOOST_TEST(DynamicBackendPaths6[0] == subDir1);
564
565 // Invalid among empty paths
566 std::string invalidAmongEmptyDirs(":" + subDir4 + "::");
567 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(invalidAmongEmptyDirs).empty());
568
569 // Valid, invalid and empty paths
570 std::string validInvalidEmptyDirs(subDir1 + ":" + subDir4 + ":");
571 std::vector<std::string> DynamicBackendPaths8 =
572 TestDynamicBackendUtils::GetBackendPathsImplTest(validInvalidEmptyDirs);
573 BOOST_TEST(DynamicBackendPaths8.size() == 1);
574 BOOST_TEST(DynamicBackendPaths8[0] == subDir1);
575
576 // Mix of duplicates of valid, invalid and empty paths
577 std::string duplicateValidInvalidEmptyDirs(validInvalidEmptyDirs + ":" + validInvalidEmptyDirs + ":" +
578 subDir2 + ":" + subDir2);
579 std::vector<std::string> DynamicBackendPaths9 =
580 TestDynamicBackendUtils::GetBackendPathsImplTest(duplicateValidInvalidEmptyDirs);
581 BOOST_TEST(DynamicBackendPaths9.size() == 2);
582 BOOST_TEST(DynamicBackendPaths9[0] == subDir1);
583 BOOST_TEST(DynamicBackendPaths9[1] == subDir2);
584}
585
586void GetBackendPathsOverrideTestImpl()
587{
588 using namespace armnn;
589 using namespace boost::filesystem;
590
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100591 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
592 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100593
594 BOOST_CHECK(exists(subDir1));
595 BOOST_CHECK(!exists(subDir4));
596
597 // Override with valid path
598 std::vector<std::string> validResult = DynamicBackendUtils::GetBackendPaths(subDir1);
599 BOOST_TEST(validResult.size() == 1);
600 BOOST_TEST(validResult[0] == subDir1);
601
602 // Override with invalid path
603 std::vector<std::string> invalidResult = DynamicBackendUtils::GetBackendPaths(subDir4);
604 BOOST_TEST(invalidResult.empty());
605}
Jan Eilers4a539fc2019-07-25 17:08:37 +0100606
607void GetSharedObjectsTestImpl()
608{
609 using namespace armnn;
610 using namespace boost::filesystem;
611
Matteo Martincighe54aa062019-08-05 14:12:11 +0100612 // The test covers four directories:
613 // <unit test path>/src/backends/backendsCommon/test/
614 // ├─ backendsTestPath1/ -> exists, contains files
615 // ├─ backendsTestPath2/ -> exists, contains files
616 // ├─ backendsTestPath3/ -> exists, but empty
617 // └─ backendsTestPath4/ -> does not exist
Jan Eilers4a539fc2019-07-25 17:08:37 +0100618 //
619 // The test sub-directory backendsTestPath1/ contains the following test files:
620 //
621 // Arm_GpuAcc_backend.so -> valid (basic backend name)
622 // Arm_GpuAcc_backend.so.1 -> valid (single field version number)
623 // Arm_GpuAcc_backend.so.1.2 -> valid (multiple field version number)
624 // Arm_GpuAcc_backend.so.1.2.3 -> valid (multiple field version number)
625 // Arm_GpuAcc_backend.so.10.1.27 -> valid (Multiple digit version)
626 // Arm_GpuAcc_backend.so.10.1.33. -> not valid (dot not followed by version number)
627 // Arm_GpuAcc_backend.so.3.4..5 -> not valid (dot not followed by version number)
628 // Arm_GpuAcc_backend.so.1,1.1 -> not valid (comma instead of dot in the version)
629 //
630 // Arm123_GpuAcc_backend.so -> valid (digits in vendor name are allowed)
631 // Arm_GpuAcc456_backend.so -> valid (digits in backend id are allowed)
632 // Arm%Co_GpuAcc_backend.so -> not valid (invalid character in vendor name)
633 // Arm_Gpu.Acc_backend.so -> not valid (invalid character in backend id)
634 //
635 // GpuAcc_backend.so -> not valid (missing vendor name)
636 // _GpuAcc_backend.so -> not valid (missing vendor name)
637 // Arm__backend.so -> not valid (missing backend id)
638 // Arm_GpuAcc.so -> not valid (missing "backend" at the end)
639 // __backend.so -> not valid (missing vendor name and backend id)
640 // __.so -> not valid (missing all fields)
641 //
642 // Arm_GpuAcc_backend -> not valid (missing at least ".so" at the end)
643 // Arm_GpuAcc_backend_v1.2.so -> not valid (extra version info at the end)
644 //
645 // The test sub-directory backendsTestPath1/ contains the following test files:
646 //
647 // Arm_CpuAcc_backend.so -> valid (basic backend name)
648 // Arm_CpuAcc_backend.so.1 -> Arm_CpuAcc_backend.so -> valid (symlink to valid backend file)
649 // Arm_CpuAcc_backend.so.1.2 -> Arm_CpuAcc_backend.so.1 -> valid (symlink to valid symlink)
650 // Arm_CpuAcc_backend.so.1.2.3 -> Arm_CpuAcc_backend.so.1.2 -> valid (symlink to valid symlink)
651 //
652 // Arm_no_backend.so -> nothing -> not valid (symlink resolves to non-existent file)
653 //
654 // Arm_GpuAcc_backend.so -> valid (but duplicated from backendsTestPath1/)
655
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100656 std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
657 std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
658 std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
659 std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Jan Eilers4a539fc2019-07-25 17:08:37 +0100660 BOOST_CHECK(exists(testDynamicBackendsSubDir1));
661 BOOST_CHECK(exists(testDynamicBackendsSubDir2));
662 BOOST_CHECK(exists(testDynamicBackendsSubDir3));
663 BOOST_CHECK(!exists(testDynamicBackendsSubDir4));
664
665 std::vector<std::string> backendPaths
666 {
667 testDynamicBackendsSubDir1,
668 testDynamicBackendsSubDir2,
669 testDynamicBackendsSubDir3,
670 testDynamicBackendsSubDir4
671 };
672 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100673 std::vector<std::string> expectedSharedObjects
Jan Eilers4a539fc2019-07-25 17:08:37 +0100674 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100675 testDynamicBackendsSubDir1 + "Arm123_GpuAcc_backend.so", // Digits in vendor name are allowed
676 testDynamicBackendsSubDir1 + "Arm_GpuAcc456_backend.so", // Digits in backend id are allowed
Jan Eilers4a539fc2019-07-25 17:08:37 +0100677 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so", // Basic backend name
678 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1", // Single field version number
679 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2", // Multiple field version number
680 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2.3", // Multiple field version number
681 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.10.1.27", // Multiple digit version
Jan Eilers4a539fc2019-07-25 17:08:37 +0100682 testDynamicBackendsSubDir2 + "Arm_CpuAcc_backend.so", // Duplicate symlinks removed
683 testDynamicBackendsSubDir2 + "Arm_GpuAcc_backend.so" // Duplicates on different paths are allowed
684 };
685
686 BOOST_TEST(sharedObjects.size() == expectedSharedObjects.size());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100687 BOOST_TEST(sharedObjects[0] == expectedSharedObjects[0]);
688 BOOST_TEST(sharedObjects[1] == expectedSharedObjects[1]);
689 BOOST_TEST(sharedObjects[2] == expectedSharedObjects[2]);
690 BOOST_TEST(sharedObjects[3] == expectedSharedObjects[3]);
691 BOOST_TEST(sharedObjects[4] == expectedSharedObjects[4]);
692 BOOST_TEST(sharedObjects[5] == expectedSharedObjects[5]);
693 BOOST_TEST(sharedObjects[6] == expectedSharedObjects[6]);
694 BOOST_TEST(sharedObjects[7] == expectedSharedObjects[7]);
695 BOOST_TEST(sharedObjects[8] == expectedSharedObjects[8]);
696}
697
698void CreateDynamicBackendsTestImpl()
699{
700 using namespace armnn;
701 using namespace boost::filesystem;
702
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100703 // The test covers four directories:
Matteo Martincighe54aa062019-08-05 14:12:11 +0100704 // <unit test path>/src/backends/backendsCommon/test/
705 // ├─ backendsTestPath5/ -> exists, contains files
706 // ├─ backendsTestPath6/ -> exists, contains files
707 // ├─ backendsTestPath7/ -> exists, but empty
708 // └─ backendsTestPath8/ -> does not exist
709 //
710 // The test sub-directory backendsTestPath5/ contains the following test files:
711 //
712 // Arm_TestValid2_backend.so -> valid (basic backend name)
713 // Arm_TestValid3_backend.so -> valid (basic backend name)
714 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
715 //
716 // The test sub-directory backendsTestPath6/ contains the following test files:
717 //
718 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
719 // Arm_TestValid4_backend.so -> valid (it has a different filename,
720 // but it has the same backend id of Arm_TestValid2_backend.so
721 // and the same version)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100722 // Arm_TestValid5_backend.so -> valid (basic backend name)
Matteo Martincighe54aa062019-08-05 14:12:11 +0100723 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
724 // but it has the same backend id of Arm_TestValid2_backend.so
725 // and a version incompatible with the Backend API)
726
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100727 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
728 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
729 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
730 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100731 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
732 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
733 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
734 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
735
736 std::vector<std::string> backendPaths
Jan Eilers4a539fc2019-07-25 17:08:37 +0100737 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100738 testDynamicBackendsSubDir5,
739 testDynamicBackendsSubDir6,
740 testDynamicBackendsSubDir7,
741 testDynamicBackendsSubDir8
742 };
743 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
744 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
745
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100746 BOOST_TEST(dynamicBackends.size() == 5);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100747 BOOST_TEST((dynamicBackends[0] != nullptr));
748 BOOST_TEST((dynamicBackends[1] != nullptr));
749 BOOST_TEST((dynamicBackends[2] != nullptr));
750 BOOST_TEST((dynamicBackends[3] != nullptr));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100751 BOOST_TEST((dynamicBackends[4] != nullptr));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100752
753 // Duplicates are allowed here, they will be skipped later during the backend registration
754 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
755 BOOST_TEST((dynamicBackends[1]->GetBackendId() == "TestValid3"));
756 BOOST_TEST((dynamicBackends[2]->GetBackendId() == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
757 BOOST_TEST((dynamicBackends[3]->GetBackendId() == "TestValid2")); // From Arm_TestValid4_backend.so
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100758 BOOST_TEST((dynamicBackends[4]->GetBackendId() == "TestValid5"));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100759}
760
761void CreateDynamicBackendsNoPathsTestImpl()
762{
763 using namespace armnn;
764
765 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends({});
766
767 BOOST_TEST(dynamicBackends.empty());
768}
769
770void CreateDynamicBackendsAllInvalidTestImpl()
771{
772 using namespace armnn;
773
774 std::vector<std::string> sharedObjects
775 {
776 "InvalidSharedObject1",
777 "InvalidSharedObject2",
778 "InvalidSharedObject3",
779 };
780 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
781
782 BOOST_TEST(dynamicBackends.empty());
783}
784
785void CreateDynamicBackendsMixedTypesTestImpl()
786{
787 using namespace armnn;
788 using namespace boost::filesystem;
789
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100790 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
791 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100792 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
793 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
794
795 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
796 g_TestValidBackend2FileName);
797 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
798 g_TestInvalidBackend8FileName);
799 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
800 g_TestInvalidBackend9FileName);
801 BOOST_CHECK(exists(testValidBackend2FilePath));
802 BOOST_CHECK(exists(testInvalidBackend8FilePath));
803 BOOST_CHECK(exists(testInvalidBackend9FilePath));
804
805 std::vector<std::string> sharedObjects
806 {
807 testValidBackend2FilePath, // Arm_TestValid2_backend.so -> valid (basic backend name)
808 testInvalidBackend8FilePath, // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
809 testInvalidBackend9FilePath, // Arm_TestInvalid9_backend.so -> not valid (incompatible version)
810 "InvalidSharedObject", // The file does not exist
811 };
812 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
813
814 BOOST_TEST(dynamicBackends.size() == 1);
815 BOOST_TEST((dynamicBackends[0] != nullptr));
816 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
Jan Eilers4a539fc2019-07-25 17:08:37 +0100817}
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100818
819void RegisterSingleDynamicBackendTestImpl()
820{
821 using namespace armnn;
822 using namespace boost::filesystem;
823
824 // Register one valid dynamic backend
825
826 // Dummy registry used for testing
827 BackendRegistry backendRegistry;
828 BOOST_TEST(backendRegistry.Size() == 0);
829
830 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
831 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
832
833 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
834 BOOST_CHECK(exists(testValidBackend2FilePath));
835
836 std::vector<std::string> sharedObjects{ testValidBackend2FilePath };
837 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
838
839 BOOST_TEST(dynamicBackends.size() == 1);
840 BOOST_TEST((dynamicBackends[0] != nullptr));
841
842 BackendId dynamicBackendId = dynamicBackends[0]->GetBackendId();
843 BOOST_TEST((dynamicBackendId == "TestValid2"));
844
845 BackendVersion dynamicBackendVersion = dynamicBackends[0]->GetBackendVersion();
846 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
847
848 TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
849 BOOST_TEST(backendRegistry.Size() == 1);
850
851 BackendIdSet backendIds = backendRegistry.GetBackendIds();
852 BOOST_TEST(backendIds.size() == 1);
853 BOOST_TEST((backendIds.find(dynamicBackendId) != backendIds.end()));
854
855 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
856 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
857
858 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
859 BOOST_TEST((dynamicBackend != nullptr));
860 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
861}
862
863void RegisterMultipleDynamicBackendsTestImpl()
864{
865 using namespace armnn;
866 using namespace boost::filesystem;
867
868 // Register many valid dynamic backends
869
870 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
871 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
872 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
873 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
874
875 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
876 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
877 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
878 BOOST_CHECK(exists(testValidBackend2FilePath));
879 BOOST_CHECK(exists(testValidBackend3FilePath));
880 BOOST_CHECK(exists(testValidBackend5FilePath));
881
882 std::vector<std::string> sharedObjects
883 {
884 testValidBackend2FilePath,
885 testValidBackend3FilePath,
886 testValidBackend5FilePath
887 };
888 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
889
890 BOOST_TEST(dynamicBackends.size() == 3);
891 BOOST_TEST((dynamicBackends[0] != nullptr));
892 BOOST_TEST((dynamicBackends[1] != nullptr));
893 BOOST_TEST((dynamicBackends[2] != nullptr));
894
895 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
896 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
897 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
898 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
899 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
900 BOOST_TEST((dynamicBackendId3 == "TestValid5"));
901
902 for (size_t i = 0; i < dynamicBackends.size(); i++)
903 {
904 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
905 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
906 }
907
908 // Dummy registry used for testing
909 BackendRegistry backendRegistry;
910 BOOST_TEST(backendRegistry.Size() == 0);
911
912 TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
913 BOOST_TEST(backendRegistry.Size() == 3);
914
915 BackendIdSet backendIds = backendRegistry.GetBackendIds();
916 BOOST_TEST(backendIds.size() == 3);
917 BOOST_TEST((backendIds.find(dynamicBackendId1) != backendIds.end()));
918 BOOST_TEST((backendIds.find(dynamicBackendId2) != backendIds.end()));
919 BOOST_TEST((backendIds.find(dynamicBackendId3) != backendIds.end()));
920
921 for (size_t i = 0; i < dynamicBackends.size(); i++)
922 {
923 BackendId dynamicBackendId = dynamicBackends[i]->GetBackendId();
924
925 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
926 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
927
928 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
929 BOOST_TEST((dynamicBackend != nullptr));
930 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
931 }
932}
933
934void RegisterMultipleInvalidDynamicBackendsTestImpl()
935{
936 using namespace armnn;
937 using namespace boost::filesystem;
938
939 // Try to register many invalid dynamic backends
940
941 // The test covers one directory:
942 // <unit test path>/src/backends/backendsCommon/test/
943 // └─ backendsTestPath9/ -> exists, contains files
944 //
945 // The test sub-directory backendsTestPath9/ contains the following test files:
946 //
947 // Arm_TestInvalid10_backend.so -> not valid (invalid backend id)
948 // Arm_TestInvalid11_backend.so -> not valid (invalid backend id)
949
950 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
951 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
952
953 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
954 g_TestInvalidBackend10FileName);
955 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
956 g_TestInvalidBackend11FileName);
957 BOOST_CHECK(exists(testInvalidBackend10FilePath));
958 BOOST_CHECK(exists(testInvalidBackend11FilePath));
959
960 std::vector<std::string> sharedObjects
961 {
962 testInvalidBackend10FilePath,
963 testInvalidBackend11FilePath,
964 "InvalidSharedObject"
965 };
966 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
967
968 BOOST_TEST(dynamicBackends.size() == 2);
969 BOOST_TEST((dynamicBackends[0] != nullptr));
970 BOOST_TEST((dynamicBackends[1] != nullptr));
971
972 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
973 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
974 BOOST_TEST((dynamicBackendId1 == ""));
975 BOOST_TEST((dynamicBackendId2 == "Unknown"));
976
977 for (size_t i = 0; i < dynamicBackends.size(); i++)
978 {
979 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
980 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
981 }
982
983 // Dummy registry used for testing
984 BackendRegistry backendRegistry;
985 BOOST_TEST(backendRegistry.Size() == 0);
986
987 // Check that no dynamic backend got registered
988 TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
989 BOOST_TEST(backendRegistry.Size() == 0);
990}
991
992void RegisterMixedDynamicBackendsTestImpl()
993{
994 using namespace armnn;
995 using namespace boost::filesystem;
996
997 // The test covers five directories:
998 // <unit test path>/src/backends/backendsCommon/test/
999 // ├─ backendsTestPath5/ -> exists, contains files
1000 // ├─ backendsTestPath6/ -> exists, contains files
1001 // ├─ backendsTestPath7/ -> exists, but empty
1002 // ├─ backendsTestPath8/ -> does not exist
1003 // └─ backendsTestPath9/ -> exists, contains files
1004 //
1005 // The test sub-directory backendsTestPath5/ contains the following test files:
1006 //
1007 // Arm_TestValid2_backend.so -> valid (basic backend name)
1008 // Arm_TestValid3_backend.so -> valid (basic backend name)
1009 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
1010 //
1011 // The test sub-directory backendsTestPath6/ contains the following test files:
1012 //
1013 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
1014 // Arm_TestValid4_backend.so -> valid (it has a different filename,
1015 // but it has the same backend id of Arm_TestValid2_backend.so
1016 // and the same version)
1017 // Arm_TestValid5_backend.so -> valid (basic backend name)
1018 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
1019 // but it has the same backend id of Arm_TestValid2_backend.so
1020 // and a version incompatible with the Backend API)
1021 //
1022 // The test sub-directory backendsTestPath9/ contains the following test files:
1023 //
1024 // Arm_TestInvalid10_backend.so -> not valid (empty backend id)
1025 // Arm_TestInvalid11_backend.so -> not valid ("Unknown" backend id)
1026
1027 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1028 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1029 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
1030 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
1031 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1032 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1033 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1034 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
1035 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
1036 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1037
1038 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
1039 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
1040 std::string testValidBackend2DupFilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend2FileName);
1041 std::string testValidBackend4FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend4FileName);
1042 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
1043 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
1044 g_TestInvalidBackend8FileName);
1045 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
1046 g_TestInvalidBackend9FileName);
1047 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1048 g_TestInvalidBackend10FileName);
1049 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1050 g_TestInvalidBackend11FileName);
1051 BOOST_CHECK(exists(testValidBackend2FilePath));
1052 BOOST_CHECK(exists(testValidBackend3FilePath));
1053 BOOST_CHECK(exists(testValidBackend2DupFilePath));
1054 BOOST_CHECK(exists(testValidBackend4FilePath));
1055 BOOST_CHECK(exists(testValidBackend5FilePath));
1056 BOOST_CHECK(exists(testInvalidBackend8FilePath));
1057 BOOST_CHECK(exists(testInvalidBackend9FilePath));
1058 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1059 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1060
1061 std::vector<std::string> sharedObjects
1062 {
1063 testValidBackend2FilePath,
1064 testValidBackend3FilePath,
1065 testValidBackend2DupFilePath,
1066 testValidBackend4FilePath,
1067 testValidBackend5FilePath,
1068 testInvalidBackend8FilePath,
1069 testInvalidBackend9FilePath,
1070 testInvalidBackend10FilePath,
1071 testInvalidBackend11FilePath,
1072 "InvalidSharedObject"
1073 };
1074 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1075
1076 BOOST_TEST(dynamicBackends.size() == 7);
1077 BOOST_TEST((dynamicBackends[0] != nullptr));
1078 BOOST_TEST((dynamicBackends[1] != nullptr));
1079 BOOST_TEST((dynamicBackends[2] != nullptr));
1080 BOOST_TEST((dynamicBackends[3] != nullptr));
1081 BOOST_TEST((dynamicBackends[4] != nullptr));
1082 BOOST_TEST((dynamicBackends[5] != nullptr));
1083 BOOST_TEST((dynamicBackends[6] != nullptr));
1084
1085 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1086 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1087 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
1088 BackendId dynamicBackendId4 = dynamicBackends[3]->GetBackendId();
1089 BackendId dynamicBackendId5 = dynamicBackends[4]->GetBackendId();
1090 BackendId dynamicBackendId6 = dynamicBackends[5]->GetBackendId();
1091 BackendId dynamicBackendId7 = dynamicBackends[6]->GetBackendId();
1092 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
1093 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
1094 BOOST_TEST((dynamicBackendId3 == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
1095 BOOST_TEST((dynamicBackendId4 == "TestValid2")); // From Arm_TestValid4_backend.so
1096 BOOST_TEST((dynamicBackendId5 == "TestValid5"));
1097 BOOST_TEST((dynamicBackendId6 == ""));
1098 BOOST_TEST((dynamicBackendId7 == "Unknown"));
1099
1100 for (size_t i = 0; i < dynamicBackends.size(); i++)
1101 {
1102 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1103 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1104 }
1105
1106 // Dummy registry used for testing
1107 BackendRegistry backendRegistry;
1108 BOOST_TEST(backendRegistry.Size() == 0);
1109
1110 std::vector<BackendId> expectedRegisteredbackendIds
1111 {
1112 "TestValid2",
1113 "TestValid3",
1114 "TestValid5"
1115 };
1116
1117 TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
1118 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1119
1120 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1121 BOOST_TEST(backendIds.size() == expectedRegisteredbackendIds.size());
1122 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1123 {
1124 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1125
1126 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(expectedRegisteredbackendId);
1127 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
1128
1129 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
1130 BOOST_TEST((dynamicBackend != nullptr));
1131 BOOST_TEST((dynamicBackend->GetId() == expectedRegisteredbackendId));
1132 }
1133}