blob: cf427626efd15f8e312c537adca326be06a34668 [file] [log] [blame]
Aron Virginas-Tardfa14772019-09-24 18:24:47 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "ProfilingConnectionDumpToFileDecorator.hpp"
7
8#include <armnn/Exceptions.hpp>
9
10#include <fstream>
11
Aron Virginas-Taraab82c52019-09-30 14:21:26 +010012#include <boost/numeric/conversion/cast.hpp>
13
Aron Virginas-Tardfa14772019-09-24 18:24:47 +010014namespace armnn
15{
16
17namespace profiling
18{
19
20ProfilingConnectionDumpToFileDecorator::ProfilingConnectionDumpToFileDecorator(
21 std::unique_ptr<IProfilingConnection> connection,
22 const Settings& settings)
23 : m_Connection(std::move(connection))
24 , m_Settings(settings)
25{
26 if (!m_Connection)
27 {
28 throw InvalidArgumentException("Connection cannot be nullptr");
29 }
30}
31
32ProfilingConnectionDumpToFileDecorator::~ProfilingConnectionDumpToFileDecorator()
33{
34 Close();
35}
36
37bool ProfilingConnectionDumpToFileDecorator::IsOpen()
38{
39 return m_Connection->IsOpen();
40}
41
42void ProfilingConnectionDumpToFileDecorator::Close()
43{
44 m_IncomingDumpFileStream.close();
45 m_OutgoingDumpFileStream.close();
46 m_Connection->Close();
47}
48
49bool ProfilingConnectionDumpToFileDecorator::WritePacket(const unsigned char* buffer, uint32_t length)
50{
51 bool success = true;
52 if (m_Settings.m_DumpOutgoing)
53 {
54 success &= DumpOutgoingToFile(reinterpret_cast<const char*>(buffer), length);
55 }
56 success &= m_Connection->WritePacket(buffer, length);
57 return success;
58}
59
60Packet ProfilingConnectionDumpToFileDecorator::ReadPacket(uint32_t timeout)
61{
62 Packet packet = m_Connection->ReadPacket(timeout);
63 if (m_Settings.m_DumpIncoming)
64 {
65 DumpIncomingToFile(packet);
66 }
67 return packet;
68}
69
70bool ProfilingConnectionDumpToFileDecorator::OpenIncomingDumpFile()
71{
72 m_IncomingDumpFileStream.open(m_Settings.m_IncomingDumpFileName, std::ios::out | std::ios::binary);
73 return m_IncomingDumpFileStream.is_open();
74}
75
76bool ProfilingConnectionDumpToFileDecorator::OpenOutgoingDumpFile()
77{
78 m_OutgoingDumpFileStream.open(m_Settings.m_OutgoingDumpFileName, std::ios::out | std::ios::binary);
79 return m_OutgoingDumpFileStream.is_open();
80}
81
82
83/// Dumps incoming data into the file specified by m_Settings.m_IncomingDumpFileName.
84/// If m_IgnoreFileErrors is set to true in m_Settings, write errors will be ignored,
85/// i.e. the method will not throw an exception if it encounters an error while trying
86/// to write the data into the specified file.
87/// @param packet data packet to write
88/// @return nothing
89void ProfilingConnectionDumpToFileDecorator::DumpIncomingToFile(const Packet& packet)
90{
91 bool success = true;
92 if (!m_IncomingDumpFileStream.is_open())
93 {
94 // attempt to open dump file
95 success &= OpenIncomingDumpFile();
96 if (!(success || m_Settings.m_IgnoreFileErrors))
97 {
98 Fail("Failed to open \"" + m_Settings.m_IncomingDumpFileName + "\" for writing");
99 }
100 }
101
102 // attempt to write binary data from packet
Aron Virginas-Taraab82c52019-09-30 14:21:26 +0100103 const unsigned int header = packet.GetHeader();
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100104 const unsigned int packetLength = packet.GetLength();
105
106 m_IncomingDumpFileStream.write(reinterpret_cast<const char*>(&header), sizeof header);
107 m_IncomingDumpFileStream.write(reinterpret_cast<const char*>(&packetLength), sizeof packetLength);
Aron Virginas-Taraab82c52019-09-30 14:21:26 +0100108 m_IncomingDumpFileStream.write(packet.GetData(), boost::numeric_cast<std::streamsize>(packetLength));
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100109
110 success &= m_IncomingDumpFileStream.good();
111 if (!(success || m_Settings.m_IgnoreFileErrors))
112 {
113 Fail("Error writing incoming packet of " + std::to_string(packetLength) + " bytes");
114 }
115}
116
117/// Dumps outgoing data into the file specified by m_Settings.m_OutgoingDumpFileName.
118/// If m_IgnoreFileErrors is set to true in m_Settings, write errors will be ignored,
119/// i.e. the method will not throw an exception if it encounters an error while trying
120/// to write the data into the specified file. However, the return value will still
121/// signal if the write has not been completed succesfully.
122/// @param buffer pointer to data to write
123/// @param length number of bytes to write
124/// @return true if write successful, false otherwise
125bool ProfilingConnectionDumpToFileDecorator::DumpOutgoingToFile(const char* buffer, uint32_t length)
126{
127 bool success = true;
128 if (!m_OutgoingDumpFileStream.is_open())
129 {
130 // attempt to open dump file
131 success &= OpenOutgoingDumpFile();
132 if (!(success || m_Settings.m_IgnoreFileErrors))
133 {
134 Fail("Failed to open \"" + m_Settings.m_OutgoingDumpFileName + "\" for writing");
135 }
136 }
137
138 // attempt to write binary data
Aron Virginas-Taraab82c52019-09-30 14:21:26 +0100139 m_OutgoingDumpFileStream.write(buffer, boost::numeric_cast<std::streamsize>(length));
Aron Virginas-Tardfa14772019-09-24 18:24:47 +0100140 success &= m_OutgoingDumpFileStream.good();
141 if (!(success || m_Settings.m_IgnoreFileErrors))
142 {
143 Fail("Error writing outgoing packet of " + std::to_string(length) + " bytes");
144 }
145
146 return success;
147}
148
149void ProfilingConnectionDumpToFileDecorator::Fail(const std::string& errorMessage)
150{
151 Close();
152 throw RuntimeException(errorMessage);
153}
154
155} // namespace profiling
156
157} // namespace armnn