CIRCT 23.0.0git
Loading...
Searching...
No Matches
TraceEncoder.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Provides an abstract TraceEncoder class implementing the trace buffer
10// management and communication between the simulation thread and the trace
11// encoder thread.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef CIRCT_DIALECT_ARC_RUNTIME_TRACEENCODER_H
16#define CIRCT_DIALECT_ARC_RUNTIME_TRACEENCODER_H
17
20
21#include <atomic>
22#include <cassert>
23#include <condition_variable>
24#include <cstddef>
25#include <cstdint>
26#include <mutex>
27#include <optional>
28#include <queue>
29#include <thread>
30#include <vector>
31
33
34/// Helper for marking time steps within a trace buffer
37 explicit TraceBufferMarker(uint32_t offset) : offset(offset), numSteps(1) {}
38 /// Offset within the buffer in number of elements
39 uint32_t offset;
40 /// Number of time steps to advance at the given offset
41 uint32_t numSteps;
42};
43
44/// A heap allocated buffer containing raw trace data and time step markers
46
47public:
48 TraceBuffer() = delete;
49 explicit TraceBuffer(uint32_t capacity) : capacity(capacity) {
50 storage = std::make_unique<uint64_t[]>(capacity + 1);
52 }
53
54 // Never copy a trace buffer
55 TraceBuffer(const TraceBuffer &other) = delete;
56 TraceBuffer operator=(const TraceBuffer &other) = delete;
57
58 TraceBuffer(TraceBuffer &&other) noexcept = default;
59 TraceBuffer &operator=(TraceBuffer &&other) noexcept = default;
60
61 /// Available storage in number of elements.
62 /// Note: Actual capacity is +1 for sentinel
63 uint32_t capacity;
64 /// Number of valid elements, set on dispatch
65 uint32_t size = 0;
66 /// Time step of the buffer's first entry
67 int64_t firstStep = -1;
68 /// Time step markers
69 std::vector<TraceBufferMarker> stepMarkers;
70
71 /// Get the pointer to the buffer's storage
72 uint64_t *getData() const { return storage.get(); }
73
74 /// Reset the buffer
75 void clear() {
76 size = 0;
77 firstStep = -1;
78 stepMarkers.clear();
79 }
80
81 /// Assert that the buffer's sentinel value has not been overwritten
82 void assertSentinel() const {
84 impl::fatalError("Trace buffer sentinel overwritten");
85 }
86
87private:
88 static constexpr uint64_t sentinelValue = UINT64_C(0xABCD1234EFBA8765);
89 std::unique_ptr<uint64_t[]> storage;
90};
91
92/// Abstract TraceEncoder managing trace buffers and the encoder thread
94public:
95 TraceEncoder() = delete;
96 /// Construct a trace encoder for the given model and the given number of
97 /// buffers. Initializes the state with the first buffer.
99 unsigned numBuffers, bool debug);
100
101 virtual ~TraceEncoder() = default;
102
103 /// Begin tracing
104 void run(ArcState *state);
105 /// Dispatch the currently active trace buffer containing `oldBufferSize`
106 /// valid entries to the encoder thread and return the storage of the
107 /// new active buffer.
108 /// Blocks execution until a new buffer is available.
109 uint64_t *dispatch(uint32_t oldBufferSize);
110 /// Signal the start of a new simulation time step
111 void step(const ArcState *state);
112 /// Stop tracing
113 void finish(const ArcState *state);
114
115 /// Return the value of the internal step counter
116 int64_t getTimeStep() const { return timeStep; }
117
118 /// Number of trace buffers in rotation
119 const unsigned numBuffers;
120
121protected:
122 // Virtual methods to be implemented by encoder backends.
123
124 /// Set-up the encoder before starting the worker thread. May return `false`
125 /// to indicate failure. In this case, no worker thread will be created.
126 /// Called by the simulation thread.
127 virtual bool initialize(const ArcState *state) = 0;
128
129 /// Called by the worker thread before entering the encode loop
130 virtual void startUpWorker(){};
131 /// Encode the given trace buffer. Called by the worker thread.
132 virtual void encode(TraceBuffer &work){};
133 /// Called by the worker thread after leaving the encode loop
134 virtual void windDownWorker(){};
135 /// Finish trace encoding. Called by the simulation thread.
136 virtual void finalize(const ArcState *state){};
137
138 /// Metadata of the traced model
140 /// Debug mode flag
141 const bool debug;
142
143private:
144 /// The encoder thread's work loop
145 void workLoop();
146
147 void enqueueBuffer(TraceBuffer &&buffer);
149
150 /// Current simulation time step
151 int64_t timeStep;
152
153 /// Trace encoder worker thread. If empty, tracing is disabled.
154 std::optional<std::thread> worker;
155
156 /// Queue and synchronization primitives for buffers to be processed by the
157 /// encoder thread
159 std::condition_variable bufferQueueCv;
160 std::queue<TraceBuffer> bufferQueue;
161
162 /// Return stack and synchronization primitives for processed buffers
164 std::condition_variable availableBuffersCv;
165 std::vector<TraceBuffer> availableBuffers;
166
167 /// Flag signaling that no more buffers will be enqueued
168 std::atomic<bool> isFinished;
169
170 /// Trace buffer currently in use by the hardware model
172};
173
174/// Dummy encoder discarding all produced trace data
175class DummyTraceEncoder final : public TraceEncoder {
176public:
179
180 ~DummyTraceEncoder() override = default;
181
182protected:
183 bool initialize(const ArcState *state) override { return false; }
184};
185
186} // namespace circt::arc::runtime::impl
187
188#endif // CIRCT_DIALECT_ARC_RUNTIME_TRACEENCODER_H
Dummy encoder discarding all produced trace data.
bool initialize(const ArcState *state) override
Set-up the encoder before starting the worker thread.
DummyTraceEncoder(const ArcRuntimeModelInfo *modelInfo, ArcState *state)
Abstract TraceEncoder managing trace buffers and the encoder thread.
virtual bool initialize(const ArcState *state)=0
Set-up the encoder before starting the worker thread.
std::atomic< bool > isFinished
Flag signaling that no more buffers will be enqueued.
std::queue< TraceBuffer > bufferQueue
virtual void startUpWorker()
Called by the worker thread before entering the encode loop.
int64_t getTimeStep() const
Return the value of the internal step counter.
void workLoop()
The encoder thread's work loop.
std::mutex bufferQueueMutex
Queue and synchronization primitives for buffers to be processed by the encoder thread.
virtual void finalize(const ArcState *state)
Finish trace encoding. Called by the simulation thread.
void step(const ArcState *state)
Signal the start of a new simulation time step.
std::mutex availableBuffersMutex
Return stack and synchronization primitives for processed buffers.
virtual void windDownWorker()
Called by the worker thread after leaving the encode loop.
const bool debug
Debug mode flag.
virtual void encode(TraceBuffer &work)
Encode the given trace buffer. Called by the worker thread.
void run(ArcState *state)
Begin tracing.
std::condition_variable availableBuffersCv
const unsigned numBuffers
Number of trace buffers in rotation.
std::vector< TraceBuffer > availableBuffers
void enqueueBuffer(TraceBuffer &&buffer)
int64_t timeStep
Current simulation time step.
const ArcRuntimeModelInfo *const modelInfo
Metadata of the traced model.
TraceBuffer activeBuffer
Trace buffer currently in use by the hardware model.
std::condition_variable bufferQueueCv
void finish(const ArcState *state)
Stop tracing.
uint64_t * dispatch(uint32_t oldBufferSize)
Dispatch the currently active trace buffer containing oldBufferSize valid entries to the encoder thre...
std::optional< std::thread > worker
Trace encoder worker thread. If empty, tracing is disabled.
static void fatalError(const char *message)
Raise an irrecoverable error.
Definition Internal.h:23
Definition debug.py:1
Static information for a compiled hardware model, generated by the MLIR lowering.
Definition Common.h:70
Combined runtime and model state for a hardware model instance.
Definition Common.h:44
Helper for marking time steps within a trace buffer.
uint32_t offset
Offset within the buffer in number of elements.
uint32_t numSteps
Number of time steps to advance at the given offset.
A heap allocated buffer containing raw trace data and time step markers.
TraceBuffer(const TraceBuffer &other)=delete
TraceBuffer(TraceBuffer &&other) noexcept=default
int64_t firstStep
Time step of the buffer's first entry.
std::unique_ptr< uint64_t[]> storage
std::vector< TraceBufferMarker > stepMarkers
Time step markers.
TraceBuffer & operator=(TraceBuffer &&other) noexcept=default
uint32_t size
Number of valid elements, set on dispatch.
void assertSentinel() const
Assert that the buffer's sentinel value has not been overwritten.
static constexpr uint64_t sentinelValue
uint64_t * getData() const
Get the pointer to the buffer's storage.
TraceBuffer operator=(const TraceBuffer &other)=delete
uint32_t capacity
Available storage in number of elements.