blob: e2ffb24bf9beb81671f5d3ff3763277676a61226 [file] [log] [blame]
Ferran Balaguer73882172019-09-02 16:39:42 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Francis Murtagh3a161982019-09-04 15:25:02 +01008#include <armnn/Exceptions.hpp>
Colm Donelan5ccb33d2020-01-24 16:27:02 +00009#include <armnn/profiling/ISendTimelinePacket.hpp>
Francis Murtagh3a161982019-09-04 15:25:02 +010010
Keith Davis3201eea2019-10-24 17:30:41 +010011#include "ICounterDirectory.hpp"
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010012#include "IPacketBuffer.hpp"
Jim Flynn4e755a52020-03-29 17:48:26 +010013#include "Packet.hpp"
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010014
Matteo Martincigh6db5f202019-09-05 12:02:04 +010015#include <boost/numeric/conversion/cast.hpp>
16
Matteo Martincigh6db5f202019-09-05 12:02:04 +010017#include <algorithm>
18#include <cstring>
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010019#include <memory>
20#include <string>
Matteo Martincigh378bbfc2019-11-04 14:05:28 +000021#include <thread>
Colm Donelan5ccb33d2020-01-24 16:27:02 +000022#include <vector>
Ferran Balaguer73882172019-09-02 16:39:42 +010023
24namespace armnn
25{
26
27namespace profiling
28{
29
Matteo Martincigh34a407d2019-11-06 15:30:54 +000030struct SwTraceHeader
31{
32 uint8_t m_StreamVersion;
33 uint8_t m_PointerBytes;
34 uint8_t m_ThreadIdBytes;
35};
36
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010037struct SwTraceMessage
38{
Matteo Martincigh34a407d2019-11-06 15:30:54 +000039 uint32_t m_Id;
40 std::string m_Name;
41 std::string m_UiName;
42 std::vector<char> m_ArgTypes;
43 std::vector<std::string> m_ArgNames;
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010044};
45
Matteo Martincigh6db5f202019-09-05 12:02:04 +010046struct SwTraceCharPolicy
47{
48 static bool IsValidChar(unsigned char c)
49 {
50 // Check that the given character has ASCII 7-bit encoding
51 return c < 128;
52 }
53};
54
55struct SwTraceNameCharPolicy
56{
57 static bool IsValidChar(unsigned char c)
58 {
59 // Check that the given character has ASCII 7-bit encoding, alpha-numeric and underscore only
60 return c < 128 && (std::isalnum(c) || c == '_');
61 }
62};
63
Matteo Martincigh34a407d2019-11-06 15:30:54 +000064struct SwTraceTypeCharPolicy
65{
66 static bool IsValidChar(unsigned char c)
67 {
68 // Check that the given character is among the allowed ones
69 switch (c)
70 {
71 case '@':
72 case 't':
73 case 'i':
74 case 'I':
75 case 'l':
76 case 'L':
77 case 'F':
78 case 'p':
79 case 's':
80 return true; // Valid char
81 default:
82 return false; // Invalid char
83 }
84 }
85};
86
Matteo Martincigh6db5f202019-09-05 12:02:04 +010087template <typename SwTracePolicy>
88bool IsValidSwTraceString(const std::string& s)
89{
90 // Check that all the characters in the given string conform to the given policy
Keith Davis3201eea2019-10-24 17:30:41 +010091 return std::all_of(s.begin(), s.end(), [](unsigned char c) { return SwTracePolicy::IsValidChar(c); });
Matteo Martincigh6db5f202019-09-05 12:02:04 +010092}
93
94template <typename SwTracePolicy>
95bool StringToSwTraceString(const std::string& s, std::vector<uint32_t>& outputBuffer)
96{
97 // Converts the given string to an SWTrace "string" (i.e. a string of "chars"), and writes it into
98 // the given buffer including the null-terminator. It also pads it to the next uint32_t if necessary
99
100 // Clear the output buffer
101 outputBuffer.clear();
102
103 // Check that the given string is a valid SWTrace "string" (i.e. a string of "chars")
104 if (!IsValidSwTraceString<SwTracePolicy>(s))
105 {
106 return false;
107 }
108
109 // Prepare the output buffer
Keith Davis3201eea2019-10-24 17:30:41 +0100110 size_t s_size = s.size() + 1; // The size of the string (in chars) plus the null-terminator
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100111 size_t uint32_t_size = sizeof(uint32_t);
Keith Davis5238aff2020-03-11 12:17:05 +0000112 // Output buffer size = StringLength (32 bit) + amount of complete 32bit words that fit into the string
113 // + an additional 32bit word if there are remaining chars to complete the string
114 // (The rest of the 32bit word is then filled with the NULL terminator)
115 size_t outBufferSize = 1 + (s_size / uint32_t_size) + (s_size % uint32_t_size != 0 ? 1 : 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100116 outputBuffer.resize(outBufferSize, '\0');
117
118 // Write the SWTrace string to the output buffer
119 outputBuffer[0] = boost::numeric_cast<uint32_t>(s_size);
120 std::memcpy(outputBuffer.data() + 1, s.data(), s_size);
121
122 return true;
123}
124
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000125template <typename SwTracePolicy,
126 typename SwTraceBuffer = std::vector<uint32_t>>
127bool ConvertDirectoryComponent(const std::string& directoryComponent, SwTraceBuffer& swTraceBuffer)
128{
129 // Convert the directory component using the given policy
130 SwTraceBuffer tempSwTraceBuffer;
131 bool result = StringToSwTraceString<SwTracePolicy>(directoryComponent, tempSwTraceBuffer);
132 if (!result)
133 {
134 return false;
135 }
136
137 swTraceBuffer.insert(swTraceBuffer.end(), tempSwTraceBuffer.begin(), tempSwTraceBuffer.end());
138
139 return true;
140}
141
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100142uint16_t GetNextUid(bool peekOnly = false);
143
Keith Davise394bd92019-12-02 15:12:19 +0000144std::vector<uint16_t> GetNextCounterUids(uint16_t firstUid, uint16_t cores);
Matteo Martincighab173e92019-09-05 12:02:04 +0100145
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000146void WriteBytes(const IPacketBuffer& packetBuffer, unsigned int offset, const void* value, unsigned int valueSize);
147
Keith Davis3201eea2019-10-24 17:30:41 +0100148uint32_t ConstructHeader(uint32_t packetFamily, uint32_t packetId);
149
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000150void WriteUint64(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint64_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100151
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000152void WriteUint32(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint32_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100153
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000154void WriteUint16(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint16_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100155
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000156void WriteUint8(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint8_t value);
157
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000158void WriteBytes(unsigned char* buffer, unsigned int offset, const void* value, unsigned int valueSize);
159
Francis Murtagh3a161982019-09-04 15:25:02 +0100160void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value);
161
Ferran Balaguer73882172019-09-02 16:39:42 +0100162void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value);
163
164void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value);
165
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000166void WriteUint8(unsigned char* buffer, unsigned int offset, uint8_t value);
167
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000168void ReadBytes(const IPacketBufferPtr& packetBuffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]);
169
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000170uint64_t ReadUint64(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Francis Murtagh3a161982019-09-04 15:25:02 +0100171
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000172uint32_t ReadUint32(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Ferran Balaguer73882172019-09-02 16:39:42 +0100173
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000174uint16_t ReadUint16(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Ferran Balaguer73882172019-09-02 16:39:42 +0100175
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000176uint8_t ReadUint8(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100177
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000178void ReadBytes(const unsigned char* buffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]);
179
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100180uint64_t ReadUint64(unsigned const char* buffer, unsigned int offset);
181
182uint32_t ReadUint32(unsigned const char* buffer, unsigned int offset);
183
184uint16_t ReadUint16(unsigned const char* buffer, unsigned int offset);
185
186uint8_t ReadUint8(unsigned const char* buffer, unsigned int offset);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100187
Keith Davis97da5e22020-03-05 16:25:28 +0000188std::pair<uint32_t, uint32_t> CreateTimelinePacketHeader(uint32_t packetFamily,
189 uint32_t packetClass,
190 uint32_t packetType,
191 uint32_t streamId,
192 uint32_t sequenceNumbered,
193 uint32_t dataLength);
194
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100195std::string GetSoftwareInfo();
196
197std::string GetSoftwareVersion();
198
199std::string GetHardwareVersion();
200
201std::string GetProcessName();
202
Matteo Martincigh0aed4f92019-10-01 14:25:34 +0100203enum class TimelinePacketStatus
204{
205 Ok,
206 Error,
207 BufferExhaustion
208};
209
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100210uint32_t CalculateSizeOfPaddedSwString(const std::string& str);
211
Finn Williamse63a0262019-10-22 10:30:49 +0100212SwTraceMessage ReadSwTraceMessage(const unsigned char*, unsigned int& offset);
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100213
Matteo Martincigh0aed4f92019-10-01 14:25:34 +0100214TimelinePacketStatus WriteTimelineLabelBinaryPacket(uint64_t profilingGuid,
215 const std::string& label,
216 unsigned char* buffer,
217 unsigned int bufferSize,
218 unsigned int& numberOfBytesWritten);
219
Keith Davis97da5e22020-03-05 16:25:28 +0000220TimelinePacketStatus WriteTimelineEntityBinary(uint64_t profilingGuid,
221 unsigned char* buffer,
222 unsigned int bufferSize,
223 unsigned int& numberOfBytesWritten);
224
225TimelinePacketStatus WriteTimelineRelationshipBinary(ProfilingRelationshipType relationshipType,
226 uint64_t relationshipGuid,
227 uint64_t headGuid,
228 uint64_t tailGuid,
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100229 unsigned char* buffer,
230 unsigned int bufferSize,
231 unsigned int& numberOfBytesWritten);
David Monahanf21f6062019-10-07 15:11:15 +0100232
Sadik Armagan784db772019-10-08 15:05:38 +0100233TimelinePacketStatus WriteTimelineMessageDirectoryPackage(unsigned char* buffer,
234 unsigned int bufferSize,
235 unsigned int& numberOfBytesWritten);
236
Keith Davis97da5e22020-03-05 16:25:28 +0000237TimelinePacketStatus WriteTimelineEventClassBinary(uint64_t profilingGuid,
238 unsigned char* buffer,
239 unsigned int bufferSize,
240 unsigned int& numberOfBytesWritten);
Jan Eilers92fa15b2019-10-15 15:23:25 +0100241
Keith Davis97da5e22020-03-05 16:25:28 +0000242TimelinePacketStatus WriteTimelineEventBinary(uint64_t timestamp,
243 std::thread::id threadId,
244 uint64_t profilingGuid,
245 unsigned char* buffer,
246 unsigned int bufferSize,
247 unsigned int& numberOfBytesWritten);
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100248
Keith Davis3201eea2019-10-24 17:30:41 +0100249std::string CentreAlignFormatting(const std::string& stringToPass, const int spacingWidth);
250
251void PrintCounterDirectory(ICounterDirectory& counterDirectory);
252
Francis Murtagh3a161982019-09-04 15:25:02 +0100253class BufferExhaustion : public armnn::Exception
254{
255 using Exception::Exception;
256};
257
Matteo Martincigh5dc816e2019-11-04 14:05:28 +0000258uint64_t GetTimestamp();
Ferran Balaguer73882172019-09-02 16:39:42 +0100259
Jim Flynn4e755a52020-03-29 17:48:26 +0100260Packet ReceivePacket(const unsigned char* buffer, uint32_t length);
261
Matteo Martincigh5dc816e2019-11-04 14:05:28 +0000262} // namespace profiling
263
264} // namespace armnn
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000265
266namespace std
267{
268
269bool operator==(const std::vector<uint8_t>& left, std::thread::id right);
270
271} // namespace std