blob: 9bbe421817bae708cd9572fb36809782afb4a06d [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>
9
Keith Davis3201eea2019-10-24 17:30:41 +010010#include "ICounterDirectory.hpp"
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010011#include "IPacketBuffer.hpp"
12
Matteo Martincigh6db5f202019-09-05 12:02:04 +010013#include <boost/numeric/conversion/cast.hpp>
14
Matteo Martincigh6db5f202019-09-05 12:02:04 +010015#include <algorithm>
16#include <cstring>
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010017#include <memory>
18#include <string>
19#include <vector>
Matteo Martincigh378bbfc2019-11-04 14:05:28 +000020#include <thread>
Ferran Balaguer73882172019-09-02 16:39:42 +010021
22namespace armnn
23{
24
25namespace profiling
26{
27
Matteo Martincigh34a407d2019-11-06 15:30:54 +000028struct SwTraceHeader
29{
30 uint8_t m_StreamVersion;
31 uint8_t m_PointerBytes;
32 uint8_t m_ThreadIdBytes;
33};
34
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010035struct SwTraceMessage
36{
Matteo Martincigh34a407d2019-11-06 15:30:54 +000037 uint32_t m_Id;
38 std::string m_Name;
39 std::string m_UiName;
40 std::vector<char> m_ArgTypes;
41 std::vector<std::string> m_ArgNames;
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +010042};
43
Matteo Martincigh6db5f202019-09-05 12:02:04 +010044struct SwTraceCharPolicy
45{
46 static bool IsValidChar(unsigned char c)
47 {
48 // Check that the given character has ASCII 7-bit encoding
49 return c < 128;
50 }
51};
52
53struct SwTraceNameCharPolicy
54{
55 static bool IsValidChar(unsigned char c)
56 {
57 // Check that the given character has ASCII 7-bit encoding, alpha-numeric and underscore only
58 return c < 128 && (std::isalnum(c) || c == '_');
59 }
60};
61
Matteo Martincigh34a407d2019-11-06 15:30:54 +000062struct SwTraceTypeCharPolicy
63{
64 static bool IsValidChar(unsigned char c)
65 {
66 // Check that the given character is among the allowed ones
67 switch (c)
68 {
69 case '@':
70 case 't':
71 case 'i':
72 case 'I':
73 case 'l':
74 case 'L':
75 case 'F':
76 case 'p':
77 case 's':
78 return true; // Valid char
79 default:
80 return false; // Invalid char
81 }
82 }
83};
84
Matteo Martincigh6db5f202019-09-05 12:02:04 +010085template <typename SwTracePolicy>
86bool IsValidSwTraceString(const std::string& s)
87{
88 // Check that all the characters in the given string conform to the given policy
Keith Davis3201eea2019-10-24 17:30:41 +010089 return std::all_of(s.begin(), s.end(), [](unsigned char c) { return SwTracePolicy::IsValidChar(c); });
Matteo Martincigh6db5f202019-09-05 12:02:04 +010090}
91
92template <typename SwTracePolicy>
93bool StringToSwTraceString(const std::string& s, std::vector<uint32_t>& outputBuffer)
94{
95 // Converts the given string to an SWTrace "string" (i.e. a string of "chars"), and writes it into
96 // the given buffer including the null-terminator. It also pads it to the next uint32_t if necessary
97
98 // Clear the output buffer
99 outputBuffer.clear();
100
101 // Check that the given string is a valid SWTrace "string" (i.e. a string of "chars")
102 if (!IsValidSwTraceString<SwTracePolicy>(s))
103 {
104 return false;
105 }
106
107 // Prepare the output buffer
Keith Davis3201eea2019-10-24 17:30:41 +0100108 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 +0100109 size_t uint32_t_size = sizeof(uint32_t);
110 size_t outBufferSize = 1 + s_size / uint32_t_size + (s_size % uint32_t_size != 0 ? 1 : 0);
111 outputBuffer.resize(outBufferSize, '\0');
112
113 // Write the SWTrace string to the output buffer
114 outputBuffer[0] = boost::numeric_cast<uint32_t>(s_size);
115 std::memcpy(outputBuffer.data() + 1, s.data(), s_size);
116
117 return true;
118}
119
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000120template <typename SwTracePolicy,
121 typename SwTraceBuffer = std::vector<uint32_t>>
122bool ConvertDirectoryComponent(const std::string& directoryComponent, SwTraceBuffer& swTraceBuffer)
123{
124 // Convert the directory component using the given policy
125 SwTraceBuffer tempSwTraceBuffer;
126 bool result = StringToSwTraceString<SwTracePolicy>(directoryComponent, tempSwTraceBuffer);
127 if (!result)
128 {
129 return false;
130 }
131
132 swTraceBuffer.insert(swTraceBuffer.end(), tempSwTraceBuffer.begin(), tempSwTraceBuffer.end());
133
134 return true;
135}
136
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100137uint16_t GetNextUid(bool peekOnly = false);
138
Keith Davise394bd92019-12-02 15:12:19 +0000139std::vector<uint16_t> GetNextCounterUids(uint16_t firstUid, uint16_t cores);
Matteo Martincighab173e92019-09-05 12:02:04 +0100140
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000141void WriteBytes(const IPacketBuffer& packetBuffer, unsigned int offset, const void* value, unsigned int valueSize);
142
Keith Davis3201eea2019-10-24 17:30:41 +0100143uint32_t ConstructHeader(uint32_t packetFamily, uint32_t packetId);
144
145uint32_t ConstructHeader(uint32_t packetFamily, uint32_t packetClass, uint32_t packetType);
146
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000147void WriteUint64(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint64_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100148
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000149void WriteUint32(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint32_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100150
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000151void WriteUint16(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint16_t value);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100152
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000153void WriteUint8(const IPacketBufferPtr& packetBuffer, unsigned int offset, uint8_t value);
154
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000155void WriteBytes(unsigned char* buffer, unsigned int offset, const void* value, unsigned int valueSize);
156
Francis Murtagh3a161982019-09-04 15:25:02 +0100157void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value);
158
Ferran Balaguer73882172019-09-02 16:39:42 +0100159void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value);
160
161void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value);
162
Matteo Martincigh34a407d2019-11-06 15:30:54 +0000163void WriteUint8(unsigned char* buffer, unsigned int offset, uint8_t value);
164
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000165void ReadBytes(const IPacketBufferPtr& packetBuffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]);
166
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000167uint64_t ReadUint64(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Francis Murtagh3a161982019-09-04 15:25:02 +0100168
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000169uint32_t ReadUint32(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Ferran Balaguer73882172019-09-02 16:39:42 +0100170
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000171uint16_t ReadUint16(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Ferran Balaguer73882172019-09-02 16:39:42 +0100172
Matteo Martincigh2ffcc412019-11-05 11:47:40 +0000173uint8_t ReadUint8(const IPacketBufferPtr& packetBuffer, unsigned int offset);
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100174
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000175void ReadBytes(const unsigned char* buffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]);
176
Narumol Prangnawarat404b2752019-09-24 17:23:16 +0100177uint64_t ReadUint64(unsigned const char* buffer, unsigned int offset);
178
179uint32_t ReadUint32(unsigned const char* buffer, unsigned int offset);
180
181uint16_t ReadUint16(unsigned const char* buffer, unsigned int offset);
182
183uint8_t ReadUint8(unsigned const char* buffer, unsigned int offset);
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +0100184
Ferran Balaguer47d0fe92019-09-04 16:47:34 +0100185std::string GetSoftwareInfo();
186
187std::string GetSoftwareVersion();
188
189std::string GetHardwareVersion();
190
191std::string GetProcessName();
192
Matteo Martincigh0aed4f92019-10-01 14:25:34 +0100193enum class TimelinePacketStatus
194{
195 Ok,
196 Error,
197 BufferExhaustion
198};
199
Narumol Prangnawarat7e5eec72019-10-16 12:16:26 +0100200enum class ProfilingRelationshipType
201{
Keith Davis3201eea2019-10-24 17:30:41 +0100202 RetentionLink, /// Head retains(parents) Tail
203 ExecutionLink, /// Head execution start depends on Tail execution completion
204 DataLink, /// Head uses data of Tail
205 LabelLink /// Head uses label Tail (Tail MUST be a guid of a label).
Narumol Prangnawarat7e5eec72019-10-16 12:16:26 +0100206};
207
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100208uint32_t CalculateSizeOfPaddedSwString(const std::string& str);
209
Finn Williamse63a0262019-10-22 10:30:49 +0100210SwTraceMessage ReadSwTraceMessage(const unsigned char*, unsigned int& offset);
Sadik Armagan7bbdf9d2019-10-24 10:26:05 +0100211
Matteo Martincigh0aed4f92019-10-01 14:25:34 +0100212TimelinePacketStatus WriteTimelineLabelBinaryPacket(uint64_t profilingGuid,
213 const std::string& label,
214 unsigned char* buffer,
215 unsigned int bufferSize,
216 unsigned int& numberOfBytesWritten);
217
David Monahanf21f6062019-10-07 15:11:15 +0100218TimelinePacketStatus WriteTimelineEntityBinaryPacket(uint64_t profilingGuid,
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100219 unsigned char* buffer,
220 unsigned int bufferSize,
221 unsigned int& numberOfBytesWritten);
David Monahanf21f6062019-10-07 15:11:15 +0100222
Narumol Prangnawarat7e5eec72019-10-16 12:16:26 +0100223TimelinePacketStatus WriteTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
224 uint64_t relationshipGuid,
225 uint64_t headGuid,
226 uint64_t tailGuid,
227 unsigned char* buffer,
228 unsigned int bufferSize,
229 unsigned int& numberOfBytesWritten);
230
Sadik Armagan784db772019-10-08 15:05:38 +0100231TimelinePacketStatus WriteTimelineMessageDirectoryPackage(unsigned char* buffer,
232 unsigned int bufferSize,
233 unsigned int& numberOfBytesWritten);
234
Jan Eilers92fa15b2019-10-15 15:23:25 +0100235TimelinePacketStatus WriteTimelineEventClassBinaryPacket(uint64_t profilingGuid,
236 unsigned char* buffer,
237 unsigned int bufferSize,
238 unsigned int& numberOfBytesWritten);
239
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100240TimelinePacketStatus WriteTimelineEventBinaryPacket(uint64_t timestamp,
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000241 std::thread::id threadId,
Matteo Martincigh8844c2f2019-10-16 10:29:17 +0100242 uint64_t profilingGuid,
243 unsigned char* buffer,
244 unsigned int bufferSize,
245 unsigned int& numberOfBytesWritten);
246
Keith Davis3201eea2019-10-24 17:30:41 +0100247std::string CentreAlignFormatting(const std::string& stringToPass, const int spacingWidth);
248
249void PrintCounterDirectory(ICounterDirectory& counterDirectory);
250
Francis Murtagh3a161982019-09-04 15:25:02 +0100251class BufferExhaustion : public armnn::Exception
252{
253 using Exception::Exception;
254};
255
Matteo Martincigh5dc816e2019-11-04 14:05:28 +0000256uint64_t GetTimestamp();
Ferran Balaguer73882172019-09-02 16:39:42 +0100257
Matteo Martincigh5dc816e2019-11-04 14:05:28 +0000258} // namespace profiling
259
260} // namespace armnn
Matteo Martincigh378bbfc2019-11-04 14:05:28 +0000261
262namespace std
263{
264
265bool operator==(const std::vector<uint8_t>& left, std::thread::id right);
266
267} // namespace std