IVGCVSW-3691 Implement SendCounterPacket.SendCounterDirectoryPacket() function
[platform/upstream/armnn.git] / src / profiling / ProfilingUtils.cpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "ProfilingUtils.hpp"
7
8 #include <armnn/Version.hpp>
9 #include <armnn/Conversion.hpp>
10
11 #include <boost/assert.hpp>
12
13 #include <fstream>
14 #include <limits>
15
16 namespace armnn
17 {
18
19 namespace profiling
20 {
21
22 namespace
23 {
24
25 void ThrowIfCantGenerateNextUid(uint16_t uid, uint16_t cores = 0)
26 {
27     // Check that it is possible to generate the next UID without causing an overflow
28     switch (cores)
29     {
30     case 0:
31     case 1:
32         // Number of cores not specified or set to 1 (a value of zero indicates the device is not capable of
33         // running multiple parallel workloads and will not provide multiple streams of data for each event)
34         if (uid == std::numeric_limits<uint16_t>::max())
35         {
36             throw RuntimeException("Generating the next UID for profiling would result in an overflow");
37         }
38         break;
39     default: // cores > 1
40         // Multiple cores available, as max_counter_uid has to be set to: counter_uid + cores - 1, the maximum
41         // allowed value for a counter UID is consequently: uint16_t_max - cores + 1
42         if (uid >= std::numeric_limits<uint16_t>::max() - cores + 1)
43         {
44             throw RuntimeException("Generating the next UID for profiling would result in an overflow");
45         }
46         break;
47     }
48 }
49
50 } // Anonymous namespace
51
52 uint16_t GetNextUid(bool peekOnly)
53 {
54     // The UID used for profiling objects and events. The first valid UID is 1, as 0 is a reserved value
55     static uint16_t uid = 1;
56
57     // Check that it is possible to generate the next UID without causing an overflow (throws in case of error)
58     ThrowIfCantGenerateNextUid(uid);
59
60     if (peekOnly)
61     {
62         // Peek only
63         return uid;
64     }
65     else
66     {
67         // Get the next UID
68         return uid++;
69     }
70 }
71
72 std::vector<uint16_t> GetNextCounterUids(uint16_t cores)
73 {
74     // The UID used for counters only. The first valid UID is 0
75     static uint16_t counterUid = 0;
76
77     // Check that it is possible to generate the next counter UID without causing an overflow (throws in case of error)
78     ThrowIfCantGenerateNextUid(counterUid, cores);
79
80     // Get the next counter UIDs
81     size_t counterUidsSize = cores == 0 ? 1 : cores;
82     std::vector<uint16_t> counterUids(counterUidsSize, 0);
83     for (size_t i = 0; i < counterUidsSize; i++)
84     {
85         counterUids[i] = counterUid++;
86     }
87     return counterUids;
88 }
89
90 void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value)
91 {
92     BOOST_ASSERT(buffer);
93
94     buffer[offset]     = static_cast<unsigned char>(value & 0xFF);
95     buffer[offset + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
96     buffer[offset + 2] = static_cast<unsigned char>((value >> 16) & 0xFF);
97     buffer[offset + 3] = static_cast<unsigned char>((value >> 24) & 0xFF);
98     buffer[offset + 4] = static_cast<unsigned char>((value >> 32) & 0xFF);
99     buffer[offset + 5] = static_cast<unsigned char>((value >> 40) & 0xFF);
100     buffer[offset + 6] = static_cast<unsigned char>((value >> 48) & 0xFF);
101     buffer[offset + 7] = static_cast<unsigned char>((value >> 56) & 0xFF);
102 }
103
104 void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value)
105 {
106     BOOST_ASSERT(buffer);
107
108     buffer[offset]     = static_cast<unsigned char>(value & 0xFF);
109     buffer[offset + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
110     buffer[offset + 2] = static_cast<unsigned char>((value >> 16) & 0xFF);
111     buffer[offset + 3] = static_cast<unsigned char>((value >> 24) & 0xFF);
112 }
113
114 void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value)
115 {
116     BOOST_ASSERT(buffer);
117
118     buffer[offset]     = static_cast<unsigned char>(value & 0xFF);
119     buffer[offset + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
120 }
121
122 uint64_t ReadUint64(const unsigned char* buffer, unsigned int offset)
123 {
124     BOOST_ASSERT(buffer);
125
126     uint64_t value = 0;
127     value  = static_cast<uint64_t>(buffer[offset]);
128     value |= static_cast<uint64_t>(buffer[offset + 1]) << 8;
129     value |= static_cast<uint64_t>(buffer[offset + 2]) << 16;
130     value |= static_cast<uint64_t>(buffer[offset + 3]) << 24;
131     value |= static_cast<uint64_t>(buffer[offset + 4]) << 32;
132     value |= static_cast<uint64_t>(buffer[offset + 5]) << 40;
133     value |= static_cast<uint64_t>(buffer[offset + 6]) << 48;
134     value |= static_cast<uint64_t>(buffer[offset + 7]) << 56;
135
136     return value;
137 }
138
139 uint32_t ReadUint32(const unsigned char* buffer, unsigned int offset)
140 {
141     BOOST_ASSERT(buffer);
142
143     uint32_t value = 0;
144     value  = static_cast<uint32_t>(buffer[offset]);
145     value |= static_cast<uint32_t>(buffer[offset + 1]) << 8;
146     value |= static_cast<uint32_t>(buffer[offset + 2]) << 16;
147     value |= static_cast<uint32_t>(buffer[offset + 3]) << 24;
148     return value;
149 }
150
151 uint16_t ReadUint16(const unsigned char* buffer, unsigned int offset)
152 {
153     BOOST_ASSERT(buffer);
154
155     uint32_t value = 0;
156     value  = static_cast<uint32_t>(buffer[offset]);
157     value |= static_cast<uint32_t>(buffer[offset + 1]) << 8;
158     return static_cast<uint16_t>(value);
159 }
160
161 uint8_t ReadUint8(const unsigned char* buffer, unsigned int offset)
162 {
163     BOOST_ASSERT(buffer);
164
165     return buffer[offset];
166 }
167
168 std::string GetSoftwareInfo()
169 {
170     return std::string("ArmNN");
171 }
172
173 std::string GetHardwareVersion()
174 {
175     return std::string();
176 }
177
178 std::string GetSoftwareVersion()
179 {
180     std::string armnnVersion(ARMNN_VERSION);
181     std::string result = "Armnn " + armnnVersion.substr(2,2) + "." + armnnVersion.substr(4,2);
182     return result;
183 }
184
185 std::string GetProcessName()
186 {
187     std::ifstream comm("/proc/self/comm");
188     std::string name;
189     getline(comm, name);
190     return name;
191 }
192
193 } // namespace profiling
194
195 } // namespace armnn