blob: a63f255aea41efc4010a846b2b539e869078ba0d [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"
13
Matteo Martincigh6db5f202019-09-05 12:02:04 +010014#include <boost/numeric/conversion/cast.hpp>
15
Matteo Martincigh6db5f202019-09-05 12:02:04 +010016#include <algorithm>
17#include <cstring>
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010018#include <memory>
19#include <string>
Matteo Martincigh378bbfc2019-11-04 14:05:28 +000020#include <thread>
Colm Donelan5ccb33d2020-01-24 16:27:02 +000021#include <vector>
Ferran Balaguer73882172019-09-02 16:39:42 +010022
23namespace armnn
24{
25
26namespace profiling
27{
28
Matteo Martincigh34a407d2019-11-06 15:30:54 +000029struct SwTraceHeader
30{
31 uint8_t m_StreamVersion;
32 uint8_t m_PointerBytes;
33 uint8_t m_ThreadIdBytes;
34};
35
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010036struct SwTraceMessage
37{
Matteo Martincigh34a407d2019-11-06 15:30:54 +000038 uint32_t m_Id;
39 std::string m_Name;
40 std::string m_UiName;
41 std::vector<char> m_ArgTypes;
42 std::vector<std::string> m_ArgNames;
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010043};
44
Matteo Martincigh6db5f202019-09-05 12:02:04 +010045struct SwTraceCharPolicy
46{
47 static bool IsValidChar(unsigned char c)
48 {
49 // Check that the given character has ASCII 7-bit encoding
50 return c < 128;
51 }
52};
53
54struct SwTraceNameCharPolicy
55{
56 static bool IsValidChar(unsigned char c)
57 {
58 // Check that the given character has ASCII 7-bit encoding, alpha-numeric and underscore only
59 return c < 128 && (std::isalnum(c) || c == '_');
60 }
61};
62
Matteo Martincigh34a407d2019-11-06 15:30:54 +000063struct SwTraceTypeCharPolicy
64{
65 static bool IsValidChar(unsigned char c)
66 {
67 // Check that the given character is among the allowed ones
68 switch (c)
69 {
70 case '@':
71 case 't':
72 case 'i':
73 case 'I':
74 case 'l':
75 case 'L':
76 case 'F':
77 case 'p':
78 case 's':
79 return true; // Valid char
80 default:
81 return false; // Invalid char
82 }
83 }
84};
85
Matteo Martincigh6db5f202019-09-05 12:02:04 +010086template <typename SwTracePolicy>
87bool IsValidSwTraceString(const std::string& s)
88{
89 // Check that all the characters in the given string conform to the given policy
Keith Davis3201eea2019-10-24 17:30:41 +010090 return std::all_of(s.begin(), s.end(), [](unsigned char c) { return SwTracePolicy::IsValidChar(c); });
Matteo Martincigh6db5f202019-09-05 12:02:04 +010091}
92
93template <typename SwTracePolicy>
94bool StringToSwTraceString(const std::string& s, std::vector<uint32_t>& outputBuffer)
95{
96 // Converts the given string to an SWTrace "string" (i.e. a string of "chars"), and writes it into
97 // the given buffer including the null-terminator. It also pads it to the next uint32_t if necessary
98
99 // Clear the output buffer
100 outputBuffer.clear();
101
102 // Check that the given string is a valid SWTrace "string" (i.e. a string of "chars")
103 if (!IsValidSwTraceString<SwTracePolicy>(s))
104 {
105 return false;
106 }
107
108 // Prepare the output buffer
Keith Davis3201eea2019-10-24 17:30:41 +0100109 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 +0100110 size_t uint32_t_size = sizeof(uint32_t);
111 size_t outBufferSize = 1 + s_size / uint32_t_size + (s_size % uint32_t_size != 0 ? 1 : 0);
112 outputBuffer.resize(outBufferSize, '\0');
113
114 // Write the SWTrace string to the output buffer
115 outputBuffer[0] = boost::numeric_cast<uint32_t>(s_size);
116 std::memcpy(outputBuffer.data() + 1, s.data(), s_size);
117
118 return true;
119}
120
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000121template <typename SwTracePolicy,
122 typename SwTraceBuffer = std::vector<uint32_t>>
123bool ConvertDirectoryComponent(const std::string& directoryComponent, SwTraceBuffer& swTraceBuffer)
124{
125 // Convert the directory component using the given policy
126 SwTraceBuffer tempSwTraceBuffer;
127 bool result = StringToSwTraceString<SwTracePolicy>(directoryComponent, tempSwTraceBuffer);
128 if (!result)
129 {
130 return false;
131 }
132
133 swTraceBuffer.insert(swTraceBuffer.end(), tempSwTraceBuffer.begin(), tempSwTraceBuffer.end());
134
135 return true;
136}
137
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100138uint16_t GetNextUid(bool peekOnly = false);
139
Keith Davise394bd92019-12-02 15:12:19 +0000140std::vector<uint16_t> GetNextCounterUids(uint16_t firstUid, uint16_t cores);
Matteo Martincighab173e92019-09-05 12:02:04 +0100141
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000142void WriteBytes(const IPacketBuffer& packetBuffer, unsigned int offset, const void* value, unsigned int valueSize);
143
Keith Davis3201eea2019-10-24 17:30:41 +0100144uint32_t ConstructHeader(uint32_t packetFamily, uint32_t packetId);
145
146uint32_t ConstructHeader(uint32_t packetFamily, uint32_t packetClass, uint32_t packetType);
147
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000148void WriteUint64(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint64_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100149
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000150void WriteUint32(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint32_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100151
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000152void WriteUint16(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint16_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100153
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000154void WriteUint8(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint8_t value);
155
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000156void WriteBytes(unsigned char* buffer, unsigned int offset, const void* value, unsigned int valueSize);
157
Francis Murtagh3a161982019-09-04 15:25:02 +0100158void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value);
159
Ferran Balaguer73882172019-09-02 16:39:42 +0100160void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value);
161
162void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value);
163
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000164void WriteUint8(unsigned char* buffer, unsigned int offset, uint8_t value);
165
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000166void ReadBytes(const IPacketBufferPtr& packetBuffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]);
167
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000168uint64_t ReadUint64(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Francis Murtagh3a161982019-09-04 15:25:02 +0100169
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000170uint32_t ReadUint32(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Ferran Balaguer73882172019-09-02 16:39:42 +0100171
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000172uint16_t ReadUint16(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Ferran Balaguer73882172019-09-02 16:39:42 +0100173
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000174uint8_t ReadUint8(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100175
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000176void ReadBytes(const unsigned char* buffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]);
177
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100178uint64_t ReadUint64(unsigned const char* buffer, unsigned int offset);
179
180uint32_t ReadUint32(unsigned const char* buffer, unsigned int offset);
181
182uint16_t ReadUint16(unsigned const char* buffer, unsigned int offset);
183
184uint8_t ReadUint8(unsigned const char* buffer, unsigned int offset);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100185
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100186std::string GetSoftwareInfo();
187
188std::string GetSoftwareVersion();
189
190std::string GetHardwareVersion();
191
192std::string GetProcessName();
193
Matteo Martincigh0aed4f92019-10-01 14:25:34 +0100194enum class TimelinePacketStatus
195{
196 Ok,
197 Error,
198 BufferExhaustion
199};
200
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100201uint32_t CalculateSizeOfPaddedSwString(const std::string& str);
202
Finn Williamse63a0262019-10-22 10:30:49 +0100203SwTraceMessage ReadSwTraceMessage(const unsigned char*, unsigned int& offset);
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100204
Matteo Martincigh0aed4f92019-10-01 14:25:34 +0100205TimelinePacketStatus WriteTimelineLabelBinaryPacket(uint64_t profilingGuid,
206 const std::string& label,
207 unsigned char* buffer,
208 unsigned int bufferSize,
209 unsigned int& numberOfBytesWritten);
210
David Monahanf21f6062019-10-07 15:11:15 +0100211TimelinePacketStatus WriteTimelineEntityBinaryPacket(uint64_t profilingGuid,
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100212 unsigned char* buffer,
213 unsigned int bufferSize,
214 unsigned int& numberOfBytesWritten);
David Monahanf21f6062019-10-07 15:11:15 +0100215
Narumol Prangnawarat7e5eec72019-10-16 12:16:26 +0100216TimelinePacketStatus WriteTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
217 uint64_t relationshipGuid,
218 uint64_t headGuid,
219 uint64_t tailGuid,
220 unsigned char* buffer,
221 unsigned int bufferSize,
222 unsigned int& numberOfBytesWritten);
223
Sadik Armagan784db772019-10-08 15:05:38 +0100224TimelinePacketStatus WriteTimelineMessageDirectoryPackage(unsigned char* buffer,
225 unsigned int bufferSize,
226 unsigned int& numberOfBytesWritten);
227
Jan Eilers92fa15b2019-10-15 15:23:25 +0100228TimelinePacketStatus WriteTimelineEventClassBinaryPacket(uint64_t profilingGuid,
229 unsigned char* buffer,
230 unsigned int bufferSize,
231 unsigned int& numberOfBytesWritten);
232
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100233TimelinePacketStatus WriteTimelineEventBinaryPacket(uint64_t timestamp,
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000234 std::thread::id threadId,
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100235 uint64_t profilingGuid,
236 unsigned char* buffer,
237 unsigned int bufferSize,
238 unsigned int& numberOfBytesWritten);
239
Keith Davis3201eea2019-10-24 17:30:41 +0100240std::string CentreAlignFormatting(const std::string& stringToPass, const int spacingWidth);
241
242void PrintCounterDirectory(ICounterDirectory& counterDirectory);
243
Francis Murtagh3a161982019-09-04 15:25:02 +0100244class BufferExhaustion : public armnn::Exception
245{
246 using Exception::Exception;
247};
248
Matteo Martincigh5dc816e2019-11-04 14:05:28 +0000249uint64_t GetTimestamp();
Ferran Balaguer73882172019-09-02 16:39:42 +0100250
Matteo Martincigh5dc816e2019-11-04 14:05:28 +0000251} // namespace profiling
252
253} // namespace armnn
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000254
255namespace std
256{
257
258bool operator==(const std::vector<uint8_t>& left, std::thread::id right);
259
260} // namespace std