xref: /aosp_15_r20/external/armnn/src/backends/backendsCommon/test/DynamicBackendTests.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2019-2023 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #pragma once
7*89c4ff92SAndroid Build Coastguard Worker 
8*89c4ff92SAndroid Build Coastguard Worker #include <armnn/BackendRegistry.hpp>
9*89c4ff92SAndroid Build Coastguard Worker #include <armnn/backends/DynamicBackend.hpp>
10*89c4ff92SAndroid Build Coastguard Worker #include <armnn/backends/ILayerSupport.hpp>
11*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/PolymorphicDowncast.hpp>
12*89c4ff92SAndroid Build Coastguard Worker #include <backendsCommon/DynamicBackendUtils.hpp>
13*89c4ff92SAndroid Build Coastguard Worker #include <armnn/backends/TensorHandle.hpp>
14*89c4ff92SAndroid Build Coastguard Worker #include <armnnUtils/Filesystem.hpp>
15*89c4ff92SAndroid Build Coastguard Worker #include <reference/workloads/RefConvolution2dWorkload.hpp>
16*89c4ff92SAndroid Build Coastguard Worker #include <Runtime.hpp>
17*89c4ff92SAndroid Build Coastguard Worker 
18*89c4ff92SAndroid Build Coastguard Worker #include <string>
19*89c4ff92SAndroid Build Coastguard Worker #include <memory>
20*89c4ff92SAndroid Build Coastguard Worker 
21*89c4ff92SAndroid Build Coastguard Worker #include <doctest/doctest.h>
22*89c4ff92SAndroid Build Coastguard Worker 
23*89c4ff92SAndroid Build Coastguard Worker #if defined(_MSC_VER)
24*89c4ff92SAndroid Build Coastguard Worker #include <Windows.h>
25*89c4ff92SAndroid Build Coastguard Worker #endif
26*89c4ff92SAndroid Build Coastguard Worker 
27*89c4ff92SAndroid Build Coastguard Worker #if !defined(DYNAMIC_BACKEND_BUILD_DIR)
28*89c4ff92SAndroid Build Coastguard Worker #define DYNAMIC_BACKEND_BUILD_DIR fs::path("./")
29*89c4ff92SAndroid Build Coastguard Worker #endif
30*89c4ff92SAndroid Build Coastguard Worker 
31*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDirCLI                             = "--dynamic-backend-build-dir";
32*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestBaseDir                            = "src/backends/backendsCommon/test/";
33*89c4ff92SAndroid Build Coastguard Worker 
34*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestSharedObjectSubDir                 = "testSharedObject/";
35*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendSubDir               = "testDynamicBackend/";
36*89c4ff92SAndroid Build Coastguard Worker 
37*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestSharedObjectFileName               = "libTestSharedObject.so";
38*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestNoSharedObjectFileName             = "libNoSharedObject.txt";
39*89c4ff92SAndroid Build Coastguard Worker 
40*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestValidTestDynamicBackendFileName    = "libValidTestDynamicBackend.so";
41*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidTestDynamicBackend1FileName = "libInvalidTestDynamicBackend1.so";
42*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidTestDynamicBackend2FileName = "libInvalidTestDynamicBackend2.so";
43*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidTestDynamicBackend3FileName = "libInvalidTestDynamicBackend3.so";
44*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidTestDynamicBackend4FileName = "libInvalidTestDynamicBackend4.so";
45*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidTestDynamicBackend5FileName = "libInvalidTestDynamicBackend5.so";
46*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidTestDynamicBackend6FileName = "libInvalidTestDynamicBackend6.so";
47*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidTestDynamicBackend7FileName = "libInvalidTestDynamicBackend7.so";
48*89c4ff92SAndroid Build Coastguard Worker 
49*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestValidBackend2FileName              = "Arm_TestValid2_backend.so";
50*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestValidBackend3FileName              = "Arm_TestValid3_backend.so";
51*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestValidBackend4FileName              = "Arm_TestValid4_backend.so";
52*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestValidBackend5FileName              = "Arm_TestValid5_backend.so";
53*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidBackend8FileName            = "Arm_TestInvalid8_backend.so";
54*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidBackend9FileName            = "Arm_TestInvalid9_backend.so";
55*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidBackend10FileName           = "Arm_TestInvalid10_backend.so";
56*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestInvalidBackend11FileName           = "Arm_TestInvalid11_backend.so";
57*89c4ff92SAndroid Build Coastguard Worker 
58*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir1  = "backendsTestPath1/";
59*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir2  = "backendsTestPath2/";
60*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir3  = "backendsTestPath3/";
61*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir4  = "backendsTestPath4/";
62*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir5  = "backendsTestPath5/";
63*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir6  = "backendsTestPath6/";
64*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir7  = "backendsTestPath7/";
65*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir8  = "backendsTestPath8/";
66*89c4ff92SAndroid Build Coastguard Worker static std::string g_TestDynamicBackendsSubDir9  = "backendsTestPath9/";
67*89c4ff92SAndroid Build Coastguard Worker 
68*89c4ff92SAndroid Build Coastguard Worker static std::string g_DynamicBackendsBaseDir                 = "src/backends/dynamic";
69*89c4ff92SAndroid Build Coastguard Worker static std::string g_ReferenceDynamicBackendSubDir          = "reference/";
70*89c4ff92SAndroid Build Coastguard Worker static std::string g_ReferenceBackendFileName               = "Arm_CpuRef_backend.so";
71*89c4ff92SAndroid Build Coastguard Worker 
72*89c4ff92SAndroid Build Coastguard Worker // DynamicBackendUtils wrapper class used for testing (allows to directly invoke the protected methods)
73*89c4ff92SAndroid Build Coastguard Worker class TestDynamicBackendUtils : public armnn::DynamicBackendUtils
74*89c4ff92SAndroid Build Coastguard Worker {
75*89c4ff92SAndroid Build Coastguard Worker public:
IsBackendCompatibleTest(const armnn::BackendVersion & backendApiVersion,const armnn::BackendVersion & backendVersion)76*89c4ff92SAndroid Build Coastguard Worker     static bool IsBackendCompatibleTest(const armnn::BackendVersion& backendApiVersion,
77*89c4ff92SAndroid Build Coastguard Worker                                         const armnn::BackendVersion& backendVersion)
78*89c4ff92SAndroid Build Coastguard Worker     {
79*89c4ff92SAndroid Build Coastguard Worker         return IsBackendCompatibleImpl(backendApiVersion, backendVersion);
80*89c4ff92SAndroid Build Coastguard Worker     }
81*89c4ff92SAndroid Build Coastguard Worker 
GetBackendPathsImplTest(const std::string & path)82*89c4ff92SAndroid Build Coastguard Worker     static std::vector<std::string> GetBackendPathsImplTest(const std::string& path)
83*89c4ff92SAndroid Build Coastguard Worker     {
84*89c4ff92SAndroid Build Coastguard Worker         return GetBackendPathsImpl(path);
85*89c4ff92SAndroid Build Coastguard Worker     }
86*89c4ff92SAndroid Build Coastguard Worker 
RegisterDynamicBackendsImplTest(armnn::BackendRegistry & backendRegistry,const std::vector<armnn::DynamicBackendPtr> & dynamicBackends)87*89c4ff92SAndroid Build Coastguard Worker     static armnn::BackendIdSet RegisterDynamicBackendsImplTest(
88*89c4ff92SAndroid Build Coastguard Worker             armnn::BackendRegistry& backendRegistry,
89*89c4ff92SAndroid Build Coastguard Worker             const std::vector<armnn::DynamicBackendPtr>& dynamicBackends)
90*89c4ff92SAndroid Build Coastguard Worker     {
91*89c4ff92SAndroid Build Coastguard Worker         return RegisterDynamicBackendsImpl(backendRegistry, dynamicBackends);
92*89c4ff92SAndroid Build Coastguard Worker     }
93*89c4ff92SAndroid Build Coastguard Worker };
94*89c4ff92SAndroid Build Coastguard Worker 
95*89c4ff92SAndroid Build Coastguard Worker // BackendRegistry wrapper class used for testing (swaps the underlying factory storage)
96*89c4ff92SAndroid Build Coastguard Worker class TestBackendRegistry : public armnn::BackendRegistry
97*89c4ff92SAndroid Build Coastguard Worker {
98*89c4ff92SAndroid Build Coastguard Worker public:
TestBackendRegistry()99*89c4ff92SAndroid Build Coastguard Worker     TestBackendRegistry() : armnn::BackendRegistry()
100*89c4ff92SAndroid Build Coastguard Worker     {
101*89c4ff92SAndroid Build Coastguard Worker         Swap(armnn::BackendRegistryInstance(), m_TempStorage);
102*89c4ff92SAndroid Build Coastguard Worker     }
103*89c4ff92SAndroid Build Coastguard Worker 
~TestBackendRegistry()104*89c4ff92SAndroid Build Coastguard Worker     ~TestBackendRegistry()
105*89c4ff92SAndroid Build Coastguard Worker     {
106*89c4ff92SAndroid Build Coastguard Worker         Swap(armnn::BackendRegistryInstance(), m_TempStorage);
107*89c4ff92SAndroid Build Coastguard Worker     }
108*89c4ff92SAndroid Build Coastguard Worker 
109*89c4ff92SAndroid Build Coastguard Worker private:
110*89c4ff92SAndroid Build Coastguard Worker     FactoryStorage m_TempStorage;
111*89c4ff92SAndroid Build Coastguard Worker };
112*89c4ff92SAndroid Build Coastguard Worker 
113*89c4ff92SAndroid Build Coastguard Worker #if defined(_MSC_VER)
GetUnitTestExecutablePath()114*89c4ff92SAndroid Build Coastguard Worker std::string GetUnitTestExecutablePath()
115*89c4ff92SAndroid Build Coastguard Worker {
116*89c4ff92SAndroid Build Coastguard Worker     char buffer[MAX_PATH] = "";
117*89c4ff92SAndroid Build Coastguard Worker     GetModuleFileNameA(NULL, buffer, MAX_PATH);
118*89c4ff92SAndroid Build Coastguard Worker     fs::path executablePath(buffer);
119*89c4ff92SAndroid Build Coastguard Worker     return executablePath.parent_path();
120*89c4ff92SAndroid Build Coastguard Worker }
121*89c4ff92SAndroid Build Coastguard Worker 
122*89c4ff92SAndroid Build Coastguard Worker #else
GetUnitTestExecutablePath()123*89c4ff92SAndroid Build Coastguard Worker std::string GetUnitTestExecutablePath()
124*89c4ff92SAndroid Build Coastguard Worker {
125*89c4ff92SAndroid Build Coastguard Worker     char buffer[PATH_MAX] = "";
126*89c4ff92SAndroid Build Coastguard Worker     if (readlink("/proc/self/exe", buffer, PATH_MAX) != -1)
127*89c4ff92SAndroid Build Coastguard Worker     {
128*89c4ff92SAndroid Build Coastguard Worker         fs::path executablePath(buffer);
129*89c4ff92SAndroid Build Coastguard Worker         return executablePath.parent_path();
130*89c4ff92SAndroid Build Coastguard Worker     }
131*89c4ff92SAndroid Build Coastguard Worker     return "";
132*89c4ff92SAndroid Build Coastguard Worker }
133*89c4ff92SAndroid Build Coastguard Worker #endif
134*89c4ff92SAndroid Build Coastguard Worker 
GetBasePath(const std::string & basePath)135*89c4ff92SAndroid Build Coastguard Worker std::string GetBasePath(const std::string& basePath)
136*89c4ff92SAndroid Build Coastguard Worker {
137*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
138*89c4ff92SAndroid Build Coastguard Worker     // What we're looking for here is the location of the UnitTests executable.
139*89c4ff92SAndroid Build Coastguard Worker     // Fall back value of current directory.
140*89c4ff92SAndroid Build Coastguard Worker     path programLocation = GetUnitTestExecutablePath();
141*89c4ff92SAndroid Build Coastguard Worker     if (!exists(programLocation))
142*89c4ff92SAndroid Build Coastguard Worker     {
143*89c4ff92SAndroid Build Coastguard Worker         programLocation = DYNAMIC_BACKEND_BUILD_DIR;
144*89c4ff92SAndroid Build Coastguard Worker     }
145*89c4ff92SAndroid Build Coastguard Worker 
146*89c4ff92SAndroid Build Coastguard Worker     // This is the base path from the build where the test libraries were built.
147*89c4ff92SAndroid Build Coastguard Worker     path sharedObjectPath = programLocation.append(basePath);
148*89c4ff92SAndroid Build Coastguard Worker     REQUIRE_MESSAGE(exists(sharedObjectPath),
149*89c4ff92SAndroid Build Coastguard Worker                     ("Base path for shared objects does not exist: " + sharedObjectPath.string()));
150*89c4ff92SAndroid Build Coastguard Worker     return sharedObjectPath.string();
151*89c4ff92SAndroid Build Coastguard Worker }
152*89c4ff92SAndroid Build Coastguard Worker 
GetTestDirectoryBasePath()153*89c4ff92SAndroid Build Coastguard Worker std::string GetTestDirectoryBasePath()
154*89c4ff92SAndroid Build Coastguard Worker {
155*89c4ff92SAndroid Build Coastguard Worker     return GetBasePath(g_TestBaseDir);
156*89c4ff92SAndroid Build Coastguard Worker }
157*89c4ff92SAndroid Build Coastguard Worker 
GetDynamicBackendsBasePath()158*89c4ff92SAndroid Build Coastguard Worker std::string GetDynamicBackendsBasePath()
159*89c4ff92SAndroid Build Coastguard Worker {
160*89c4ff92SAndroid Build Coastguard Worker     return GetBasePath(g_DynamicBackendsBaseDir);
161*89c4ff92SAndroid Build Coastguard Worker }
162*89c4ff92SAndroid Build Coastguard Worker 
GetTestSubDirectory(const std::string & subdir)163*89c4ff92SAndroid Build Coastguard Worker std::string GetTestSubDirectory(const std::string& subdir)
164*89c4ff92SAndroid Build Coastguard Worker {
165*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
166*89c4ff92SAndroid Build Coastguard Worker 
167*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsBaseDir = GetTestDirectoryBasePath();
168*89c4ff92SAndroid Build Coastguard Worker     path testDynamicBackendsBasePath(testDynamicBackendsBaseDir);
169*89c4ff92SAndroid Build Coastguard Worker     path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
170*89c4ff92SAndroid Build Coastguard Worker     // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
171*89c4ff92SAndroid Build Coastguard Worker 
172*89c4ff92SAndroid Build Coastguard Worker     return testDynamicBackendsSubDir.string();
173*89c4ff92SAndroid Build Coastguard Worker }
174*89c4ff92SAndroid Build Coastguard Worker 
GetTestSubDirectory(const std::string & basePath,const std::string & subdir)175*89c4ff92SAndroid Build Coastguard Worker std::string GetTestSubDirectory(const std::string& basePath, const std::string& subdir)
176*89c4ff92SAndroid Build Coastguard Worker {
177*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
178*89c4ff92SAndroid Build Coastguard Worker 
179*89c4ff92SAndroid Build Coastguard Worker     path testDynamicBackendsBasePath(basePath);
180*89c4ff92SAndroid Build Coastguard Worker     path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
181*89c4ff92SAndroid Build Coastguard Worker     // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
182*89c4ff92SAndroid Build Coastguard Worker 
183*89c4ff92SAndroid Build Coastguard Worker     return testDynamicBackendsSubDir.string();
184*89c4ff92SAndroid Build Coastguard Worker }
185*89c4ff92SAndroid Build Coastguard Worker 
GetTestFilePath(const std::string & directory,const std::string & fileName)186*89c4ff92SAndroid Build Coastguard Worker std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
187*89c4ff92SAndroid Build Coastguard Worker {
188*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
189*89c4ff92SAndroid Build Coastguard Worker 
190*89c4ff92SAndroid Build Coastguard Worker     path directoryPath(directory);
191*89c4ff92SAndroid Build Coastguard Worker     path fileNamePath = directoryPath.append(fileName);
192*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(fileNamePath));
193*89c4ff92SAndroid Build Coastguard Worker 
194*89c4ff92SAndroid Build Coastguard Worker     return fileNamePath.string();
195*89c4ff92SAndroid Build Coastguard Worker }
196*89c4ff92SAndroid Build Coastguard Worker 
OpenCloseHandleTestImpl()197*89c4ff92SAndroid Build Coastguard Worker void OpenCloseHandleTestImpl()
198*89c4ff92SAndroid Build Coastguard Worker {
199*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
200*89c4ff92SAndroid Build Coastguard Worker 
201*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
202*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
203*89c4ff92SAndroid Build Coastguard Worker 
204*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
205*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
206*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
207*89c4ff92SAndroid Build Coastguard Worker 
208*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendUtils::CloseHandle(sharedObjectHandle);
209*89c4ff92SAndroid Build Coastguard Worker }
210*89c4ff92SAndroid Build Coastguard Worker 
CloseInvalidHandleTestImpl()211*89c4ff92SAndroid Build Coastguard Worker void CloseInvalidHandleTestImpl()
212*89c4ff92SAndroid Build Coastguard Worker {
213*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
214*89c4ff92SAndroid Build Coastguard Worker 
215*89c4ff92SAndroid Build Coastguard Worker     // This calls must silently handle invalid handles and complete successfully (no segfaults, etc.)
216*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendUtils::CloseHandle(nullptr);
217*89c4ff92SAndroid Build Coastguard Worker }
218*89c4ff92SAndroid Build Coastguard Worker 
OpenEmptyFileNameTestImpl()219*89c4ff92SAndroid Build Coastguard Worker void OpenEmptyFileNameTestImpl()
220*89c4ff92SAndroid Build Coastguard Worker {
221*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
222*89c4ff92SAndroid Build Coastguard Worker 
223*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
224*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(sharedObjectHandle = DynamicBackendUtils::OpenHandle(""), RuntimeException);
225*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle == nullptr));
226*89c4ff92SAndroid Build Coastguard Worker }
227*89c4ff92SAndroid Build Coastguard Worker 
OpenNotExistingFileTestImpl()228*89c4ff92SAndroid Build Coastguard Worker void OpenNotExistingFileTestImpl()
229*89c4ff92SAndroid Build Coastguard Worker {
230*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
231*89c4ff92SAndroid Build Coastguard Worker 
232*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
233*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(sharedObjectHandle = DynamicBackendUtils::OpenHandle("NotExistingFileName"), RuntimeException);
234*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle == nullptr));
235*89c4ff92SAndroid Build Coastguard Worker }
236*89c4ff92SAndroid Build Coastguard Worker 
OpenNotSharedObjectTestImpl()237*89c4ff92SAndroid Build Coastguard Worker void OpenNotSharedObjectTestImpl()
238*89c4ff92SAndroid Build Coastguard Worker {
239*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
240*89c4ff92SAndroid Build Coastguard Worker 
241*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
242*89c4ff92SAndroid Build Coastguard Worker     std::string notSharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestNoSharedObjectFileName);
243*89c4ff92SAndroid Build Coastguard Worker 
244*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
245*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(sharedObjectHandle = DynamicBackendUtils::OpenHandle(notSharedObjectFilePath), RuntimeException);
246*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle == nullptr));
247*89c4ff92SAndroid Build Coastguard Worker }
248*89c4ff92SAndroid Build Coastguard Worker 
GetValidEntryPointTestImpl()249*89c4ff92SAndroid Build Coastguard Worker void GetValidEntryPointTestImpl()
250*89c4ff92SAndroid Build Coastguard Worker {
251*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
252*89c4ff92SAndroid Build Coastguard Worker 
253*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
254*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
255*89c4ff92SAndroid Build Coastguard Worker 
256*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
257*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
258*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
259*89c4ff92SAndroid Build Coastguard Worker 
260*89c4ff92SAndroid Build Coastguard Worker     using TestFunctionType = int(*)(int);
261*89c4ff92SAndroid Build Coastguard Worker     TestFunctionType testFunctionPointer = nullptr;
262*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
263*89c4ff92SAndroid Build Coastguard Worker                                                                                                     "TestFunction1"));
264*89c4ff92SAndroid Build Coastguard Worker     CHECK((testFunctionPointer != nullptr));
265*89c4ff92SAndroid Build Coastguard Worker     CHECK(testFunctionPointer(7) == 7);
266*89c4ff92SAndroid Build Coastguard Worker 
267*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendUtils::CloseHandle(sharedObjectHandle);
268*89c4ff92SAndroid Build Coastguard Worker }
269*89c4ff92SAndroid Build Coastguard Worker 
GetNameMangledEntryPointTestImpl()270*89c4ff92SAndroid Build Coastguard Worker void GetNameMangledEntryPointTestImpl()
271*89c4ff92SAndroid Build Coastguard Worker {
272*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
273*89c4ff92SAndroid Build Coastguard Worker 
274*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
275*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
276*89c4ff92SAndroid Build Coastguard Worker 
277*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
278*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
279*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
280*89c4ff92SAndroid Build Coastguard Worker 
281*89c4ff92SAndroid Build Coastguard Worker     using TestFunctionType = int(*)(int);
282*89c4ff92SAndroid Build Coastguard Worker     TestFunctionType testFunctionPointer = nullptr;
283*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
284*89c4ff92SAndroid Build Coastguard Worker                                                                                                  "TestFunction2"),
285*89c4ff92SAndroid Build Coastguard Worker                       RuntimeException);
286*89c4ff92SAndroid Build Coastguard Worker     CHECK((testFunctionPointer == nullptr));
287*89c4ff92SAndroid Build Coastguard Worker 
288*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendUtils::CloseHandle(sharedObjectHandle);
289*89c4ff92SAndroid Build Coastguard Worker }
290*89c4ff92SAndroid Build Coastguard Worker 
GetNoExternEntryPointTestImpl()291*89c4ff92SAndroid Build Coastguard Worker void GetNoExternEntryPointTestImpl()
292*89c4ff92SAndroid Build Coastguard Worker {
293*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
294*89c4ff92SAndroid Build Coastguard Worker 
295*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
296*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
297*89c4ff92SAndroid Build Coastguard Worker 
298*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
299*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
300*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
301*89c4ff92SAndroid Build Coastguard Worker 
302*89c4ff92SAndroid Build Coastguard Worker     using TestFunctionType = int(*)(int);
303*89c4ff92SAndroid Build Coastguard Worker     TestFunctionType testFunctionPointer = nullptr;
304*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
305*89c4ff92SAndroid Build Coastguard Worker                                                                                                  "TestFunction3"),
306*89c4ff92SAndroid Build Coastguard Worker                       RuntimeException);
307*89c4ff92SAndroid Build Coastguard Worker     CHECK((testFunctionPointer == nullptr));
308*89c4ff92SAndroid Build Coastguard Worker 
309*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendUtils::CloseHandle(sharedObjectHandle);
310*89c4ff92SAndroid Build Coastguard Worker }
311*89c4ff92SAndroid Build Coastguard Worker 
GetNotExistingEntryPointTestImpl()312*89c4ff92SAndroid Build Coastguard Worker void GetNotExistingEntryPointTestImpl()
313*89c4ff92SAndroid Build Coastguard Worker {
314*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
315*89c4ff92SAndroid Build Coastguard Worker 
316*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestSharedObjectSubDir);
317*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestSharedObjectFileName);
318*89c4ff92SAndroid Build Coastguard Worker 
319*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
320*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
321*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
322*89c4ff92SAndroid Build Coastguard Worker 
323*89c4ff92SAndroid Build Coastguard Worker     using TestFunctionType = int(*)(int);
324*89c4ff92SAndroid Build Coastguard Worker     TestFunctionType testFunctionPointer = nullptr;
325*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(testFunctionPointer = DynamicBackendUtils::GetEntryPoint<TestFunctionType>(sharedObjectHandle,
326*89c4ff92SAndroid Build Coastguard Worker                                                                                                  "TestFunction4"),
327*89c4ff92SAndroid Build Coastguard Worker                       RuntimeException);
328*89c4ff92SAndroid Build Coastguard Worker     CHECK((testFunctionPointer == nullptr));
329*89c4ff92SAndroid Build Coastguard Worker 
330*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendUtils::CloseHandle(sharedObjectHandle);
331*89c4ff92SAndroid Build Coastguard Worker }
332*89c4ff92SAndroid Build Coastguard Worker 
BackendVersioningTestImpl()333*89c4ff92SAndroid Build Coastguard Worker void BackendVersioningTestImpl()
334*89c4ff92SAndroid Build Coastguard Worker {
335*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
336*89c4ff92SAndroid Build Coastguard Worker 
337*89c4ff92SAndroid Build Coastguard Worker     // The backend API version used for the tests
338*89c4ff92SAndroid Build Coastguard Worker     BackendVersion backendApiVersion{ 2, 4 };
339*89c4ff92SAndroid Build Coastguard Worker 
340*89c4ff92SAndroid Build Coastguard Worker     // Same backend and backend API versions are compatible with the backend API
341*89c4ff92SAndroid Build Coastguard Worker     BackendVersion sameBackendVersion{ 2, 4 };
342*89c4ff92SAndroid Build Coastguard Worker     CHECK(sameBackendVersion == backendApiVersion);
343*89c4ff92SAndroid Build Coastguard Worker     CHECK(sameBackendVersion <= backendApiVersion);
344*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true);
345*89c4ff92SAndroid Build Coastguard Worker 
346*89c4ff92SAndroid Build Coastguard Worker     // Backend versions that differ from the backend API version by major revision are not compatible
347*89c4ff92SAndroid Build Coastguard Worker     // with the backend API
348*89c4ff92SAndroid Build Coastguard Worker     BackendVersion laterMajorBackendVersion{ 3, 4 };
349*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(laterMajorBackendVersion == backendApiVersion));
350*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(laterMajorBackendVersion <= backendApiVersion));
351*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false);
352*89c4ff92SAndroid Build Coastguard Worker 
353*89c4ff92SAndroid Build Coastguard Worker     BackendVersion earlierMajorBackendVersion{ 1, 4 };
354*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(earlierMajorBackendVersion == backendApiVersion));
355*89c4ff92SAndroid Build Coastguard Worker     CHECK(earlierMajorBackendVersion <= backendApiVersion);
356*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion,
357*89c4ff92SAndroid Build Coastguard Worker                                                                 earlierMajorBackendVersion) == false);
358*89c4ff92SAndroid Build Coastguard Worker 
359*89c4ff92SAndroid Build Coastguard Worker     // Backend versions with the same major revision but later minor revision than
360*89c4ff92SAndroid Build Coastguard Worker     // the backend API version are not compatible with the backend API
361*89c4ff92SAndroid Build Coastguard Worker     BackendVersion laterMinorBackendVersion{ 2, 5 };
362*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(laterMinorBackendVersion == backendApiVersion));
363*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(laterMinorBackendVersion <= backendApiVersion));
364*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false);
365*89c4ff92SAndroid Build Coastguard Worker 
366*89c4ff92SAndroid Build Coastguard Worker     // Backend versions with the same major revision but earlier minor revision than
367*89c4ff92SAndroid Build Coastguard Worker     // the backend API version are compatible with the backend API
368*89c4ff92SAndroid Build Coastguard Worker     BackendVersion earlierMinorBackendVersion{ 2, 3 };
369*89c4ff92SAndroid Build Coastguard Worker     CHECK(!(earlierMinorBackendVersion == backendApiVersion));
370*89c4ff92SAndroid Build Coastguard Worker     CHECK(earlierMinorBackendVersion <= backendApiVersion);
371*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true);
372*89c4ff92SAndroid Build Coastguard Worker }
373*89c4ff92SAndroid Build Coastguard Worker 
374*89c4ff92SAndroid Build Coastguard Worker #if defined(ARMNNREF_ENABLED)
CreateValidDynamicBackendObjectTestImpl()375*89c4ff92SAndroid Build Coastguard Worker void CreateValidDynamicBackendObjectTestImpl()
376*89c4ff92SAndroid Build Coastguard Worker {
377*89c4ff92SAndroid Build Coastguard Worker     // Valid shared object handle
378*89c4ff92SAndroid Build Coastguard Worker     // Correct name mangling
379*89c4ff92SAndroid Build Coastguard Worker     // Correct interface
380*89c4ff92SAndroid Build Coastguard Worker     // Correct backend implementation
381*89c4ff92SAndroid Build Coastguard Worker 
382*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
383*89c4ff92SAndroid Build Coastguard Worker 
384*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
385*89c4ff92SAndroid Build Coastguard Worker 
386*89c4ff92SAndroid Build Coastguard Worker     // We expect this path to exists so we can load a valid dynamic backend.
387*89c4ff92SAndroid Build Coastguard Worker     CHECK_MESSAGE(fs::exists(testSubDirectory),
388*89c4ff92SAndroid Build Coastguard Worker                   ("Base path for shared objects does not exist: " + testSubDirectory));
389*89c4ff92SAndroid Build Coastguard Worker 
390*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestValidTestDynamicBackendFileName);
391*89c4ff92SAndroid Build Coastguard Worker 
392*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
393*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
394*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
395*89c4ff92SAndroid Build Coastguard Worker 
396*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
397*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
398*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend != nullptr));
399*89c4ff92SAndroid Build Coastguard Worker 
400*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId;
401*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackendId = dynamicBackend->GetBackendId());
402*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId == "ValidTestDynamicBackend"));
403*89c4ff92SAndroid Build Coastguard Worker 
404*89c4ff92SAndroid Build Coastguard Worker     BackendVersion dynamicBackendVersion;
405*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
406*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendVersion == IBackendInternal::GetApiVersion()));
407*89c4ff92SAndroid Build Coastguard Worker 
408*89c4ff92SAndroid Build Coastguard Worker     IBackendInternalUniquePtr dynamicBackendInstance1;
409*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackendInstance1 = dynamicBackend->GetBackend());
410*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendInstance1 != nullptr));
411*89c4ff92SAndroid Build Coastguard Worker 
412*89c4ff92SAndroid Build Coastguard Worker     BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
413*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
414*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendFactoryFunction != nullptr));
415*89c4ff92SAndroid Build Coastguard Worker 
416*89c4ff92SAndroid Build Coastguard Worker     IBackendInternalUniquePtr dynamicBackendInstance2;
417*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction());
418*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendInstance2 != nullptr));
419*89c4ff92SAndroid Build Coastguard Worker 
420*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendInstance1->GetId() == "ValidTestDynamicBackend"));
421*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendInstance2->GetId() == "ValidTestDynamicBackend"));
422*89c4ff92SAndroid Build Coastguard Worker }
423*89c4ff92SAndroid Build Coastguard Worker #endif
424*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendObjectInvalidHandleTestImpl()425*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendObjectInvalidHandleTestImpl()
426*89c4ff92SAndroid Build Coastguard Worker {
427*89c4ff92SAndroid Build Coastguard Worker     // Invalid (null) shared object handle
428*89c4ff92SAndroid Build Coastguard Worker 
429*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
430*89c4ff92SAndroid Build Coastguard Worker 
431*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
432*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
433*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), InvalidArgumentException);
434*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend == nullptr));
435*89c4ff92SAndroid Build Coastguard Worker }
436*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendObjectInvalidInterface1TestImpl()437*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendObjectInvalidInterface1TestImpl()
438*89c4ff92SAndroid Build Coastguard Worker {
439*89c4ff92SAndroid Build Coastguard Worker     // Valid shared object handle
440*89c4ff92SAndroid Build Coastguard Worker     // Wrong (not C-style) name mangling
441*89c4ff92SAndroid Build Coastguard Worker 
442*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
443*89c4ff92SAndroid Build Coastguard Worker 
444*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
445*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend1FileName);
446*89c4ff92SAndroid Build Coastguard Worker 
447*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
448*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
449*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
450*89c4ff92SAndroid Build Coastguard Worker 
451*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
452*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
453*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend == nullptr));
454*89c4ff92SAndroid Build Coastguard Worker }
455*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendObjectInvalidInterface2TestImpl()456*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendObjectInvalidInterface2TestImpl()
457*89c4ff92SAndroid Build Coastguard Worker {
458*89c4ff92SAndroid Build Coastguard Worker     // Valid shared object handle
459*89c4ff92SAndroid Build Coastguard Worker     // Correct name mangling
460*89c4ff92SAndroid Build Coastguard Worker     // Wrong interface (missing GetBackendId())
461*89c4ff92SAndroid Build Coastguard Worker 
462*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
463*89c4ff92SAndroid Build Coastguard Worker 
464*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
465*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend2FileName);
466*89c4ff92SAndroid Build Coastguard Worker 
467*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
468*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
469*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
470*89c4ff92SAndroid Build Coastguard Worker 
471*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
472*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
473*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend == nullptr));
474*89c4ff92SAndroid Build Coastguard Worker }
475*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendObjectInvalidInterface3TestImpl()476*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendObjectInvalidInterface3TestImpl()
477*89c4ff92SAndroid Build Coastguard Worker {
478*89c4ff92SAndroid Build Coastguard Worker     // Valid shared object handle
479*89c4ff92SAndroid Build Coastguard Worker     // Correct name mangling
480*89c4ff92SAndroid Build Coastguard Worker     // Wrong interface (missing GetVersion())
481*89c4ff92SAndroid Build Coastguard Worker 
482*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
483*89c4ff92SAndroid Build Coastguard Worker 
484*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
485*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend3FileName);
486*89c4ff92SAndroid Build Coastguard Worker 
487*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
488*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
489*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
490*89c4ff92SAndroid Build Coastguard Worker 
491*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
492*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
493*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend == nullptr));
494*89c4ff92SAndroid Build Coastguard Worker }
495*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendObjectInvalidInterface4TestImpl()496*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendObjectInvalidInterface4TestImpl()
497*89c4ff92SAndroid Build Coastguard Worker {
498*89c4ff92SAndroid Build Coastguard Worker     // Valid shared object handle
499*89c4ff92SAndroid Build Coastguard Worker     // Correct name mangling
500*89c4ff92SAndroid Build Coastguard Worker     // Wrong interface (missing BackendFactory())
501*89c4ff92SAndroid Build Coastguard Worker 
502*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
503*89c4ff92SAndroid Build Coastguard Worker 
504*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
505*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend4FileName);
506*89c4ff92SAndroid Build Coastguard Worker 
507*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
508*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
509*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
510*89c4ff92SAndroid Build Coastguard Worker 
511*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
512*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
513*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend == nullptr));
514*89c4ff92SAndroid Build Coastguard Worker }
515*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendObjectInvalidInterface5TestImpl()516*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendObjectInvalidInterface5TestImpl()
517*89c4ff92SAndroid Build Coastguard Worker {
518*89c4ff92SAndroid Build Coastguard Worker     // Valid shared object handle
519*89c4ff92SAndroid Build Coastguard Worker     // Correct name mangling
520*89c4ff92SAndroid Build Coastguard Worker     // Correct interface
521*89c4ff92SAndroid Build Coastguard Worker     // Invalid (null) backend id returned by GetBackendId()
522*89c4ff92SAndroid Build Coastguard Worker 
523*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
524*89c4ff92SAndroid Build Coastguard Worker 
525*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
526*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend5FileName);
527*89c4ff92SAndroid Build Coastguard Worker 
528*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
529*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
530*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
531*89c4ff92SAndroid Build Coastguard Worker 
532*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
533*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
534*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend == nullptr));
535*89c4ff92SAndroid Build Coastguard Worker }
536*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendObjectInvalidInterface6TestImpl()537*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendObjectInvalidInterface6TestImpl()
538*89c4ff92SAndroid Build Coastguard Worker {
539*89c4ff92SAndroid Build Coastguard Worker     // Valid shared object handle
540*89c4ff92SAndroid Build Coastguard Worker     // Correct name mangling
541*89c4ff92SAndroid Build Coastguard Worker     // Correct interface
542*89c4ff92SAndroid Build Coastguard Worker     // Invalid (null) backend instance returned by BackendFactory()
543*89c4ff92SAndroid Build Coastguard Worker 
544*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
545*89c4ff92SAndroid Build Coastguard Worker 
546*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
547*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend6FileName);
548*89c4ff92SAndroid Build Coastguard Worker 
549*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
550*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
551*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
552*89c4ff92SAndroid Build Coastguard Worker 
553*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
554*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)));
555*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend != nullptr));
556*89c4ff92SAndroid Build Coastguard Worker 
557*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId;
558*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackendId = dynamicBackend->GetBackendId());
559*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId == "InvalidTestDynamicBackend"));
560*89c4ff92SAndroid Build Coastguard Worker 
561*89c4ff92SAndroid Build Coastguard Worker     BackendVersion dynamicBackendVersion;
562*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
563*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendVersion >= BackendVersion({ 1, 0 })));
564*89c4ff92SAndroid Build Coastguard Worker 
565*89c4ff92SAndroid Build Coastguard Worker     IBackendInternalUniquePtr dynamicBackendInstance1;
566*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException);
567*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendInstance1 == nullptr));
568*89c4ff92SAndroid Build Coastguard Worker 
569*89c4ff92SAndroid Build Coastguard Worker     BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
570*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
571*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendFactoryFunction != nullptr));
572*89c4ff92SAndroid Build Coastguard Worker 
573*89c4ff92SAndroid Build Coastguard Worker     IBackendInternalUniquePtr dynamicBackendInstance2;
574*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackendInstance2 = dynamicBackendFactoryFunction(), RuntimeException);
575*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendInstance2 == nullptr));
576*89c4ff92SAndroid Build Coastguard Worker }
577*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendObjectInvalidInterface7TestImpl()578*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendObjectInvalidInterface7TestImpl()
579*89c4ff92SAndroid Build Coastguard Worker {
580*89c4ff92SAndroid Build Coastguard Worker     // Valid shared object handle
581*89c4ff92SAndroid Build Coastguard Worker     // Correct name mangling
582*89c4ff92SAndroid Build Coastguard Worker     // Correct interface
583*89c4ff92SAndroid Build Coastguard Worker     // Invalid (incompatible backend API version) backend instance returned by BackendFactory()
584*89c4ff92SAndroid Build Coastguard Worker 
585*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
586*89c4ff92SAndroid Build Coastguard Worker 
587*89c4ff92SAndroid Build Coastguard Worker     std::string testSubDirectory = GetTestSubDirectory(g_TestDynamicBackendSubDir);
588*89c4ff92SAndroid Build Coastguard Worker     std::string sharedObjectFilePath = GetTestFilePath(testSubDirectory, g_TestInvalidTestDynamicBackend7FileName);
589*89c4ff92SAndroid Build Coastguard Worker 
590*89c4ff92SAndroid Build Coastguard Worker     void* sharedObjectHandle = nullptr;
591*89c4ff92SAndroid Build Coastguard Worker     CHECK_NOTHROW(sharedObjectHandle = DynamicBackendUtils::OpenHandle(sharedObjectFilePath));
592*89c4ff92SAndroid Build Coastguard Worker     CHECK((sharedObjectHandle != nullptr));
593*89c4ff92SAndroid Build Coastguard Worker 
594*89c4ff92SAndroid Build Coastguard Worker     DynamicBackendPtr dynamicBackend;
595*89c4ff92SAndroid Build Coastguard Worker     CHECK_THROWS_AS(dynamicBackend.reset(new DynamicBackend(sharedObjectHandle)), RuntimeException);
596*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend == nullptr));
597*89c4ff92SAndroid Build Coastguard Worker }
598*89c4ff92SAndroid Build Coastguard Worker 
GetBackendPathsTestImpl()599*89c4ff92SAndroid Build Coastguard Worker void GetBackendPathsTestImpl()
600*89c4ff92SAndroid Build Coastguard Worker {
601*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
602*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
603*89c4ff92SAndroid Build Coastguard Worker 
604*89c4ff92SAndroid Build Coastguard Worker     // The test covers four directories:
605*89c4ff92SAndroid Build Coastguard Worker     // <unit test path>/src/backends/backendsCommon/test/
606*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath1/   -> exists, contains files
607*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath2/   -> exists, contains files
608*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath3/   -> exists, but empty
609*89c4ff92SAndroid Build Coastguard Worker     //                                                └─ backendsTestPath4/   -> does not exist
610*89c4ff92SAndroid Build Coastguard Worker 
611*89c4ff92SAndroid Build Coastguard Worker     std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
612*89c4ff92SAndroid Build Coastguard Worker     std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
613*89c4ff92SAndroid Build Coastguard Worker     std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
614*89c4ff92SAndroid Build Coastguard Worker     std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
615*89c4ff92SAndroid Build Coastguard Worker 
616*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(subDir1));
617*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(subDir2));
618*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(subDir3));
619*89c4ff92SAndroid Build Coastguard Worker     CHECK(!exists(subDir4));
620*89c4ff92SAndroid Build Coastguard Worker 
621*89c4ff92SAndroid Build Coastguard Worker     // No path
622*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());
623*89c4ff92SAndroid Build Coastguard Worker 
624*89c4ff92SAndroid Build Coastguard Worker     // Malformed path
625*89c4ff92SAndroid Build Coastguard Worker     std::string malformedDir(subDir1 + "/" + subDir1);
626*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::GetBackendPathsImplTest(malformedDir).size()==0);
627*89c4ff92SAndroid Build Coastguard Worker 
628*89c4ff92SAndroid Build Coastguard Worker     // Single valid path
629*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> DynamicBackendPaths2 = TestDynamicBackendUtils::GetBackendPathsImplTest(subDir1);
630*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths2.size() == 1);
631*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths2[0] == subDir1);
632*89c4ff92SAndroid Build Coastguard Worker 
633*89c4ff92SAndroid Build Coastguard Worker     // Multiple equal and valid paths
634*89c4ff92SAndroid Build Coastguard Worker     std::string multipleEqualDirs(subDir1 + ":" + subDir1);
635*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> DynamicBackendPaths3 = TestDynamicBackendUtils::GetBackendPathsImplTest(multipleEqualDirs);
636*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths3.size() == 1);
637*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths3[0] == subDir1);
638*89c4ff92SAndroid Build Coastguard Worker 
639*89c4ff92SAndroid Build Coastguard Worker     // Multiple empty paths
640*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::GetBackendPathsImplTest(":::").empty());
641*89c4ff92SAndroid Build Coastguard Worker 
642*89c4ff92SAndroid Build Coastguard Worker     // Multiple valid paths
643*89c4ff92SAndroid Build Coastguard Worker     std::string multipleValidPaths(subDir1 + ":" + subDir2 + ":" + subDir3);
644*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> DynamicBackendPaths5 =
645*89c4ff92SAndroid Build Coastguard Worker         TestDynamicBackendUtils::GetBackendPathsImplTest(multipleValidPaths);
646*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths5.size() == 3);
647*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths5[0] == subDir1);
648*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths5[1] == subDir2);
649*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths5[2] == subDir3);
650*89c4ff92SAndroid Build Coastguard Worker 
651*89c4ff92SAndroid Build Coastguard Worker     // Valid among empty paths
652*89c4ff92SAndroid Build Coastguard Worker     std::string validAmongEmptyDirs("::" + subDir1 + ":");
653*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> DynamicBackendPaths6 =
654*89c4ff92SAndroid Build Coastguard Worker         TestDynamicBackendUtils::GetBackendPathsImplTest(validAmongEmptyDirs);
655*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths6.size() == 1);
656*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths6[0] == subDir1);
657*89c4ff92SAndroid Build Coastguard Worker 
658*89c4ff92SAndroid Build Coastguard Worker     // Invalid among empty paths
659*89c4ff92SAndroid Build Coastguard Worker     std::string invalidAmongEmptyDirs(":" + subDir4 + "::");
660*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::GetBackendPathsImplTest(invalidAmongEmptyDirs).empty());
661*89c4ff92SAndroid Build Coastguard Worker 
662*89c4ff92SAndroid Build Coastguard Worker     // Valid, invalid and empty paths
663*89c4ff92SAndroid Build Coastguard Worker     std::string validInvalidEmptyDirs(subDir1 + ":" + subDir4 + ":");
664*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> DynamicBackendPaths8 =
665*89c4ff92SAndroid Build Coastguard Worker         TestDynamicBackendUtils::GetBackendPathsImplTest(validInvalidEmptyDirs);
666*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths8.size() == 1);
667*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths8[0] == subDir1);
668*89c4ff92SAndroid Build Coastguard Worker 
669*89c4ff92SAndroid Build Coastguard Worker     // Mix of duplicates of valid, invalid and empty paths
670*89c4ff92SAndroid Build Coastguard Worker     std::string duplicateValidInvalidEmptyDirs(validInvalidEmptyDirs + ":" + validInvalidEmptyDirs + ":" +
671*89c4ff92SAndroid Build Coastguard Worker                                                subDir2 + ":" + subDir2);
672*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> DynamicBackendPaths9 =
673*89c4ff92SAndroid Build Coastguard Worker         TestDynamicBackendUtils::GetBackendPathsImplTest(duplicateValidInvalidEmptyDirs);
674*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths9.size() == 2);
675*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths9[0] == subDir1);
676*89c4ff92SAndroid Build Coastguard Worker     CHECK(DynamicBackendPaths9[1] == subDir2);
677*89c4ff92SAndroid Build Coastguard Worker }
678*89c4ff92SAndroid Build Coastguard Worker 
GetBackendPathsOverrideTestImpl()679*89c4ff92SAndroid Build Coastguard Worker void GetBackendPathsOverrideTestImpl()
680*89c4ff92SAndroid Build Coastguard Worker {
681*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
682*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
683*89c4ff92SAndroid Build Coastguard Worker 
684*89c4ff92SAndroid Build Coastguard Worker     std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
685*89c4ff92SAndroid Build Coastguard Worker     std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
686*89c4ff92SAndroid Build Coastguard Worker 
687*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(subDir1));
688*89c4ff92SAndroid Build Coastguard Worker     CHECK(!exists(subDir4));
689*89c4ff92SAndroid Build Coastguard Worker 
690*89c4ff92SAndroid Build Coastguard Worker     // Override with valid path
691*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> validResult = DynamicBackendUtils::GetBackendPaths(subDir1);
692*89c4ff92SAndroid Build Coastguard Worker     CHECK(validResult.size() == 1);
693*89c4ff92SAndroid Build Coastguard Worker     CHECK(validResult[0] == subDir1);
694*89c4ff92SAndroid Build Coastguard Worker 
695*89c4ff92SAndroid Build Coastguard Worker     // Override with invalid path
696*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> invalidResult = DynamicBackendUtils::GetBackendPaths(subDir4);
697*89c4ff92SAndroid Build Coastguard Worker     CHECK(invalidResult.empty());
698*89c4ff92SAndroid Build Coastguard Worker }
699*89c4ff92SAndroid Build Coastguard Worker 
GetSharedObjectsTestImpl()700*89c4ff92SAndroid Build Coastguard Worker void GetSharedObjectsTestImpl()
701*89c4ff92SAndroid Build Coastguard Worker {
702*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
703*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
704*89c4ff92SAndroid Build Coastguard Worker 
705*89c4ff92SAndroid Build Coastguard Worker     // The test covers four directories:
706*89c4ff92SAndroid Build Coastguard Worker     // <unit test path>/src/backends/backendsCommon/test/
707*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath1/   -> exists, contains files
708*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath2/   -> exists, contains files
709*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath3/   -> exists, but empty
710*89c4ff92SAndroid Build Coastguard Worker     //                                                └─ backendsTestPath4/   -> does not exist
711*89c4ff92SAndroid Build Coastguard Worker     //
712*89c4ff92SAndroid Build Coastguard Worker     // The test sub-directory backendsTestPath1/ contains the following test files:
713*89c4ff92SAndroid Build Coastguard Worker     //
714*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so                                       -> valid (basic backend name)
715*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so.1                                     -> valid (single field version number)
716*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so.1.2                                   -> valid (multiple field version number)
717*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so.1.2.3                                 -> valid (multiple field version number)
718*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so.10.1.27                               -> valid (Multiple digit version)
719*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so.10.1.33.                              -> not valid (dot not followed by version number)
720*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so.3.4..5                                -> not valid (dot not followed by version number)
721*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so.1,1.1                                 -> not valid (comma instead of dot in the version)
722*89c4ff92SAndroid Build Coastguard Worker     //
723*89c4ff92SAndroid Build Coastguard Worker     // Arm123_GpuAcc_backend.so                                    -> valid (digits in vendor name are allowed)
724*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc456_backend.so                                    -> valid (digits in backend id are allowed)
725*89c4ff92SAndroid Build Coastguard Worker     // Arm%Co_GpuAcc_backend.so                                    -> not valid (invalid character in vendor name)
726*89c4ff92SAndroid Build Coastguard Worker     // Arm_Gpu.Acc_backend.so                                      -> not valid (invalid character in backend id)
727*89c4ff92SAndroid Build Coastguard Worker     //
728*89c4ff92SAndroid Build Coastguard Worker     // GpuAcc_backend.so                                           -> not valid (missing vendor name)
729*89c4ff92SAndroid Build Coastguard Worker     // _GpuAcc_backend.so                                          -> not valid (missing vendor name)
730*89c4ff92SAndroid Build Coastguard Worker     // Arm__backend.so                                             -> not valid (missing backend id)
731*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc.so                                               -> not valid (missing "backend" at the end)
732*89c4ff92SAndroid Build Coastguard Worker     // __backend.so                                                -> not valid (missing vendor name and backend id)
733*89c4ff92SAndroid Build Coastguard Worker     // __.so                                                       -> not valid (missing all fields)
734*89c4ff92SAndroid Build Coastguard Worker     //
735*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend                                          -> not valid (missing at least ".so" at the end)
736*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend_v1.2.so                                  -> not valid (extra version info at the end)
737*89c4ff92SAndroid Build Coastguard Worker     //
738*89c4ff92SAndroid Build Coastguard Worker     // The test sub-directory backendsTestPath1/ contains the following test files:
739*89c4ff92SAndroid Build Coastguard Worker     //
740*89c4ff92SAndroid Build Coastguard Worker     // Arm_CpuAcc_backend.so                                       -> valid (basic backend name)
741*89c4ff92SAndroid Build Coastguard Worker     // Arm_CpuAcc_backend.so.1 -> Arm_CpuAcc_backend.so            -> valid (symlink to valid backend file)
742*89c4ff92SAndroid Build Coastguard Worker     // Arm_CpuAcc_backend.so.1.2 -> Arm_CpuAcc_backend.so.1        -> valid (symlink to valid symlink)
743*89c4ff92SAndroid Build Coastguard Worker     // Arm_CpuAcc_backend.so.1.2.3 -> Arm_CpuAcc_backend.so.1.2    -> valid (symlink to valid symlink)
744*89c4ff92SAndroid Build Coastguard Worker     //
745*89c4ff92SAndroid Build Coastguard Worker     // Arm_no_backend.so -> nothing                                -> not valid (symlink resolves to non-existent file)
746*89c4ff92SAndroid Build Coastguard Worker     //
747*89c4ff92SAndroid Build Coastguard Worker     // Arm_GpuAcc_backend.so                                       -> valid (but duplicated from backendsTestPath1/)
748*89c4ff92SAndroid Build Coastguard Worker 
749*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
750*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
751*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
752*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
753*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir1));
754*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir2));
755*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir3));
756*89c4ff92SAndroid Build Coastguard Worker     CHECK(!exists(testDynamicBackendsSubDir4));
757*89c4ff92SAndroid Build Coastguard Worker 
758*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> backendPaths
759*89c4ff92SAndroid Build Coastguard Worker     {
760*89c4ff92SAndroid Build Coastguard Worker         testDynamicBackendsSubDir1,
761*89c4ff92SAndroid Build Coastguard Worker         testDynamicBackendsSubDir2,
762*89c4ff92SAndroid Build Coastguard Worker         testDynamicBackendsSubDir3,
763*89c4ff92SAndroid Build Coastguard Worker         testDynamicBackendsSubDir4
764*89c4ff92SAndroid Build Coastguard Worker     };
765*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
766*89c4ff92SAndroid Build Coastguard Worker     std::vector<fs::path> expectedSharedObjects
767*89c4ff92SAndroid Build Coastguard Worker     {
768*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir1 + "Arm123_GpuAcc_backend.so"),      // Digits in vendor name are allowed
769*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir1 + "Arm_GpuAcc456_backend.so"),      // Digits in backend id are allowed
770*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so"),         // Basic backend name
771*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1"),       // Single field version number
772*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2"),     // Multiple field version number
773*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.1.2.3"),   // Multiple field version number
774*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir1 + "Arm_GpuAcc_backend.so.10.1.27"), // Multiple digit version
775*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir2 + "Arm_CpuAcc_backend.so"),         // Duplicate symlinks removed
776*89c4ff92SAndroid Build Coastguard Worker         path(testDynamicBackendsSubDir2 + "Arm_GpuAcc_backend.so")          // Duplicates on different paths are allowed
777*89c4ff92SAndroid Build Coastguard Worker     };
778*89c4ff92SAndroid Build Coastguard Worker 
779*89c4ff92SAndroid Build Coastguard Worker     CHECK(sharedObjects.size() == expectedSharedObjects.size());
780*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[0]), expectedSharedObjects[0]));
781*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[1]), expectedSharedObjects[1]));
782*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[2]), expectedSharedObjects[2]));
783*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[3]), expectedSharedObjects[3]));
784*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[4]), expectedSharedObjects[4]));
785*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[5]), expectedSharedObjects[5]));
786*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[6]), expectedSharedObjects[6]));
787*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[7]), expectedSharedObjects[7]));
788*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::equivalent(path(sharedObjects[8]), expectedSharedObjects[8]));
789*89c4ff92SAndroid Build Coastguard Worker }
790*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendsTestImpl()791*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendsTestImpl()
792*89c4ff92SAndroid Build Coastguard Worker {
793*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
794*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
795*89c4ff92SAndroid Build Coastguard Worker 
796*89c4ff92SAndroid Build Coastguard Worker     // The test covers four directories:
797*89c4ff92SAndroid Build Coastguard Worker     // <unit test path>/src/backends/backendsCommon/test/
798*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath5/   -> exists, contains files
799*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath6/   -> exists, contains files
800*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath7/   -> exists, but empty
801*89c4ff92SAndroid Build Coastguard Worker     //                                                └─ backendsTestPath8/   -> does not exist
802*89c4ff92SAndroid Build Coastguard Worker     //
803*89c4ff92SAndroid Build Coastguard Worker     // The test sub-directory backendsTestPath5/ contains the following test files:
804*89c4ff92SAndroid Build Coastguard Worker     //
805*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid2_backend.so   -> valid (basic backend name)
806*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid3_backend.so   -> valid (basic backend name)
807*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
808*89c4ff92SAndroid Build Coastguard Worker     //
809*89c4ff92SAndroid Build Coastguard Worker     // The test sub-directory backendsTestPath6/ contains the following test files:
810*89c4ff92SAndroid Build Coastguard Worker     //
811*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid2_backend.so   -> valid (but duplicated from backendsTestPath5/)
812*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid4_backend.so   -> valid (it has a different filename,
813*89c4ff92SAndroid Build Coastguard Worker     //                                       but it has the same backend id of Arm_TestValid2_backend.so
814*89c4ff92SAndroid Build Coastguard Worker     //                                       and the same version)
815*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid5_backend.so   -> valid (basic backend name)
816*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
817*89c4ff92SAndroid Build Coastguard Worker     //                                           but it has the same backend id of Arm_TestValid2_backend.so
818*89c4ff92SAndroid Build Coastguard Worker     //                                           and a version incompatible with the Backend API)
819*89c4ff92SAndroid Build Coastguard Worker 
820*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
821*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
822*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
823*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
824*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir5));
825*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir6));
826*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir7));
827*89c4ff92SAndroid Build Coastguard Worker     CHECK(!exists(testDynamicBackendsSubDir8));
828*89c4ff92SAndroid Build Coastguard Worker 
829*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> backendPaths
830*89c4ff92SAndroid Build Coastguard Worker     {
831*89c4ff92SAndroid Build Coastguard Worker         testDynamicBackendsSubDir5,
832*89c4ff92SAndroid Build Coastguard Worker         testDynamicBackendsSubDir6,
833*89c4ff92SAndroid Build Coastguard Worker         testDynamicBackendsSubDir7,
834*89c4ff92SAndroid Build Coastguard Worker         testDynamicBackendsSubDir8
835*89c4ff92SAndroid Build Coastguard Worker     };
836*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
837*89c4ff92SAndroid Build Coastguard Worker     std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
838*89c4ff92SAndroid Build Coastguard Worker 
839*89c4ff92SAndroid Build Coastguard Worker     CHECK(dynamicBackends.size() == 5);
840*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[0] != nullptr));
841*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[1] != nullptr));
842*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[2] != nullptr));
843*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[3] != nullptr));
844*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[4] != nullptr));
845*89c4ff92SAndroid Build Coastguard Worker 
846*89c4ff92SAndroid Build Coastguard Worker     // Duplicates are allowed here, they will be skipped later during the backend registration
847*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[0]->GetBackendId() == "TestValid2"));
848*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[1]->GetBackendId() == "TestValid3"));
849*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[2]->GetBackendId() == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
850*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[3]->GetBackendId() == "TestValid2")); // From Arm_TestValid4_backend.so
851*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[4]->GetBackendId() == "TestValid5"));
852*89c4ff92SAndroid Build Coastguard Worker }
853*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendsNoPathsTestImpl()854*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendsNoPathsTestImpl()
855*89c4ff92SAndroid Build Coastguard Worker {
856*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
857*89c4ff92SAndroid Build Coastguard Worker 
858*89c4ff92SAndroid Build Coastguard Worker     std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends({});
859*89c4ff92SAndroid Build Coastguard Worker 
860*89c4ff92SAndroid Build Coastguard Worker     CHECK(dynamicBackends.empty());
861*89c4ff92SAndroid Build Coastguard Worker }
862*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendsAllInvalidTestImpl()863*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendsAllInvalidTestImpl()
864*89c4ff92SAndroid Build Coastguard Worker {
865*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
866*89c4ff92SAndroid Build Coastguard Worker 
867*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> sharedObjects
868*89c4ff92SAndroid Build Coastguard Worker     {
869*89c4ff92SAndroid Build Coastguard Worker         "InvalidSharedObject1",
870*89c4ff92SAndroid Build Coastguard Worker         "InvalidSharedObject2",
871*89c4ff92SAndroid Build Coastguard Worker         "InvalidSharedObject3",
872*89c4ff92SAndroid Build Coastguard Worker     };
873*89c4ff92SAndroid Build Coastguard Worker     std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
874*89c4ff92SAndroid Build Coastguard Worker 
875*89c4ff92SAndroid Build Coastguard Worker     CHECK(dynamicBackends.empty());
876*89c4ff92SAndroid Build Coastguard Worker }
877*89c4ff92SAndroid Build Coastguard Worker 
CreateDynamicBackendsMixedTypesTestImpl()878*89c4ff92SAndroid Build Coastguard Worker void CreateDynamicBackendsMixedTypesTestImpl()
879*89c4ff92SAndroid Build Coastguard Worker {
880*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
881*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
882*89c4ff92SAndroid Build Coastguard Worker 
883*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
884*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
885*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir5));
886*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir6));
887*89c4ff92SAndroid Build Coastguard Worker 
888*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
889*89c4ff92SAndroid Build Coastguard Worker                                                             g_TestValidBackend2FileName);
890*89c4ff92SAndroid Build Coastguard Worker     std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
891*89c4ff92SAndroid Build Coastguard Worker                                                               g_TestInvalidBackend8FileName);
892*89c4ff92SAndroid Build Coastguard Worker     std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
893*89c4ff92SAndroid Build Coastguard Worker                                                               g_TestInvalidBackend9FileName);
894*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend2FilePath));
895*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testInvalidBackend8FilePath));
896*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testInvalidBackend9FilePath));
897*89c4ff92SAndroid Build Coastguard Worker 
898*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> sharedObjects
899*89c4ff92SAndroid Build Coastguard Worker     {
900*89c4ff92SAndroid Build Coastguard Worker         testValidBackend2FilePath,   // Arm_TestValid2_backend.so     -> valid (basic backend name)
901*89c4ff92SAndroid Build Coastguard Worker         testInvalidBackend8FilePath, // Arm_TestInvalid8_backend.so   -> not valid (invalid backend id)
902*89c4ff92SAndroid Build Coastguard Worker         testInvalidBackend9FilePath, // Arm_TestInvalid9_backend.so   -> not valid (incompatible version)
903*89c4ff92SAndroid Build Coastguard Worker         "InvalidSharedObject",       // The file does not exist
904*89c4ff92SAndroid Build Coastguard Worker     };
905*89c4ff92SAndroid Build Coastguard Worker     std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
906*89c4ff92SAndroid Build Coastguard Worker 
907*89c4ff92SAndroid Build Coastguard Worker     CHECK(dynamicBackends.size() == 1);
908*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[0] != nullptr));
909*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[0]->GetBackendId() == "TestValid2"));
910*89c4ff92SAndroid Build Coastguard Worker }
911*89c4ff92SAndroid Build Coastguard Worker 
912*89c4ff92SAndroid Build Coastguard Worker #if defined(ARMNNREF_ENABLED)
RegisterSingleDynamicBackendTestImpl()913*89c4ff92SAndroid Build Coastguard Worker void RegisterSingleDynamicBackendTestImpl()
914*89c4ff92SAndroid Build Coastguard Worker {
915*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
916*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
917*89c4ff92SAndroid Build Coastguard Worker 
918*89c4ff92SAndroid Build Coastguard Worker     // Register one valid dynamic backend
919*89c4ff92SAndroid Build Coastguard Worker 
920*89c4ff92SAndroid Build Coastguard Worker     // Dummy registry used for testing
921*89c4ff92SAndroid Build Coastguard Worker     BackendRegistry backendRegistry;
922*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
923*89c4ff92SAndroid Build Coastguard Worker 
924*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
925*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir5));
926*89c4ff92SAndroid Build Coastguard Worker 
927*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
928*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend2FilePath));
929*89c4ff92SAndroid Build Coastguard Worker 
930*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> sharedObjects{ testValidBackend2FilePath };
931*89c4ff92SAndroid Build Coastguard Worker     std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
932*89c4ff92SAndroid Build Coastguard Worker 
933*89c4ff92SAndroid Build Coastguard Worker     CHECK(dynamicBackends.size() == 1);
934*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[0] != nullptr));
935*89c4ff92SAndroid Build Coastguard Worker 
936*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId = dynamicBackends[0]->GetBackendId();
937*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId == "TestValid2"));
938*89c4ff92SAndroid Build Coastguard Worker 
939*89c4ff92SAndroid Build Coastguard Worker     BackendVersion dynamicBackendVersion = dynamicBackends[0]->GetBackendVersion();
940*89c4ff92SAndroid Build Coastguard Worker     CHECK(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
941*89c4ff92SAndroid Build Coastguard Worker 
942*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
943*89c4ff92SAndroid Build Coastguard Worker                                                                                                  dynamicBackends);
944*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 1);
945*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredBackendIds.size() == 1);
946*89c4ff92SAndroid Build Coastguard Worker 
947*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet backendIds = backendRegistry.GetBackendIds();
948*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendIds.size() == 1);
949*89c4ff92SAndroid Build Coastguard Worker     CHECK((backendIds.find(dynamicBackendId) != backendIds.end()));
950*89c4ff92SAndroid Build Coastguard Worker     CHECK((registeredBackendIds.find(dynamicBackendId) != registeredBackendIds.end()));
951*89c4ff92SAndroid Build Coastguard Worker 
952*89c4ff92SAndroid Build Coastguard Worker     auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
953*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendFactoryFunction != nullptr));
954*89c4ff92SAndroid Build Coastguard Worker 
955*89c4ff92SAndroid Build Coastguard Worker     IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
956*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend != nullptr));
957*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackend->GetId() == dynamicBackendId));
958*89c4ff92SAndroid Build Coastguard Worker }
959*89c4ff92SAndroid Build Coastguard Worker 
RegisterMultipleDynamicBackendsTestImpl()960*89c4ff92SAndroid Build Coastguard Worker void RegisterMultipleDynamicBackendsTestImpl()
961*89c4ff92SAndroid Build Coastguard Worker {
962*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
963*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
964*89c4ff92SAndroid Build Coastguard Worker 
965*89c4ff92SAndroid Build Coastguard Worker     // Register many valid dynamic backends
966*89c4ff92SAndroid Build Coastguard Worker 
967*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
968*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
969*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir5));
970*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir6));
971*89c4ff92SAndroid Build Coastguard Worker 
972*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
973*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
974*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
975*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend2FilePath));
976*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend3FilePath));
977*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend5FilePath));
978*89c4ff92SAndroid Build Coastguard Worker 
979*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> sharedObjects
980*89c4ff92SAndroid Build Coastguard Worker     {
981*89c4ff92SAndroid Build Coastguard Worker         testValidBackend2FilePath,
982*89c4ff92SAndroid Build Coastguard Worker         testValidBackend3FilePath,
983*89c4ff92SAndroid Build Coastguard Worker         testValidBackend5FilePath
984*89c4ff92SAndroid Build Coastguard Worker     };
985*89c4ff92SAndroid Build Coastguard Worker     std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
986*89c4ff92SAndroid Build Coastguard Worker 
987*89c4ff92SAndroid Build Coastguard Worker     CHECK(dynamicBackends.size() == 3);
988*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[0] != nullptr));
989*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[1] != nullptr));
990*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[2] != nullptr));
991*89c4ff92SAndroid Build Coastguard Worker 
992*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
993*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
994*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
995*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId1 == "TestValid2"));
996*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId2 == "TestValid3"));
997*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId3 == "TestValid5"));
998*89c4ff92SAndroid Build Coastguard Worker 
999*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0; i < dynamicBackends.size(); i++)
1000*89c4ff92SAndroid Build Coastguard Worker     {
1001*89c4ff92SAndroid Build Coastguard Worker         BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1002*89c4ff92SAndroid Build Coastguard Worker         CHECK(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1003*89c4ff92SAndroid Build Coastguard Worker     }
1004*89c4ff92SAndroid Build Coastguard Worker 
1005*89c4ff92SAndroid Build Coastguard Worker     // Dummy registry used for testing
1006*89c4ff92SAndroid Build Coastguard Worker     BackendRegistry backendRegistry;
1007*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
1008*89c4ff92SAndroid Build Coastguard Worker 
1009*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1010*89c4ff92SAndroid Build Coastguard Worker                                                                                                  dynamicBackends);
1011*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 3);
1012*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredBackendIds.size() == 3);
1013*89c4ff92SAndroid Build Coastguard Worker 
1014*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet backendIds = backendRegistry.GetBackendIds();
1015*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendIds.size() == 3);
1016*89c4ff92SAndroid Build Coastguard Worker     CHECK((backendIds.find(dynamicBackendId1) != backendIds.end()));
1017*89c4ff92SAndroid Build Coastguard Worker     CHECK((backendIds.find(dynamicBackendId2) != backendIds.end()));
1018*89c4ff92SAndroid Build Coastguard Worker     CHECK((backendIds.find(dynamicBackendId3) != backendIds.end()));
1019*89c4ff92SAndroid Build Coastguard Worker     CHECK((registeredBackendIds.find(dynamicBackendId1) != registeredBackendIds.end()));
1020*89c4ff92SAndroid Build Coastguard Worker     CHECK((registeredBackendIds.find(dynamicBackendId2) != registeredBackendIds.end()));
1021*89c4ff92SAndroid Build Coastguard Worker     CHECK((registeredBackendIds.find(dynamicBackendId3) != registeredBackendIds.end()));
1022*89c4ff92SAndroid Build Coastguard Worker 
1023*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0; i < dynamicBackends.size(); i++)
1024*89c4ff92SAndroid Build Coastguard Worker     {
1025*89c4ff92SAndroid Build Coastguard Worker         BackendId dynamicBackendId = dynamicBackends[i]->GetBackendId();
1026*89c4ff92SAndroid Build Coastguard Worker 
1027*89c4ff92SAndroid Build Coastguard Worker         auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
1028*89c4ff92SAndroid Build Coastguard Worker         CHECK((dynamicBackendFactoryFunction != nullptr));
1029*89c4ff92SAndroid Build Coastguard Worker 
1030*89c4ff92SAndroid Build Coastguard Worker         IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
1031*89c4ff92SAndroid Build Coastguard Worker         CHECK((dynamicBackend != nullptr));
1032*89c4ff92SAndroid Build Coastguard Worker         CHECK((dynamicBackend->GetId() == dynamicBackendId));
1033*89c4ff92SAndroid Build Coastguard Worker     }
1034*89c4ff92SAndroid Build Coastguard Worker }
1035*89c4ff92SAndroid Build Coastguard Worker 
RegisterMixedDynamicBackendsTestImpl()1036*89c4ff92SAndroid Build Coastguard Worker void RegisterMixedDynamicBackendsTestImpl()
1037*89c4ff92SAndroid Build Coastguard Worker {
1038*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1039*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
1040*89c4ff92SAndroid Build Coastguard Worker 
1041*89c4ff92SAndroid Build Coastguard Worker     // The test covers five directories:
1042*89c4ff92SAndroid Build Coastguard Worker     // <unit test path>/src/backends/backendsCommon/test/
1043*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath5/   -> exists, contains files
1044*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath6/   -> exists, contains files
1045*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath7/   -> exists, but empty
1046*89c4ff92SAndroid Build Coastguard Worker     //                                                ├─ backendsTestPath8/   -> does not exist
1047*89c4ff92SAndroid Build Coastguard Worker     //                                                └─ backendsTestPath9/   -> exists, contains files
1048*89c4ff92SAndroid Build Coastguard Worker     //
1049*89c4ff92SAndroid Build Coastguard Worker     // The test sub-directory backendsTestPath5/ contains the following test files:
1050*89c4ff92SAndroid Build Coastguard Worker     //
1051*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid2_backend.so   -> valid (basic backend name)
1052*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid3_backend.so   -> valid (basic backend name)
1053*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
1054*89c4ff92SAndroid Build Coastguard Worker     //
1055*89c4ff92SAndroid Build Coastguard Worker     // The test sub-directory backendsTestPath6/ contains the following test files:
1056*89c4ff92SAndroid Build Coastguard Worker     //
1057*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid2_backend.so   -> valid (but duplicated from backendsTestPath5/)
1058*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid4_backend.so   -> valid (it has a different filename,
1059*89c4ff92SAndroid Build Coastguard Worker     //                                       but it has the same backend id of Arm_TestValid2_backend.so
1060*89c4ff92SAndroid Build Coastguard Worker     //                                       and the same version)
1061*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestValid5_backend.so   -> valid (basic backend name)
1062*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
1063*89c4ff92SAndroid Build Coastguard Worker     //                                           but it has the same backend id of Arm_TestValid2_backend.so
1064*89c4ff92SAndroid Build Coastguard Worker     //                                           and a version incompatible with the Backend API)
1065*89c4ff92SAndroid Build Coastguard Worker     //
1066*89c4ff92SAndroid Build Coastguard Worker     // The test sub-directory backendsTestPath9/ contains the following test files:
1067*89c4ff92SAndroid Build Coastguard Worker     //
1068*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestInvalid10_backend.so -> not valid (empty backend id)
1069*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestInvalid11_backend.so -> not valid ("Unknown" backend id)
1070*89c4ff92SAndroid Build Coastguard Worker 
1071*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1072*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1073*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
1074*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
1075*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1076*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir5));
1077*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir6));
1078*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir7));
1079*89c4ff92SAndroid Build Coastguard Worker     CHECK(!exists(testDynamicBackendsSubDir8));
1080*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir9));
1081*89c4ff92SAndroid Build Coastguard Worker 
1082*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend2FilePath    = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
1083*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend3FilePath    = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
1084*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend2DupFilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend2FileName);
1085*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend4FilePath    = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend4FileName);
1086*89c4ff92SAndroid Build Coastguard Worker     std::string testValidBackend5FilePath    = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
1087*89c4ff92SAndroid Build Coastguard Worker     std::string testInvalidBackend8FilePath  = GetTestFilePath(testDynamicBackendsSubDir5,
1088*89c4ff92SAndroid Build Coastguard Worker                                                                g_TestInvalidBackend8FileName);
1089*89c4ff92SAndroid Build Coastguard Worker     std::string testInvalidBackend9FilePath  = GetTestFilePath(testDynamicBackendsSubDir6,
1090*89c4ff92SAndroid Build Coastguard Worker                                                                g_TestInvalidBackend9FileName);
1091*89c4ff92SAndroid Build Coastguard Worker     std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1092*89c4ff92SAndroid Build Coastguard Worker                                                                g_TestInvalidBackend10FileName);
1093*89c4ff92SAndroid Build Coastguard Worker     std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1094*89c4ff92SAndroid Build Coastguard Worker                                                                g_TestInvalidBackend11FileName);
1095*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend2FilePath));
1096*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend3FilePath));
1097*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend2DupFilePath));
1098*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend4FilePath));
1099*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testValidBackend5FilePath));
1100*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testInvalidBackend8FilePath));
1101*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testInvalidBackend9FilePath));
1102*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testInvalidBackend10FilePath));
1103*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testInvalidBackend11FilePath));
1104*89c4ff92SAndroid Build Coastguard Worker 
1105*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> sharedObjects
1106*89c4ff92SAndroid Build Coastguard Worker     {
1107*89c4ff92SAndroid Build Coastguard Worker         testValidBackend2FilePath,
1108*89c4ff92SAndroid Build Coastguard Worker         testValidBackend3FilePath,
1109*89c4ff92SAndroid Build Coastguard Worker         testValidBackend2DupFilePath,
1110*89c4ff92SAndroid Build Coastguard Worker         testValidBackend4FilePath,
1111*89c4ff92SAndroid Build Coastguard Worker         testValidBackend5FilePath,
1112*89c4ff92SAndroid Build Coastguard Worker         testInvalidBackend8FilePath,
1113*89c4ff92SAndroid Build Coastguard Worker         testInvalidBackend9FilePath,
1114*89c4ff92SAndroid Build Coastguard Worker         testInvalidBackend10FilePath,
1115*89c4ff92SAndroid Build Coastguard Worker         testInvalidBackend11FilePath,
1116*89c4ff92SAndroid Build Coastguard Worker         "InvalidSharedObject"
1117*89c4ff92SAndroid Build Coastguard Worker     };
1118*89c4ff92SAndroid Build Coastguard Worker     std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1119*89c4ff92SAndroid Build Coastguard Worker 
1120*89c4ff92SAndroid Build Coastguard Worker     CHECK(dynamicBackends.size() == 7);
1121*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[0] != nullptr));
1122*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[1] != nullptr));
1123*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[2] != nullptr));
1124*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[3] != nullptr));
1125*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[4] != nullptr));
1126*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[5] != nullptr));
1127*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[6] != nullptr));
1128*89c4ff92SAndroid Build Coastguard Worker 
1129*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1130*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1131*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
1132*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId4 = dynamicBackends[3]->GetBackendId();
1133*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId5 = dynamicBackends[4]->GetBackendId();
1134*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId6 = dynamicBackends[5]->GetBackendId();
1135*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId7 = dynamicBackends[6]->GetBackendId();
1136*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId1 == "TestValid2"));
1137*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId2 == "TestValid3"));
1138*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId3 == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
1139*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId4 == "TestValid2")); // From Arm_TestValid4_backend.so
1140*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId5 == "TestValid5"));
1141*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId6 == ""));
1142*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId7 == "Unknown"));
1143*89c4ff92SAndroid Build Coastguard Worker 
1144*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0; i < dynamicBackends.size(); i++)
1145*89c4ff92SAndroid Build Coastguard Worker     {
1146*89c4ff92SAndroid Build Coastguard Worker         BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1147*89c4ff92SAndroid Build Coastguard Worker         CHECK(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1148*89c4ff92SAndroid Build Coastguard Worker     }
1149*89c4ff92SAndroid Build Coastguard Worker 
1150*89c4ff92SAndroid Build Coastguard Worker     // Dummy registry used for testing
1151*89c4ff92SAndroid Build Coastguard Worker     BackendRegistry backendRegistry;
1152*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
1153*89c4ff92SAndroid Build Coastguard Worker 
1154*89c4ff92SAndroid Build Coastguard Worker     std::vector<BackendId> expectedRegisteredbackendIds
1155*89c4ff92SAndroid Build Coastguard Worker     {
1156*89c4ff92SAndroid Build Coastguard Worker         "TestValid2",
1157*89c4ff92SAndroid Build Coastguard Worker         "TestValid3",
1158*89c4ff92SAndroid Build Coastguard Worker         "TestValid5"
1159*89c4ff92SAndroid Build Coastguard Worker     };
1160*89c4ff92SAndroid Build Coastguard Worker 
1161*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1162*89c4ff92SAndroid Build Coastguard Worker                                                                                                  dynamicBackends);
1163*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1164*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredBackendIds.size() == expectedRegisteredbackendIds.size());
1165*89c4ff92SAndroid Build Coastguard Worker 
1166*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet backendIds = backendRegistry.GetBackendIds();
1167*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendIds.size() == expectedRegisteredbackendIds.size());
1168*89c4ff92SAndroid Build Coastguard Worker     for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1169*89c4ff92SAndroid Build Coastguard Worker     {
1170*89c4ff92SAndroid Build Coastguard Worker         CHECK((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1171*89c4ff92SAndroid Build Coastguard Worker         CHECK((registeredBackendIds.find(expectedRegisteredbackendId) != registeredBackendIds.end()));
1172*89c4ff92SAndroid Build Coastguard Worker 
1173*89c4ff92SAndroid Build Coastguard Worker         auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(expectedRegisteredbackendId);
1174*89c4ff92SAndroid Build Coastguard Worker         CHECK((dynamicBackendFactoryFunction != nullptr));
1175*89c4ff92SAndroid Build Coastguard Worker 
1176*89c4ff92SAndroid Build Coastguard Worker         IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
1177*89c4ff92SAndroid Build Coastguard Worker         CHECK((dynamicBackend != nullptr));
1178*89c4ff92SAndroid Build Coastguard Worker         CHECK((dynamicBackend->GetId() == expectedRegisteredbackendId));
1179*89c4ff92SAndroid Build Coastguard Worker     }
1180*89c4ff92SAndroid Build Coastguard Worker }
1181*89c4ff92SAndroid Build Coastguard Worker #endif
1182*89c4ff92SAndroid Build Coastguard Worker 
RegisterMultipleInvalidDynamicBackendsTestImpl()1183*89c4ff92SAndroid Build Coastguard Worker void RegisterMultipleInvalidDynamicBackendsTestImpl()
1184*89c4ff92SAndroid Build Coastguard Worker {
1185*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1186*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
1187*89c4ff92SAndroid Build Coastguard Worker 
1188*89c4ff92SAndroid Build Coastguard Worker     // Try to register many invalid dynamic backends
1189*89c4ff92SAndroid Build Coastguard Worker 
1190*89c4ff92SAndroid Build Coastguard Worker     // The test covers one directory:
1191*89c4ff92SAndroid Build Coastguard Worker     // <unit test path>/src/backends/backendsCommon/test/
1192*89c4ff92SAndroid Build Coastguard Worker     //                                                └─ backendsTestPath9/   -> exists, contains files
1193*89c4ff92SAndroid Build Coastguard Worker     //
1194*89c4ff92SAndroid Build Coastguard Worker     // The test sub-directory backendsTestPath9/ contains the following test files:
1195*89c4ff92SAndroid Build Coastguard Worker     //
1196*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestInvalid10_backend.so -> not valid (invalid backend id)
1197*89c4ff92SAndroid Build Coastguard Worker     // Arm_TestInvalid11_backend.so -> not valid (invalid backend id)
1198*89c4ff92SAndroid Build Coastguard Worker 
1199*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1200*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir9));
1201*89c4ff92SAndroid Build Coastguard Worker 
1202*89c4ff92SAndroid Build Coastguard Worker     std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1203*89c4ff92SAndroid Build Coastguard Worker                                                                g_TestInvalidBackend10FileName);
1204*89c4ff92SAndroid Build Coastguard Worker     std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
1205*89c4ff92SAndroid Build Coastguard Worker                                                                g_TestInvalidBackend11FileName);
1206*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testInvalidBackend10FilePath));
1207*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testInvalidBackend11FilePath));
1208*89c4ff92SAndroid Build Coastguard Worker 
1209*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> sharedObjects
1210*89c4ff92SAndroid Build Coastguard Worker     {
1211*89c4ff92SAndroid Build Coastguard Worker         testInvalidBackend10FilePath,
1212*89c4ff92SAndroid Build Coastguard Worker         testInvalidBackend11FilePath,
1213*89c4ff92SAndroid Build Coastguard Worker         "InvalidSharedObject"
1214*89c4ff92SAndroid Build Coastguard Worker     };
1215*89c4ff92SAndroid Build Coastguard Worker     std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
1216*89c4ff92SAndroid Build Coastguard Worker 
1217*89c4ff92SAndroid Build Coastguard Worker     CHECK(dynamicBackends.size() == 2);
1218*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[0] != nullptr));
1219*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackends[1] != nullptr));
1220*89c4ff92SAndroid Build Coastguard Worker 
1221*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
1222*89c4ff92SAndroid Build Coastguard Worker     BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
1223*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId1 == ""));
1224*89c4ff92SAndroid Build Coastguard Worker     CHECK((dynamicBackendId2 == "Unknown"));
1225*89c4ff92SAndroid Build Coastguard Worker 
1226*89c4ff92SAndroid Build Coastguard Worker     for (size_t i = 0; i < dynamicBackends.size(); i++)
1227*89c4ff92SAndroid Build Coastguard Worker     {
1228*89c4ff92SAndroid Build Coastguard Worker         BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
1229*89c4ff92SAndroid Build Coastguard Worker         CHECK(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
1230*89c4ff92SAndroid Build Coastguard Worker     }
1231*89c4ff92SAndroid Build Coastguard Worker 
1232*89c4ff92SAndroid Build Coastguard Worker     // Dummy registry used for testing
1233*89c4ff92SAndroid Build Coastguard Worker     BackendRegistry backendRegistry;
1234*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
1235*89c4ff92SAndroid Build Coastguard Worker 
1236*89c4ff92SAndroid Build Coastguard Worker     // Check that no dynamic backend got registered
1237*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet registeredBackendIds = TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry,
1238*89c4ff92SAndroid Build Coastguard Worker                                                                                                  dynamicBackends);
1239*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
1240*89c4ff92SAndroid Build Coastguard Worker     CHECK(registeredBackendIds.empty());
1241*89c4ff92SAndroid Build Coastguard Worker }
1242*89c4ff92SAndroid Build Coastguard Worker 
1243*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DYNAMIC_BACKEND_ENABLED)
1244*89c4ff92SAndroid Build Coastguard Worker 
RuntimeEmptyTestImpl()1245*89c4ff92SAndroid Build Coastguard Worker void RuntimeEmptyTestImpl()
1246*89c4ff92SAndroid Build Coastguard Worker {
1247*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1248*89c4ff92SAndroid Build Coastguard Worker 
1249*89c4ff92SAndroid Build Coastguard Worker     // Swapping the backend registry storage for testing
1250*89c4ff92SAndroid Build Coastguard Worker     TestBackendRegistry testBackendRegistry;
1251*89c4ff92SAndroid Build Coastguard Worker 
1252*89c4ff92SAndroid Build Coastguard Worker     const BackendRegistry& backendRegistry = BackendRegistryInstance();
1253*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
1254*89c4ff92SAndroid Build Coastguard Worker 
1255*89c4ff92SAndroid Build Coastguard Worker     IRuntime::CreationOptions creationOptions;
1256*89c4ff92SAndroid Build Coastguard Worker     IRuntimePtr runtime = IRuntime::Create(creationOptions);
1257*89c4ff92SAndroid Build Coastguard Worker 
1258*89c4ff92SAndroid Build Coastguard Worker     const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1259*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1260*89c4ff92SAndroid Build Coastguard Worker     CHECK(supportedBackendIds.empty());
1261*89c4ff92SAndroid Build Coastguard Worker 
1262*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
1263*89c4ff92SAndroid Build Coastguard Worker }
1264*89c4ff92SAndroid Build Coastguard Worker 
1265*89c4ff92SAndroid Build Coastguard Worker #endif
1266*89c4ff92SAndroid Build Coastguard Worker 
RuntimeDynamicBackendsTestImpl()1267*89c4ff92SAndroid Build Coastguard Worker void RuntimeDynamicBackendsTestImpl()
1268*89c4ff92SAndroid Build Coastguard Worker {
1269*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1270*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
1271*89c4ff92SAndroid Build Coastguard Worker 
1272*89c4ff92SAndroid Build Coastguard Worker     // Swapping the backend registry storage for testing
1273*89c4ff92SAndroid Build Coastguard Worker     TestBackendRegistry testBackendRegistry;
1274*89c4ff92SAndroid Build Coastguard Worker 
1275*89c4ff92SAndroid Build Coastguard Worker     // This directory contains valid and invalid backends
1276*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
1277*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir5));
1278*89c4ff92SAndroid Build Coastguard Worker 
1279*89c4ff92SAndroid Build Coastguard Worker     // Using the path override in CreationOptions to load some test dynamic backends
1280*89c4ff92SAndroid Build Coastguard Worker     IRuntime::CreationOptions creationOptions;
1281*89c4ff92SAndroid Build Coastguard Worker     creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir5;
1282*89c4ff92SAndroid Build Coastguard Worker     IRuntimePtr runtime = IRuntime::Create(creationOptions);
1283*89c4ff92SAndroid Build Coastguard Worker 
1284*89c4ff92SAndroid Build Coastguard Worker     std::vector<BackendId> expectedRegisteredbackendIds
1285*89c4ff92SAndroid Build Coastguard Worker     {
1286*89c4ff92SAndroid Build Coastguard Worker         "TestValid2",
1287*89c4ff92SAndroid Build Coastguard Worker         "TestValid3"
1288*89c4ff92SAndroid Build Coastguard Worker     };
1289*89c4ff92SAndroid Build Coastguard Worker 
1290*89c4ff92SAndroid Build Coastguard Worker     const BackendRegistry& backendRegistry = BackendRegistryInstance();
1291*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1292*89c4ff92SAndroid Build Coastguard Worker 
1293*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet backendIds = backendRegistry.GetBackendIds();
1294*89c4ff92SAndroid Build Coastguard Worker     for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1295*89c4ff92SAndroid Build Coastguard Worker     {
1296*89c4ff92SAndroid Build Coastguard Worker         CHECK((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1297*89c4ff92SAndroid Build Coastguard Worker     }
1298*89c4ff92SAndroid Build Coastguard Worker 
1299*89c4ff92SAndroid Build Coastguard Worker     const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1300*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1301*89c4ff92SAndroid Build Coastguard Worker     CHECK(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
1302*89c4ff92SAndroid Build Coastguard Worker     for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1303*89c4ff92SAndroid Build Coastguard Worker     {
1304*89c4ff92SAndroid Build Coastguard Worker         CHECK((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
1305*89c4ff92SAndroid Build Coastguard Worker     }
1306*89c4ff92SAndroid Build Coastguard Worker }
1307*89c4ff92SAndroid Build Coastguard Worker 
RuntimeDuplicateDynamicBackendsTestImpl()1308*89c4ff92SAndroid Build Coastguard Worker void RuntimeDuplicateDynamicBackendsTestImpl()
1309*89c4ff92SAndroid Build Coastguard Worker {
1310*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1311*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
1312*89c4ff92SAndroid Build Coastguard Worker 
1313*89c4ff92SAndroid Build Coastguard Worker     // Swapping the backend registry storage for testing
1314*89c4ff92SAndroid Build Coastguard Worker     TestBackendRegistry testBackendRegistry;
1315*89c4ff92SAndroid Build Coastguard Worker 
1316*89c4ff92SAndroid Build Coastguard Worker     // This directory contains valid, invalid and duplicate backends
1317*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
1318*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir6));
1319*89c4ff92SAndroid Build Coastguard Worker 
1320*89c4ff92SAndroid Build Coastguard Worker     // Using the path override in CreationOptions to load some test dynamic backends
1321*89c4ff92SAndroid Build Coastguard Worker     IRuntime::CreationOptions creationOptions;
1322*89c4ff92SAndroid Build Coastguard Worker     creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir6;
1323*89c4ff92SAndroid Build Coastguard Worker     IRuntimePtr runtime = IRuntime::Create(creationOptions);
1324*89c4ff92SAndroid Build Coastguard Worker 
1325*89c4ff92SAndroid Build Coastguard Worker     std::vector<BackendId> expectedRegisteredbackendIds
1326*89c4ff92SAndroid Build Coastguard Worker     {
1327*89c4ff92SAndroid Build Coastguard Worker         "TestValid2",
1328*89c4ff92SAndroid Build Coastguard Worker         "TestValid5"
1329*89c4ff92SAndroid Build Coastguard Worker     };
1330*89c4ff92SAndroid Build Coastguard Worker 
1331*89c4ff92SAndroid Build Coastguard Worker     const BackendRegistry& backendRegistry = BackendRegistryInstance();
1332*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == expectedRegisteredbackendIds.size());
1333*89c4ff92SAndroid Build Coastguard Worker 
1334*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet backendIds = backendRegistry.GetBackendIds();
1335*89c4ff92SAndroid Build Coastguard Worker     for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1336*89c4ff92SAndroid Build Coastguard Worker     {
1337*89c4ff92SAndroid Build Coastguard Worker         CHECK((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
1338*89c4ff92SAndroid Build Coastguard Worker     }
1339*89c4ff92SAndroid Build Coastguard Worker 
1340*89c4ff92SAndroid Build Coastguard Worker     const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1341*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1342*89c4ff92SAndroid Build Coastguard Worker     CHECK(supportedBackendIds.size() == expectedRegisteredbackendIds.size());
1343*89c4ff92SAndroid Build Coastguard Worker     for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
1344*89c4ff92SAndroid Build Coastguard Worker     {
1345*89c4ff92SAndroid Build Coastguard Worker         CHECK((supportedBackendIds.find(expectedRegisteredbackendId) != supportedBackendIds.end()));
1346*89c4ff92SAndroid Build Coastguard Worker     }
1347*89c4ff92SAndroid Build Coastguard Worker }
1348*89c4ff92SAndroid Build Coastguard Worker 
RuntimeInvalidDynamicBackendsTestImpl()1349*89c4ff92SAndroid Build Coastguard Worker void RuntimeInvalidDynamicBackendsTestImpl()
1350*89c4ff92SAndroid Build Coastguard Worker {
1351*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1352*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
1353*89c4ff92SAndroid Build Coastguard Worker 
1354*89c4ff92SAndroid Build Coastguard Worker     // Swapping the backend registry storage for testing
1355*89c4ff92SAndroid Build Coastguard Worker     TestBackendRegistry testBackendRegistry;
1356*89c4ff92SAndroid Build Coastguard Worker 
1357*89c4ff92SAndroid Build Coastguard Worker     // This directory contains only invalid backends
1358*89c4ff92SAndroid Build Coastguard Worker     std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
1359*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(testDynamicBackendsSubDir9));
1360*89c4ff92SAndroid Build Coastguard Worker 
1361*89c4ff92SAndroid Build Coastguard Worker     // Using the path override in CreationOptions to load some test dynamic backends
1362*89c4ff92SAndroid Build Coastguard Worker     IRuntime::CreationOptions creationOptions;
1363*89c4ff92SAndroid Build Coastguard Worker     creationOptions.m_DynamicBackendsPath = testDynamicBackendsSubDir9;
1364*89c4ff92SAndroid Build Coastguard Worker     IRuntimePtr runtime = IRuntime::Create(creationOptions);
1365*89c4ff92SAndroid Build Coastguard Worker 
1366*89c4ff92SAndroid Build Coastguard Worker     const BackendRegistry& backendRegistry = BackendRegistryInstance();
1367*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
1368*89c4ff92SAndroid Build Coastguard Worker 
1369*89c4ff92SAndroid Build Coastguard Worker     const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1370*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1371*89c4ff92SAndroid Build Coastguard Worker     CHECK(supportedBackendIds.empty());
1372*89c4ff92SAndroid Build Coastguard Worker }
1373*89c4ff92SAndroid Build Coastguard Worker 
RuntimeInvalidOverridePathTestImpl()1374*89c4ff92SAndroid Build Coastguard Worker void RuntimeInvalidOverridePathTestImpl()
1375*89c4ff92SAndroid Build Coastguard Worker {
1376*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1377*89c4ff92SAndroid Build Coastguard Worker 
1378*89c4ff92SAndroid Build Coastguard Worker     // Swapping the backend registry storage for testing
1379*89c4ff92SAndroid Build Coastguard Worker     TestBackendRegistry testBackendRegistry;
1380*89c4ff92SAndroid Build Coastguard Worker 
1381*89c4ff92SAndroid Build Coastguard Worker     // Using the path override in CreationOptions to load some test dynamic backends
1382*89c4ff92SAndroid Build Coastguard Worker     IRuntime::CreationOptions creationOptions;
1383*89c4ff92SAndroid Build Coastguard Worker     creationOptions.m_DynamicBackendsPath = "InvalidPath";
1384*89c4ff92SAndroid Build Coastguard Worker     IRuntimePtr runtime = IRuntime::Create(creationOptions);
1385*89c4ff92SAndroid Build Coastguard Worker 
1386*89c4ff92SAndroid Build Coastguard Worker     const BackendRegistry& backendRegistry = BackendRegistryInstance();
1387*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 0);
1388*89c4ff92SAndroid Build Coastguard Worker 
1389*89c4ff92SAndroid Build Coastguard Worker     const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1390*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1391*89c4ff92SAndroid Build Coastguard Worker     CHECK(supportedBackendIds.empty());
1392*89c4ff92SAndroid Build Coastguard Worker }
1393*89c4ff92SAndroid Build Coastguard Worker 
1394*89c4ff92SAndroid Build Coastguard Worker #if defined(ARMNNREF_ENABLED)
1395*89c4ff92SAndroid Build Coastguard Worker 
1396*89c4ff92SAndroid Build Coastguard Worker // This test unit needs the reference backend, it's not available if the reference backend is not built
1397*89c4ff92SAndroid Build Coastguard Worker 
CreateReferenceDynamicBackendTestImpl()1398*89c4ff92SAndroid Build Coastguard Worker void CreateReferenceDynamicBackendTestImpl()
1399*89c4ff92SAndroid Build Coastguard Worker {
1400*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1401*89c4ff92SAndroid Build Coastguard Worker     using namespace fs;
1402*89c4ff92SAndroid Build Coastguard Worker 
1403*89c4ff92SAndroid Build Coastguard Worker     // Swapping the backend registry storage for testing
1404*89c4ff92SAndroid Build Coastguard Worker     TestBackendRegistry testBackendRegistry;
1405*89c4ff92SAndroid Build Coastguard Worker 
1406*89c4ff92SAndroid Build Coastguard Worker     // This directory contains the reference dynamic backend
1407*89c4ff92SAndroid Build Coastguard Worker     std::string dynamicBackendsBaseDir = GetDynamicBackendsBasePath();
1408*89c4ff92SAndroid Build Coastguard Worker     std::string referenceDynamicBackendSubDir = GetTestSubDirectory(dynamicBackendsBaseDir,
1409*89c4ff92SAndroid Build Coastguard Worker                                                                     g_ReferenceDynamicBackendSubDir);
1410*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(referenceDynamicBackendSubDir));
1411*89c4ff92SAndroid Build Coastguard Worker 
1412*89c4ff92SAndroid Build Coastguard Worker     // Check that the reference dynamic backend file exists
1413*89c4ff92SAndroid Build Coastguard Worker     std::string referenceBackendFilePath = GetTestFilePath(referenceDynamicBackendSubDir,
1414*89c4ff92SAndroid Build Coastguard Worker                                                            g_ReferenceBackendFileName);
1415*89c4ff92SAndroid Build Coastguard Worker     CHECK(exists(referenceBackendFilePath));
1416*89c4ff92SAndroid Build Coastguard Worker 
1417*89c4ff92SAndroid Build Coastguard Worker     // Using the path override in CreationOptions to load the reference dynamic backend
1418*89c4ff92SAndroid Build Coastguard Worker     IRuntime::CreationOptions creationOptions;
1419*89c4ff92SAndroid Build Coastguard Worker     creationOptions.m_DynamicBackendsPath = referenceDynamicBackendSubDir;
1420*89c4ff92SAndroid Build Coastguard Worker     IRuntimePtr runtime = IRuntime::Create(creationOptions);
1421*89c4ff92SAndroid Build Coastguard Worker 
1422*89c4ff92SAndroid Build Coastguard Worker     const BackendRegistry& backendRegistry = BackendRegistryInstance();
1423*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() == 1);
1424*89c4ff92SAndroid Build Coastguard Worker 
1425*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet backendIds = backendRegistry.GetBackendIds();
1426*89c4ff92SAndroid Build Coastguard Worker     CHECK((backendIds.find("CpuRef") != backendIds.end()));
1427*89c4ff92SAndroid Build Coastguard Worker 
1428*89c4ff92SAndroid Build Coastguard Worker     const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1429*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1430*89c4ff92SAndroid Build Coastguard Worker     CHECK(supportedBackendIds.size() == 1);
1431*89c4ff92SAndroid Build Coastguard Worker     CHECK((supportedBackendIds.find("CpuRef") != supportedBackendIds.end()));
1432*89c4ff92SAndroid Build Coastguard Worker 
1433*89c4ff92SAndroid Build Coastguard Worker     // Get the factory function
1434*89c4ff92SAndroid Build Coastguard Worker     auto referenceDynamicBackendFactoryFunction = backendRegistry.GetFactory("CpuRef");
1435*89c4ff92SAndroid Build Coastguard Worker     CHECK((referenceDynamicBackendFactoryFunction != nullptr));
1436*89c4ff92SAndroid Build Coastguard Worker 
1437*89c4ff92SAndroid Build Coastguard Worker     // Use the factory function to create an instance of the reference backend
1438*89c4ff92SAndroid Build Coastguard Worker     IBackendInternalUniquePtr referenceDynamicBackend = referenceDynamicBackendFactoryFunction();
1439*89c4ff92SAndroid Build Coastguard Worker     CHECK((referenceDynamicBackend != nullptr));
1440*89c4ff92SAndroid Build Coastguard Worker     CHECK((referenceDynamicBackend->GetId() == "CpuRef"));
1441*89c4ff92SAndroid Build Coastguard Worker 
1442*89c4ff92SAndroid Build Coastguard Worker     // Test the backend instance by querying the layer support
1443*89c4ff92SAndroid Build Coastguard Worker     IBackendInternal::ILayerSupportSharedPtr referenceLayerSupport = referenceDynamicBackend->GetLayerSupport();
1444*89c4ff92SAndroid Build Coastguard Worker     CHECK((referenceLayerSupport != nullptr));
1445*89c4ff92SAndroid Build Coastguard Worker 
1446*89c4ff92SAndroid Build Coastguard Worker     TensorShape inputShape {  1, 16, 16, 16 };
1447*89c4ff92SAndroid Build Coastguard Worker     TensorShape outputShape{  1, 16, 16, 16 };
1448*89c4ff92SAndroid Build Coastguard Worker     TensorShape weightShape{ 16,  1,  1, 16 };
1449*89c4ff92SAndroid Build Coastguard Worker     TensorInfo inputInfo (inputShape,  DataType::Float32);
1450*89c4ff92SAndroid Build Coastguard Worker     TensorInfo outputInfo(outputShape, DataType::Float32);
1451*89c4ff92SAndroid Build Coastguard Worker     TensorInfo weightInfo(weightShape, DataType::Float32);
1452*89c4ff92SAndroid Build Coastguard Worker     Convolution2dDescriptor convolution2dDescriptor;
1453*89c4ff92SAndroid Build Coastguard Worker     std::vector<TensorInfo> infos = {inputInfo, outputInfo, weightInfo, TensorInfo()};
1454*89c4ff92SAndroid Build Coastguard Worker     bool referenceConvolution2dSupported =
1455*89c4ff92SAndroid Build Coastguard Worker              referenceLayerSupport->IsLayerSupported(LayerType::Convolution2d,
1456*89c4ff92SAndroid Build Coastguard Worker                                                      infos,
1457*89c4ff92SAndroid Build Coastguard Worker                                                      convolution2dDescriptor);
1458*89c4ff92SAndroid Build Coastguard Worker     CHECK(referenceConvolution2dSupported);
1459*89c4ff92SAndroid Build Coastguard Worker 
1460*89c4ff92SAndroid Build Coastguard Worker     // Test the backend instance by creating a workload
1461*89c4ff92SAndroid Build Coastguard Worker     IBackendInternal::IWorkloadFactoryPtr referenceWorkloadFactory = referenceDynamicBackend->CreateWorkloadFactory();
1462*89c4ff92SAndroid Build Coastguard Worker     CHECK((referenceWorkloadFactory != nullptr));
1463*89c4ff92SAndroid Build Coastguard Worker 
1464*89c4ff92SAndroid Build Coastguard Worker     // Create dummy settings for the workload
1465*89c4ff92SAndroid Build Coastguard Worker     Convolution2dQueueDescriptor convolution2dQueueDescriptor;
1466*89c4ff92SAndroid Build Coastguard Worker     WorkloadInfo workloadInfo
1467*89c4ff92SAndroid Build Coastguard Worker     {
1468*89c4ff92SAndroid Build Coastguard Worker         { inputInfo, weightInfo },
1469*89c4ff92SAndroid Build Coastguard Worker         { outputInfo }
1470*89c4ff92SAndroid Build Coastguard Worker     };
1471*89c4ff92SAndroid Build Coastguard Worker     convolution2dQueueDescriptor.m_Inputs.push_back(nullptr);
1472*89c4ff92SAndroid Build Coastguard Worker 
1473*89c4ff92SAndroid Build Coastguard Worker     // Create a convolution workload with the dummy settings
1474*89c4ff92SAndroid Build Coastguard Worker     auto workload = referenceWorkloadFactory->CreateWorkload(LayerType::Convolution2d,
1475*89c4ff92SAndroid Build Coastguard Worker                                                              convolution2dQueueDescriptor,
1476*89c4ff92SAndroid Build Coastguard Worker                                                              workloadInfo);
1477*89c4ff92SAndroid Build Coastguard Worker     CHECK((workload != nullptr));
1478*89c4ff92SAndroid Build Coastguard Worker     CHECK(workload.get() == PolymorphicDowncast<RefConvolution2dWorkload*>(workload.get()));
1479*89c4ff92SAndroid Build Coastguard Worker }
1480*89c4ff92SAndroid Build Coastguard Worker 
1481*89c4ff92SAndroid Build Coastguard Worker #endif
1482*89c4ff92SAndroid Build Coastguard Worker 
1483*89c4ff92SAndroid Build Coastguard Worker #if defined(SAMPLE_DYNAMIC_BACKEND_ENABLED)
1484*89c4ff92SAndroid Build Coastguard Worker 
CheckSampleDynamicBackendLoaded()1485*89c4ff92SAndroid Build Coastguard Worker void CheckSampleDynamicBackendLoaded()
1486*89c4ff92SAndroid Build Coastguard Worker {
1487*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1488*89c4ff92SAndroid Build Coastguard Worker     // At this point we expect DYNAMIC_BACKEND_PATHS to include a path to where libArm_SampleDynamic_backend.so is.
1489*89c4ff92SAndroid Build Coastguard Worker     // If it hasn't been loaded there's no point continuing with the rest of the tests.
1490*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet backendIds = BackendRegistryInstance().GetBackendIds();
1491*89c4ff92SAndroid Build Coastguard Worker     if (backendIds.find("SampleDynamic") == backendIds.end())
1492*89c4ff92SAndroid Build Coastguard Worker     {
1493*89c4ff92SAndroid Build Coastguard Worker         std::string message = "The SampleDynamic backend has not been loaded. This may be a build configuration error. "
1494*89c4ff92SAndroid Build Coastguard Worker                               "Ensure a DYNAMIC_BACKEND_PATHS was set at compile time to the location of "
1495*89c4ff92SAndroid Build Coastguard Worker                               "libArm_SampleDynamic_backend.so. "
1496*89c4ff92SAndroid Build Coastguard Worker                               "To disable this test recompile with: -DSAMPLE_DYNAMIC_BACKEND_ENABLED=0";
1497*89c4ff92SAndroid Build Coastguard Worker         FAIL(message);
1498*89c4ff92SAndroid Build Coastguard Worker     }
1499*89c4ff92SAndroid Build Coastguard Worker }
1500*89c4ff92SAndroid Build Coastguard Worker 
CreateSampleDynamicBackendTestImpl()1501*89c4ff92SAndroid Build Coastguard Worker void CreateSampleDynamicBackendTestImpl()
1502*89c4ff92SAndroid Build Coastguard Worker {
1503*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1504*89c4ff92SAndroid Build Coastguard Worker     // Using the path override in CreationOptions to load the reference dynamic backend
1505*89c4ff92SAndroid Build Coastguard Worker     IRuntime::CreationOptions creationOptions;
1506*89c4ff92SAndroid Build Coastguard Worker     IRuntimePtr runtime = IRuntime::Create(creationOptions);
1507*89c4ff92SAndroid Build Coastguard Worker     const BackendRegistry& backendRegistry = BackendRegistryInstance();
1508*89c4ff92SAndroid Build Coastguard Worker     CHECK(backendRegistry.Size() >= 1);
1509*89c4ff92SAndroid Build Coastguard Worker     CheckSampleDynamicBackendLoaded();
1510*89c4ff92SAndroid Build Coastguard Worker     const DeviceSpec& deviceSpec = *PolymorphicDowncast<const DeviceSpec*>(&runtime->GetDeviceSpec());
1511*89c4ff92SAndroid Build Coastguard Worker     BackendIdSet supportedBackendIds = deviceSpec.GetSupportedBackends();
1512*89c4ff92SAndroid Build Coastguard Worker     CHECK(supportedBackendIds.size()>= 1);
1513*89c4ff92SAndroid Build Coastguard Worker     CHECK((supportedBackendIds.find("SampleDynamic") != supportedBackendIds.end()));
1514*89c4ff92SAndroid Build Coastguard Worker 
1515*89c4ff92SAndroid Build Coastguard Worker     // Get the factory function
1516*89c4ff92SAndroid Build Coastguard Worker     auto sampleDynamicBackendFactoryFunction = backendRegistry.GetFactory("SampleDynamic");
1517*89c4ff92SAndroid Build Coastguard Worker     CHECK((sampleDynamicBackendFactoryFunction != nullptr));
1518*89c4ff92SAndroid Build Coastguard Worker 
1519*89c4ff92SAndroid Build Coastguard Worker     // Use the factory function to create an instance of the dynamic backend
1520*89c4ff92SAndroid Build Coastguard Worker     IBackendInternalUniquePtr sampleDynamicBackend = sampleDynamicBackendFactoryFunction();
1521*89c4ff92SAndroid Build Coastguard Worker     CHECK((sampleDynamicBackend != nullptr));
1522*89c4ff92SAndroid Build Coastguard Worker     CHECK((sampleDynamicBackend->GetId() == "SampleDynamic"));
1523*89c4ff92SAndroid Build Coastguard Worker 
1524*89c4ff92SAndroid Build Coastguard Worker     // Test the backend instance by querying the layer support
1525*89c4ff92SAndroid Build Coastguard Worker     IBackendInternal::ILayerSupportSharedPtr sampleLayerSupport = sampleDynamicBackend->GetLayerSupport();
1526*89c4ff92SAndroid Build Coastguard Worker     CHECK((sampleLayerSupport != nullptr));
1527*89c4ff92SAndroid Build Coastguard Worker 
1528*89c4ff92SAndroid Build Coastguard Worker     TensorShape inputShape {  1, 16, 16, 16 };
1529*89c4ff92SAndroid Build Coastguard Worker     TensorShape outputShape{  1, 16, 16, 16 };
1530*89c4ff92SAndroid Build Coastguard Worker     TensorShape weightShape{ 16,  1,  1, 16 };
1531*89c4ff92SAndroid Build Coastguard Worker     TensorInfo inputInfo (inputShape,  DataType::Float32);
1532*89c4ff92SAndroid Build Coastguard Worker     TensorInfo outputInfo(outputShape, DataType::Float32);
1533*89c4ff92SAndroid Build Coastguard Worker     TensorInfo weightInfo(weightShape, DataType::Float32);
1534*89c4ff92SAndroid Build Coastguard Worker     Convolution2dDescriptor convolution2dDescriptor;
1535*89c4ff92SAndroid Build Coastguard Worker     std::vector<TensorInfo> infos = {inputInfo, outputInfo, weightInfo, TensorInfo()};
1536*89c4ff92SAndroid Build Coastguard Worker     bool sampleConvolution2dSupported =
1537*89c4ff92SAndroid Build Coastguard Worker              sampleLayerSupport->IsLayerSupported(LayerType::Convolution2d,
1538*89c4ff92SAndroid Build Coastguard Worker                                                   infos,
1539*89c4ff92SAndroid Build Coastguard Worker                                                   convolution2dDescriptor);
1540*89c4ff92SAndroid Build Coastguard Worker     CHECK(!sampleConvolution2dSupported);
1541*89c4ff92SAndroid Build Coastguard Worker 
1542*89c4ff92SAndroid Build Coastguard Worker     // Test the backend instance by creating a workload
1543*89c4ff92SAndroid Build Coastguard Worker     IBackendInternal::IWorkloadFactoryPtr sampleWorkloadFactory = sampleDynamicBackend->CreateWorkloadFactory();
1544*89c4ff92SAndroid Build Coastguard Worker     CHECK((sampleWorkloadFactory != nullptr));
1545*89c4ff92SAndroid Build Coastguard Worker 
1546*89c4ff92SAndroid Build Coastguard Worker     // Create dummy settings for the workload
1547*89c4ff92SAndroid Build Coastguard Worker     AdditionQueueDescriptor additionQueueDescriptor;
1548*89c4ff92SAndroid Build Coastguard Worker     WorkloadInfo workloadInfo
1549*89c4ff92SAndroid Build Coastguard Worker     {
1550*89c4ff92SAndroid Build Coastguard Worker         { inputInfo, inputInfo },
1551*89c4ff92SAndroid Build Coastguard Worker         { outputInfo }
1552*89c4ff92SAndroid Build Coastguard Worker     };
1553*89c4ff92SAndroid Build Coastguard Worker 
1554*89c4ff92SAndroid Build Coastguard Worker     // Create a addition workload
1555*89c4ff92SAndroid Build Coastguard Worker     auto workload = sampleWorkloadFactory->CreateWorkload(LayerType::Addition, additionQueueDescriptor, workloadInfo);
1556*89c4ff92SAndroid Build Coastguard Worker     CHECK((workload != nullptr));
1557*89c4ff92SAndroid Build Coastguard Worker }
1558*89c4ff92SAndroid Build Coastguard Worker 
SampleDynamicBackendEndToEndTestImpl()1559*89c4ff92SAndroid Build Coastguard Worker void SampleDynamicBackendEndToEndTestImpl()
1560*89c4ff92SAndroid Build Coastguard Worker {
1561*89c4ff92SAndroid Build Coastguard Worker     using namespace armnn;
1562*89c4ff92SAndroid Build Coastguard Worker     // Create runtime in which test will run
1563*89c4ff92SAndroid Build Coastguard Worker     IRuntime::CreationOptions options;
1564*89c4ff92SAndroid Build Coastguard Worker     IRuntimePtr runtime(IRuntime::Create(options));
1565*89c4ff92SAndroid Build Coastguard Worker     CheckSampleDynamicBackendLoaded();
1566*89c4ff92SAndroid Build Coastguard Worker     // Builds up the structure of the network.
1567*89c4ff92SAndroid Build Coastguard Worker     INetworkPtr net(INetwork::Create());
1568*89c4ff92SAndroid Build Coastguard Worker 
1569*89c4ff92SAndroid Build Coastguard Worker     IConnectableLayer* input0 = net->AddInputLayer(0);
1570*89c4ff92SAndroid Build Coastguard Worker     IConnectableLayer* input1 = net->AddInputLayer(1);
1571*89c4ff92SAndroid Build Coastguard Worker     ARMNN_NO_DEPRECATE_WARN_BEGIN
1572*89c4ff92SAndroid Build Coastguard Worker     IConnectableLayer* add = net->AddAdditionLayer();
1573*89c4ff92SAndroid Build Coastguard Worker     ARMNN_NO_DEPRECATE_WARN_END
1574*89c4ff92SAndroid Build Coastguard Worker     IConnectableLayer* output = net->AddOutputLayer(0);
1575*89c4ff92SAndroid Build Coastguard Worker 
1576*89c4ff92SAndroid Build Coastguard Worker     input0->GetOutputSlot(0).Connect(add->GetInputSlot(0));
1577*89c4ff92SAndroid Build Coastguard Worker     input1->GetOutputSlot(0).Connect(add->GetInputSlot(1));
1578*89c4ff92SAndroid Build Coastguard Worker     add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
1579*89c4ff92SAndroid Build Coastguard Worker 
1580*89c4ff92SAndroid Build Coastguard Worker     TensorInfo tensorInfo(TensorShape({2, 1}), DataType::Float32);
1581*89c4ff92SAndroid Build Coastguard Worker     input0->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1582*89c4ff92SAndroid Build Coastguard Worker     input1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1583*89c4ff92SAndroid Build Coastguard Worker     add->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1584*89c4ff92SAndroid Build Coastguard Worker 
1585*89c4ff92SAndroid Build Coastguard Worker     // optimize the network
1586*89c4ff92SAndroid Build Coastguard Worker     IOptimizedNetworkPtr optNet = Optimize(*net, {"SampleDynamic"}, runtime->GetDeviceSpec());
1587*89c4ff92SAndroid Build Coastguard Worker 
1588*89c4ff92SAndroid Build Coastguard Worker     // Loads it into the runtime.
1589*89c4ff92SAndroid Build Coastguard Worker     NetworkId netId;
1590*89c4ff92SAndroid Build Coastguard Worker     runtime->LoadNetwork(netId, std::move(optNet));
1591*89c4ff92SAndroid Build Coastguard Worker 
1592*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> input0Data{ 5.0f, 3.0f };
1593*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> input1Data{ 10.0f, 8.0f };
1594*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> expectedOutputData{ 15.0f, 11.0f };
1595*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> outputData(2);
1596*89c4ff92SAndroid Build Coastguard Worker 
1597*89c4ff92SAndroid Build Coastguard Worker     TensorInfo inputTensorInfo = runtime->GetInputTensorInfo(netId, 0);
1598*89c4ff92SAndroid Build Coastguard Worker     inputTensorInfo.SetConstant(true);
1599*89c4ff92SAndroid Build Coastguard Worker     InputTensors inputTensors
1600*89c4ff92SAndroid Build Coastguard Worker         {
1601*89c4ff92SAndroid Build Coastguard Worker             {0,armnn::ConstTensor(inputTensorInfo, input0Data.data())},
1602*89c4ff92SAndroid Build Coastguard Worker             {1,armnn::ConstTensor(inputTensorInfo, input1Data.data())}
1603*89c4ff92SAndroid Build Coastguard Worker         };
1604*89c4ff92SAndroid Build Coastguard Worker     OutputTensors outputTensors
1605*89c4ff92SAndroid Build Coastguard Worker         {
1606*89c4ff92SAndroid Build Coastguard Worker             {0,armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
1607*89c4ff92SAndroid Build Coastguard Worker         };
1608*89c4ff92SAndroid Build Coastguard Worker 
1609*89c4ff92SAndroid Build Coastguard Worker     // Does the inference.
1610*89c4ff92SAndroid Build Coastguard Worker     runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
1611*89c4ff92SAndroid Build Coastguard Worker 
1612*89c4ff92SAndroid Build Coastguard Worker     // Checks the results.
1613*89c4ff92SAndroid Build Coastguard Worker     CHECK(outputData == expectedOutputData);
1614*89c4ff92SAndroid Build Coastguard Worker }
1615*89c4ff92SAndroid Build Coastguard Worker #endif
1616