IVGCVSW-3872 Add Missing packet to SendMetaDataPacket
[platform/upstream/armnn.git] / src / profiling / SendCounterPacket.cpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "SendCounterPacket.hpp"
7 #include "EncodeVersion.hpp"
8 #include "ProfilingUtils.hpp"
9
10 #include <armnn/Exceptions.hpp>
11
12 #include <boost/format.hpp>
13 #include <boost/numeric/conversion/cast.hpp>
14 #include <boost/core/ignore_unused.hpp>
15
16 #include <cstring>
17
18 namespace armnn
19 {
20
21 namespace profiling
22 {
23
24 using boost::numeric_cast;
25
26 const unsigned int SendCounterPacket::PIPE_MAGIC;
27 const unsigned int SendCounterPacket::MAX_METADATA_PACKET_LENGTH;
28
29 void SendCounterPacket::SendStreamMetaDataPacket()
30 {
31     std::string info(GetSoftwareInfo());
32     std::string hardwareVersion(GetHardwareVersion());
33     std::string softwareVersion(GetSoftwareVersion());
34     std::string processName = GetProcessName().substr(0, 60);
35
36     uint32_t infoSize = numeric_cast<uint32_t>(info.size()) > 0 ? numeric_cast<uint32_t>(info.size()) + 1 : 0;
37     uint32_t hardwareVersionSize = numeric_cast<uint32_t>(hardwareVersion.size()) > 0 ?
38                                    numeric_cast<uint32_t>(hardwareVersion.size()) + 1 : 0;
39     uint32_t softwareVersionSize = numeric_cast<uint32_t>(softwareVersion.size()) > 0 ?
40                                    numeric_cast<uint32_t>(softwareVersion.size()) + 1 : 0;
41     uint32_t processNameSize = numeric_cast<uint32_t>(processName.size()) > 0 ?
42                                numeric_cast<uint32_t>(processName.size()) + 1 : 0;
43
44     uint32_t sizeUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
45
46     uint32_t headerSize = 2 * sizeUint32;
47     uint32_t bodySize = 10 * sizeUint32;
48     uint32_t packetVersionCountSize = sizeUint32;
49
50     // Supported Packets
51     // Stream metadata packet            (packet family=0; packet id=0)
52     // Connection Acknowledged packet    (packet family=0, packet id=1)
53     // Counter Directory packet          (packet family=0; packet id=2)
54     // Request Counter Directory packet  (packet family=0, packet id=3)
55     // Periodic Counter Selection packet (packet family=0, packet id=4)
56     // Periodic Counter Capture packet   (packet family=1, packet class=0, type=0)
57     uint32_t packetVersionEntries = 6;
58
59     uint32_t payloadSize = numeric_cast<uint32_t>(infoSize + hardwareVersionSize + softwareVersionSize +
60                                                   processNameSize + packetVersionCountSize +
61                                                   (packetVersionEntries * 2 * sizeUint32));
62
63     uint32_t totalSize = headerSize + bodySize + payloadSize;
64     uint32_t offset = 0;
65     uint32_t reserved = 0;
66
67     unsigned char *writeBuffer = m_Buffer.Reserve(totalSize, reserved);
68
69     if (reserved < totalSize)
70     {
71         CancelOperationAndThrow<BufferExhaustion>(
72                     boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.")
73                                % totalSize));
74     }
75
76     if (writeBuffer == nullptr)
77     {
78         CancelOperationAndThrow<RuntimeException>("Error reserving buffer memory.");
79     }
80
81     try
82     {
83         // Create header
84
85         WriteUint32(writeBuffer, offset, 0);
86         offset += sizeUint32;
87         WriteUint32(writeBuffer, offset, totalSize - headerSize);
88
89         // Packet body
90
91         offset += sizeUint32;
92         WriteUint32(writeBuffer, offset, PIPE_MAGIC); // pipe_magic
93         offset += sizeUint32;
94         WriteUint32(writeBuffer, offset, EncodeVersion(1, 0, 0)); // stream_metadata_version
95         offset += sizeUint32;
96         WriteUint32(writeBuffer, offset, MAX_METADATA_PACKET_LENGTH); // max_data_length
97         offset += sizeUint32;
98         WriteUint32(writeBuffer, offset, numeric_cast<uint32_t>(getpid())); // pid
99         offset += sizeUint32;
100         uint32_t poolOffset = bodySize;
101         WriteUint32(writeBuffer, offset, infoSize ? poolOffset : 0); // offset_info
102         offset += sizeUint32;
103         poolOffset += infoSize;
104         WriteUint32(writeBuffer, offset, hardwareVersionSize ? poolOffset : 0); // offset_hw_version
105         offset += sizeUint32;
106         poolOffset += hardwareVersionSize;
107         WriteUint32(writeBuffer, offset, softwareVersionSize ? poolOffset : 0); // offset_sw_version
108         offset += sizeUint32;
109         poolOffset += softwareVersionSize;
110         WriteUint32(writeBuffer, offset, processNameSize ? poolOffset : 0); // offset_process_name
111         offset += sizeUint32;
112         poolOffset += processNameSize;
113         WriteUint32(writeBuffer, offset, packetVersionEntries ? poolOffset : 0); // offset_packet_version_table
114         offset += sizeUint32;
115         WriteUint32(writeBuffer, offset, 0); // reserved
116         offset += sizeUint32;
117
118         // Pool
119
120         if (infoSize)
121         {
122             memcpy(&writeBuffer[offset], info.c_str(), infoSize);
123             offset += infoSize;
124         }
125
126         if (hardwareVersionSize)
127         {
128             memcpy(&writeBuffer[offset], hardwareVersion.c_str(), hardwareVersionSize);
129             offset += hardwareVersionSize;
130         }
131
132         if (softwareVersionSize)
133         {
134             memcpy(&writeBuffer[offset], softwareVersion.c_str(), softwareVersionSize);
135             offset += softwareVersionSize;
136         }
137
138         if (processNameSize)
139         {
140             memcpy(&writeBuffer[offset], processName.c_str(), processNameSize);
141             offset += processNameSize;
142         }
143
144         if (packetVersionEntries)
145         {
146             // Packet Version Count
147             WriteUint32(writeBuffer, offset, packetVersionEntries << 16);
148
149             // Packet Version Entries
150             uint32_t packetFamily = 0;
151             uint32_t packetId = 0;
152
153             offset += sizeUint32;
154             for (uint32_t i = 0; i < packetVersionEntries - 1; ++i)
155             {
156                 WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId++ & 0x3FF) << 16));
157                 offset += sizeUint32;
158                 WriteUint32(writeBuffer, offset, EncodeVersion(1, 0, 0));
159                 offset += sizeUint32;
160             }
161
162             packetFamily = 1;
163             packetId = 0;
164
165             WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16));
166             offset += sizeUint32;
167             WriteUint32(writeBuffer, offset, EncodeVersion(1, 0, 0));
168         }
169     }
170     catch(...)
171     {
172         CancelOperationAndThrow<RuntimeException>("Error processing packet.");
173     }
174
175     m_Buffer.Commit(totalSize);
176 }
177
178 void SendCounterPacket::SendCounterDirectoryPacket(const CounterDirectory& counterDirectory)
179 {
180     throw armnn::UnimplementedException();
181 }
182
183 void SendCounterPacket::SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector& values)
184 {
185     uint32_t packetFamily = 1;
186     uint32_t packetClass = 0;
187     uint32_t packetType = 0;
188     uint32_t headerSize = numeric_cast<uint32_t>(2 * sizeof(uint32_t));
189     uint32_t bodySize = numeric_cast<uint32_t>((1 * sizeof(uint64_t)) +
190                                                (values.size() * (sizeof(uint16_t) + sizeof(uint32_t))));
191     uint32_t totalSize = headerSize + bodySize;
192     uint32_t offset = 0;
193     uint32_t reserved = 0;
194
195     unsigned char* writeBuffer = m_Buffer.Reserve(totalSize, reserved);
196
197     if (reserved < totalSize)
198     {
199         CancelOperationAndThrow<BufferExhaustion>(
200                     boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.")
201                                % totalSize));
202     }
203
204     if (writeBuffer == nullptr)
205     {
206         CancelOperationAndThrow<RuntimeException>("Error reserving buffer memory.");
207     }
208
209     // Create header.
210     WriteUint32(writeBuffer,
211                 offset,
212                 ((packetFamily & 0x3F) << 26) | ((packetClass & 0x3FF) << 19) | ((packetType & 0x3FFF) << 16));
213     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
214     WriteUint32(writeBuffer, offset, bodySize);
215
216     // Copy captured Timestamp.
217     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
218     WriteUint64(writeBuffer, offset, timestamp);
219
220     // Copy selectedCounterIds.
221     offset += numeric_cast<uint32_t>(sizeof(uint64_t));
222     for (const auto& pair: values)
223     {
224         WriteUint16(writeBuffer, offset, pair.first);
225         offset += numeric_cast<uint32_t>(sizeof(uint16_t));
226         WriteUint32(writeBuffer, offset, pair.second);
227         offset += numeric_cast<uint32_t>(sizeof(uint32_t));
228     }
229
230     m_Buffer.Commit(totalSize);
231 }
232
233 void SendCounterPacket::SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
234                                                            const std::vector<uint16_t>& selectedCounterIds)
235 {
236     uint32_t packetFamily = 0;
237     uint32_t packetId = 4;
238     uint32_t headerSize = numeric_cast<uint32_t>(2 * sizeof(uint32_t));
239     uint32_t bodySize   = numeric_cast<uint32_t>((1 * sizeof(uint32_t)) +
240                                                  (selectedCounterIds.size() * sizeof(uint16_t)));
241     uint32_t totalSize = headerSize + bodySize;
242     uint32_t offset = 0;
243     uint32_t reserved = 0;
244
245     unsigned char* writeBuffer = m_Buffer.Reserve(totalSize, reserved);
246
247     if (reserved < totalSize)
248     {
249         CancelOperationAndThrow<BufferExhaustion>(
250                     boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.")
251                                % totalSize));
252     }
253
254     if (writeBuffer == nullptr)
255     {
256         CancelOperationAndThrow<RuntimeException>("Error reserving buffer memory.");
257     }
258
259     // Create header.
260     WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16));
261     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
262     WriteUint32(writeBuffer, offset, bodySize);
263
264     // Copy capturePeriod.
265     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
266     WriteUint32(writeBuffer, offset, capturePeriod);
267
268     // Copy selectedCounterIds.
269     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
270     for(const uint16_t& id: selectedCounterIds)
271     {
272         WriteUint16(writeBuffer, offset, id);
273         offset += numeric_cast<uint32_t>(sizeof(uint16_t));
274     }
275
276     m_Buffer.Commit(totalSize);
277 }
278
279 void SendCounterPacket::SetReadyToRead()
280 {
281     m_ReadyToRead = true;
282 }
283
284 } // namespace profiling
285
286 } // namespace armnn