1 //
2 // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #pragma once
7
8 #include "IBufferManager.hpp"
9 #include "armnn/profiling/ISendTimelinePacket.hpp"
10 #include "ProfilingUtils.hpp"
11
12 #include <armnn/utility/Assert.hpp>
13
14 #include <memory>
15
16 namespace armnn
17 {
18
19 namespace profiling
20 {
21
22 class SendTimelinePacket : public ISendTimelinePacket
23 {
24 public:
SendTimelinePacket(IBufferManager & bufferManager)25 SendTimelinePacket(IBufferManager& bufferManager)
26 : m_BufferManager(bufferManager)
27 , m_WriteBuffer(nullptr)
28 , m_Offset(8u)
29 , m_RemainingBufferSize(0u)
30 {}
31
32 /// Commits the current buffer and reset the member variables
33 void Commit() override;
34
35 /// Create and write a TimelineEntityBinaryPacket from the parameters to the buffer.
36 void SendTimelineEntityBinaryPacket(uint64_t profilingGuid) override;
37
38 /// Create and write a TimelineEventBinaryPacket from the parameters to the buffer.
39 void SendTimelineEventBinaryPacket(uint64_t timestamp, int threadId, uint64_t profilingGuid) override;
40
41 /// Create and write a TimelineEventClassBinaryPacket from the parameters to the buffer.
42 void SendTimelineEventClassBinaryPacket(uint64_t profilingGuid, uint64_t nameGuid) override;
43
44 /// Create and write a TimelineLabelBinaryPacket from the parameters to the buffer.
45 void SendTimelineLabelBinaryPacket(uint64_t profilingGuid, const std::string& label) override;
46
47 /// Create and write a TimelineMessageDirectoryPackage in the buffer
48 void SendTimelineMessageDirectoryPackage() override;
49
50 /// Create and write a TimelineRelationshipBinaryPacket from the parameters to the buffer.
51 virtual void SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
52 uint64_t relationshipGuid,
53 uint64_t headGuid,
54 uint64_t tailGuid,
55 uint64_t attributeGuid) override;
56 private:
57 /// Reserves maximum packet size from buffer
58 void ReserveBuffer();
59
60 template <typename Func, typename ... Params>
61 void ForwardWriteBinaryFunction(Func& func, Params&& ... params);
62
63 IBufferManager& m_BufferManager;
64 IPacketBufferPtr m_WriteBuffer;
65 unsigned int m_Offset;
66 unsigned int m_RemainingBufferSize;
67
68 const unsigned int m_uint32_t_size = sizeof(uint32_t);
69
70 std::pair<uint32_t, uint32_t> m_PacketHeader;
71 uint32_t m_PacketDataLength;
72
73 bool m_DirectoryPackage = false;
74 };
75
76 template<typename Func, typename ... Params>
ForwardWriteBinaryFunction(Func & func,Params &&...params)77 void SendTimelinePacket::ForwardWriteBinaryFunction(Func& func, Params&& ... params)
78 {
79 try
80 {
81 ReserveBuffer();
82 ARMNN_ASSERT(m_WriteBuffer);
83 unsigned int numberOfBytesWritten = 0;
84 // Header will be prepended to the buffer on Commit()
85 while ( true )
86 {
87 TimelinePacketStatus result = func(std::forward<Params>(params)...,
88 &m_WriteBuffer->GetWritableData()[m_Offset],
89 m_RemainingBufferSize,
90 numberOfBytesWritten);
91 switch ( result )
92 {
93 case TimelinePacketStatus::BufferExhaustion:
94 Commit();
95 ReserveBuffer();
96 continue;
97
98 case TimelinePacketStatus::Error:
99 throw RuntimeException("Error processing while sending TimelineBinaryPacket", CHECK_LOCATION());
100
101 default:
102 m_Offset += numberOfBytesWritten;
103 m_RemainingBufferSize -= numberOfBytesWritten;
104 return;
105 }
106 }
107 }
108 catch (const RuntimeException& ex)
109 {
110 // don't swallow in the catch all block
111 throw ex;
112 }
113 catch (const BufferExhaustion& ex)
114 {
115 // ditto
116 throw ex;
117 }
118 catch (const Exception& ex)
119 {
120 throw ex;
121 }
122 catch ( ... )
123 {
124 throw RuntimeException("Unknown Exception thrown while sending TimelineBinaryPacket", CHECK_LOCATION());
125 }
126 }
127
128 } // namespace profiling
129
130 } // namespace armnn
131