CIRCT 24.0.0git
Loading...
Searching...
No Matches
Common.h
Go to the documentation of this file.
1//===- Common.h - Commonly used classes w/o dependencies --------*- C++ -*-===//
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// DO NOT EDIT!
10// This file is distributed as part of an ESI package. The source for this file
11// should always be modified within CIRCT.
12//
13//===----------------------------------------------------------------------===//
14
15// NOLINTNEXTLINE(llvm-header-guard)
16#ifndef ESI_COMMON_H
17#define ESI_COMMON_H
18
19#include <any>
20#include <cstdint>
21#include <map>
22#include <memory>
23#include <optional>
24#include <span>
25#include <stdexcept>
26#include <string>
27#include <vector>
28
29namespace esi {
30class Type;
31
32//===----------------------------------------------------------------------===//
33// Common accelerator description types.
34//===----------------------------------------------------------------------===//
35
36struct AppID {
37 std::string name;
38 std::optional<uint32_t> idx;
39
40 AppID(const std::string &name, std::optional<uint32_t> idx = std::nullopt)
41 : name(name), idx(idx) {}
42
43 bool operator==(const AppID &other) const {
44 return name == other.name && idx == other.idx;
45 }
46 bool operator!=(const AppID &other) const { return !(*this == other); }
47 friend std::ostream &operator<<(std::ostream &os, const AppID &id);
48
49 std::string toString() const {
50 if (idx.has_value())
51 return name + "[" + std::to_string(idx.value()) + "]";
52 return name;
53 }
54};
55bool operator<(const AppID &a, const AppID &b);
56
57class AppIDPath : public std::vector<AppID> {
58public:
59 using std::vector<AppID>::vector;
60
61 AppIDPath operator+(const AppIDPath &b) const;
62 AppIDPath parent() const;
63 std::string toStr() const;
64 friend std::ostream &operator<<(std::ostream &os, const AppIDPath &path);
65};
66bool operator<(const AppIDPath &a, const AppIDPath &b);
67
68struct Constant {
69 std::any value;
70 std::optional<const Type *> type;
71};
72
73struct ModuleInfo {
74 std::optional<std::string> name;
75 std::optional<std::string> summary;
76 std::optional<std::string> version;
77 std::optional<std::string> repo;
78 std::optional<std::string> commitHash;
79 std::map<std::string, Constant> constants;
80 std::map<std::string, std::any> extra;
81};
82
83/// A description of a service port. Used pretty exclusively in setting up the
84/// design.
86 std::string name;
87 std::string portName;
88};
89
90/// Details about how to connect to a particular channel.
92 /// The name of the type of connection. Typically, the name of the DMA engine
93 /// or "cosim" if a cosimulation channel is being used.
94 std::string type;
95 /// Implementation-specific options.
96 std::map<std::string, std::any> implOptions;
97};
98using ChannelAssignments = std::map<std::string, ChannelAssignment>;
99
100/// A description of a hardware client. Used pretty exclusively in setting up
101/// the design.
108using HWClientDetails = std::vector<HWClientDetail>;
109using ServiceImplDetails = std::map<std::string, std::any>;
110
111class MessageData;
112namespace services {
113struct HostMemRegion;
114} // namespace services
115
116//===----------------------------------------------------------------------===//
117// SegmentedMessageData -- multi-segment message support.
118//===----------------------------------------------------------------------===//
119
120/// A contiguous, non-owning view of bytes within a SegmentedMessageData.
121/// Valid only while the owning SegmentedMessageData is alive.
122struct Segment {
123 const uint8_t *data;
124 size_t size;
125 /// The HostMem region (from services::HostMem::allocate()) which holds
126 /// [data, data + size), if any. Several segments may share a region.
127 /// Non-owning: the SegmentedMessageData keeps the region alive; backends may
128 /// be able to obtain ownership via SegmentedMessageData::take().
130
131 std::span<const uint8_t> span() const { return {data, size}; }
132 bool empty() const { return size == 0; }
133
134 /// Device address of this segment's bytes, if `region` is set and contains
135 /// them; std::nullopt otherwise.
136 std::optional<uint64_t> getDeviceAddress() const;
137};
138
139/// Abstract multi-segment message. Generated types subclass this to expose
140/// header + list segments without flattening into a contiguous buffer.
141///
142/// MessageData is the canonical flat, one-segment implementation of this
143/// interface. Other subclasses represent naturally segmented layouts.
144///
145/// Subclasses MUST own all data that their segments point to. Read and write
146/// APIs can hold the message across async boundaries / retries. Subclasses
147/// which hold data in HostMem regions must keep those regions alive for the
148/// lifetime of the message (e.g. by owning them as unique_ptr<HostMemRegion>)
149/// and point their segments' `region` at them. Subclasses which own their
150/// regions exclusively may override take() to hand them to the backend.
152public:
153 virtual ~SegmentedMessageData() = default;
154
155 /// Number of segments in the message.
156 virtual size_t numSegments() const = 0;
157 /// Get a segment by index. Throws if the segment has been take()n.
158 virtual Segment segment(size_t idx) const = 0;
159
160 /// Optionally called by a backend once it has transmitted segment `segIdx`,
161 /// to obtain ownership of the HostMem region backing it (e.g. to re-use the
162 /// region or return it to a pool).
163 ///
164 /// Returns nullptr, leaving the segment accessible, if the segment isn't
165 /// backed by a region or the message doesn't transfer region ownership.
166 /// Otherwise, marks the segment as taken -- after which segment(segIdx) (and
167 /// thus anything which reads the whole message, such as toMessageData()) and
168 /// further calls to take(segIdx) throw -- and returns the region if no other
169 /// untaken segment references it, or nullptr if some still do. Since several
170 /// segments may share a region, a backend which calls take() on each segment
171 /// as it is transmitted receives each region exactly once, after the last
172 /// segment using it.
173 ///
174 /// Since SegmentedMessageDataCursor reads segments via segment(), a backend
175 /// must not take a segment which a cursor over the message can still reach,
176 /// and must not take a segment it may need to retransmit. Any cursor
177 /// (including one created after the take()) throws when it reaches a taken
178 /// segment. Segment copies of a taken segment obtained before the take() are
179 /// invalid: their `data` may point into a region which has been re-used.
180 ///
181 /// The default implementation returns nullptr.
182 virtual std::unique_ptr<services::HostMemRegion> take(size_t segIdx);
183
184 /// Total size across all segments.
185 size_t totalSize() const;
186 /// True if totalSize() == 0.
187 bool empty() const;
188
189 /// Flatten all segments into a standard MessageData.
190 virtual MessageData toMessageData() const;
191};
192
193/// A concrete flat message backed by a single vector of bytes.
194///
195/// This is also a one-segment SegmentedMessageData so flat and segmented
196/// messages can flow through the same internal APIs.
198public:
199 /// Adopts the data vector buffer.
200 MessageData() = default;
201 MessageData(std::span<const uint8_t> data)
202 : data(data.data(), data.data() + data.size()) {}
203 MessageData(std::vector<uint8_t> &data) : data(std::move(data)) {}
204 MessageData(std::vector<uint8_t> &&data) : data(std::move(data)) {}
205 MessageData(const uint8_t *data, size_t size) : data(data, data + size) {}
206 ~MessageData() = default;
207
208 const uint8_t *getBytes() const { return data.data(); }
209
210 /// Get the data as a vector of bytes.
211 const std::vector<uint8_t> &getData() const { return data; }
212
213 /// Implicit conversion to a vector/span of bytes, to play nice with other
214 /// APIs that accept bytearray-like things.
215 operator const std::vector<uint8_t> &() const { return data; }
216 operator std::span<const uint8_t>() const { return data; }
217
218 /// Move the data out of this object.
219 std::vector<uint8_t> takeData() { return std::move(data); }
220
221 /// Get the size of the data in bytes.
222 size_t getSize() const { return data.size(); }
223 size_t size() const { return getSize(); }
224
225 /// Returns true if this message contains no data.
226 bool empty() const { return data.empty(); }
227
228 /// Cast to a type. Throws if the size of the data does not match the size of
229 /// the message. The lifetime of the resulting pointer is tied to the lifetime
230 /// of this object.
231 template <typename T>
232 const T *as() const {
233 if (data.size() != sizeof(T))
234 throw std::runtime_error("Data size does not match type size. Size is " +
235 std::to_string(data.size()) + ", expected " +
236 std::to_string(sizeof(T)) + ".");
237 return reinterpret_cast<const T *>(data.data());
238 }
239
240 /// Cast from a type to its raw bytes.
241 template <typename T>
242 static MessageData from(T &t) {
243 return MessageData(reinterpret_cast<const uint8_t *>(&t), sizeof(T));
244 }
245
246 /// Convert the data to a hex string.
247 std::string toHex() const;
248
249 size_t numSegments() const override { return 1; }
250 Segment segment(size_t idx) const override {
251 if (idx != 0)
252 throw std::out_of_range("MessageData only has one segment");
253 return {data.data(), data.size()};
254 }
255 MessageData toMessageData() const override { return *this; }
256
257private:
258 std::vector<uint8_t> data;
259};
260
261/// Cursor for incremental consumption of a SegmentedMessageData.
262/// Tracks position across segment boundaries. Backends store this alongside
263/// a unique_ptr<SegmentedMessageData> for partial writes.
264///
265/// The cursor reads segments through SegmentedMessageData::segment() on every
266/// access and caches nothing, so it throws upon reaching a segment which has
267/// been take()n -- regardless of whether it was created before or after the
268/// take().
269///
270/// Deliberately a separate class (not embedded in SegmentedMessageData) so
271/// that generated types have no hidden members — their layout matches the
272/// hardware wire format exactly.
274public:
276
277 /// Contiguous span from current position to end of current segment.
278 std::span<const uint8_t> remaining() const;
279
280 /// The unconsumed part of the current segment, with its `region`. `data` and
281 /// `size` match remaining().
283
284 /// Advance by `n` bytes, crossing segment boundaries as needed.
285 void advance(size_t n);
286
287 /// True when all segments have been consumed.
288 bool done() const;
289
290private:
292 size_t segIdx = 0;
293 size_t offset = 0;
294};
295
296} // namespace esi
297
298std::ostream &operator<<(std::ostream &, const esi::ModuleInfo &);
299
300//===----------------------------------------------------------------------===//
301// Functions which should be in the standard library.
302//===----------------------------------------------------------------------===//
303
304namespace esi {
305std::string toHex(void *val);
306std::string toHex(uint64_t val);
307} // namespace esi
308
309#endif // ESI_COMMON_H
std::string toStr() const
Definition Manifest.cpp:816
friend std::ostream & operator<<(std::ostream &os, const AppIDPath &path)
Definition Manifest.cpp:842
AppIDPath operator+(const AppIDPath &b) const
Definition Manifest.cpp:803
AppIDPath parent() const
Definition Manifest.cpp:809
A concrete flat message backed by a single vector of bytes.
Definition Common.h:197
const std::vector< uint8_t > & getData() const
Get the data as a vector of bytes.
Definition Common.h:211
const uint8_t * getBytes() const
Definition Common.h:208
std::string toHex() const
Convert the data to a hex string.
Definition Common.cpp:23
~MessageData()=default
const T * as() const
Cast to a type.
Definition Common.h:232
std::vector< uint8_t > takeData()
Move the data out of this object.
Definition Common.h:219
size_t numSegments() const override
Number of segments in the message.
Definition Common.h:249
Segment segment(size_t idx) const override
Get a segment by index. Throws if the segment has been take()n.
Definition Common.h:250
size_t getSize() const
Get the size of the data in bytes.
Definition Common.h:222
MessageData()=default
Adopts the data vector buffer.
MessageData(const uint8_t *data, size_t size)
Definition Common.h:205
size_t size() const
Definition Common.h:223
MessageData(std::vector< uint8_t > &data)
Definition Common.h:203
MessageData toMessageData() const override
Flatten all segments into a standard MessageData.
Definition Common.h:255
MessageData(std::span< const uint8_t > data)
Definition Common.h:201
bool empty() const
Returns true if this message contains no data.
Definition Common.h:226
static MessageData from(T &t)
Cast from a type to its raw bytes.
Definition Common.h:242
std::vector< uint8_t > data
Definition Common.h:258
MessageData(std::vector< uint8_t > &&data)
Definition Common.h:204
Segment remainingSegment() const
The unconsumed part of the current segment, with its region.
Definition Common.cpp:99
const SegmentedMessageData & msg
Definition Common.h:291
void advance(size_t n)
Advance by n bytes, crossing segment boundaries as needed.
Definition Common.cpp:113
bool done() const
True when all segments have been consumed.
Definition Common.cpp:133
std::span< const uint8_t > remaining() const
Contiguous span from current position to end of current segment.
Definition Common.cpp:95
SegmentedMessageDataCursor(const SegmentedMessageData &msg)
Definition Common.h:275
Abstract multi-segment message.
Definition Common.h:151
virtual Segment segment(size_t idx) const =0
Get a segment by index. Throws if the segment has been take()n.
virtual ~SegmentedMessageData()=default
virtual MessageData toMessageData() const
Flatten all segments into a standard MessageData.
Definition Common.cpp:61
bool empty() const
True if totalSize() == 0.
Definition Common.cpp:59
virtual std::unique_ptr< services::HostMemRegion > take(size_t segIdx)
Optionally called by a backend once it has transmitted segment segIdx, to obtain ownership of the Hos...
Definition Common.cpp:87
size_t totalSize() const
Total size across all segments.
Definition Common.cpp:52
virtual size_t numSegments() const =0
Number of segments in the message.
Root class of the ESI type system.
Definition Types.h:36
std::ostream & operator<<(std::ostream &, const esi::ModuleInfo &)
Definition esi.py:1
std::string toHex(void *val)
Definition Common.cpp:38
std::vector< HWClientDetail > HWClientDetails
Definition Common.h:108
std::map< std::string, std::any > ServiceImplDetails
Definition Common.h:109
std::map< std::string, ChannelAssignment > ChannelAssignments
Definition Common.h:98
bool operator<(const AppID &a, const AppID &b)
Definition Manifest.cpp:822
std::string name
Definition Common.h:37
bool operator!=(const AppID &other) const
Definition Common.h:46
std::string toString() const
Definition Common.h:49
bool operator==(const AppID &other) const
Definition Common.h:43
friend std::ostream & operator<<(std::ostream &os, const AppID &id)
Definition Manifest.cpp:836
std::optional< uint32_t > idx
Definition Common.h:38
AppID(const std::string &name, std::optional< uint32_t > idx=std::nullopt)
Definition Common.h:40
Details about how to connect to a particular channel.
Definition Common.h:91
std::map< std::string, std::any > implOptions
Implementation-specific options.
Definition Common.h:96
std::string type
The name of the type of connection.
Definition Common.h:94
std::any value
Definition Common.h:69
std::optional< const Type * > type
Definition Common.h:70
A description of a hardware client.
Definition Common.h:102
std::map< std::string, std::any > implOptions
Definition Common.h:106
AppIDPath relPath
Definition Common.h:103
ChannelAssignments channelAssignments
Definition Common.h:105
ServicePortDesc port
Definition Common.h:104
std::optional< std::string > version
Definition Common.h:76
std::optional< std::string > name
Definition Common.h:74
std::map< std::string, Constant > constants
Definition Common.h:79
std::optional< std::string > commitHash
Definition Common.h:78
std::optional< std::string > repo
Definition Common.h:77
std::map< std::string, std::any > extra
Definition Common.h:80
std::optional< std::string > summary
Definition Common.h:75
A contiguous, non-owning view of bytes within a SegmentedMessageData.
Definition Common.h:122
std::span< const uint8_t > span() const
Definition Common.h:131
std::optional< uint64_t > getDeviceAddress() const
Device address of this segment's bytes, if region is set and contains them; std::nullopt otherwise.
Definition Common.cpp:80
const uint8_t * data
Definition Common.h:123
bool empty() const
Definition Common.h:132
services::HostMemRegion * region
The HostMem region (from services::HostMem::allocate()) which holds [data, data + size),...
Definition Common.h:129
size_t size
Definition Common.h:124
A description of a service port.
Definition Common.h:85
std::string name
Definition Common.h:86
std::string portName
Definition Common.h:87
RAII memory region for host memory in accelerator-accessible address space.
Definition Services.h:237