IVGCVSW-3692 Implement SendPeriodicCounterCapturePacket() function
[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
15 #include <unistd.h>
16
17 namespace armnn
18 {
19
20 namespace profiling
21 {
22
23 using boost::numeric_cast;
24
25 void SendCounterPacket::SendStreamMetaDataPacket()
26 {
27     throw armnn::UnimplementedException();
28 }
29
30 void SendCounterPacket::SendCounterDirectoryPacket(const Category& category, const std::vector<Counter>& counters)
31 {
32     throw armnn::UnimplementedException();
33 }
34
35 void SendCounterPacket::SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector& values)
36 {
37     uint32_t packetFamily = 1;
38     uint32_t packetClass = 0;
39     uint32_t packetType = 0;
40     uint32_t headerSize = numeric_cast<uint32_t>(2 * sizeof(uint32_t));
41     uint32_t bodySize = numeric_cast<uint32_t>((1 * sizeof(uint64_t)) +
42                                                (values.size() * (sizeof(uint16_t) + sizeof(uint32_t))));
43     uint32_t totalSize = headerSize + bodySize;
44     uint32_t offset = 0;
45     uint32_t reserved = 0;
46
47     unsigned char* writeBuffer = m_Buffer.Reserve(totalSize, reserved);
48
49     if (reserved < totalSize)
50     {
51         // Cancel the operation.
52         m_Buffer.Commit(0);
53         throw profiling::BufferExhaustion(
54                 boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize));
55     }
56
57     if (writeBuffer == nullptr)
58     {
59         // Cancel the operation.
60         m_Buffer.Commit(0);
61         throw RuntimeException("Error reserving buffer memory.");
62     }
63
64     // Create header.
65     WriteUint32(writeBuffer,
66                 offset,
67                 ((packetFamily & 0x3F) << 26) | ((packetClass & 0x3FF) << 19) | ((packetType & 0x3FFF) << 16));
68     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
69     WriteUint32(writeBuffer, offset, bodySize);
70
71     // Copy captured Timestamp.
72     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
73     WriteUint64(writeBuffer, offset, timestamp);
74
75     // Copy selectedCounterIds.
76     offset += numeric_cast<uint32_t>(sizeof(uint64_t));
77     for (const auto& pair: values)
78     {
79         WriteUint16(writeBuffer, offset, pair.first);
80         offset += numeric_cast<uint32_t>(sizeof(uint16_t));
81         WriteUint32(writeBuffer, offset, pair.second);
82         offset += numeric_cast<uint32_t>(sizeof(uint32_t));
83     }
84
85     m_Buffer.Commit(totalSize);
86 }
87
88 void SendCounterPacket::SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
89                                                            const std::vector<uint16_t>& selectedCounterIds)
90 {
91     uint32_t packetFamily = 0;
92     uint32_t packetId = 4;
93     uint32_t headerSize = numeric_cast<uint32_t>(2 * sizeof(uint32_t));
94     uint32_t bodySize   = numeric_cast<uint32_t>((1 * sizeof(uint32_t)) +
95                                                  (selectedCounterIds.size() * sizeof(uint16_t)));
96     uint32_t totalSize = headerSize + bodySize;
97     uint32_t offset = 0;
98     uint32_t reserved = 0;
99
100     unsigned char* writeBuffer = m_Buffer.Reserve(totalSize, reserved);
101
102     if (reserved < totalSize)
103     {
104         // Cancel the operation.
105         m_Buffer.Commit(0);
106         throw RuntimeException(boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.")
107                                % totalSize));
108     }
109
110     if (writeBuffer == nullptr)
111     {
112         // Cancel the operation.
113         m_Buffer.Commit(0);
114         throw RuntimeException("Error reserving buffer memory.");
115     }
116
117     // Create header.
118     WriteUint32(writeBuffer, offset, ((packetFamily & 0x3F) << 26) | ((packetId & 0x3FF) << 16));
119     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
120     WriteUint32(writeBuffer, offset, bodySize);
121
122     // Copy capturePeriod.
123     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
124     WriteUint32(writeBuffer, offset, capturePeriod);
125
126     // Copy selectedCounterIds.
127     offset += numeric_cast<uint32_t>(sizeof(uint32_t));
128     for(const uint16_t& id: selectedCounterIds)
129     {
130         WriteUint16(writeBuffer, offset, id);
131         offset += numeric_cast<uint32_t>(sizeof(uint16_t));
132     }
133
134     m_Buffer.Commit(totalSize);
135 }
136
137 void SendCounterPacket::SetReadyToRead()
138 {
139     m_ReadyToRead = true;
140 }
141
142 } // namespace profiling
143
144 } // namespace armnn