blob: e225124e017a8a2fcc9b564b78c15106beb9a4d6 [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>
Matteo Martincigh4e73b422019-08-08 13:46:32 +010010#include <backendsCommon/BackendRegistry.hpp>
11#include <backendsCommon/CpuTensorHandle.hpp>
12
13#include <armnn/ILayerSupport.hpp>
14
15#include <reference/workloads/RefConvolution2dWorkload.hpp>
Matteo Martincighac60d282019-07-25 15:25:44 +010016
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +010017#include <Runtime.hpp>
18
Matteo Martincighbc2e2102019-07-24 14:56:13 +010019#include <string>
20#include <memory>
Matteo Martincigh986c1862019-07-26 15:12:47 +010021#include <string>
22
Matteo Martincighac60d282019-07-25 15:25:44 +010023#include <boost/test/unit_test.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010024#include <boost/filesystem.hpp>
Matteo Martincigha77d80e2019-07-31 11:05:16 +010025#include <boost/dll.hpp>
Matteo Martincigh986c1862019-07-26 15:12:47 +010026
Matteo Martincighd0dc7702019-08-01 17:09:03 +010027static std::string g_TestBaseDir = "src/backends/backendsCommon/test/";
Matteo Martincigh986c1862019-07-26 15:12:47 +010028
Matteo Martincighd0dc7702019-08-01 17:09:03 +010029static std::string g_TestSharedObjectSubDir = "testSharedObject/";
30static std::string g_TestDynamicBackendSubDir = "testDynamicBackend/";
31
32static std::string g_TestSharedObjectFileName = "libTestSharedObject.so";
33static std::string g_TestNoSharedObjectFileName = "libNoSharedObject.txt";
34
35static std::string g_TestValidTestDynamicBackendFileName = "libValidTestDynamicBackend.so";
36static std::string g_TestInvalidTestDynamicBackend1FileName = "libInvalidTestDynamicBackend1.so";
37static std::string g_TestInvalidTestDynamicBackend2FileName = "libInvalidTestDynamicBackend2.so";
38static std::string g_TestInvalidTestDynamicBackend3FileName = "libInvalidTestDynamicBackend3.so";
39static std::string g_TestInvalidTestDynamicBackend4FileName = "libInvalidTestDynamicBackend4.so";
40static std::string g_TestInvalidTestDynamicBackend5FileName = "libInvalidTestDynamicBackend5.so";
41static std::string g_TestInvalidTestDynamicBackend6FileName = "libInvalidTestDynamicBackend6.so";
42static std::string g_TestInvalidTestDynamicBackend7FileName = "libInvalidTestDynamicBackend7.so";
43
Matteo Martincighe54aa062019-08-05 14:12:11 +010044static std::string g_TestValidBackend2FileName = "Arm_TestValid2_backend.so";
45static std::string g_TestValidBackend3FileName = "Arm_TestValid3_backend.so";
46static std::string g_TestValidBackend4FileName = "Arm_TestValid4_backend.so";
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010047static std::string g_TestValidBackend5FileName = "Arm_TestValid5_backend.so";
Matteo Martincighe54aa062019-08-05 14:12:11 +010048static std::string g_TestInvalidBackend8FileName = "Arm_TestInvalid8_backend.so";
49static std::string g_TestInvalidBackend9FileName = "Arm_TestInvalid9_backend.so";
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010050static std::string g_TestInvalidBackend10FileName = "Arm_TestInvalid10_backend.so";
51static std::string g_TestInvalidBackend11FileName = "Arm_TestInvalid11_backend.so";
Matteo Martincighe54aa062019-08-05 14:12:11 +010052
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010053static std::string g_TestDynamicBackendsSubDir1 = "backendsTestPath1/";
54static std::string g_TestDynamicBackendsSubDir2 = "backendsTestPath2/";
55static std::string g_TestDynamicBackendsSubDir3 = "backendsTestPath3/";
56static std::string g_TestDynamicBackendsSubDir4 = "backendsTestPath4/";
57static std::string g_TestDynamicBackendsSubDir5 = "backendsTestPath5/";
58static std::string g_TestDynamicBackendsSubDir6 = "backendsTestPath6/";
59static std::string g_TestDynamicBackendsSubDir7 = "backendsTestPath7/";
60static std::string g_TestDynamicBackendsSubDir8 = "backendsTestPath8/";
61static std::string g_TestDynamicBackendsSubDir9 = "backendsTestPath9/";
62
Matteo Martincigh4e73b422019-08-08 13:46:32 +010063static std::string g_DynamicBackendsBaseDir = "src/backends/dynamic";
64static std::string g_ReferenceDynamicBackendSubDir = "reference/";
65static std::string g_ReferenceBackendFileName = "Arm_CpuRef_backend.so";
66
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +010067// DynamicBackendUtils wrapper class used for testing (allows to directly invoke the protected methods)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010068class TestDynamicBackendUtils : public armnn::DynamicBackendUtils
69{
70public:
71 static bool IsBackendCompatibleTest(const armnn::BackendVersion& backendApiVersion,
72 const armnn::BackendVersion& backendVersion)
73 {
74 return IsBackendCompatibleImpl(backendApiVersion, backendVersion);
75 }
76
77 static std::vector<std::string> GetBackendPathsImplTest(const std::string& path)
78 {
79 return GetBackendPathsImpl(path);
80 }
81
Matteo Martincigh89533902019-08-15 12:08:06 +010082 static armnn::BackendIdSet RegisterDynamicBackendsImplTest(
83 armnn::BackendRegistry& backendRegistry,
84 const std::vector<armnn::DynamicBackendPtr>& dynamicBackends)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010085 {
Matteo Martincigh89533902019-08-15 12:08:06 +010086 return RegisterDynamicBackendsImpl(backendRegistry, dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +010087 }
88};
Matteo Martincighe7d44982019-08-05 12:16:47 +010089
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +010090// BackendRegistry wrapper class used for testing (swaps the underlying factory storage)
91class TestBackendRegistry : public armnn::BackendRegistry
92{
93public:
94 TestBackendRegistry() : armnn::BackendRegistry()
95 {
96 Swap(armnn::BackendRegistryInstance(), m_TempStorage);
97 }
98
99 ~TestBackendRegistry()
100 {
101 Swap(armnn::BackendRegistryInstance(), m_TempStorage);
102 }
103
104private:
105 FactoryStorage m_TempStorage;
106};
107
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100108std::string GetBasePath(const std::string& basePath)
Matteo Martincigh986c1862019-07-26 15:12:47 +0100109{
110 using namespace boost::filesystem;
111
Matteo Martincigha77d80e2019-07-31 11:05:16 +0100112 path programLocation = boost::dll::program_location().parent_path();
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100113 path sharedObjectPath = programLocation.append(basePath);
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100114 BOOST_CHECK(exists(sharedObjectPath));
Matteo Martincigh986c1862019-07-26 15:12:47 +0100115
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100116 return sharedObjectPath.string();
117}
118
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100119std::string GetTestDirectoryBasePath()
120{
121 return GetBasePath(g_TestBaseDir);
122}
123
124std::string GetDynamicBackendsBasePath()
125{
126 return GetBasePath(g_DynamicBackendsBaseDir);
127}
128
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100129std::string GetTestSubDirectory(const std::string& subdir)
130{
131 using namespace boost::filesystem;
132
133 std::string testDynamicBackendsBaseDir = GetTestDirectoryBasePath();
134 path testDynamicBackendsBasePath(testDynamicBackendsBaseDir);
135 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
136 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
137
138 return testDynamicBackendsSubDir.string();
139}
140
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100141std::string GetTestSubDirectory(const std::string& basePath, const std::string& subdir)
142{
143 using namespace boost::filesystem;
144
145 path testDynamicBackendsBasePath(basePath);
146 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
147 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
148
149 return testDynamicBackendsSubDir.string();
150}
151
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100152std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
153{
154 using namespace boost::filesystem;
155
156 path directoryPath(directory);
157 path fileNamePath = directoryPath.append(fileName);
158 BOOST_CHECK(exists(fileNamePath));
159
160 return fileNamePath.string();
Matteo Martincigh986c1862019-07-26 15:12:47 +0100161}
162
163void OpenCloseHandleTestImpl()
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 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
175}
176
177void CloseInvalidHandleTestImpl()
178{
179 using namespace armnn;
180
181 // This calls must silently handle invalid handles and complete successfully (no segfaults, etc.)
182 DynamicBackendUtils::CloseHandle(nullptr);
183}
184
185void OpenEmptyFileNameTestImpl()
186{
187 using namespace armnn;
188
189 void* sharedObjectHandle = nullptr;
190 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(""), RuntimeException);
191 BOOST_TEST((sharedObjectHandle == nullptr));
192}
193
194void OpenNotExistingFileTestImpl()
195{
196 using namespace armnn;
197
198 void* sharedObjectHandle = nullptr;
199 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle("NotExistingFileName"), RuntimeException);
200 BOOST_TEST((sharedObjectHandle == nullptr));
201}
202
203void OpenNotSharedObjectTestImpl()
204{
205 using namespace armnn;
206
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100207 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
208 std::string notSharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestNoSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100209
210 void* sharedObjectHandle = nullptr;
211 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(notSharedObjectFilePath), RuntimeException);
212 BOOST_TEST((sharedObjectHandle == nullptr));
213}
214
215void GetValidEntryPointTestImpl()
216{
217 using namespace armnn;
218
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100219 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
220 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100221
222 void* sharedObjectHandle = nullptr;
223 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
224 BOOST_TEST((sharedObjectHandle != nullptr));
225
226 using TestFunctionType = int(*)(int);
227 TestFunctionType testFunctionPointer = nullptr;
228 BOOST_CHECK_NO_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
229 "TestFunction1"));
230 BOOST_TEST((testFunctionPointer != nullptr));
231 BOOST_TEST(testFunctionPointer(7) == 7);
232
233 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
234}
235
236void GetNameMangledEntryPointTestImpl()
237{
238 using namespace armnn;
239
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100240 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
241 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100242
243 void* sharedObjectHandle = nullptr;
244 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
245 BOOST_TEST((sharedObjectHandle != nullptr));
246
247 using TestFunctionType = int(*)(int);
248 TestFunctionType testFunctionPointer = nullptr;
249 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
250 "TestFunction2"),
251 RuntimeException);
252 BOOST_TEST((testFunctionPointer == nullptr));
253
254 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
255}
256
257void GetNoExternEntryPointTestImpl()
258{
259 using namespace armnn;
260
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100261 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
262 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100263
264 void* sharedObjectHandle = nullptr;
265 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
266 BOOST_TEST((sharedObjectHandle != nullptr));
267
268 using TestFunctionType = int(*)(int);
269 TestFunctionType testFunctionPointer = nullptr;
270 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
271 "TestFunction3"),
272 RuntimeException);
273 BOOST_TEST((testFunctionPointer == nullptr));
274
275 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
276}
277
278void GetNotExistingEntryPointTestImpl()
279{
280 using namespace armnn;
281
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100282 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
283 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100284
285 void* sharedObjectHandle = nullptr;
286 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
287 BOOST_TEST((sharedObjectHandle != nullptr));
288
289 using TestFunctionType = int(*)(int);
290 TestFunctionType testFunctionPointer = nullptr;
291 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
292 "TestFunction4"),
293 RuntimeException);
294 BOOST_TEST((testFunctionPointer == nullptr));
295
296 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
297}
Matteo Martincighac60d282019-07-25 15:25:44 +0100298
299void BackendVersioningTestImpl()
300{
Matteo Martincigh986c1862019-07-26 15:12:47 +0100301 using namespace armnn;
302
Matteo Martincighac60d282019-07-25 15:25:44 +0100303 // The backend API version used for the tests
Matteo Martincigh986c1862019-07-26 15:12:47 +0100304 BackendVersion backendApiVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100305
306 // Same backend and backend API versions are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100307 BackendVersion sameBackendVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100308 BOOST_TEST(sameBackendVersion == backendApiVersion);
309 BOOST_TEST(sameBackendVersion <= backendApiVersion);
310 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true);
311
312 // Backend versions that differ from the backend API version by major revision are not compatible
313 // with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100314 BackendVersion laterMajorBackendVersion{ 3, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100315 BOOST_TEST(!(laterMajorBackendVersion == backendApiVersion));
316 BOOST_TEST(!(laterMajorBackendVersion <= backendApiVersion));
317 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false);
318
Matteo Martincigh986c1862019-07-26 15:12:47 +0100319 BackendVersion earlierMajorBackendVersion{ 1, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100320 BOOST_TEST(!(earlierMajorBackendVersion == backendApiVersion));
321 BOOST_TEST(earlierMajorBackendVersion <= backendApiVersion);
322 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion,
323 earlierMajorBackendVersion) == false);
324
325 // Backend versions with the same major revision but later minor revision than
326 // the backend API version are not compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100327 BackendVersion laterMinorBackendVersion{ 2, 5 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100328 BOOST_TEST(!(laterMinorBackendVersion == backendApiVersion));
329 BOOST_TEST(!(laterMinorBackendVersion <= backendApiVersion));
330 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false);
331
332 // Backend versions with the same major revision but earlier minor revision than
333 // the backend API version are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100334 BackendVersion earlierMinorBackendVersion{ 2, 3 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100335 BOOST_TEST(!(earlierMinorBackendVersion == backendApiVersion));
336 BOOST_TEST(earlierMinorBackendVersion <= backendApiVersion);
337 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
338}
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100339
340void CreateValidDynamicBackendObjectTestImpl()
341{
342 // Valid shared object handle
343 // Correct name mangling
344 // Correct interface
345 // Correct backend implementation
346
347 using namespace armnn;
348
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100349 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
350 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestValidTestDynamicBackendFileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100351
352 void* sharedObjectHandle = nullptr;
353 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
354 BOOST_TEST((sharedObjectHandle != nullptr));
355
Matteo Martincighe54aa062019-08-05 14:12:11 +0100356 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100357 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
358 BOOST_TEST((dynamicBackend != nullptr));
359
360 BackendId dynamicBackendId;
361 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
362 BOOST_TEST((dynamicBackendId == "ValidTestDynamicBackend"));
363
364 BackendVersion dynamicBackendVersion;
365 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100366 BOOST_TEST((dynamicBackendVersion == IBackendInternal::GetApiVersion()));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100367
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100368 IBackendInternalUniquePtr dynamicBackendInstance1;
369 BOOST_CHECK_NO_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend());
370 BOOST_TEST((dynamicBackendInstance1 != nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100371
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100372 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
373 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
374 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
375
376 IBackendInternalUniquePtr dynamicBackendInstance2;
377 BOOST_CHECK_NO_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction());
378 BOOST_TEST((dynamicBackendInstance2 != nullptr));
379
380 BOOST_TEST((dynamicBackendInstance1->GetId() == "ValidTestDynamicBackend"));
381 BOOST_TEST((dynamicBackendInstance2->GetId() == "ValidTestDynamicBackend"));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100382}
383
384void CreateDynamicBackendObjectInvalidHandleTestImpl()
385{
386 // Invalid (null) shared object handle
387
388 using namespace armnn;
389
390 void* sharedObjectHandle = nullptr;
Matteo Martincighe54aa062019-08-05 14:12:11 +0100391 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100392 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
393 BOOST_TEST((dynamicBackend == nullptr));
394}
395
396void CreateDynamicBackendObjectInvalidInterface1TestImpl()
397{
398 // Valid shared object handle
399 // Wrong (not C-style) name mangling
400
401 using namespace armnn;
402
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100403 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
404 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend1FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100405
406 void* sharedObjectHandle = nullptr;
407 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
408 BOOST_TEST((sharedObjectHandle != nullptr));
409
Matteo Martincighe54aa062019-08-05 14:12:11 +0100410 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100411 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
412 BOOST_TEST((dynamicBackend == nullptr));
413}
414
415void CreateDynamicBackendObjectInvalidInterface2TestImpl()
416{
417 // Valid shared object handle
418 // Correct name mangling
419 // Wrong interface (missing GetBackendId())
420
421 using namespace armnn;
422
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100423 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
424 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend2FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100425
426 void* sharedObjectHandle = nullptr;
427 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
428 BOOST_TEST((sharedObjectHandle != nullptr));
429
Matteo Martincighe54aa062019-08-05 14:12:11 +0100430 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100431 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
432 BOOST_TEST((dynamicBackend == nullptr));
433}
434
435void CreateDynamicBackendObjectInvalidInterface3TestImpl()
436{
437 // Valid shared object handle
438 // Correct name mangling
439 // Wrong interface (missing GetVersion())
440
441 using namespace armnn;
442
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100443 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
444 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend3FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100445
446 void* sharedObjectHandle = nullptr;
447 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
448 BOOST_TEST((sharedObjectHandle != nullptr));
449
Matteo Martincighe54aa062019-08-05 14:12:11 +0100450 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100451 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
452 BOOST_TEST((dynamicBackend == nullptr));
453}
454
455void CreateDynamicBackendObjectInvalidInterface4TestImpl()
456{
457 // Valid shared object handle
458 // Correct name mangling
459 // Wrong interface (missing BackendFactory())
460
461 using namespace armnn;
462
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100463 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
464 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend4FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100465
466 void* sharedObjectHandle = nullptr;
467 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
468 BOOST_TEST((sharedObjectHandle != nullptr));
469
Matteo Martincighe54aa062019-08-05 14:12:11 +0100470 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100471 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
472 BOOST_TEST((dynamicBackend == nullptr));
473}
474
475void CreateDynamicBackendObjectInvalidInterface5TestImpl()
476{
477 // Valid shared object handle
478 // Correct name mangling
479 // Correct interface
480 // Invalid (null) backend id returned by GetBackendId()
481
482 using namespace armnn;
483
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100484 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
485 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend5FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100486
487 void* sharedObjectHandle = nullptr;
488 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
489 BOOST_TEST((sharedObjectHandle != nullptr));
490
Matteo Martincighe54aa062019-08-05 14:12:11 +0100491 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100492 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
493 BOOST_TEST((dynamicBackend == nullptr));
494}
495
496void CreateDynamicBackendObjectInvalidInterface6TestImpl()
497{
498 // Valid shared object handle
499 // Correct name mangling
500 // Correct interface
501 // Invalid (null) backend instance returned by BackendFactory()
502
503 using namespace armnn;
504
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100505 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
506 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend6FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100507
508 void* sharedObjectHandle = nullptr;
509 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
510 BOOST_TEST((sharedObjectHandle != nullptr));
511
Matteo Martincighe54aa062019-08-05 14:12:11 +0100512 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100513 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
514 BOOST_TEST((dynamicBackend != nullptr));
515
516 BackendId dynamicBackendId;
517 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
518 BOOST_TEST((dynamicBackendId == "InvalidTestDynamicBackend"));
519
520 BackendVersion dynamicBackendVersion;
521 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
522 BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
523
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100524 IBackendInternalUniquePtr dynamicBackendInstance1;
525 BOOST_CHECK_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException);
526 BOOST_TEST((dynamicBackendInstance1 == nullptr));
527
528 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
529 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
530 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
531
532 IBackendInternalUniquePtr dynamicBackendInstance2;
533 BOOST_CHECK_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction(), RuntimeException);
534 BOOST_TEST((dynamicBackendInstance2 == nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100535}
536
537void CreateDynamicBackendObjectInvalidInterface7TestImpl()
538{
539 // Valid shared object handle
540 // Correct name mangling
541 // Correct interface
542 // Invalid (incompatible backend API version) backend instance returned by BackendFactory()
543
544 using namespace armnn;
545
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100546 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
547 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend7FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100548
549 void* sharedObjectHandle = nullptr;
550 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
551 BOOST_TEST((sharedObjectHandle != nullptr));
552
Matteo Martincighe54aa062019-08-05 14:12:11 +0100553 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100554 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
555 BOOST_TEST((dynamicBackend == nullptr));
556}
Matteo Martincighe7d44982019-08-05 12:16:47 +0100557
558void GetBackendPathsTestImpl()
559{
560 using namespace armnn;
561 using namespace boost::filesystem;
562
563 // The test covers four directories:
564 // <unit test path>/src/backends/backendsCommon/test/
Matteo Martincighe54aa062019-08-05 14:12:11 +0100565 // ├─ backendsTestPath1/ -> exists, contains files
566 // ├─ backendsTestPath2/ -> exists, contains files
567 // ├─ backendsTestPath3/ -> exists, but empty
568 // └─ backendsTestPath4/ -> does not exist
Matteo Martincighe7d44982019-08-05 12:16:47 +0100569
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100570 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
571 std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
572 std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
573 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100574
575 BOOST_CHECK(exists(subDir1));
576 BOOST_CHECK(exists(subDir2));
577 BOOST_CHECK(exists(subDir3));
578 BOOST_CHECK(!exists(subDir4));
579
Matteo Martincighe7d44982019-08-05 12:16:47 +0100580 // No path
581 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());
582
583 // Malformed path
584 std::string malformedDir(subDir1 + "/" + subDir1);
585 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(malformedDir).size()==0);
586
587 // Single valid path
588 std::vector<std::string> DynamicBackendPaths2 = TestDynamicBackendUtils::GetBackendPathsImplTest(subDir1);
589 BOOST_TEST(DynamicBackendPaths2.size() == 1);
590 BOOST_TEST(DynamicBackendPaths2[0] == subDir1);
591
592 // Multiple equal and valid paths
593 std::string multipleEqualDirs(subDir1 + ":" + subDir1);
594 std::vector<std::string> DynamicBackendPaths3 = TestDynamicBackendUtils::GetBackendPathsImplTest(multipleEqualDirs);
595 BOOST_TEST(DynamicBackendPaths3.size() == 1);
596 BOOST_TEST(DynamicBackendPaths3[0] == subDir1);
597
598 // Multiple empty paths
599 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(":::").empty());
600
601 // Multiple valid paths
602 std::string multipleValidPaths(subDir1 + ":" + subDir2 + ":" + subDir3);
603 std::vector<std::string> DynamicBackendPaths5 =
604 TestDynamicBackendUtils::GetBackendPathsImplTest(multipleValidPaths);
605 BOOST_TEST(DynamicBackendPaths5.size() == 3);
606 BOOST_TEST(DynamicBackendPaths5[0] == subDir1);
607 BOOST_TEST(DynamicBackendPaths5[1] == subDir2);
608 BOOST_TEST(DynamicBackendPaths5[2] == subDir3);
609
610 // Valid among empty paths
611 std::string validAmongEmptyDirs("::" + subDir1 + ":");
612 std::vector<std::string> DynamicBackendPaths6 =
613 TestDynamicBackendUtils::GetBackendPathsImplTest(validAmongEmptyDirs);
614 BOOST_TEST(DynamicBackendPaths6.size() == 1);
615 BOOST_TEST(DynamicBackendPaths6[0] == subDir1);
616
617 // Invalid among empty paths
618 std::string invalidAmongEmptyDirs(":" + subDir4 + "::");
619 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(invalidAmongEmptyDirs).empty());
620
621 // Valid, invalid and empty paths
622 std::string validInvalidEmptyDirs(subDir1 + ":" + subDir4 + ":");
623 std::vector<std::string> DynamicBackendPaths8 =
624 TestDynamicBackendUtils::GetBackendPathsImplTest(validInvalidEmptyDirs);
625 BOOST_TEST(DynamicBackendPaths8.size() == 1);
626 BOOST_TEST(DynamicBackendPaths8[0] == subDir1);
627
628 // Mix of duplicates of valid, invalid and empty paths
629 std::string duplicateValidInvalidEmptyDirs(validInvalidEmptyDirs + ":" + validInvalidEmptyDirs + ":" +
630 subDir2 + ":" + subDir2);
631 std::vector<std::string> DynamicBackendPaths9 =
632 TestDynamicBackendUtils::GetBackendPathsImplTest(duplicateValidInvalidEmptyDirs);
633 BOOST_TEST(DynamicBackendPaths9.size() == 2);
634 BOOST_TEST(DynamicBackendPaths9[0] == subDir1);
635 BOOST_TEST(DynamicBackendPaths9[1] == subDir2);
636}
637
638void GetBackendPathsOverrideTestImpl()
639{
640 using namespace armnn;
641 using namespace boost::filesystem;
642
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100643 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
644 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100645
646 BOOST_CHECK(exists(subDir1));
647 BOOST_CHECK(!exists(subDir4));
648
649 // Override with valid path
650 std::vector<std::string> validResult = DynamicBackendUtils::GetBackendPaths(subDir1);
651 BOOST_TEST(validResult.size() == 1);
652 BOOST_TEST(validResult[0] == subDir1);
653
654 // Override with invalid path
655 std::vector<std::string> invalidResult = DynamicBackendUtils::GetBackendPaths(subDir4);
656 BOOST_TEST(invalidResult.empty());
657}
Jan Eilers4a539fc2019-07-25 17:08:37 +0100658
659void GetSharedObjectsTestImpl()
660{
661 using namespace armnn;
662 using namespace boost::filesystem;
663
Matteo Martincighe54aa062019-08-05 14:12:11 +0100664 // The test covers four directories:
665 // <unit test path>/src/backends/backendsCommon/test/
666 // ├─ backendsTestPath1/ -> exists, contains files
667 // ├─ backendsTestPath2/ -> exists, contains files
668 // ├─ backendsTestPath3/ -> exists, but empty
669 // └─ backendsTestPath4/ -> does not exist
Jan Eilers4a539fc2019-07-25 17:08:37 +0100670 //
671 // The test sub-directory backendsTestPath1/ contains the following test files:
672 //
673 // Arm_GpuAcc_backend.so -> valid (basic backend name)
674 // Arm_GpuAcc_backend.so.1 -> valid (single field version number)
675 // Arm_GpuAcc_backend.so.1.2 -> valid (multiple field version number)
676 // Arm_GpuAcc_backend.so.1.2.3 -> valid (multiple field version number)
677 // Arm_GpuAcc_backend.so.10.1.27 -> valid (Multiple digit version)
678 // Arm_GpuAcc_backend.so.10.1.33. -> not valid (dot not followed by version number)
679 // Arm_GpuAcc_backend.so.3.4..5 -> not valid (dot not followed by version number)
680 // Arm_GpuAcc_backend.so.1,1.1 -> not valid (comma instead of dot in the version)
681 //
682 // Arm123_GpuAcc_backend.so -> valid (digits in vendor name are allowed)
683 // Arm_GpuAcc456_backend.so -> valid (digits in backend id are allowed)
684 // Arm%Co_GpuAcc_backend.so -> not valid (invalid character in vendor name)
685 // Arm_Gpu.Acc_backend.so -> not valid (invalid character in backend id)
686 //
687 // GpuAcc_backend.so -> not valid (missing vendor name)
688 // _GpuAcc_backend.so -> not valid (missing vendor name)
689 // Arm__backend.so -> not valid (missing backend id)
690 // Arm_GpuAcc.so -> not valid (missing "backend" at the end)
691 // __backend.so -> not valid (missing vendor name and backend id)
692 // __.so -> not valid (missing all fields)
693 //
694 // Arm_GpuAcc_backend -> not valid (missing at least ".so" at the end)
695 // Arm_GpuAcc_backend_v1.2.so -> not valid (extra version info at the end)
696 //
697 // The test sub-directory backendsTestPath1/ contains the following test files:
698 //
699 // Arm_CpuAcc_backend.so -> valid (basic backend name)
700 // Arm_CpuAcc_backend.so.1 -> Arm_CpuAcc_backend.so -> valid (symlink to valid backend file)
701 // Arm_CpuAcc_backend.so.1.2 -> Arm_CpuAcc_backend.so.1 -> valid (symlink to valid symlink)
702 // Arm_CpuAcc_backend.so.1.2.3 -> Arm_CpuAcc_backend.so.1.2 -> valid (symlink to valid symlink)
703 //
704 // Arm_no_backend.so -> nothing -> not valid (symlink resolves to non-existent file)
705 //
706 // Arm_GpuAcc_backend.so -> valid (but duplicated from backendsTestPath1/)
707
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100708 std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
709 std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
710 std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
711 std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Jan Eilers4a539fc2019-07-25 17:08:37 +0100712 BOOST_CHECK(exists(testDynamicBackendsSubDir1));
713 BOOST_CHECK(exists(testDynamicBackendsSubDir2));
714 BOOST_CHECK(exists(testDynamicBackendsSubDir3));
715 BOOST_CHECK(!exists(testDynamicBackendsSubDir4));
716
717 std::vector<std::string> backendPaths
718 {
719 testDynamicBackendsSubDir1,
720 testDynamicBackendsSubDir2,
721 testDynamicBackendsSubDir3,
722 testDynamicBackendsSubDir4
723 };
724 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100725 std::vector<std::string> expectedSharedObjects
Jan Eilers4a539fc2019-07-25 17:08:37 +0100726 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100727 testDynamicBackendsSubDir1 + "Arm123_GpuAcc_backend.so", // Digits in vendor name are allowed
728 testDynamicBackendsSubDir1 + "Arm_GpuAcc456_backend.so", // Digits in backend id are allowed
Jan Eilers4a539fc2019-07-25 17:08:37 +0100729 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so", // Basic backend name
730 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1", // Single field version number
731 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2", // Multiple field version number
732 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2.3", // Multiple field version number
733 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.10.1.27", // Multiple digit version
Jan Eilers4a539fc2019-07-25 17:08:37 +0100734 testDynamicBackendsSubDir2 + "Arm_CpuAcc_backend.so", // Duplicate symlinks removed
735 testDynamicBackendsSubDir2 + "Arm_GpuAcc_backend.so" // Duplicates on different paths are allowed
736 };
737
738 BOOST_TEST(sharedObjects.size() == expectedSharedObjects.size());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100739 BOOST_TEST(sharedObjects[0] == expectedSharedObjects[0]);
740 BOOST_TEST(sharedObjects[1] == expectedSharedObjects[1]);
741 BOOST_TEST(sharedObjects[2] == expectedSharedObjects[2]);
742 BOOST_TEST(sharedObjects[3] == expectedSharedObjects[3]);
743 BOOST_TEST(sharedObjects[4] == expectedSharedObjects[4]);
744 BOOST_TEST(sharedObjects[5] == expectedSharedObjects[5]);
745 BOOST_TEST(sharedObjects[6] == expectedSharedObjects[6]);
746 BOOST_TEST(sharedObjects[7] == expectedSharedObjects[7]);
747 BOOST_TEST(sharedObjects[8] == expectedSharedObjects[8]);
748}
749
750void CreateDynamicBackendsTestImpl()
751{
752 using namespace armnn;
753 using namespace boost::filesystem;
754
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100755 // The test covers four directories:
Matteo Martincighe54aa062019-08-05 14:12:11 +0100756 // <unit test path>/src/backends/backendsCommon/test/
757 // ├─ backendsTestPath5/ -> exists, contains files
758 // ├─ backendsTestPath6/ -> exists, contains files
759 // ├─ backendsTestPath7/ -> exists, but empty
760 // └─ backendsTestPath8/ -> does not exist
761 //
762 // The test sub-directory backendsTestPath5/ contains the following test files:
763 //
764 // Arm_TestValid2_backend.so -> valid (basic backend name)
765 // Arm_TestValid3_backend.so -> valid (basic backend name)
766 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
767 //
768 // The test sub-directory backendsTestPath6/ contains the following test files:
769 //
770 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
771 // Arm_TestValid4_backend.so -> valid (it has a different filename,
772 // but it has the same backend id of Arm_TestValid2_backend.so
773 // and the same version)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100774 // Arm_TestValid5_backend.so -> valid (basic backend name)
Matteo Martincighe54aa062019-08-05 14:12:11 +0100775 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
776 // but it has the same backend id of Arm_TestValid2_backend.so
777 // and a version incompatible with the Backend API)
778
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100779 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
780 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
781 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
782 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100783 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
784 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
785 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
786 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
787
788 std::vector<std::string> backendPaths
Jan Eilers4a539fc2019-07-25 17:08:37 +0100789 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100790 testDynamicBackendsSubDir5,
791 testDynamicBackendsSubDir6,
792 testDynamicBackendsSubDir7,
793 testDynamicBackendsSubDir8
794 };
795 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
796 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
797
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100798 BOOST_TEST(dynamicBackends.size() == 5);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100799 BOOST_TEST((dynamicBackends[0] != nullptr));
800 BOOST_TEST((dynamicBackends[1] != nullptr));
801 BOOST_TEST((dynamicBackends[2] != nullptr));
802 BOOST_TEST((dynamicBackends[3] != nullptr));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100803 BOOST_TEST((dynamicBackends[4] != nullptr));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100804
805 // Duplicates are allowed here, they will be skipped later during the backend registration
806 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
807 BOOST_TEST((dynamicBackends[1]->GetBackendId() == "TestValid3"));
808 BOOST_TEST((dynamicBackends[2]->GetBackendId() == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
809 BOOST_TEST((dynamicBackends[3]->GetBackendId() == "TestValid2")); // From Arm_TestValid4_backend.so
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100810 BOOST_TEST((dynamicBackends[4]->GetBackendId() == "TestValid5"));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100811}
812
813void CreateDynamicBackendsNoPathsTestImpl()
814{
815 using namespace armnn;
816
817 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends({});
818
819 BOOST_TEST(dynamicBackends.empty());
820}
821
822void CreateDynamicBackendsAllInvalidTestImpl()
823{
824 using namespace armnn;
825
826 std::vector<std::string> sharedObjects
827 {
828 "InvalidSharedObject1",
829 "InvalidSharedObject2",
830 "InvalidSharedObject3",
831 };
832 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
833
834 BOOST_TEST(dynamicBackends.empty());
835}
836
837void CreateDynamicBackendsMixedTypesTestImpl()
838{
839 using namespace armnn;
840 using namespace boost::filesystem;
841
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100842 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
843 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100844 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
845 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
846
847 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
848 g_TestValidBackend2FileName);
849 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
850 g_TestInvalidBackend8FileName);
851 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
852 g_TestInvalidBackend9FileName);
853 BOOST_CHECK(exists(testValidBackend2FilePath));
854 BOOST_CHECK(exists(testInvalidBackend8FilePath));
855 BOOST_CHECK(exists(testInvalidBackend9FilePath));
856
857 std::vector<std::string> sharedObjects
858 {
859 testValidBackend2FilePath, // Arm_TestValid2_backend.so -> valid (basic backend name)
860 testInvalidBackend8FilePath, // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
861 testInvalidBackend9FilePath, // Arm_TestInvalid9_backend.so -> not valid (incompatible version)
862 "InvalidSharedObject", // The file does not exist
863 };
864 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
865
866 BOOST_TEST(dynamicBackends.size() == 1);
867 BOOST_TEST((dynamicBackends[0] != nullptr));
868 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
Jan Eilers4a539fc2019-07-25 17:08:37 +0100869}
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100870
871void RegisterSingleDynamicBackendTestImpl()
872{
873 using namespace armnn;
874 using namespace boost::filesystem;
875
876 // Register one valid dynamic backend
877
878 // Dummy registry used for testing
879 BackendRegistry backendRegistry;
880 BOOST_TEST(backendRegistry.Size() == 0);
881
882 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
883 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
884
885 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
886 BOOST_CHECK(exists(testValidBackend2FilePath));
887
888 std::vector<std::string> sharedObjects{ testValidBackend2FilePath };
889 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
890
891 BOOST_TEST(dynamicBackends.size() == 1);
892 BOOST_TEST((dynamicBackends[0] != nullptr));
893
894 BackendId dynamicBackendId = dynamicBackends[0]->GetBackendId();
895 BOOST_TEST((dynamicBackendId == "TestValid2"));
896
897 BackendVersion dynamicBackendVersion = dynamicBackends[0]->GetBackendVersion();
898 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
899
Matteo Martincigh89533902019-08-15 12:08:06 +0100900 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
901 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100902 BOOST_TEST(backendRegistry.Size() == 1);
Matteo Martincigh89533902019-08-15 12:08:06 +0100903 BOOST_TEST(registeredBackendIds.size() == 1);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100904
905 BackendIdSet backendIds = backendRegistry.GetBackendIds();
906 BOOST_TEST(backendIds.size() == 1);
907 BOOST_TEST((backendIds.find(dynamicBackendId) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +0100908 BOOST_TEST((registeredBackendIds.find(dynamicBackendId) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100909
910 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
911 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
912
913 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
914 BOOST_TEST((dynamicBackend != nullptr));
915 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
916}
917
918void RegisterMultipleDynamicBackendsTestImpl()
919{
920 using namespace armnn;
921 using namespace boost::filesystem;
922
923 // Register many valid dynamic backends
924
925 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
926 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
927 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
928 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
929
930 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
931 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
932 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
933 BOOST_CHECK(exists(testValidBackend2FilePath));
934 BOOST_CHECK(exists(testValidBackend3FilePath));
935 BOOST_CHECK(exists(testValidBackend5FilePath));
936
937 std::vector<std::string> sharedObjects
938 {
939 testValidBackend2FilePath,
940 testValidBackend3FilePath,
941 testValidBackend5FilePath
942 };
943 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
944
945 BOOST_TEST(dynamicBackends.size() == 3);
946 BOOST_TEST((dynamicBackends[0] != nullptr));
947 BOOST_TEST((dynamicBackends[1] != nullptr));
948 BOOST_TEST((dynamicBackends[2] != nullptr));
949
950 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
951 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
952 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
953 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
954 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
955 BOOST_TEST((dynamicBackendId3 == "TestValid5"));
956
957 for (size_t i = 0; i < dynamicBackends.size(); i++)
958 {
959 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
960 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
961 }
962
963 // Dummy registry used for testing
964 BackendRegistry backendRegistry;
965 BOOST_TEST(backendRegistry.Size() == 0);
966
Matteo Martincigh89533902019-08-15 12:08:06 +0100967 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
968 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100969 BOOST_TEST(backendRegistry.Size() == 3);
Matteo Martincigh89533902019-08-15 12:08:06 +0100970 BOOST_TEST(registeredBackendIds.size() == 3);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100971
972 BackendIdSet backendIds = backendRegistry.GetBackendIds();
973 BOOST_TEST(backendIds.size() == 3);
974 BOOST_TEST((backendIds.find(dynamicBackendId1) != backendIds.end()));
975 BOOST_TEST((backendIds.find(dynamicBackendId2) != backendIds.end()));
976 BOOST_TEST((backendIds.find(dynamicBackendId3) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +0100977 BOOST_TEST((registeredBackendIds.find(dynamicBackendId1) != registeredBackendIds.end()));
978 BOOST_TEST((registeredBackendIds.find(dynamicBackendId2) != registeredBackendIds.end()));
979 BOOST_TEST((registeredBackendIds.find(dynamicBackendId3) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100980
981 for (size_t i = 0; i < dynamicBackends.size(); i++)
982 {
983 BackendId dynamicBackendId = dynamicBackends[i]->GetBackendId();
984
985 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
986 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
987
988 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
989 BOOST_TEST((dynamicBackend != nullptr));
990 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
991 }
992}
993
994void RegisterMultipleInvalidDynamicBackendsTestImpl()
995{
996 using namespace armnn;
997 using namespace boost::filesystem;
998
999 // Try to register many invalid dynamic backends
1000
1001 // The test covers one directory:
1002 // <unit test path>/src/backends/backendsCommon/test/
1003 // └─ backendsTestPath9/ -> exists, contains files
1004 //
1005 // The test sub-directory backendsTestPath9/ contains the following test files:
1006 //
1007 // Arm_TestInvalid10_backend.so -> not valid (invalid backend id)
1008 // Arm_TestInvalid11_backend.so -> not valid (invalid backend id)
1009
1010 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1011 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1012
1013 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1014 g_TestInvalidBackend10FileName);
1015 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1016 g_TestInvalidBackend11FileName);
1017 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1018 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1019
1020 std::vector<std::string> sharedObjects
1021 {
1022 testInvalidBackend10FilePath,
1023 testInvalidBackend11FilePath,
1024 "InvalidSharedObject"
1025 };
1026 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1027
1028 BOOST_TEST(dynamicBackends.size() == 2);
1029 BOOST_TEST((dynamicBackends[0] != nullptr));
1030 BOOST_TEST((dynamicBackends[1] != nullptr));
1031
1032 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1033 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1034 BOOST_TEST((dynamicBackendId1 == ""));
1035 BOOST_TEST((dynamicBackendId2 == "Unknown"));
1036
1037 for (size_t i = 0; i < dynamicBackends.size(); i++)
1038 {
1039 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1040 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1041 }
1042
1043 // Dummy registry used for testing
1044 BackendRegistry backendRegistry;
1045 BOOST_TEST(backendRegistry.Size() == 0);
1046
1047 // Check that no dynamic backend got registered
Matteo Martincigh89533902019-08-15 12:08:06 +01001048 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1049 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001050 BOOST_TEST(backendRegistry.Size() == 0);
Matteo Martincigh89533902019-08-15 12:08:06 +01001051 BOOST_TEST(registeredBackendIds.empty());
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001052}
1053
1054void RegisterMixedDynamicBackendsTestImpl()
1055{
1056 using namespace armnn;
1057 using namespace boost::filesystem;
1058
1059 // The test covers five directories:
1060 // <unit test path>/src/backends/backendsCommon/test/
1061 // ├─ backendsTestPath5/ -> exists, contains files
1062 // ├─ backendsTestPath6/ -> exists, contains files
1063 // ├─ backendsTestPath7/ -> exists, but empty
1064 // ├─ backendsTestPath8/ -> does not exist
1065 // └─ backendsTestPath9/ -> exists, contains files
1066 //
1067 // The test sub-directory backendsTestPath5/ contains the following test files:
1068 //
1069 // Arm_TestValid2_backend.so -> valid (basic backend name)
1070 // Arm_TestValid3_backend.so -> valid (basic backend name)
1071 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
1072 //
1073 // The test sub-directory backendsTestPath6/ contains the following test files:
1074 //
1075 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
1076 // Arm_TestValid4_backend.so -> valid (it has a different filename,
1077 // but it has the same backend id of Arm_TestValid2_backend.so
1078 // and the same version)
1079 // Arm_TestValid5_backend.so -> valid (basic backend name)
1080 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
1081 // but it has the same backend id of Arm_TestValid2_backend.so
1082 // and a version incompatible with the Backend API)
1083 //
1084 // The test sub-directory backendsTestPath9/ contains the following test files:
1085 //
1086 // Arm_TestInvalid10_backend.so -> not valid (empty backend id)
1087 // Arm_TestInvalid11_backend.so -> not valid ("Unknown" backend id)
1088
1089 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1090 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1091 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
1092 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
1093 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1094 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1095 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1096 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
1097 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
1098 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1099
1100 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
1101 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
1102 std::string testValidBackend2DupFilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend2FileName);
1103 std::string testValidBackend4FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend4FileName);
1104 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
1105 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
1106 g_TestInvalidBackend8FileName);
1107 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
1108 g_TestInvalidBackend9FileName);
1109 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1110 g_TestInvalidBackend10FileName);
1111 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1112 g_TestInvalidBackend11FileName);
1113 BOOST_CHECK(exists(testValidBackend2FilePath));
1114 BOOST_CHECK(exists(testValidBackend3FilePath));
1115 BOOST_CHECK(exists(testValidBackend2DupFilePath));
1116 BOOST_CHECK(exists(testValidBackend4FilePath));
1117 BOOST_CHECK(exists(testValidBackend5FilePath));
1118 BOOST_CHECK(exists(testInvalidBackend8FilePath));
1119 BOOST_CHECK(exists(testInvalidBackend9FilePath));
1120 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1121 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1122
1123 std::vector<std::string> sharedObjects
1124 {
1125 testValidBackend2FilePath,
1126 testValidBackend3FilePath,
1127 testValidBackend2DupFilePath,
1128 testValidBackend4FilePath,
1129 testValidBackend5FilePath,
1130 testInvalidBackend8FilePath,
1131 testInvalidBackend9FilePath,
1132 testInvalidBackend10FilePath,
1133 testInvalidBackend11FilePath,
1134 "InvalidSharedObject"
1135 };
1136 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1137
1138 BOOST_TEST(dynamicBackends.size() == 7);
1139 BOOST_TEST((dynamicBackends[0] != nullptr));
1140 BOOST_TEST((dynamicBackends[1] != nullptr));
1141 BOOST_TEST((dynamicBackends[2] != nullptr));
1142 BOOST_TEST((dynamicBackends[3] != nullptr));
1143 BOOST_TEST((dynamicBackends[4] != nullptr));
1144 BOOST_TEST((dynamicBackends[5] != nullptr));
1145 BOOST_TEST((dynamicBackends[6] != nullptr));
1146
1147 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1148 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1149 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
1150 BackendId dynamicBackendId4 = dynamicBackends[3]->GetBackendId();
1151 BackendId dynamicBackendId5 = dynamicBackends[4]->GetBackendId();
1152 BackendId dynamicBackendId6 = dynamicBackends[5]->GetBackendId();
1153 BackendId dynamicBackendId7 = dynamicBackends[6]->GetBackendId();
1154 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
1155 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
1156 BOOST_TEST((dynamicBackendId3 == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
1157 BOOST_TEST((dynamicBackendId4 == "TestValid2")); // From Arm_TestValid4_backend.so
1158 BOOST_TEST((dynamicBackendId5 == "TestValid5"));
1159 BOOST_TEST((dynamicBackendId6 == ""));
1160 BOOST_TEST((dynamicBackendId7 == "Unknown"));
1161
1162 for (size_t i = 0; i < dynamicBackends.size(); i++)
1163 {
1164 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1165 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1166 }
1167
1168 // Dummy registry used for testing
1169 BackendRegistry backendRegistry;
1170 BOOST_TEST(backendRegistry.Size() == 0);
1171
1172 std::vector<BackendId> expectedRegisteredbackendIds
1173 {
1174 "TestValid2",
1175 "TestValid3",
1176 "TestValid5"
1177 };
1178
Matteo Martincigh89533902019-08-15 12:08:06 +01001179 BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1180 dynamicBackends);
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001181 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
Matteo Martincigh89533902019-08-15 12:08:06 +01001182 BOOST_TEST(registeredBackendIds.size() == expectedRegisteredbackendIds.size());
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001183
1184 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1185 BOOST_TEST(backendIds.size() == expectedRegisteredbackendIds.size());
1186 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1187 {
1188 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
Matteo Martincigh89533902019-08-15 12:08:06 +01001189 BOOST_TEST((registeredBackendIds.find(expectedRegisteredbackendId) != registeredBackendIds.end()));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +01001190
1191 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(expectedRegisteredbackendId);
1192 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
1193
1194 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
1195 BOOST_TEST((dynamicBackend != nullptr));
1196 BOOST_TEST((dynamicBackend->GetId() == expectedRegisteredbackendId));
1197 }
1198}
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001199
1200void RuntimeEmptyTestImpl()
1201{
1202 using namespace armnn;
1203
1204 // Swapping the backend registry storage for testing
1205 TestBackendRegistry testBackendRegistry;
1206
Matteo Martincigh89533902019-08-15 12:08:06 +01001207 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1208 BOOST_TEST(backendRegistry.Size() == 0);
1209
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001210 IRuntime::CreationOptions creationOptions;
1211 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1212
Matteo Martincigh89533902019-08-15 12:08:06 +01001213 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1214 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1215 BOOST_TEST(supportedBackendIds.empty());
1216
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001217 BOOST_TEST(backendRegistry.Size() == 0);
1218}
1219
1220void RuntimeDynamicBackendsTestImpl()
1221{
1222 using namespace armnn;
1223 using namespace boost::filesystem;
1224
1225 // Swapping the backend registry storage for testing
1226 TestBackendRegistry testBackendRegistry;
1227
1228 // This directory contains valid and invalid backends
1229 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1230 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1231
1232 // Using the path override in CreationOptions to load some test dynamic backends
1233 IRuntime::CreationOptions creationOptions;
1234 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir5;
1235 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1236
1237 std::vector<BackendId> expectedRegisteredbackendIds
1238 {
1239 "TestValid2",
1240 "TestValid3"
1241 };
1242
1243 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1244 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1245
1246 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1247 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1248 {
1249 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1250 }
Matteo Martincigh89533902019-08-15 12:08:06 +01001251
1252 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1253 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1254 BOOST_TEST(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
1255 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1256 {
1257 BOOST_TEST((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
1258 }
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001259}
1260
1261void RuntimeDuplicateDynamicBackendsTestImpl()
1262{
1263 using namespace armnn;
1264 using namespace boost::filesystem;
1265
1266 // Swapping the backend registry storage for testing
1267 TestBackendRegistry testBackendRegistry;
1268
1269 // This directory contains valid, invalid and duplicate backends
1270 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1271 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1272
1273 // Using the path override in CreationOptions to load some test dynamic backends
1274 IRuntime::CreationOptions creationOptions;
1275 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir6;
1276 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1277
1278 std::vector<BackendId> expectedRegisteredbackendIds
1279 {
1280 "TestValid2",
1281 "TestValid5"
1282 };
1283
1284 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1285 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1286
1287 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1288 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1289 {
1290 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1291 }
Matteo Martincigh89533902019-08-15 12:08:06 +01001292
1293 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1294 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1295 BOOST_TEST(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
1296 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1297 {
1298 BOOST_TEST((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
1299 }
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001300}
1301
1302void RuntimeInvalidDynamicBackendsTestImpl()
1303{
1304 using namespace armnn;
1305 using namespace boost::filesystem;
1306
1307 // Swapping the backend registry storage for testing
1308 TestBackendRegistry testBackendRegistry;
1309
1310 // This directory contains only invalid backends
1311 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1312 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1313
1314 // Using the path override in CreationOptions to load some test dynamic backends
1315 IRuntime::CreationOptions creationOptions;
1316 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir9;
1317 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1318
1319 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1320 BOOST_TEST(backendRegistry.Size() == 0);
Matteo Martincigh89533902019-08-15 12:08:06 +01001321
1322 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1323 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1324 BOOST_TEST(supportedBackendIds.empty());
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001325}
1326
1327void RuntimeInvalidOverridePathTestImpl()
1328{
1329 using namespace armnn;
1330
1331 // Swapping the backend registry storage for testing
1332 TestBackendRegistry testBackendRegistry;
1333
1334 // Using the path override in CreationOptions to load some test dynamic backends
1335 IRuntime::CreationOptions creationOptions;
1336 creationOptions.m_DynamicBackendsPath = "InvalidPath";
1337 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1338
1339 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1340 BOOST_TEST(backendRegistry.Size() == 0);
Matteo Martincigh89533902019-08-15 12:08:06 +01001341
1342 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1343 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1344 BOOST_TEST(supportedBackendIds.empty());
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001345}
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001346
1347void CreateReferenceDynamicBackendTestImpl()
1348{
1349 using namespace armnn;
1350 using namespace boost::filesystem;
1351
1352 // Swapping the backend registry storage for testing
1353 TestBackendRegistry testBackendRegistry;
1354
1355 // This directory contains the reference dynamic backend
1356 std::string dynamicBackendsBaseDir = GetDynamicBackendsBasePath();
1357 std::string referenceDynamicBackendSubDir = GetTestSubDirectory(dynamicBackendsBaseDir,
1358 g_ReferenceDynamicBackendSubDir);
1359 BOOST_CHECK(exists(referenceDynamicBackendSubDir));
1360
1361 // Check that the reference dynamic backend file exists
1362 std::string referenceBackendFilePath = GetTestFilePath(referenceDynamicBackendSubDir,
1363 g_ReferenceBackendFileName);
1364 BOOST_CHECK(exists(referenceBackendFilePath));
1365
1366 // Using the path override in CreationOptions to load the reference dynamic backend
1367 IRuntime::CreationOptions creationOptions;
1368 creationOptions.m_DynamicBackendsPath = referenceDynamicBackendSubDir;
1369 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1370
1371 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1372 BOOST_TEST(backendRegistry.Size() == 1);
1373
1374 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1375 BOOST_TEST((backendIds.find("CpuRef") != backendIds.end()));
1376
Matteo Martincigh89533902019-08-15 12:08:06 +01001377 const DeviceSpec& deviceSpec = *boost::polymorphic_downcast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1378 BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1379 BOOST_TEST(supportedBackendIds.size() == 1);
1380 BOOST_TEST((supportedBackendIds.find("CpuRef") != supportedBackendIds.end()));
1381
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001382 // Get the factory function
1383 auto referenceDynamicBackendFactoryFunction = backendRegistry.GetFactory("CpuRef");
1384 BOOST_TEST((referenceDynamicBackendFactoryFunction != nullptr));
1385
1386 // Use the factory function to create an instance of the reference backend
1387 IBackendInternalUniquePtr referenceDynamicBackend = referenceDynamicBackendFactoryFunction();
1388 BOOST_TEST((referenceDynamicBackend != nullptr));
1389 BOOST_TEST((referenceDynamicBackend->GetId() == "CpuRef"));
1390
1391 // Test the backend instance by querying the layer support
1392 IBackendInternal::ILayerSupportSharedPtr referenceLayerSupport = referenceDynamicBackend->GetLayerSupport();
1393 BOOST_TEST((referenceLayerSupport != nullptr));
1394
1395 TensorShape inputShape { 1, 16, 16, 16 };
1396 TensorShape outputShape{ 1, 16, 16, 16 };
1397 TensorShape weightShape{ 16, 1, 1, 16 };
1398 TensorInfo inputInfo (inputShape, DataType::Float32);
1399 TensorInfo outputInfo(outputShape, DataType::Float32);
1400 TensorInfo weightInfo(weightShape, DataType::Float32);
1401 Convolution2dDescriptor convolution2dDescriptor;
1402 bool referenceConvolution2dSupported =
1403 referenceLayerSupport->IsConvolution2dSupported(inputInfo,
1404 outputInfo,
1405 convolution2dDescriptor,
1406 weightInfo,
1407 EmptyOptional());
1408 BOOST_TEST(referenceConvolution2dSupported);
1409
1410 // Test the backend instance by creating a workload
1411 IBackendInternal::IWorkloadFactoryPtr referenceWorkloadFactory = referenceDynamicBackend->CreateWorkloadFactory();
1412 BOOST_TEST((referenceWorkloadFactory != nullptr));
1413
1414 // Create dummy settings for the workload
1415 Convolution2dQueueDescriptor convolution2dQueueDescriptor;
1416 WorkloadInfo workloadInfo
1417 {
1418 { inputInfo },
1419 { outputInfo }
1420 };
1421 convolution2dQueueDescriptor.m_Inputs.push_back(nullptr);
1422 auto weights = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
1423 convolution2dQueueDescriptor.m_Weight = weights.get();
1424
1425 // Create a convolution workload with the dummy settings
1426 auto workload = referenceWorkloadFactory->CreateConvolution2d(convolution2dQueueDescriptor, workloadInfo);
1427 BOOST_TEST((workload != nullptr));
1428 BOOST_TEST(workload.get() == boost::polymorphic_downcast<RefConvolution2dWorkload*>(workload.get()));
1429}