1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "DriverTestHelpers.hpp"
7 #include <boost/test/unit_test.hpp>
8 #include <log/log.h>
9
10 #include "../Utils.hpp"
11
12 #include <fstream>
13 #include <iomanip>
14 #include <armnn/INetwork.hpp>
15
16 #include <Filesystem.hpp>
17
18 BOOST_AUTO_TEST_SUITE(UtilsTests)
19
20 using namespace android;
21 using namespace android::nn;
22 using namespace android::hardware;
23 using namespace armnn_driver;
24
25 // The following are helpers for writing unit tests for the driver.
26 namespace
27 {
28
29 struct ExportNetworkGraphFixture
30 {
31 public:
32 // Setup: set the output dump directory and an empty dummy model (as only its memory address is used).
33 // Defaulting the output dump directory to "/data" because it should exist and be writable in all deployments.
ExportNetworkGraphFixture__anone17f23f30111::ExportNetworkGraphFixture34 ExportNetworkGraphFixture()
35 : ExportNetworkGraphFixture("/data")
36 {}
ExportNetworkGraphFixture__anone17f23f30111::ExportNetworkGraphFixture37 ExportNetworkGraphFixture(const std::string& requestInputsAndOutputsDumpDir)
38 : m_RequestInputsAndOutputsDumpDir(requestInputsAndOutputsDumpDir)
39 , m_FileName()
40 , m_FileStream()
41 {
42 // Set the name of the output .dot file.
43 // NOTE: the export now uses a time stamp to name the file so we
44 // can't predict ahead of time what the file name will be.
45 std::string timestamp = "dummy";
46 m_FileName = m_RequestInputsAndOutputsDumpDir / (timestamp + "_networkgraph.dot");
47 }
48
49 // Teardown: delete the dump file regardless of the outcome of the tests.
~ExportNetworkGraphFixture__anone17f23f30111::ExportNetworkGraphFixture50 ~ExportNetworkGraphFixture()
51 {
52 // Close the file stream.
53 m_FileStream.close();
54
55 // Ignore any error (such as file not found).
56 (void)remove(m_FileName.c_str());
57 }
58
FileExists__anone17f23f30111::ExportNetworkGraphFixture59 bool FileExists()
60 {
61 // Close any file opened in a previous session.
62 if (m_FileStream.is_open())
63 {
64 m_FileStream.close();
65 }
66
67 if (m_FileName.empty())
68 {
69 return false;
70 }
71
72 // Open the file.
73 m_FileStream.open(m_FileName, std::ifstream::in);
74
75 // Check that the file is open.
76 if (!m_FileStream.is_open())
77 {
78 return false;
79 }
80
81 // Check that the stream is readable.
82 return m_FileStream.good();
83 }
84
GetFileContent__anone17f23f30111::ExportNetworkGraphFixture85 std::string GetFileContent()
86 {
87 // Check that the stream is readable.
88 if (!m_FileStream.good())
89 {
90 return "";
91 }
92
93 // Get all the contents of the file.
94 return std::string((std::istreambuf_iterator<char>(m_FileStream)),
95 (std::istreambuf_iterator<char>()));
96 }
97
98 fs::path m_RequestInputsAndOutputsDumpDir;
99 fs::path m_FileName;
100
101 private:
102 std::ifstream m_FileStream;
103 };
104
105 class MockOptimizedNetwork final : public armnn::IOptimizedNetwork
106 {
107 public:
MockOptimizedNetwork(const std::string & mockSerializedContent)108 MockOptimizedNetwork(const std::string& mockSerializedContent)
109 : m_MockSerializedContent(mockSerializedContent)
110 {}
~MockOptimizedNetwork()111 ~MockOptimizedNetwork() {}
112
PrintGraph()113 armnn::Status PrintGraph() override { return armnn::Status::Failure; }
SerializeToDot(std::ostream & stream) const114 armnn::Status SerializeToDot(std::ostream& stream) const override
115 {
116 stream << m_MockSerializedContent;
117
118 return stream.good() ? armnn::Status::Success : armnn::Status::Failure;
119 }
120
GetGuid() const121 armnn::profiling::ProfilingGuid GetGuid() const final { return armnn::profiling::ProfilingGuid(0); }
122
UpdateMockSerializedContent(const std::string & mockSerializedContent)123 void UpdateMockSerializedContent(const std::string& mockSerializedContent)
124 {
125 this->m_MockSerializedContent = mockSerializedContent;
126 }
127
128 private:
129 std::string m_MockSerializedContent;
130 };
131
132 } // namespace
133
BOOST_AUTO_TEST_CASE(ExportToEmptyDirectory)134 BOOST_AUTO_TEST_CASE(ExportToEmptyDirectory)
135 {
136 // Set the fixture for this test.
137 ExportNetworkGraphFixture fixture("");
138
139 // Set a mock content for the optimized network.
140 std::string mockSerializedContent = "This is a mock serialized content.";
141
142 // Set a mock optimized network.
143 MockOptimizedNetwork mockOptimizedNetwork(mockSerializedContent);
144
145 // Export the mock optimized network.
146 fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
147 fixture.m_RequestInputsAndOutputsDumpDir);
148
149 // Check that the output file does not exist.
150 BOOST_TEST(!fixture.FileExists());
151 }
152
BOOST_AUTO_TEST_CASE(ExportNetwork)153 BOOST_AUTO_TEST_CASE(ExportNetwork)
154 {
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.
162 MockOptimizedNetwork mockOptimizedNetwork(mockSerializedContent);
163
164 // Export the mock optimized network.
165 fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
166 fixture.m_RequestInputsAndOutputsDumpDir);
167
168 // Check that the output file exists and that it has the correct name.
169 BOOST_TEST(fixture.FileExists());
170
171 // Check that the content of the output file matches the mock content.
172 BOOST_TEST(fixture.GetFileContent() == mockSerializedContent);
173 }
174
BOOST_AUTO_TEST_CASE(ExportNetworkOverwriteFile)175 BOOST_AUTO_TEST_CASE(ExportNetworkOverwriteFile)
176 {
177 // Set the fixture for this test.
178 ExportNetworkGraphFixture fixture;
179
180 // Set a mock content for the optimized network.
181 std::string mockSerializedContent = "This is a mock serialized content.";
182
183 // Set a mock optimized network.
184 MockOptimizedNetwork mockOptimizedNetwork(mockSerializedContent);
185
186 // Export the mock optimized network.
187 fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
188 fixture.m_RequestInputsAndOutputsDumpDir);
189
190 // Check that the output file exists and that it has the correct name.
191 BOOST_TEST(fixture.FileExists());
192
193 // Check that the content of the output file matches the mock content.
194 BOOST_TEST(fixture.GetFileContent() == mockSerializedContent);
195
196 // Update the mock serialized content of the network.
197 mockSerializedContent = "This is ANOTHER mock serialized content!";
198 mockOptimizedNetwork.UpdateMockSerializedContent(mockSerializedContent);
199
200 // Export the mock optimized network.
201 fixture.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
202 fixture.m_RequestInputsAndOutputsDumpDir);
203
204 // Check that the output file still exists and that it has the correct name.
205 BOOST_TEST(fixture.FileExists());
206
207 // Check that the content of the output file matches the mock content.
208 BOOST_TEST(fixture.GetFileContent() == mockSerializedContent);
209 }
210
BOOST_AUTO_TEST_CASE(ExportMultipleNetworks)211 BOOST_AUTO_TEST_CASE(ExportMultipleNetworks)
212 {
213 // Set the fixtures for this test.
214 ExportNetworkGraphFixture fixture1;
215 ExportNetworkGraphFixture fixture2;
216 ExportNetworkGraphFixture fixture3;
217
218 // Set a mock content for the optimized network.
219 std::string mockSerializedContent = "This is a mock serialized content.";
220
221 // Set a mock optimized network.
222 MockOptimizedNetwork mockOptimizedNetwork(mockSerializedContent);
223
224 // Export the mock optimized network.
225 fixture1.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
226 fixture1.m_RequestInputsAndOutputsDumpDir);
227
228 // Check that the output file exists and that it has the correct name.
229 BOOST_TEST(fixture1.FileExists());
230
231 // Check that the content of the output file matches the mock content.
232 BOOST_TEST(fixture1.GetFileContent() == mockSerializedContent);
233
234 // Export the mock optimized network.
235 fixture2.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
236 fixture2.m_RequestInputsAndOutputsDumpDir);
237
238 // Check that the output file exists and that it has the correct name.
239 BOOST_TEST(fixture2.FileExists());
240
241 // Check that the content of the output file matches the mock content.
242 BOOST_TEST(fixture2.GetFileContent() == mockSerializedContent);
243
244 // Export the mock optimized network.
245 fixture3.m_FileName = armnn_driver::ExportNetworkGraphToDotFile(mockOptimizedNetwork,
246 fixture3.m_RequestInputsAndOutputsDumpDir);
247 // Check that the output file exists and that it has the correct name.
248 BOOST_TEST(fixture3.FileExists());
249
250 // Check that the content of the output file matches the mock content.
251 BOOST_TEST(fixture3.GetFileContent() == mockSerializedContent);
252 }
253
254 BOOST_AUTO_TEST_SUITE_END()
255