blob: fcb0c4f556571b8efc0167ee6d7ce21d681f0bf1 [file] [log] [blame]
surmeh0176660052018-03-29 16:33:54 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beck93e48982018-09-05 13:05:09 +01003// SPDX-License-Identifier: MIT
surmeh0176660052018-03-29 16:33:54 +01004//
5
surmeh0149b9e102018-05-17 14:11:25 +01006#include "DriverTestHelpers.hpp"
surmeh0176660052018-03-29 16:33:54 +01007#include <log/log.h>
8
surmeh0176660052018-03-29 16:33:54 +01009#include "../Utils.hpp"
Francis Murtaghd5232962021-02-12 15:01:22 +000010#include <armnn/src/armnn/OptimizedNetworkImpl.hpp>
surmeh0176660052018-03-29 16:33:54 +010011
12#include <fstream>
13#include <iomanip>
Francis Murtaghd5232962021-02-12 15:01:22 +000014#include <memory>
surmeh0176660052018-03-29 16:33:54 +010015#include <armnn/INetwork.hpp>
Francis Murtaghd5232962021-02-12 15:01:22 +000016#include "armnn/NetworkFwd.hpp"
surmeh0176660052018-03-29 16:33:54 +010017
Rob Hughes083be702021-07-19 15:29:47 +010018#include <armnnUtils/Filesystem.hpp>
Colm Donelan08d9a1c2020-09-09 17:56:55 +010019
Sadik Armagan9150bff2021-05-26 15:40:53 +010020#include <doctest/doctest.h>
surmeh0176660052018-03-29 16:33:54 +010021
surmeh0176660052018-03-29 16:33:54 +010022using namespace android;
telsoa01ce3e84a2018-08-31 09:31:35 +010023using namespace android::nn;
24using namespace android::hardware;
25using namespace armnn_driver;
surmeh0176660052018-03-29 16:33:54 +010026
Francis Murtaghd5232962021-02-12 15:01:22 +000027namespace armnn
28{
29
30class Graph
31{
32public:
33 Graph(Graph&& graph) = default;
34};
35
36class MockOptimizedNetworkImpl final : public ::armnn::OptimizedNetworkImpl
37{
38public:
39 MockOptimizedNetworkImpl(const std::string& mockSerializedContent, std::unique_ptr<armnn::Graph>)
40 : ::armnn::OptimizedNetworkImpl(nullptr)
41 , m_MockSerializedContent(mockSerializedContent)
42 {}
43 ~MockOptimizedNetworkImpl() {}
44
45 ::armnn::Status PrintGraph() override { return ::armnn::Status::Failure; }
46 ::armnn::Status SerializeToDot(std::ostream& stream) const override
47 {
48 stream << m_MockSerializedContent;
49
50 return stream.good() ? ::armnn::Status::Success : ::armnn::Status::Failure;
51 }
52
53 ::armnn::profiling::ProfilingGuid GetGuid() const final { return ::armnn::profiling::ProfilingGuid(0); }
54
55 void UpdateMockSerializedContent(const std::string& mockSerializedContent)
56 {
57 this->m_MockSerializedContent = mockSerializedContent;
58 }
59
60private:
61 std::string m_MockSerializedContent;
62};
63
64
65} // armnn namespace
66
Francis Murtaghd5232962021-02-12 15:01:22 +000067
surmeh0176660052018-03-29 16:33:54 +010068// The following are helpers for writing unit tests for the driver.
69namespace
70{
71
72struct ExportNetworkGraphFixture
73{
74public:
75 // Setup: set the output dump directory and an empty dummy model (as only its memory address is used).
telsoa01ce3e84a2018-08-31 09:31:35 +010076 // Defaulting the output dump directory to "/data" because it should exist and be writable in all deployments.
surmeh0176660052018-03-29 16:33:54 +010077 ExportNetworkGraphFixture()
telsoa01ce3e84a2018-08-31 09:31:35 +010078 : ExportNetworkGraphFixture("/data")
surmeh0176660052018-03-29 16:33:54 +010079 {}
Sadik Armagan9150bff2021-05-26 15:40:53 +010080
surmeh0176660052018-03-29 16:33:54 +010081 ExportNetworkGraphFixture(const std::string& requestInputsAndOutputsDumpDir)
Sadik Armagan9150bff2021-05-26 15:40:53 +010082 : m_RequestInputsAndOutputsDumpDir(requestInputsAndOutputsDumpDir), m_FileName(), m_FileStream()
surmeh0176660052018-03-29 16:33:54 +010083 {
surmeh0176660052018-03-29 16:33:54 +010084 // Set the name of the output .dot file.
Jim Flynn829ad302019-12-13 14:43:24 +000085 // NOTE: the export now uses a time stamp to name the file so we
86 // can't predict ahead of time what the file name will be.
87 std::string timestamp = "dummy";
Colm Donelan08d9a1c2020-09-09 17:56:55 +010088 m_FileName = m_RequestInputsAndOutputsDumpDir / (timestamp + "_networkgraph.dot");
surmeh0176660052018-03-29 16:33:54 +010089 }
90
91 // Teardown: delete the dump file regardless of the outcome of the tests.
92 ~ExportNetworkGraphFixture()
93 {
94 // Close the file stream.
95 m_FileStream.close();
96
97 // Ignore any error (such as file not found).
Sadik Armagan9150bff2021-05-26 15:40:53 +010098 (void) remove(m_FileName.c_str());
surmeh0176660052018-03-29 16:33:54 +010099 }
100
101 bool FileExists()
102 {
103 // Close any file opened in a previous session.
104 if (m_FileStream.is_open())
105 {
106 m_FileStream.close();
107 }
108
Jim Flynn829ad302019-12-13 14:43:24 +0000109 if (m_FileName.empty())
110 {
111 return false;
112 }
113
surmeh0176660052018-03-29 16:33:54 +0100114 // Open the file.
115 m_FileStream.open(m_FileName, std::ifstream::in);
116
117 // Check that the file is open.
118 if (!m_FileStream.is_open())
119 {
120 return false;
121 }
122
123 // Check that the stream is readable.
124 return m_FileStream.good();
125 }
126
127 std::string GetFileContent()
128 {
129 // Check that the stream is readable.
130 if (!m_FileStream.good())
131 {
132 return "";
133 }
134
135 // Get all the contents of the file.
136 return std::string((std::istreambuf_iterator<char>(m_FileStream)),
137 (std::istreambuf_iterator<char>()));
138 }
139
Colm Donelan08d9a1c2020-09-09 17:56:55 +0100140 fs::path m_RequestInputsAndOutputsDumpDir;
141 fs::path m_FileName;
surmeh0176660052018-03-29 16:33:54 +0100142
143private:
surmeh0176660052018-03-29 16:33:54 +0100144 std::ifstream m_FileStream;
145};
146
surmeh0176660052018-03-29 16:33:54 +0100147
surmeh0176660052018-03-29 16:33:54 +0100148} // namespace
149
Sadik Armagan9150bff2021-05-26 15:40:53 +0100150TEST_SUITE("UtilsTests")
151{
152
153TEST_CASE("ExportToEmptyDirectory")
surmeh0176660052018-03-29 16:33:54 +0100154{
155 // Set the fixture for this test.
156 ExportNetworkGraphFixture fixture("");
157
158 // Set a mock content for the optimized network.
159 std::string mockSerializedContent = "This is a mock serialized content.";
160
161 // Set a mock optimized network.
Francis Murtaghd5232962021-02-12 15:01:22 +0000162 std::unique_ptr<armnn::Graph> graphPtr;
163
164 std::unique_ptr<::armnn::OptimizedNetworkImpl> mockImpl(
165 new armnn::MockOptimizedNetworkImpl(mockSerializedContent, std::move(graphPtr)));
166 ::armnn::IOptimizedNetwork mockOptimizedNetwork(std::move(mockImpl));
surmeh0176660052018-03-29 16:33:54 +0100167
168 // Export the mock optimized network.
Jim Flynn829ad302019-12-13 14:43:24 +0000169 fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
Sadik Armagan9150bff2021-05-26 15:40:53 +0100170 fixture.m_RequestInputsAndOutputsDumpDir);
surmeh0176660052018-03-29 16:33:54 +0100171
172 // Check that the output file does not exist.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100173 CHECK(!fixture.FileExists());
surmeh0176660052018-03-29 16:33:54 +0100174}
175
Sadik Armagan9150bff2021-05-26 15:40:53 +0100176TEST_CASE("ExportNetwork")
surmeh0176660052018-03-29 16:33:54 +0100177{
178 // Set the fixture for this test.
179 ExportNetworkGraphFixture fixture;
180
181 // Set a mock content for the optimized network.
182 std::string mockSerializedContent = "This is a mock serialized content.";
183
184 // Set a mock optimized network.
Francis Murtaghd5232962021-02-12 15:01:22 +0000185 std::unique_ptr<armnn::Graph> graphPtr;
186
187 std::unique_ptr<::armnn::OptimizedNetworkImpl> mockImpl(
188 new armnn::MockOptimizedNetworkImpl(mockSerializedContent, std::move(graphPtr)));
189 ::armnn::IOptimizedNetwork mockOptimizedNetwork(std::move(mockImpl));
190
surmeh0176660052018-03-29 16:33:54 +0100191
192 // Export the mock optimized network.
Jim Flynn829ad302019-12-13 14:43:24 +0000193 fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
Sadik Armagan9150bff2021-05-26 15:40:53 +0100194 fixture.m_RequestInputsAndOutputsDumpDir);
surmeh0176660052018-03-29 16:33:54 +0100195
196 // Check that the output file exists and that it has the correct name.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100197 CHECK(fixture.FileExists());
surmeh0176660052018-03-29 16:33:54 +0100198
199 // Check that the content of the output file matches the mock content.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100200 CHECK(fixture.GetFileContent() == mockSerializedContent);
surmeh0176660052018-03-29 16:33:54 +0100201}
202
Sadik Armagan9150bff2021-05-26 15:40:53 +0100203TEST_CASE("ExportNetworkOverwriteFile")
surmeh0176660052018-03-29 16:33:54 +0100204{
205 // Set the fixture for this test.
206 ExportNetworkGraphFixture fixture;
207
208 // Set a mock content for the optimized network.
209 std::string mockSerializedContent = "This is a mock serialized content.";
210
211 // Set a mock optimized network.
Francis Murtaghd5232962021-02-12 15:01:22 +0000212 std::unique_ptr<armnn::Graph> graphPtr;
213
214 std::unique_ptr<::armnn::OptimizedNetworkImpl> mockImpl(
215 new armnn::MockOptimizedNetworkImpl(mockSerializedContent, std::move(graphPtr)));
216 ::armnn::IOptimizedNetwork mockOptimizedNetwork(std::move(mockImpl));
surmeh0176660052018-03-29 16:33:54 +0100217
218 // Export the mock optimized network.
Jim Flynn829ad302019-12-13 14:43:24 +0000219 fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
Sadik Armagan9150bff2021-05-26 15:40:53 +0100220 fixture.m_RequestInputsAndOutputsDumpDir);
surmeh0176660052018-03-29 16:33:54 +0100221
222 // Check that the output file exists and that it has the correct name.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100223 CHECK(fixture.FileExists());
surmeh0176660052018-03-29 16:33:54 +0100224
225 // Check that the content of the output file matches the mock content.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100226 CHECK(fixture.GetFileContent() == mockSerializedContent);
surmeh0176660052018-03-29 16:33:54 +0100227
228 // Update the mock serialized content of the network.
229 mockSerializedContent = "This is ANOTHER mock serialized content!";
Francis Murtaghd5232962021-02-12 15:01:22 +0000230 std::unique_ptr<armnn::Graph> graphPtr2;
231 std::unique_ptr<::armnn::OptimizedNetworkImpl> mockImpl2(
232 new armnn::MockOptimizedNetworkImpl(mockSerializedContent, std::move(graphPtr2)));
233 static_cast<armnn::MockOptimizedNetworkImpl*>(mockImpl2.get())->UpdateMockSerializedContent(mockSerializedContent);
234 ::armnn::IOptimizedNetwork mockOptimizedNetwork2(std::move(mockImpl2));
surmeh0176660052018-03-29 16:33:54 +0100235
236 // Export the mock optimized network.
Francis Murtaghd5232962021-02-12 15:01:22 +0000237 fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork2,
Sadik Armagan9150bff2021-05-26 15:40:53 +0100238 fixture.m_RequestInputsAndOutputsDumpDir);
surmeh0176660052018-03-29 16:33:54 +0100239
240 // Check that the output file still exists and that it has the correct name.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100241 CHECK(fixture.FileExists());
surmeh0176660052018-03-29 16:33:54 +0100242
243 // Check that the content of the output file matches the mock content.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100244 CHECK(fixture.GetFileContent() == mockSerializedContent);
surmeh0176660052018-03-29 16:33:54 +0100245}
246
Sadik Armagan9150bff2021-05-26 15:40:53 +0100247TEST_CASE("ExportMultipleNetworks")
surmeh0176660052018-03-29 16:33:54 +0100248{
249 // Set the fixtures for this test.
250 ExportNetworkGraphFixture fixture1;
251 ExportNetworkGraphFixture fixture2;
252 ExportNetworkGraphFixture fixture3;
253
254 // Set a mock content for the optimized network.
255 std::string mockSerializedContent = "This is a mock serialized content.";
256
257 // Set a mock optimized network.
Francis Murtaghd5232962021-02-12 15:01:22 +0000258 std::unique_ptr<armnn::Graph> graphPtr;
259
260 std::unique_ptr<::armnn::OptimizedNetworkImpl> mockImpl(
261 new armnn::MockOptimizedNetworkImpl(mockSerializedContent, std::move(graphPtr)));
262 ::armnn::IOptimizedNetwork mockOptimizedNetwork(std::move(mockImpl));
surmeh0176660052018-03-29 16:33:54 +0100263
264 // Export the mock optimized network.
Jim Flynn829ad302019-12-13 14:43:24 +0000265 fixture1.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
Sadik Armagan9150bff2021-05-26 15:40:53 +0100266 fixture1.m_RequestInputsAndOutputsDumpDir);
surmeh0176660052018-03-29 16:33:54 +0100267
268 // Check that the output file exists and that it has the correct name.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100269 CHECK(fixture1.FileExists());
surmeh0176660052018-03-29 16:33:54 +0100270
271 // Check that the content of the output file matches the mock content.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100272 CHECK(fixture1.GetFileContent() == mockSerializedContent);
surmeh0176660052018-03-29 16:33:54 +0100273
274 // Export the mock optimized network.
Jim Flynn829ad302019-12-13 14:43:24 +0000275 fixture2.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
Sadik Armagan9150bff2021-05-26 15:40:53 +0100276 fixture2.m_RequestInputsAndOutputsDumpDir);
surmeh0176660052018-03-29 16:33:54 +0100277
278 // Check that the output file exists and that it has the correct name.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100279 CHECK(fixture2.FileExists());
surmeh0176660052018-03-29 16:33:54 +0100280
281 // Check that the content of the output file matches the mock content.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100282 CHECK(fixture2.GetFileContent() == mockSerializedContent);
surmeh0176660052018-03-29 16:33:54 +0100283
284 // Export the mock optimized network.
Jim Flynn829ad302019-12-13 14:43:24 +0000285 fixture3.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
Sadik Armagan9150bff2021-05-26 15:40:53 +0100286 fixture3.m_RequestInputsAndOutputsDumpDir);
surmeh0176660052018-03-29 16:33:54 +0100287 // Check that the output file exists and that it has the correct name.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100288 CHECK(fixture3.FileExists());
surmeh0176660052018-03-29 16:33:54 +0100289
290 // Check that the content of the output file matches the mock content.
Sadik Armagan9150bff2021-05-26 15:40:53 +0100291 CHECK(fixture3.GetFileContent() == mockSerializedContent);
surmeh0176660052018-03-29 16:33:54 +0100292}
293
Sadik Armagan9150bff2021-05-26 15:40:53 +0100294}