blob: 985c49ef1047eac4c5e8961d05ffa43237cfe183 [file] [log] [blame]
Ferran Balaguer73882172019-09-02 16:39:42 +01001//
Jim Flynn6398a982020-05-27 17:05:21 +01002// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
Ferran Balaguer73882172019-09-02 16:39:42 +01003// 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"
Finn Williams0c8cb992020-05-07 10:38:15 +010013
Finn Williams56b465d2020-05-15 13:34:12 +010014#include <Packet.hpp>
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010015
Matteo Martincigh6db5f202019-09-05 12:02:04 +010016#include <boost/numeric/conversion/cast.hpp>
17
Matteo Martincigh6db5f202019-09-05 12:02:04 +010018#include <algorithm>
19#include <cstring>
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010020#include <memory>
21#include <string>
Matteo Martincigh378bbfc2019-11-04 14:05:28 +000022#include <thread>
Colm Donelan5ccb33d2020-01-24 16:27:02 +000023#include <vector>
Ferran Balaguer73882172019-09-02 16:39:42 +010024
25namespace armnn
26{
27
28namespace profiling
29{
30
Jim Flynn1fdeb992020-07-09 07:28:37 +010031constexpr unsigned int ThreadIdSize = sizeof(int); // Is platform dependent
Colm Donelan5bb3d8a2020-05-12 16:36:46 +010032
Matteo Martincigh34a407d2019-11-06 15:30:54 +000033struct SwTraceHeader
34{
35 uint8_t m_StreamVersion;
36 uint8_t m_PointerBytes;
37 uint8_t m_ThreadIdBytes;
38};
39
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010040struct SwTraceMessage
41{
Matteo Martincigh34a407d2019-11-06 15:30:54 +000042 uint32_t m_Id;
43 std::string m_Name;
44 std::string m_UiName;
45 std::vector<char> m_ArgTypes;
46 std::vector<std::string> m_ArgNames;
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010047};
48
Matteo Martincigh6db5f202019-09-05 12:02:04 +010049struct SwTraceCharPolicy
50{
51 static bool IsValidChar(unsigned char c)
52 {
53 // Check that the given character has ASCII 7-bit encoding
54 return c < 128;
55 }
56};
57
58struct SwTraceNameCharPolicy
59{
60 static bool IsValidChar(unsigned char c)
61 {
62 // Check that the given character has ASCII 7-bit encoding, alpha-numeric and underscore only
63 return c < 128 && (std::isalnum(c) || c == '_');
64 }
65};
66
Matteo Martincigh34a407d2019-11-06 15:30:54 +000067struct SwTraceTypeCharPolicy
68{
69 static bool IsValidChar(unsigned char c)
70 {
71 // Check that the given character is among the allowed ones
72 switch (c)
73 {
74 case '@':
75 case 't':
76 case 'i':
77 case 'I':
78 case 'l':
79 case 'L':
80 case 'F':
81 case 'p':
82 case 's':
83 return true; // Valid char
84 default:
85 return false; // Invalid char
86 }
87 }
88};
89
Matteo Martincigh6db5f202019-09-05 12:02:04 +010090template <typename SwTracePolicy>
91bool IsValidSwTraceString(const std::string& s)
92{
93 // Check that all the characters in the given string conform to the given policy
Keith Davis3201eea2019-10-24 17:30:41 +010094 return std::all_of(s.begin(), s.end(), [](unsigned char c) { return SwTracePolicy::IsValidChar(c); });
Matteo Martincigh6db5f202019-09-05 12:02:04 +010095}
96
97template <typename SwTracePolicy>
98bool StringToSwTraceString(const std::string& s, std::vector<uint32_t>& outputBuffer)
99{
100 // Converts the given string to an SWTrace "string" (i.e. a string of "chars"), and writes it into
101 // the given buffer including the null-terminator. It also pads it to the next uint32_t if necessary
102
103 // Clear the output buffer
104 outputBuffer.clear();
105
106 // Check that the given string is a valid SWTrace "string" (i.e. a string of "chars")
107 if (!IsValidSwTraceString<SwTracePolicy>(s))
108 {
109 return false;
110 }
111
112 // Prepare the output buffer
Keith Davis3201eea2019-10-24 17:30:41 +0100113 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 +0100114 size_t uint32_t_size = sizeof(uint32_t);
Keith Davis5238aff2020-03-11 12:17:05 +0000115 // Output buffer size = StringLength (32 bit) + amount of complete 32bit words that fit into the string
116 // + an additional 32bit word if there are remaining chars to complete the string
117 // (The rest of the 32bit word is then filled with the NULL terminator)
118 size_t outBufferSize = 1 + (s_size / uint32_t_size) + (s_size % uint32_t_size != 0 ? 1 : 0);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100119 outputBuffer.resize(outBufferSize, '\0');
120
121 // Write the SWTrace string to the output buffer
122 outputBuffer[0] = boost::numeric_cast<uint32_t>(s_size);
123 std::memcpy(outputBuffer.data() + 1, s.data(), s_size);
124
125 return true;
126}
127
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000128template <typename SwTracePolicy,
129 typename SwTraceBuffer = std::vector<uint32_t>>
130bool ConvertDirectoryComponent(const std::string& directoryComponent, SwTraceBuffer& swTraceBuffer)
131{
132 // Convert the directory component using the given policy
133 SwTraceBuffer tempSwTraceBuffer;
134 bool result = StringToSwTraceString<SwTracePolicy>(directoryComponent, tempSwTraceBuffer);
135 if (!result)
136 {
137 return false;
138 }
139
140 swTraceBuffer.insert(swTraceBuffer.end(), tempSwTraceBuffer.begin(), tempSwTraceBuffer.end());
141
142 return true;
143}
144
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100145uint16_t GetNextUid(bool peekOnly = false);
146
Keith Davise394bd92019-12-02 15:12:19 +0000147std::vector<uint16_t> GetNextCounterUids(uint16_t firstUid, uint16_t cores);
Matteo Martincighab173e92019-09-05 12:02:04 +0100148
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000149void WriteBytes(const IPacketBuffer& packetBuffer, unsigned int offset, const void* value, unsigned int valueSize);
150
Keith Davis3201eea2019-10-24 17:30:41 +0100151uint32_t ConstructHeader(uint32_t packetFamily, uint32_t packetId);
152
Jim Flynn83d08a92020-07-09 13:48:16 +0100153uint32_t ConstructHeader(uint32_t packetFamily, uint32_t packetClass, uint32_t packetType);
154
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000155void WriteUint64(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint64_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100156
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000157void WriteUint32(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint32_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100158
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000159void WriteUint16(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint16_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100160
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000161void WriteUint8(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint8_t value);
162
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000163void WriteBytes(unsigned char* buffer, unsigned int offset, const void* value, unsigned int valueSize);
164
Francis Murtagh3a161982019-09-04 15:25:02 +0100165void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value);
166
Ferran Balaguer73882172019-09-02 16:39:42 +0100167void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value);
168
169void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value);
170
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000171void WriteUint8(unsigned char* buffer, unsigned int offset, uint8_t value);
172
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000173void ReadBytes(const IPacketBufferPtr& packetBuffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]);
174
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000175uint64_t ReadUint64(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Francis Murtagh3a161982019-09-04 15:25:02 +0100176
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000177uint32_t ReadUint32(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Ferran Balaguer73882172019-09-02 16:39:42 +0100178
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000179uint16_t ReadUint16(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Ferran Balaguer73882172019-09-02 16:39:42 +0100180
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000181uint8_t ReadUint8(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100182
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000183void ReadBytes(const unsigned char* buffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]);
184
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100185uint64_t ReadUint64(unsigned const char* buffer, unsigned int offset);
186
187uint32_t ReadUint32(unsigned const char* buffer, unsigned int offset);
188
189uint16_t ReadUint16(unsigned const char* buffer, unsigned int offset);
190
191uint8_t ReadUint8(unsigned const char* buffer, unsigned int offset);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100192
Keith Davis97da5e22020-03-05 16:25:28 +0000193std::pair<uint32_t, uint32_t> CreateTimelinePacketHeader(uint32_t packetFamily,
194 uint32_t packetClass,
195 uint32_t packetType,
196 uint32_t streamId,
197 uint32_t sequenceNumbered,
198 uint32_t dataLength);
199
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100200std::string GetSoftwareInfo();
201
202std::string GetSoftwareVersion();
203
204std::string GetHardwareVersion();
205
206std::string GetProcessName();
207
Matteo Martincigh0aed4f92019-10-01 14:25:34 +0100208enum class TimelinePacketStatus
209{
210 Ok,
211 Error,
212 BufferExhaustion
213};
214
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100215uint32_t CalculateSizeOfPaddedSwString(const std::string& str);
216
Finn Williamse63a0262019-10-22 10:30:49 +0100217SwTraceMessage ReadSwTraceMessage(const unsigned char*, unsigned int& offset);
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100218
Matteo Martincigh0aed4f92019-10-01 14:25:34 +0100219TimelinePacketStatus WriteTimelineLabelBinaryPacket(uint64_t profilingGuid,
220 const std::string& label,
221 unsigned char* buffer,
222 unsigned int bufferSize,
223 unsigned int& numberOfBytesWritten);
224
Keith Davis97da5e22020-03-05 16:25:28 +0000225TimelinePacketStatus WriteTimelineEntityBinary(uint64_t profilingGuid,
226 unsigned char* buffer,
227 unsigned int bufferSize,
228 unsigned int& numberOfBytesWritten);
229
230TimelinePacketStatus WriteTimelineRelationshipBinary(ProfilingRelationshipType relationshipType,
231 uint64_t relationshipGuid,
232 uint64_t headGuid,
233 uint64_t tailGuid,
Finn Williams0a336dc2020-05-11 15:39:58 +0100234 uint64_t attributeGuid,
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100235 unsigned char* buffer,
236 unsigned int bufferSize,
237 unsigned int& numberOfBytesWritten);
David Monahanf21f6062019-10-07 15:11:15 +0100238
Sadik Armagan784db772019-10-08 15:05:38 +0100239TimelinePacketStatus WriteTimelineMessageDirectoryPackage(unsigned char* buffer,
240 unsigned int bufferSize,
241 unsigned int& numberOfBytesWritten);
242
Keith Davis97da5e22020-03-05 16:25:28 +0000243TimelinePacketStatus WriteTimelineEventClassBinary(uint64_t profilingGuid,
Jim Flynn1892d212020-05-26 21:10:49 +0100244 uint64_t nameGuid,
Keith Davis97da5e22020-03-05 16:25:28 +0000245 unsigned char* buffer,
246 unsigned int bufferSize,
247 unsigned int& numberOfBytesWritten);
Jan Eilers92fa15b2019-10-15 15:23:25 +0100248
Keith Davis97da5e22020-03-05 16:25:28 +0000249TimelinePacketStatus WriteTimelineEventBinary(uint64_t timestamp,
Jim Flynn1fdeb992020-07-09 07:28:37 +0100250 int threadId,
Keith Davis97da5e22020-03-05 16:25:28 +0000251 uint64_t profilingGuid,
252 unsigned char* buffer,
253 unsigned int bufferSize,
254 unsigned int& numberOfBytesWritten);
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100255
Keith Davis3201eea2019-10-24 17:30:41 +0100256std::string CentreAlignFormatting(const std::string& stringToPass, const int spacingWidth);
257
258void PrintCounterDirectory(ICounterDirectory& counterDirectory);
259
Francis Murtagh3a161982019-09-04 15:25:02 +0100260class BufferExhaustion : public armnn::Exception
261{
262 using Exception::Exception;
263};
264
Matteo Martincigh5dc816e2019-11-04 14:05:28 +0000265uint64_t GetTimestamp();
Ferran Balaguer73882172019-09-02 16:39:42 +0100266
Jim Flynn4e755a52020-03-29 17:48:26 +0100267Packet ReceivePacket(const unsigned char* buffer, uint32_t length);
268
Matteo Martincigh5dc816e2019-11-04 14:05:28 +0000269} // namespace profiling
270
271} // namespace armnn
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000272
273namespace std
274{
275
Jim Flynn1fdeb992020-07-09 07:28:37 +0100276bool operator==(const std::vector<uint8_t>& left, int right);
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000277
278} // namespace std