executionStats.h
Go to the documentation of this file.
1 //
2 // Copyright 2025 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_EXEC_VDF_EXECUTION_STATS_H
8 #define PXR_EXEC_VDF_EXECUTION_STATS_H
9 
11 
12 #include "pxr/pxr.h"
13 
14 #include "pxr/exec/vdf/api.h"
15 #include "pxr/exec/vdf/types.h"
16 #include "pxr/exec/vdf/node.h"
17 
18 #include "pxr/base/arch/timing.h"
19 
20 #include <tbb/concurrent_queue.h>
21 #include <tbb/enumerable_thread_specific.h>
22 
23 #include <deque>
24 #include <optional>
25 #include <thread>
26 
27 PXR_NAMESPACE_OPEN_SCOPE
28 
29 class VdfNetwork;
30 
37 {
38  // Flag for a begin event.
39  //
40  constexpr static uint8_t _StartFlag = 0x80;
41 
42  // Flag for a corresponding end event.
43  //
44  constexpr static uint8_t _EndFlag = 0xC0;
45 
46 public:
47 
55  enum EventType : uint8_t {
56  // Base enum of timed events
57  NodeEvaluateEvent = 0x0,
58  NodePrepareEvent = 0x1,
59  NodeRequiredInputsEvent = 0x2,
60  NodeInputsTaskEvent = 0x3,
61 
62  // Single events
63  NodeDidComputeEvent = 0x10,
64  ElementsCopiedEvent = 0x11,
65  ElementsProcessedEvent = 0x12,
66  RequestedOutputInSpeculationsEvent = 0x13,
67 
68  // NOTE : All event types must be less than or equal to MaxEvent
69  MaxEvent = 0x3F
70  };
71 
72  typedef uint64_t EventData;
73 
77  struct Event {
78  VdfId nodeId;
79  EventData data;
80  EventType event;
81 
82  Event(
83  EventType event,
84  VdfId nodeId,
85  EventData data) :
86  nodeId(nodeId), data(data), event(event) {}
87  };
88 
93  struct ScopedEvent {
94  VDF_API
96  VdfExecutionStats* stats,
97  const VdfNode& node,
98  EventType eventType);
99 
100  VDF_API
101  ~ScopedEvent();
102 
103  protected:
104  VdfExecutionStats* _stats;
105 
106  private:
107  const VdfNode* _node;
108  EventType _event;
109  };
110 
114  struct ScopedMallocEvent : public ScopedEvent {
115  VDF_API
117  VdfExecutionStats* stats,
118  const VdfNode& node,
119  EventType eventType);
120 
121  VDF_API
123 
124  private:
125  std::string _tagName;
126  };
127 
130  VDF_API
131  explicit VdfExecutionStats(const VdfNetwork* network);
132 
135  VDF_API
137 
140  void LogData(EventType event, const VdfNode& node, EventData data) {
141  _Log(event, node.GetId(), data);
142  }
143 
146  void LogTimestamp(EventType event, const VdfNode& node) {
147  _LogTime(event, node);
148  }
149 
153  void LogBeginTimestamp(EventType event, const VdfNode& node) {
154  _LogTime(_TagBegin(event), node);
155  }
156 
160  void LogEndTimestamp(EventType event, const VdfNode& node) {
161  _LogTime(_TagEnd(event), node);
162  }
163 
166  VDF_API
168  const VdfNetwork* network,
169  const VdfNode* invokingNode);
170 
173  const std::optional<VdfId>& GetInvokingNodeId() const {
174  return _invokingNodeId;
175  }
176 
179  VDF_API
180  static std::string GetMallocTagName(
181  const VdfId *invokingNodeId,
182  const VdfNode &node);
183 
187  return (EventType)(static_cast<uint8_t>(event) & 0x3F);
188  }
189 
193  static bool IsEndEvent(EventType event) {
194  return 0x40 & static_cast<uint8_t>(event);
195  }
196 
199  static bool IsBeginEvent(EventType event) {
200  return !IsEndEvent(event);
201  }
202 
203 protected:
206  VDF_API
207  VdfExecutionStats(const VdfNetwork* network, VdfId nodeId);
208 
211  void _Log(EventType event, VdfId nodeId, EventData data)
212  {
213  _events.local().events.push_back(Event(event, nodeId, data));
214  }
215 
218  void _LogTime(EventType event, const VdfNode& node)
219  {
220  _Log(event, node.GetId(), ArchGetTickTime());
221  }
222 
225  VDF_API
227  const VdfNetwork* network,
228  VdfId invokingNodeId);
229 
233  return (EventType)(static_cast<uint8_t>(event) | _StartFlag);
234  }
235 
239  return (EventType)(static_cast<uint8_t>(event) | _EndFlag);
240  }
241 
242 private:
243  friend class VdfExecutionStatsProcessor;
244 
245  // Pointer to the VdfNetwork for whose nodes this execution stats tracks.
246  //
247  const VdfNetwork* _network;
248 
249  // Index of the VdfNode that calls into this network.
250  //
251  std::optional<VdfId> _invokingNodeId;
252 
253  // A structure of events recorded per thread.
254  //
255  struct _PerThreadEvents {
256  _PerThreadEvents() : threadId(std::this_thread::get_id()) {}
257 
258  // The thread id
259  std::thread::id threadId;
260 
261  // The vector of events recorded
262  typedef std::deque<Event> EventVector;
263  EventVector events;
264  };
265 
266  // The per-thread event vectors.
267  //
268  tbb::enumerable_thread_specific<_PerThreadEvents> _events;
269 
270  // Concurrent vector of VdfExecutionStats to keep track of execution stats
271  // from networks (i.e. sharing network) that are invoked during computation
272  // while profiling.
273  //
274  tbb::concurrent_queue<VdfExecutionStats*> _subStats;
275 };
276 
278 
279 PXR_NAMESPACE_CLOSE_SCOPE
280 
281 #endif
A VdfNetwork is a collection of VdfNodes and their connections.
Definition: network.h:59
VDF_API VdfExecutionStats(const VdfNetwork *network)
Constructor for parent execution stats that have no invoking node.
VDF_API VdfExecutionStats * _AddSubStat(const VdfNetwork *network, VdfId invokingNodeId)
Adds sub stat.
const std::optional< VdfId > & GetInvokingNodeId() const
Returns the invoking node, if any.
EventType _TagEnd(EventType event)
Tags the end flag.
Execution stats profiling event logger.
static EventType GetBaseEvent(EventType event)
Returns the base event (e.g.
uint64_t ArchGetTickTime()
Return the current time in system-dependent units.
Definition: timing.h:67
void LogTimestamp(EventType event, const VdfNode &node)
Log timestamp API.
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:52
VdfId GetId() const
Returns the unique id of this node in its network.
Definition: node.h:116
EventType
The upper 2 bits are reserved as a flag for the event type: Highest bit : time event flag 2nd high bi...
Scoped event that automatically logs when created and destroyed.
void LogEndTimestamp(EventType event, const VdfNode &node)
Logs timestamped end event.
static bool IsEndEvent(EventType event)
Returns true if the event is an end event (e.g.
EventType _TagBegin(EventType event)
Tags the begin flag.
void LogBeginTimestamp(EventType event, const VdfNode &node)
Logs timestamped begin event.
VDF_API ~VdfExecutionStats()
Destructor.
void LogData(EventType event, const VdfNode &node, EventData data)
Log event API.
Scoped event that automatically pushes and pops malloc tags for the given VdfNode.
void _Log(EventType event, VdfId nodeId, EventData data)
Logs data.
static VDF_API std::string GetMallocTagName(const VdfId *invokingNodeId, const VdfNode &node)
Returns a unique name for the given node.
void _LogTime(EventType event, const VdfNode &node)
Logs timestamp.
VDF_API VdfExecutionStats * AddSubStat(const VdfNetwork *network, const VdfNode *invokingNode)
Push execution stats onto the hierarchy queue.
Execution Stats event.
static bool IsBeginEvent(EventType event)
Returns true if the event is a begin event.
High-resolution, low-cost timing routines.
uint64_t VdfId
The unique identifier type for Vdf objects.
Definition: types.h:107