blob: 74ef6f1ba7841b26bf81329c4e76a78d9a8eaccf [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
82 static void RegisterDynamicBackendsImplTest(armnn::BackendRegistry& backendRegistry,
83 const std::vector<armnn::DynamicBackendPtr>& dynamicBackends)
84 {
85 RegisterDynamicBackendsImpl(backendRegistry, dynamicBackends);
86 }
87};
Matteo Martincighe7d44982019-08-05 12:16:47 +010088
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +010089// BackendRegistry wrapper class used for testing (swaps the underlying factory storage)
90class TestBackendRegistry : public armnn::BackendRegistry
91{
92public:
93 TestBackendRegistry() : armnn::BackendRegistry()
94 {
95 Swap(armnn::BackendRegistryInstance(), m_TempStorage);
96 }
97
98 ~TestBackendRegistry()
99 {
100 Swap(armnn::BackendRegistryInstance(), m_TempStorage);
101 }
102
103private:
104 FactoryStorage m_TempStorage;
105};
106
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100107std::string GetBasePath(const std::string& basePath)
Matteo Martincigh986c1862019-07-26 15:12:47 +0100108{
109 using namespace boost::filesystem;
110
Matteo Martincigha77d80e2019-07-31 11:05:16 +0100111 path programLocation = boost::dll::program_location().parent_path();
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100112 path sharedObjectPath = programLocation.append(basePath);
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100113 BOOST_CHECK(exists(sharedObjectPath));
Matteo Martincigh986c1862019-07-26 15:12:47 +0100114
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100115 return sharedObjectPath.string();
116}
117
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100118std::string GetTestDirectoryBasePath()
119{
120 return GetBasePath(g_TestBaseDir);
121}
122
123std::string GetDynamicBackendsBasePath()
124{
125 return GetBasePath(g_DynamicBackendsBaseDir);
126}
127
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100128std::string GetTestSubDirectory(const std::string& subdir)
129{
130 using namespace boost::filesystem;
131
132 std::string testDynamicBackendsBaseDir = GetTestDirectoryBasePath();
133 path testDynamicBackendsBasePath(testDynamicBackendsBaseDir);
134 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
135 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
136
137 return testDynamicBackendsSubDir.string();
138}
139
Matteo Martincigh4e73b422019-08-08 13:46:32 +0100140std::string GetTestSubDirectory(const std::string& basePath, const std::string& subdir)
141{
142 using namespace boost::filesystem;
143
144 path testDynamicBackendsBasePath(basePath);
145 path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
146 // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
147
148 return testDynamicBackendsSubDir.string();
149}
150
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100151std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
152{
153 using namespace boost::filesystem;
154
155 path directoryPath(directory);
156 path fileNamePath = directoryPath.append(fileName);
157 BOOST_CHECK(exists(fileNamePath));
158
159 return fileNamePath.string();
Matteo Martincigh986c1862019-07-26 15:12:47 +0100160}
161
162void OpenCloseHandleTestImpl()
163{
164 using namespace armnn;
165
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100166 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
167 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100168
169 void* sharedObjectHandle = nullptr;
170 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
171 BOOST_TEST((sharedObjectHandle != nullptr));
172
173 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
174}
175
176void CloseInvalidHandleTestImpl()
177{
178 using namespace armnn;
179
180 // This calls must silently handle invalid handles and complete successfully (no segfaults, etc.)
181 DynamicBackendUtils::CloseHandle(nullptr);
182}
183
184void OpenEmptyFileNameTestImpl()
185{
186 using namespace armnn;
187
188 void* sharedObjectHandle = nullptr;
189 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(""), RuntimeException);
190 BOOST_TEST((sharedObjectHandle == nullptr));
191}
192
193void OpenNotExistingFileTestImpl()
194{
195 using namespace armnn;
196
197 void* sharedObjectHandle = nullptr;
198 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle("NotExistingFileName"), RuntimeException);
199 BOOST_TEST((sharedObjectHandle == nullptr));
200}
201
202void OpenNotSharedObjectTestImpl()
203{
204 using namespace armnn;
205
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100206 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
207 std::string notSharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestNoSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100208
209 void* sharedObjectHandle = nullptr;
210 BOOST_CHECK_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(notSharedObjectFilePath), RuntimeException);
211 BOOST_TEST((sharedObjectHandle == nullptr));
212}
213
214void GetValidEntryPointTestImpl()
215{
216 using namespace armnn;
217
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100218 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
219 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100220
221 void* sharedObjectHandle = nullptr;
222 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
223 BOOST_TEST((sharedObjectHandle != nullptr));
224
225 using TestFunctionType = int(*)(int);
226 TestFunctionType testFunctionPointer = nullptr;
227 BOOST_CHECK_NO_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
228 "TestFunction1"));
229 BOOST_TEST((testFunctionPointer != nullptr));
230 BOOST_TEST(testFunctionPointer(7) == 7);
231
232 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
233}
234
235void GetNameMangledEntryPointTestImpl()
236{
237 using namespace armnn;
238
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100239 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
240 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100241
242 void* sharedObjectHandle = nullptr;
243 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
244 BOOST_TEST((sharedObjectHandle != nullptr));
245
246 using TestFunctionType = int(*)(int);
247 TestFunctionType testFunctionPointer = nullptr;
248 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
249 "TestFunction2"),
250 RuntimeException);
251 BOOST_TEST((testFunctionPointer == nullptr));
252
253 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
254}
255
256void GetNoExternEntryPointTestImpl()
257{
258 using namespace armnn;
259
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100260 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
261 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100262
263 void* sharedObjectHandle = nullptr;
264 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
265 BOOST_TEST((sharedObjectHandle != nullptr));
266
267 using TestFunctionType = int(*)(int);
268 TestFunctionType testFunctionPointer = nullptr;
269 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
270 "TestFunction3"),
271 RuntimeException);
272 BOOST_TEST((testFunctionPointer == nullptr));
273
274 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
275}
276
277void GetNotExistingEntryPointTestImpl()
278{
279 using namespace armnn;
280
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100281 std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
282 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
Matteo Martincigh986c1862019-07-26 15:12:47 +0100283
284 void* sharedObjectHandle = nullptr;
285 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
286 BOOST_TEST((sharedObjectHandle != nullptr));
287
288 using TestFunctionType = int(*)(int);
289 TestFunctionType testFunctionPointer = nullptr;
290 BOOST_CHECK_THROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
291 "TestFunction4"),
292 RuntimeException);
293 BOOST_TEST((testFunctionPointer == nullptr));
294
295 DynamicBackendUtils::CloseHandle(sharedObjectHandle);
296}
Matteo Martincighac60d282019-07-25 15:25:44 +0100297
298void BackendVersioningTestImpl()
299{
Matteo Martincigh986c1862019-07-26 15:12:47 +0100300 using namespace armnn;
301
Matteo Martincighac60d282019-07-25 15:25:44 +0100302 // The backend API version used for the tests
Matteo Martincigh986c1862019-07-26 15:12:47 +0100303 BackendVersion backendApiVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100304
305 // Same backend and backend API versions are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100306 BackendVersion sameBackendVersion{ 2, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100307 BOOST_TEST(sameBackendVersion == backendApiVersion);
308 BOOST_TEST(sameBackendVersion <= backendApiVersion);
309 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true);
310
311 // Backend versions that differ from the backend API version by major revision are not compatible
312 // with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100313 BackendVersion laterMajorBackendVersion{ 3, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100314 BOOST_TEST(!(laterMajorBackendVersion == backendApiVersion));
315 BOOST_TEST(!(laterMajorBackendVersion <= backendApiVersion));
316 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false);
317
Matteo Martincigh986c1862019-07-26 15:12:47 +0100318 BackendVersion earlierMajorBackendVersion{ 1, 4 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100319 BOOST_TEST(!(earlierMajorBackendVersion == backendApiVersion));
320 BOOST_TEST(earlierMajorBackendVersion <= backendApiVersion);
321 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion,
322 earlierMajorBackendVersion) == false);
323
324 // Backend versions with the same major revision but later minor revision than
325 // the backend API version are not compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100326 BackendVersion laterMinorBackendVersion{ 2, 5 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100327 BOOST_TEST(!(laterMinorBackendVersion == backendApiVersion));
328 BOOST_TEST(!(laterMinorBackendVersion <= backendApiVersion));
329 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false);
330
331 // Backend versions with the same major revision but earlier minor revision than
332 // the backend API version are compatible with the backend API
Matteo Martincigh986c1862019-07-26 15:12:47 +0100333 BackendVersion earlierMinorBackendVersion{ 2, 3 };
Matteo Martincighac60d282019-07-25 15:25:44 +0100334 BOOST_TEST(!(earlierMinorBackendVersion == backendApiVersion));
335 BOOST_TEST(earlierMinorBackendVersion <= backendApiVersion);
336 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
337}
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100338
339void CreateValidDynamicBackendObjectTestImpl()
340{
341 // Valid shared object handle
342 // Correct name mangling
343 // Correct interface
344 // Correct backend implementation
345
346 using namespace armnn;
347
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100348 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
349 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestValidTestDynamicBackendFileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100350
351 void* sharedObjectHandle = nullptr;
352 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
353 BOOST_TEST((sharedObjectHandle != nullptr));
354
Matteo Martincighe54aa062019-08-05 14:12:11 +0100355 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100356 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
357 BOOST_TEST((dynamicBackend != nullptr));
358
359 BackendId dynamicBackendId;
360 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
361 BOOST_TEST((dynamicBackendId == "ValidTestDynamicBackend"));
362
363 BackendVersion dynamicBackendVersion;
364 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100365 BOOST_TEST((dynamicBackendVersion == IBackendInternal::GetApiVersion()));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100366
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100367 IBackendInternalUniquePtr dynamicBackendInstance1;
368 BOOST_CHECK_NO_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend());
369 BOOST_TEST((dynamicBackendInstance1 != nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100370
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100371 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
372 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
373 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
374
375 IBackendInternalUniquePtr dynamicBackendInstance2;
376 BOOST_CHECK_NO_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction());
377 BOOST_TEST((dynamicBackendInstance2 != nullptr));
378
379 BOOST_TEST((dynamicBackendInstance1->GetId() == "ValidTestDynamicBackend"));
380 BOOST_TEST((dynamicBackendInstance2->GetId() == "ValidTestDynamicBackend"));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100381}
382
383void CreateDynamicBackendObjectInvalidHandleTestImpl()
384{
385 // Invalid (null) shared object handle
386
387 using namespace armnn;
388
389 void* sharedObjectHandle = nullptr;
Matteo Martincighe54aa062019-08-05 14:12:11 +0100390 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100391 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
392 BOOST_TEST((dynamicBackend == nullptr));
393}
394
395void CreateDynamicBackendObjectInvalidInterface1TestImpl()
396{
397 // Valid shared object handle
398 // Wrong (not C-style) name mangling
399
400 using namespace armnn;
401
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100402 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
403 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend1FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100404
405 void* sharedObjectHandle = nullptr;
406 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
407 BOOST_TEST((sharedObjectHandle != nullptr));
408
Matteo Martincighe54aa062019-08-05 14:12:11 +0100409 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100410 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
411 BOOST_TEST((dynamicBackend == nullptr));
412}
413
414void CreateDynamicBackendObjectInvalidInterface2TestImpl()
415{
416 // Valid shared object handle
417 // Correct name mangling
418 // Wrong interface (missing GetBackendId())
419
420 using namespace armnn;
421
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100422 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
423 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend2FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100424
425 void* sharedObjectHandle = nullptr;
426 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
427 BOOST_TEST((sharedObjectHandle != nullptr));
428
Matteo Martincighe54aa062019-08-05 14:12:11 +0100429 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100430 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
431 BOOST_TEST((dynamicBackend == nullptr));
432}
433
434void CreateDynamicBackendObjectInvalidInterface3TestImpl()
435{
436 // Valid shared object handle
437 // Correct name mangling
438 // Wrong interface (missing GetVersion())
439
440 using namespace armnn;
441
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100442 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
443 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend3FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100444
445 void* sharedObjectHandle = nullptr;
446 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
447 BOOST_TEST((sharedObjectHandle != nullptr));
448
Matteo Martincighe54aa062019-08-05 14:12:11 +0100449 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100450 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
451 BOOST_TEST((dynamicBackend == nullptr));
452}
453
454void CreateDynamicBackendObjectInvalidInterface4TestImpl()
455{
456 // Valid shared object handle
457 // Correct name mangling
458 // Wrong interface (missing BackendFactory())
459
460 using namespace armnn;
461
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100462 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
463 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend4FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100464
465 void* sharedObjectHandle = nullptr;
466 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
467 BOOST_TEST((sharedObjectHandle != nullptr));
468
Matteo Martincighe54aa062019-08-05 14:12:11 +0100469 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100470 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
471 BOOST_TEST((dynamicBackend == nullptr));
472}
473
474void CreateDynamicBackendObjectInvalidInterface5TestImpl()
475{
476 // Valid shared object handle
477 // Correct name mangling
478 // Correct interface
479 // Invalid (null) backend id returned by GetBackendId()
480
481 using namespace armnn;
482
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100483 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
484 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend5FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100485
486 void* sharedObjectHandle = nullptr;
487 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
488 BOOST_TEST((sharedObjectHandle != nullptr));
489
Matteo Martincighe54aa062019-08-05 14:12:11 +0100490 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100491 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
492 BOOST_TEST((dynamicBackend == nullptr));
493}
494
495void CreateDynamicBackendObjectInvalidInterface6TestImpl()
496{
497 // Valid shared object handle
498 // Correct name mangling
499 // Correct interface
500 // Invalid (null) backend instance returned by BackendFactory()
501
502 using namespace armnn;
503
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100504 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
505 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend6FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100506
507 void* sharedObjectHandle = nullptr;
508 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
509 BOOST_TEST((sharedObjectHandle != nullptr));
510
Matteo Martincighe54aa062019-08-05 14:12:11 +0100511 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100512 BOOST_CHECK_NO_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
513 BOOST_TEST((dynamicBackend != nullptr));
514
515 BackendId dynamicBackendId;
516 BOOST_CHECK_NO_THROW(dynamicBackendId = dynamicBackend->GetBackendId());
517 BOOST_TEST((dynamicBackendId == "InvalidTestDynamicBackend"));
518
519 BackendVersion dynamicBackendVersion;
520 BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
521 BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
522
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100523 IBackendInternalUniquePtr dynamicBackendInstance1;
524 BOOST_CHECK_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException);
525 BOOST_TEST((dynamicBackendInstance1 == nullptr));
526
527 BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
528 BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
529 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
530
531 IBackendInternalUniquePtr dynamicBackendInstance2;
532 BOOST_CHECK_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction(), RuntimeException);
533 BOOST_TEST((dynamicBackendInstance2 == nullptr));
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100534}
535
536void CreateDynamicBackendObjectInvalidInterface7TestImpl()
537{
538 // Valid shared object handle
539 // Correct name mangling
540 // Correct interface
541 // Invalid (incompatible backend API version) backend instance returned by BackendFactory()
542
543 using namespace armnn;
544
Matteo Martincighd0dc7702019-08-01 17:09:03 +0100545 std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
546 std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend7FileName);
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100547
548 void* sharedObjectHandle = nullptr;
549 BOOST_CHECK_NO_THROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
550 BOOST_TEST((sharedObjectHandle != nullptr));
551
Matteo Martincighe54aa062019-08-05 14:12:11 +0100552 DynamicBackendPtr dynamicBackend;
Matteo Martincighbc2e2102019-07-24 14:56:13 +0100553 BOOST_CHECK_THROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
554 BOOST_TEST((dynamicBackend == nullptr));
555}
Matteo Martincighe7d44982019-08-05 12:16:47 +0100556
557void GetBackendPathsTestImpl()
558{
559 using namespace armnn;
560 using namespace boost::filesystem;
561
562 // The test covers four directories:
563 // <unit test path>/src/backends/backendsCommon/test/
Matteo Martincighe54aa062019-08-05 14:12:11 +0100564 // ├─ backendsTestPath1/ -> exists, contains files
565 // ├─ backendsTestPath2/ -> exists, contains files
566 // ├─ backendsTestPath3/ -> exists, but empty
567 // └─ backendsTestPath4/ -> does not exist
Matteo Martincighe7d44982019-08-05 12:16:47 +0100568
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100569 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
570 std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
571 std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
572 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100573
574 BOOST_CHECK(exists(subDir1));
575 BOOST_CHECK(exists(subDir2));
576 BOOST_CHECK(exists(subDir3));
577 BOOST_CHECK(!exists(subDir4));
578
Matteo Martincighe7d44982019-08-05 12:16:47 +0100579 // No path
580 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());
581
582 // Malformed path
583 std::string malformedDir(subDir1 + "/" + subDir1);
584 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(malformedDir).size()==0);
585
586 // Single valid path
587 std::vector<std::string> DynamicBackendPaths2 = TestDynamicBackendUtils::GetBackendPathsImplTest(subDir1);
588 BOOST_TEST(DynamicBackendPaths2.size() == 1);
589 BOOST_TEST(DynamicBackendPaths2[0] == subDir1);
590
591 // Multiple equal and valid paths
592 std::string multipleEqualDirs(subDir1 + ":" + subDir1);
593 std::vector<std::string> DynamicBackendPaths3 = TestDynamicBackendUtils::GetBackendPathsImplTest(multipleEqualDirs);
594 BOOST_TEST(DynamicBackendPaths3.size() == 1);
595 BOOST_TEST(DynamicBackendPaths3[0] == subDir1);
596
597 // Multiple empty paths
598 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(":::").empty());
599
600 // Multiple valid paths
601 std::string multipleValidPaths(subDir1 + ":" + subDir2 + ":" + subDir3);
602 std::vector<std::string> DynamicBackendPaths5 =
603 TestDynamicBackendUtils::GetBackendPathsImplTest(multipleValidPaths);
604 BOOST_TEST(DynamicBackendPaths5.size() == 3);
605 BOOST_TEST(DynamicBackendPaths5[0] == subDir1);
606 BOOST_TEST(DynamicBackendPaths5[1] == subDir2);
607 BOOST_TEST(DynamicBackendPaths5[2] == subDir3);
608
609 // Valid among empty paths
610 std::string validAmongEmptyDirs("::" + subDir1 + ":");
611 std::vector<std::string> DynamicBackendPaths6 =
612 TestDynamicBackendUtils::GetBackendPathsImplTest(validAmongEmptyDirs);
613 BOOST_TEST(DynamicBackendPaths6.size() == 1);
614 BOOST_TEST(DynamicBackendPaths6[0] == subDir1);
615
616 // Invalid among empty paths
617 std::string invalidAmongEmptyDirs(":" + subDir4 + "::");
618 BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest(invalidAmongEmptyDirs).empty());
619
620 // Valid, invalid and empty paths
621 std::string validInvalidEmptyDirs(subDir1 + ":" + subDir4 + ":");
622 std::vector<std::string> DynamicBackendPaths8 =
623 TestDynamicBackendUtils::GetBackendPathsImplTest(validInvalidEmptyDirs);
624 BOOST_TEST(DynamicBackendPaths8.size() == 1);
625 BOOST_TEST(DynamicBackendPaths8[0] == subDir1);
626
627 // Mix of duplicates of valid, invalid and empty paths
628 std::string duplicateValidInvalidEmptyDirs(validInvalidEmptyDirs + ":" + validInvalidEmptyDirs + ":" +
629 subDir2 + ":" + subDir2);
630 std::vector<std::string> DynamicBackendPaths9 =
631 TestDynamicBackendUtils::GetBackendPathsImplTest(duplicateValidInvalidEmptyDirs);
632 BOOST_TEST(DynamicBackendPaths9.size() == 2);
633 BOOST_TEST(DynamicBackendPaths9[0] == subDir1);
634 BOOST_TEST(DynamicBackendPaths9[1] == subDir2);
635}
636
637void GetBackendPathsOverrideTestImpl()
638{
639 using namespace armnn;
640 using namespace boost::filesystem;
641
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100642 std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
643 std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Matteo Martincighe7d44982019-08-05 12:16:47 +0100644
645 BOOST_CHECK(exists(subDir1));
646 BOOST_CHECK(!exists(subDir4));
647
648 // Override with valid path
649 std::vector<std::string> validResult = DynamicBackendUtils::GetBackendPaths(subDir1);
650 BOOST_TEST(validResult.size() == 1);
651 BOOST_TEST(validResult[0] == subDir1);
652
653 // Override with invalid path
654 std::vector<std::string> invalidResult = DynamicBackendUtils::GetBackendPaths(subDir4);
655 BOOST_TEST(invalidResult.empty());
656}
Jan Eilers4a539fc2019-07-25 17:08:37 +0100657
658void GetSharedObjectsTestImpl()
659{
660 using namespace armnn;
661 using namespace boost::filesystem;
662
Matteo Martincighe54aa062019-08-05 14:12:11 +0100663 // The test covers four directories:
664 // <unit test path>/src/backends/backendsCommon/test/
665 // ├─ backendsTestPath1/ -> exists, contains files
666 // ├─ backendsTestPath2/ -> exists, contains files
667 // ├─ backendsTestPath3/ -> exists, but empty
668 // └─ backendsTestPath4/ -> does not exist
Jan Eilers4a539fc2019-07-25 17:08:37 +0100669 //
670 // The test sub-directory backendsTestPath1/ contains the following test files:
671 //
672 // Arm_GpuAcc_backend.so -> valid (basic backend name)
673 // Arm_GpuAcc_backend.so.1 -> valid (single field version number)
674 // Arm_GpuAcc_backend.so.1.2 -> valid (multiple field version number)
675 // Arm_GpuAcc_backend.so.1.2.3 -> valid (multiple field version number)
676 // Arm_GpuAcc_backend.so.10.1.27 -> valid (Multiple digit version)
677 // Arm_GpuAcc_backend.so.10.1.33. -> not valid (dot not followed by version number)
678 // Arm_GpuAcc_backend.so.3.4..5 -> not valid (dot not followed by version number)
679 // Arm_GpuAcc_backend.so.1,1.1 -> not valid (comma instead of dot in the version)
680 //
681 // Arm123_GpuAcc_backend.so -> valid (digits in vendor name are allowed)
682 // Arm_GpuAcc456_backend.so -> valid (digits in backend id are allowed)
683 // Arm%Co_GpuAcc_backend.so -> not valid (invalid character in vendor name)
684 // Arm_Gpu.Acc_backend.so -> not valid (invalid character in backend id)
685 //
686 // GpuAcc_backend.so -> not valid (missing vendor name)
687 // _GpuAcc_backend.so -> not valid (missing vendor name)
688 // Arm__backend.so -> not valid (missing backend id)
689 // Arm_GpuAcc.so -> not valid (missing "backend" at the end)
690 // __backend.so -> not valid (missing vendor name and backend id)
691 // __.so -> not valid (missing all fields)
692 //
693 // Arm_GpuAcc_backend -> not valid (missing at least ".so" at the end)
694 // Arm_GpuAcc_backend_v1.2.so -> not valid (extra version info at the end)
695 //
696 // The test sub-directory backendsTestPath1/ contains the following test files:
697 //
698 // Arm_CpuAcc_backend.so -> valid (basic backend name)
699 // Arm_CpuAcc_backend.so.1 -> Arm_CpuAcc_backend.so -> valid (symlink to valid backend file)
700 // Arm_CpuAcc_backend.so.1.2 -> Arm_CpuAcc_backend.so.1 -> valid (symlink to valid symlink)
701 // Arm_CpuAcc_backend.so.1.2.3 -> Arm_CpuAcc_backend.so.1.2 -> valid (symlink to valid symlink)
702 //
703 // Arm_no_backend.so -> nothing -> not valid (symlink resolves to non-existent file)
704 //
705 // Arm_GpuAcc_backend.so -> valid (but duplicated from backendsTestPath1/)
706
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100707 std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
708 std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
709 std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
710 std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
Jan Eilers4a539fc2019-07-25 17:08:37 +0100711 BOOST_CHECK(exists(testDynamicBackendsSubDir1));
712 BOOST_CHECK(exists(testDynamicBackendsSubDir2));
713 BOOST_CHECK(exists(testDynamicBackendsSubDir3));
714 BOOST_CHECK(!exists(testDynamicBackendsSubDir4));
715
716 std::vector<std::string> backendPaths
717 {
718 testDynamicBackendsSubDir1,
719 testDynamicBackendsSubDir2,
720 testDynamicBackendsSubDir3,
721 testDynamicBackendsSubDir4
722 };
723 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100724 std::vector<std::string> expectedSharedObjects
Jan Eilers4a539fc2019-07-25 17:08:37 +0100725 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100726 testDynamicBackendsSubDir1 + "Arm123_GpuAcc_backend.so", // Digits in vendor name are allowed
727 testDynamicBackendsSubDir1 + "Arm_GpuAcc456_backend.so", // Digits in backend id are allowed
Jan Eilers4a539fc2019-07-25 17:08:37 +0100728 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so", // Basic backend name
729 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1", // Single field version number
730 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2", // Multiple field version number
731 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2.3", // Multiple field version number
732 testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.10.1.27", // Multiple digit version
Jan Eilers4a539fc2019-07-25 17:08:37 +0100733 testDynamicBackendsSubDir2 + "Arm_CpuAcc_backend.so", // Duplicate symlinks removed
734 testDynamicBackendsSubDir2 + "Arm_GpuAcc_backend.so" // Duplicates on different paths are allowed
735 };
736
737 BOOST_TEST(sharedObjects.size() == expectedSharedObjects.size());
Matteo Martincighe54aa062019-08-05 14:12:11 +0100738 BOOST_TEST(sharedObjects[0] == expectedSharedObjects[0]);
739 BOOST_TEST(sharedObjects[1] == expectedSharedObjects[1]);
740 BOOST_TEST(sharedObjects[2] == expectedSharedObjects[2]);
741 BOOST_TEST(sharedObjects[3] == expectedSharedObjects[3]);
742 BOOST_TEST(sharedObjects[4] == expectedSharedObjects[4]);
743 BOOST_TEST(sharedObjects[5] == expectedSharedObjects[5]);
744 BOOST_TEST(sharedObjects[6] == expectedSharedObjects[6]);
745 BOOST_TEST(sharedObjects[7] == expectedSharedObjects[7]);
746 BOOST_TEST(sharedObjects[8] == expectedSharedObjects[8]);
747}
748
749void CreateDynamicBackendsTestImpl()
750{
751 using namespace armnn;
752 using namespace boost::filesystem;
753
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100754 // The test covers four directories:
Matteo Martincighe54aa062019-08-05 14:12:11 +0100755 // <unit test path>/src/backends/backendsCommon/test/
756 // ├─ backendsTestPath5/ -> exists, contains files
757 // ├─ backendsTestPath6/ -> exists, contains files
758 // ├─ backendsTestPath7/ -> exists, but empty
759 // └─ backendsTestPath8/ -> does not exist
760 //
761 // The test sub-directory backendsTestPath5/ contains the following test files:
762 //
763 // Arm_TestValid2_backend.so -> valid (basic backend name)
764 // Arm_TestValid3_backend.so -> valid (basic backend name)
765 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
766 //
767 // The test sub-directory backendsTestPath6/ contains the following test files:
768 //
769 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
770 // Arm_TestValid4_backend.so -> valid (it has a different filename,
771 // but it has the same backend id of Arm_TestValid2_backend.so
772 // and the same version)
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100773 // Arm_TestValid5_backend.so -> valid (basic backend name)
Matteo Martincighe54aa062019-08-05 14:12:11 +0100774 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
775 // but it has the same backend id of Arm_TestValid2_backend.so
776 // and a version incompatible with the Backend API)
777
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100778 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
779 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
780 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
781 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100782 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
783 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
784 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
785 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
786
787 std::vector<std::string> backendPaths
Jan Eilers4a539fc2019-07-25 17:08:37 +0100788 {
Matteo Martincighe54aa062019-08-05 14:12:11 +0100789 testDynamicBackendsSubDir5,
790 testDynamicBackendsSubDir6,
791 testDynamicBackendsSubDir7,
792 testDynamicBackendsSubDir8
793 };
794 std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
795 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
796
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100797 BOOST_TEST(dynamicBackends.size() == 5);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100798 BOOST_TEST((dynamicBackends[0] != nullptr));
799 BOOST_TEST((dynamicBackends[1] != nullptr));
800 BOOST_TEST((dynamicBackends[2] != nullptr));
801 BOOST_TEST((dynamicBackends[3] != nullptr));
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100802 BOOST_TEST((dynamicBackends[4] != nullptr));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100803
804 // Duplicates are allowed here, they will be skipped later during the backend registration
805 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
806 BOOST_TEST((dynamicBackends[1]->GetBackendId() == "TestValid3"));
807 BOOST_TEST((dynamicBackends[2]->GetBackendId() == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
808 BOOST_TEST((dynamicBackends[3]->GetBackendId() == "TestValid2")); // From Arm_TestValid4_backend.so
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100809 BOOST_TEST((dynamicBackends[4]->GetBackendId() == "TestValid5"));
Matteo Martincighe54aa062019-08-05 14:12:11 +0100810}
811
812void CreateDynamicBackendsNoPathsTestImpl()
813{
814 using namespace armnn;
815
816 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends({});
817
818 BOOST_TEST(dynamicBackends.empty());
819}
820
821void CreateDynamicBackendsAllInvalidTestImpl()
822{
823 using namespace armnn;
824
825 std::vector<std::string> sharedObjects
826 {
827 "InvalidSharedObject1",
828 "InvalidSharedObject2",
829 "InvalidSharedObject3",
830 };
831 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
832
833 BOOST_TEST(dynamicBackends.empty());
834}
835
836void CreateDynamicBackendsMixedTypesTestImpl()
837{
838 using namespace armnn;
839 using namespace boost::filesystem;
840
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100841 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
842 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
Matteo Martincighe54aa062019-08-05 14:12:11 +0100843 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
844 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
845
846 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
847 g_TestValidBackend2FileName);
848 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
849 g_TestInvalidBackend8FileName);
850 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
851 g_TestInvalidBackend9FileName);
852 BOOST_CHECK(exists(testValidBackend2FilePath));
853 BOOST_CHECK(exists(testInvalidBackend8FilePath));
854 BOOST_CHECK(exists(testInvalidBackend9FilePath));
855
856 std::vector<std::string> sharedObjects
857 {
858 testValidBackend2FilePath, // Arm_TestValid2_backend.so -> valid (basic backend name)
859 testInvalidBackend8FilePath, // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
860 testInvalidBackend9FilePath, // Arm_TestInvalid9_backend.so -> not valid (incompatible version)
861 "InvalidSharedObject", // The file does not exist
862 };
863 std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
864
865 BOOST_TEST(dynamicBackends.size() == 1);
866 BOOST_TEST((dynamicBackends[0] != nullptr));
867 BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
Jan Eilers4a539fc2019-07-25 17:08:37 +0100868}
Matteo Martincigh0c2b2892019-08-05 14:12:11 +0100869
870void RegisterSingleDynamicBackendTestImpl()
871{
872 using namespace armnn;
873 using namespace boost::filesystem;
874
875 // Register one valid dynamic backend
876
877 // Dummy registry used for testing
878 BackendRegistry backendRegistry;
879 BOOST_TEST(backendRegistry.Size() == 0);
880
881 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
882 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
883
884 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
885 BOOST_CHECK(exists(testValidBackend2FilePath));
886
887 std::vector<std::string> sharedObjects{ testValidBackend2FilePath };
888 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
889
890 BOOST_TEST(dynamicBackends.size() == 1);
891 BOOST_TEST((dynamicBackends[0] != nullptr));
892
893 BackendId dynamicBackendId = dynamicBackends[0]->GetBackendId();
894 BOOST_TEST((dynamicBackendId == "TestValid2"));
895
896 BackendVersion dynamicBackendVersion = dynamicBackends[0]->GetBackendVersion();
897 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
898
899 TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
900 BOOST_TEST(backendRegistry.Size() == 1);
901
902 BackendIdSet backendIds = backendRegistry.GetBackendIds();
903 BOOST_TEST(backendIds.size() == 1);
904 BOOST_TEST((backendIds.find(dynamicBackendId) != backendIds.end()));
905
906 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
907 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
908
909 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
910 BOOST_TEST((dynamicBackend != nullptr));
911 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
912}
913
914void RegisterMultipleDynamicBackendsTestImpl()
915{
916 using namespace armnn;
917 using namespace boost::filesystem;
918
919 // Register many valid dynamic backends
920
921 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
922 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
923 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
924 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
925
926 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
927 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
928 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
929 BOOST_CHECK(exists(testValidBackend2FilePath));
930 BOOST_CHECK(exists(testValidBackend3FilePath));
931 BOOST_CHECK(exists(testValidBackend5FilePath));
932
933 std::vector<std::string> sharedObjects
934 {
935 testValidBackend2FilePath,
936 testValidBackend3FilePath,
937 testValidBackend5FilePath
938 };
939 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
940
941 BOOST_TEST(dynamicBackends.size() == 3);
942 BOOST_TEST((dynamicBackends[0] != nullptr));
943 BOOST_TEST((dynamicBackends[1] != nullptr));
944 BOOST_TEST((dynamicBackends[2] != nullptr));
945
946 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
947 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
948 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
949 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
950 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
951 BOOST_TEST((dynamicBackendId3 == "TestValid5"));
952
953 for (size_t i = 0; i < dynamicBackends.size(); i++)
954 {
955 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
956 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
957 }
958
959 // Dummy registry used for testing
960 BackendRegistry backendRegistry;
961 BOOST_TEST(backendRegistry.Size() == 0);
962
963 TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
964 BOOST_TEST(backendRegistry.Size() == 3);
965
966 BackendIdSet backendIds = backendRegistry.GetBackendIds();
967 BOOST_TEST(backendIds.size() == 3);
968 BOOST_TEST((backendIds.find(dynamicBackendId1) != backendIds.end()));
969 BOOST_TEST((backendIds.find(dynamicBackendId2) != backendIds.end()));
970 BOOST_TEST((backendIds.find(dynamicBackendId3) != backendIds.end()));
971
972 for (size_t i = 0; i < dynamicBackends.size(); i++)
973 {
974 BackendId dynamicBackendId = dynamicBackends[i]->GetBackendId();
975
976 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
977 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
978
979 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
980 BOOST_TEST((dynamicBackend != nullptr));
981 BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
982 }
983}
984
985void RegisterMultipleInvalidDynamicBackendsTestImpl()
986{
987 using namespace armnn;
988 using namespace boost::filesystem;
989
990 // Try to register many invalid dynamic backends
991
992 // The test covers one directory:
993 // <unit test path>/src/backends/backendsCommon/test/
994 // └─ backendsTestPath9/ -> exists, contains files
995 //
996 // The test sub-directory backendsTestPath9/ contains the following test files:
997 //
998 // Arm_TestInvalid10_backend.so -> not valid (invalid backend id)
999 // Arm_TestInvalid11_backend.so -> not valid (invalid backend id)
1000
1001 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1002 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1003
1004 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1005 g_TestInvalidBackend10FileName);
1006 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1007 g_TestInvalidBackend11FileName);
1008 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1009 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1010
1011 std::vector<std::string> sharedObjects
1012 {
1013 testInvalidBackend10FilePath,
1014 testInvalidBackend11FilePath,
1015 "InvalidSharedObject"
1016 };
1017 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1018
1019 BOOST_TEST(dynamicBackends.size() == 2);
1020 BOOST_TEST((dynamicBackends[0] != nullptr));
1021 BOOST_TEST((dynamicBackends[1] != nullptr));
1022
1023 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1024 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1025 BOOST_TEST((dynamicBackendId1 == ""));
1026 BOOST_TEST((dynamicBackendId2 == "Unknown"));
1027
1028 for (size_t i = 0; i < dynamicBackends.size(); i++)
1029 {
1030 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1031 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1032 }
1033
1034 // Dummy registry used for testing
1035 BackendRegistry backendRegistry;
1036 BOOST_TEST(backendRegistry.Size() == 0);
1037
1038 // Check that no dynamic backend got registered
1039 TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
1040 BOOST_TEST(backendRegistry.Size() == 0);
1041}
1042
1043void RegisterMixedDynamicBackendsTestImpl()
1044{
1045 using namespace armnn;
1046 using namespace boost::filesystem;
1047
1048 // The test covers five directories:
1049 // <unit test path>/src/backends/backendsCommon/test/
1050 // ├─ backendsTestPath5/ -> exists, contains files
1051 // ├─ backendsTestPath6/ -> exists, contains files
1052 // ├─ backendsTestPath7/ -> exists, but empty
1053 // ├─ backendsTestPath8/ -> does not exist
1054 // └─ backendsTestPath9/ -> exists, contains files
1055 //
1056 // The test sub-directory backendsTestPath5/ contains the following test files:
1057 //
1058 // Arm_TestValid2_backend.so -> valid (basic backend name)
1059 // Arm_TestValid3_backend.so -> valid (basic backend name)
1060 // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
1061 //
1062 // The test sub-directory backendsTestPath6/ contains the following test files:
1063 //
1064 // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
1065 // Arm_TestValid4_backend.so -> valid (it has a different filename,
1066 // but it has the same backend id of Arm_TestValid2_backend.so
1067 // and the same version)
1068 // Arm_TestValid5_backend.so -> valid (basic backend name)
1069 // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
1070 // but it has the same backend id of Arm_TestValid2_backend.so
1071 // and a version incompatible with the Backend API)
1072 //
1073 // The test sub-directory backendsTestPath9/ contains the following test files:
1074 //
1075 // Arm_TestInvalid10_backend.so -> not valid (empty backend id)
1076 // Arm_TestInvalid11_backend.so -> not valid ("Unknown" backend id)
1077
1078 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1079 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1080 std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
1081 std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
1082 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1083 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1084 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1085 BOOST_CHECK(exists(testDynamicBackendsSubDir7));
1086 BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
1087 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1088
1089 std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
1090 std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
1091 std::string testValidBackend2DupFilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend2FileName);
1092 std::string testValidBackend4FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend4FileName);
1093 std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
1094 std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
1095 g_TestInvalidBackend8FileName);
1096 std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
1097 g_TestInvalidBackend9FileName);
1098 std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1099 g_TestInvalidBackend10FileName);
1100 std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1101 g_TestInvalidBackend11FileName);
1102 BOOST_CHECK(exists(testValidBackend2FilePath));
1103 BOOST_CHECK(exists(testValidBackend3FilePath));
1104 BOOST_CHECK(exists(testValidBackend2DupFilePath));
1105 BOOST_CHECK(exists(testValidBackend4FilePath));
1106 BOOST_CHECK(exists(testValidBackend5FilePath));
1107 BOOST_CHECK(exists(testInvalidBackend8FilePath));
1108 BOOST_CHECK(exists(testInvalidBackend9FilePath));
1109 BOOST_CHECK(exists(testInvalidBackend10FilePath));
1110 BOOST_CHECK(exists(testInvalidBackend11FilePath));
1111
1112 std::vector<std::string> sharedObjects
1113 {
1114 testValidBackend2FilePath,
1115 testValidBackend3FilePath,
1116 testValidBackend2DupFilePath,
1117 testValidBackend4FilePath,
1118 testValidBackend5FilePath,
1119 testInvalidBackend8FilePath,
1120 testInvalidBackend9FilePath,
1121 testInvalidBackend10FilePath,
1122 testInvalidBackend11FilePath,
1123 "InvalidSharedObject"
1124 };
1125 std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1126
1127 BOOST_TEST(dynamicBackends.size() == 7);
1128 BOOST_TEST((dynamicBackends[0] != nullptr));
1129 BOOST_TEST((dynamicBackends[1] != nullptr));
1130 BOOST_TEST((dynamicBackends[2] != nullptr));
1131 BOOST_TEST((dynamicBackends[3] != nullptr));
1132 BOOST_TEST((dynamicBackends[4] != nullptr));
1133 BOOST_TEST((dynamicBackends[5] != nullptr));
1134 BOOST_TEST((dynamicBackends[6] != nullptr));
1135
1136 BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1137 BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1138 BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
1139 BackendId dynamicBackendId4 = dynamicBackends[3]->GetBackendId();
1140 BackendId dynamicBackendId5 = dynamicBackends[4]->GetBackendId();
1141 BackendId dynamicBackendId6 = dynamicBackends[5]->GetBackendId();
1142 BackendId dynamicBackendId7 = dynamicBackends[6]->GetBackendId();
1143 BOOST_TEST((dynamicBackendId1 == "TestValid2"));
1144 BOOST_TEST((dynamicBackendId2 == "TestValid3"));
1145 BOOST_TEST((dynamicBackendId3 == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
1146 BOOST_TEST((dynamicBackendId4 == "TestValid2")); // From Arm_TestValid4_backend.so
1147 BOOST_TEST((dynamicBackendId5 == "TestValid5"));
1148 BOOST_TEST((dynamicBackendId6 == ""));
1149 BOOST_TEST((dynamicBackendId7 == "Unknown"));
1150
1151 for (size_t i = 0; i < dynamicBackends.size(); i++)
1152 {
1153 BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1154 BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1155 }
1156
1157 // Dummy registry used for testing
1158 BackendRegistry backendRegistry;
1159 BOOST_TEST(backendRegistry.Size() == 0);
1160
1161 std::vector<BackendId> expectedRegisteredbackendIds
1162 {
1163 "TestValid2",
1164 "TestValid3",
1165 "TestValid5"
1166 };
1167
1168 TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
1169 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1170
1171 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1172 BOOST_TEST(backendIds.size() == expectedRegisteredbackendIds.size());
1173 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1174 {
1175 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1176
1177 auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(expectedRegisteredbackendId);
1178 BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
1179
1180 IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
1181 BOOST_TEST((dynamicBackend != nullptr));
1182 BOOST_TEST((dynamicBackend->GetId() == expectedRegisteredbackendId));
1183 }
1184}
Matteo Martincigh3d8a9ed2019-08-08 10:49:03 +01001185
1186void RuntimeEmptyTestImpl()
1187{
1188 using namespace armnn;
1189
1190 // Swapping the backend registry storage for testing
1191 TestBackendRegistry testBackendRegistry;
1192
1193 IRuntime::CreationOptions creationOptions;
1194 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1195
1196 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1197 BOOST_TEST(backendRegistry.Size() == 0);
1198}
1199
1200void RuntimeDynamicBackendsTestImpl()
1201{
1202 using namespace armnn;
1203 using namespace boost::filesystem;
1204
1205 // Swapping the backend registry storage for testing
1206 TestBackendRegistry testBackendRegistry;
1207
1208 // This directory contains valid and invalid backends
1209 std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1210 BOOST_CHECK(exists(testDynamicBackendsSubDir5));
1211
1212 // Using the path override in CreationOptions to load some test dynamic backends
1213 IRuntime::CreationOptions creationOptions;
1214 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir5;
1215 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1216
1217 std::vector<BackendId> expectedRegisteredbackendIds
1218 {
1219 "TestValid2",
1220 "TestValid3"
1221 };
1222
1223 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1224 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1225
1226 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1227 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1228 {
1229 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1230 }
1231}
1232
1233void RuntimeDuplicateDynamicBackendsTestImpl()
1234{
1235 using namespace armnn;
1236 using namespace boost::filesystem;
1237
1238 // Swapping the backend registry storage for testing
1239 TestBackendRegistry testBackendRegistry;
1240
1241 // This directory contains valid, invalid and duplicate backends
1242 std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1243 BOOST_CHECK(exists(testDynamicBackendsSubDir6));
1244
1245 // Using the path override in CreationOptions to load some test dynamic backends
1246 IRuntime::CreationOptions creationOptions;
1247 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir6;
1248 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1249
1250 std::vector<BackendId> expectedRegisteredbackendIds
1251 {
1252 "TestValid2",
1253 "TestValid5"
1254 };
1255
1256 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1257 BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1258
1259 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1260 for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1261 {
1262 BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1263 }
1264}
1265
1266void RuntimeInvalidDynamicBackendsTestImpl()
1267{
1268 using namespace armnn;
1269 using namespace boost::filesystem;
1270
1271 // Swapping the backend registry storage for testing
1272 TestBackendRegistry testBackendRegistry;
1273
1274 // This directory contains only invalid backends
1275 std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1276 BOOST_CHECK(exists(testDynamicBackendsSubDir9));
1277
1278 // Using the path override in CreationOptions to load some test dynamic backends
1279 IRuntime::CreationOptions creationOptions;
1280 creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir9;
1281 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1282
1283 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1284 BOOST_TEST(backendRegistry.Size() == 0);
1285}
1286
1287void RuntimeInvalidOverridePathTestImpl()
1288{
1289 using namespace armnn;
1290
1291 // Swapping the backend registry storage for testing
1292 TestBackendRegistry testBackendRegistry;
1293
1294 // Using the path override in CreationOptions to load some test dynamic backends
1295 IRuntime::CreationOptions creationOptions;
1296 creationOptions.m_DynamicBackendsPath = "InvalidPath";
1297 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1298
1299 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1300 BOOST_TEST(backendRegistry.Size() == 0);
1301}
Matteo Martincigh4e73b422019-08-08 13:46:32 +01001302
1303void CreateReferenceDynamicBackendTestImpl()
1304{
1305 using namespace armnn;
1306 using namespace boost::filesystem;
1307
1308 // Swapping the backend registry storage for testing
1309 TestBackendRegistry testBackendRegistry;
1310
1311 // This directory contains the reference dynamic backend
1312 std::string dynamicBackendsBaseDir = GetDynamicBackendsBasePath();
1313 std::string referenceDynamicBackendSubDir = GetTestSubDirectory(dynamicBackendsBaseDir,
1314 g_ReferenceDynamicBackendSubDir);
1315 BOOST_CHECK(exists(referenceDynamicBackendSubDir));
1316
1317 // Check that the reference dynamic backend file exists
1318 std::string referenceBackendFilePath = GetTestFilePath(referenceDynamicBackendSubDir,
1319 g_ReferenceBackendFileName);
1320 BOOST_CHECK(exists(referenceBackendFilePath));
1321
1322 // Using the path override in CreationOptions to load the reference dynamic backend
1323 IRuntime::CreationOptions creationOptions;
1324 creationOptions.m_DynamicBackendsPath = referenceDynamicBackendSubDir;
1325 IRuntimePtr runtime = IRuntime::Create(creationOptions);
1326
1327 const BackendRegistry& backendRegistry = BackendRegistryInstance();
1328 BOOST_TEST(backendRegistry.Size() == 1);
1329
1330 BackendIdSet backendIds = backendRegistry.GetBackendIds();
1331 BOOST_TEST((backendIds.find("CpuRef") != backendIds.end()));
1332
1333 // Get the factory function
1334 auto referenceDynamicBackendFactoryFunction = backendRegistry.GetFactory("CpuRef");
1335 BOOST_TEST((referenceDynamicBackendFactoryFunction != nullptr));
1336
1337 // Use the factory function to create an instance of the reference backend
1338 IBackendInternalUniquePtr referenceDynamicBackend = referenceDynamicBackendFactoryFunction();
1339 BOOST_TEST((referenceDynamicBackend != nullptr));
1340 BOOST_TEST((referenceDynamicBackend->GetId() == "CpuRef"));
1341
1342 // Test the backend instance by querying the layer support
1343 IBackendInternal::ILayerSupportSharedPtr referenceLayerSupport = referenceDynamicBackend->GetLayerSupport();
1344 BOOST_TEST((referenceLayerSupport != nullptr));
1345
1346 TensorShape inputShape { 1, 16, 16, 16 };
1347 TensorShape outputShape{ 1, 16, 16, 16 };
1348 TensorShape weightShape{ 16, 1, 1, 16 };
1349 TensorInfo inputInfo (inputShape, DataType::Float32);
1350 TensorInfo outputInfo(outputShape, DataType::Float32);
1351 TensorInfo weightInfo(weightShape, DataType::Float32);
1352 Convolution2dDescriptor convolution2dDescriptor;
1353 bool referenceConvolution2dSupported =
1354 referenceLayerSupport->IsConvolution2dSupported(inputInfo,
1355 outputInfo,
1356 convolution2dDescriptor,
1357 weightInfo,
1358 EmptyOptional());
1359 BOOST_TEST(referenceConvolution2dSupported);
1360
1361 // Test the backend instance by creating a workload
1362 IBackendInternal::IWorkloadFactoryPtr referenceWorkloadFactory = referenceDynamicBackend->CreateWorkloadFactory();
1363 BOOST_TEST((referenceWorkloadFactory != nullptr));
1364
1365 // Create dummy settings for the workload
1366 Convolution2dQueueDescriptor convolution2dQueueDescriptor;
1367 WorkloadInfo workloadInfo
1368 {
1369 { inputInfo },
1370 { outputInfo }
1371 };
1372 convolution2dQueueDescriptor.m_Inputs.push_back(nullptr);
1373 auto weights = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
1374 convolution2dQueueDescriptor.m_Weight = weights.get();
1375
1376 // Create a convolution workload with the dummy settings
1377 auto workload = referenceWorkloadFactory->CreateConvolution2d(convolution2dQueueDescriptor, workloadInfo);
1378 BOOST_TEST((workload != nullptr));
1379 BOOST_TEST(workload.get() == boost::polymorphic_downcast<RefConvolution2dWorkload*>(workload.get()));
1380}