CIRCT 23.0.0git
Loading...
Searching...
No Matches
TypedPorts.h
Go to the documentation of this file.
1//===- TypedPorts.h - Strongly-typed ESI port wrappers ----------*- 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// Thin, non-owning wrappers around WriteChannelPort / ReadChannelPort that
16// verify type compatibility at connect() time and provide strongly-typed
17// write/read APIs. Purely additive — no changes to the untyped port classes.
18//
19//===----------------------------------------------------------------------===//
20
21// NOLINTNEXTLINE(llvm-header-guard)
22#ifndef ESI_TYPED_PORTS_H
23#define ESI_TYPED_PORTS_H
24
25#include "esi/Ports.h"
26#include "esi/Services.h"
27#include "esi/Types.h"
28
29#include <cstdint>
30#include <cstring>
31#include <functional>
32#include <future>
33#include <stdexcept>
34#include <string>
35#include <string_view>
36#include <type_traits>
37#include <typeinfo>
38
39namespace esi {
40
41//===----------------------------------------------------------------------===//
42// AcceleratorMismatchError — thrown for type mismatches and port-not-found.
43//===----------------------------------------------------------------------===//
44
45class AcceleratorMismatchError : public std::runtime_error {
46public:
47 using std::runtime_error::runtime_error;
48};
49
50//===----------------------------------------------------------------------===//
51// Helpers: unwrap TypeAliasType and width-aware serialization.
52//===----------------------------------------------------------------------===//
53
54/// Unwrap TypeAliasType (possibly recursively) to get the underlying type.
55inline const Type *unwrapTypeAlias(const Type *t) {
56 while (auto *alias = dynamic_cast<const TypeAliasType *>(t))
57 t = alias->getInnerType();
58 return t;
59}
60
61/// Compute the wire byte count for a port type. Returns 0 if not a
62/// BitVectorType (meaning sizeof(T) should be used instead).
63/// Wire format info for a port type, cached at connect() time.
64struct WireInfo {
65 size_t bytes = 0; // (bitWidth+7)/8, or 0 if not a BitVectorType.
66 size_t bitWidth = 0;
67};
68
69inline WireInfo getWireInfo(const Type *portType) {
70 const Type *inner = unwrapTypeAlias(portType);
71 if (auto *bv = dynamic_cast<const BitVectorType *>(inner))
72 return {(bv->getWidth() + 7) / 8, bv->getWidth()};
73 return {};
74}
75
76/// Pack a C++ integral value into a MessageData with the given wire byte count.
77/// If wi.bytes is 0, falls back to sizeof(T).
78template <typename T>
80 if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>) {
81 if (wi.bytes > 0 && wi.bytes != sizeof(T)) {
82 std::vector<uint8_t> buf(wi.bytes, 0);
83 std::memcpy(buf.data(), &data, std::min(wi.bytes, sizeof(T)));
84 return MessageData(std::move(buf));
85 }
86 } else if constexpr (std::is_base_of_v<SegmentedMessageData, T>) {
87 return data.toMessageData();
88 }
89 return MessageData(reinterpret_cast<const uint8_t *>(&data), sizeof(T));
90}
91
92/// Unpack a MessageData into a C++ integral value with the given wire info.
93/// If the wire size differs from sizeof(T), copies available bytes into
94/// a zero-initialized value and sign-extends for signed types using the
95/// actual bit width to locate the sign bit.
96template <typename T>
98 if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>) {
99 if (wi.bytes > 0 && msg.getSize() == wi.bytes &&
100 wi.bitWidth < sizeof(T) * 8) {
101 // Copy wire bytes into a zero-initialized value.
102 T val = 0;
103 std::memcpy(&val, msg.getBytes(), std::min(wi.bytes, sizeof(T)));
104 // Sign-extend for signed types if the sign bit is set.
105 if constexpr (std::is_signed_v<T>) {
106 size_t signBit = wi.bitWidth - 1;
107 size_t signByte = signBit / 8;
108 uint8_t signMask = uint8_t(1) << (signBit % 8);
109 if (signByte < wi.bytes && (msg.getBytes()[signByte] & signMask)) {
110 // Set all bits above the sign bit to 1.
111 if (wi.bitWidth < sizeof(T) * 8)
112 val |= static_cast<T>(~T(0)) << wi.bitWidth;
113 }
114 }
115 return val;
116 }
117 }
118 return *msg.as<T>();
119}
120
121//===----------------------------------------------------------------------===//
122// Type-trait: detect T::_ESI_ID (a static constexpr std::string_view).
123//===----------------------------------------------------------------------===//
124
125template <typename T, typename = void>
126struct has_esi_id : std::false_type {};
127
128template <typename T>
129struct has_esi_id<T, std::void_t<decltype(T::_ESI_ID)>>
130 : std::is_convertible<decltype(T::_ESI_ID), std::string_view> {};
131
132template <typename T>
133inline constexpr bool has_esi_id_v = has_esi_id<T>::value;
134
135//===----------------------------------------------------------------------===//
136// verifyTypeCompatibility<T>(const Type *portType)
137//
138// Checks that the ESI runtime Type is compatible with the C++ type T.
139// Dispatch order: _ESI_ID → void → bool → signed int → unsigned int → error.
140//===----------------------------------------------------------------------===//
141
142template <typename T>
143void verifyTypeCompatibility(const Type *portType) {
144 if (!portType)
145 throw AcceleratorMismatchError("Port type is null");
146
147 // Unwrap TypeAliasType to get the inner type for verification.
148 portType = unwrapTypeAlias(portType);
149
150 if constexpr (has_esi_id_v<T>) {
151 // Highest priority: user-defined ESI ID string comparison.
152 if (std::string_view(portType->getID()) != T::_ESI_ID)
154 "ESI type mismatch: C++ type has _ESI_ID '" +
155 std::string(T::_ESI_ID) + "' but port type is '" +
156 portType->toString(/*oneLine=*/true) + "'");
157 } else if constexpr (std::is_void_v<T>) {
158 if (!dynamic_cast<const VoidType *>(portType))
159 throw AcceleratorMismatchError("ESI type mismatch: expected VoidType for "
160 "void, but port type is '" +
161 portType->toString(/*oneLine=*/true) +
162 "'");
163 } else if constexpr (std::is_same_v<T, bool>) {
164 // bool maps to signless i1, which is BitsType with width <= 1.
165 auto *bits = dynamic_cast<const BitsType *>(portType);
166 if (!bits || bits->getWidth() > 1)
168 "ESI type mismatch: expected BitsType with width <= 1 for "
169 "bool, but port type is '" +
170 portType->toString(/*oneLine=*/true) + "'");
171 } else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>) {
172 auto *sint = dynamic_cast<const SIntType *>(portType);
173 if (!sint)
175 "ESI type mismatch: expected SIntType for signed integer, "
176 "but port type is '" +
177 portType->toString(/*oneLine=*/true) + "'");
178 if (sint->getWidth() > sizeof(T) * 8)
180 "ESI type mismatch: SIntType width " +
181 std::to_string(sint->getWidth()) + " does not fit in " +
182 std::to_string(sizeof(T) * 8) + "-bit signed integer");
183 // Require closest-size match: reject if a smaller C++ type would suffice.
184 if (sizeof(T) > 1 && sint->getWidth() <= (sizeof(T) / 2) * 8)
185 throw AcceleratorMismatchError("ESI type mismatch: SIntType width " +
186 std::to_string(sint->getWidth()) +
187 " should use a smaller C++ type than " +
188 std::to_string(sizeof(T) * 8) + "-bit");
189 } else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>) {
190 // Accept UIntType (uiM) or BitsType (iM, signless).
191 auto *uintPort = dynamic_cast<const UIntType *>(portType);
192 auto *bits = dynamic_cast<const BitsType *>(portType);
193 if (!uintPort && !bits)
195 "ESI type mismatch: expected UIntType or BitsType for unsigned "
196 "integer, but port type is '" +
197 portType->toString(/*oneLine=*/true) + "'");
198 uint64_t width = uintPort ? uintPort->getWidth() : bits->getWidth();
199 if (width > sizeof(T) * 8)
201 "ESI type mismatch: bit width " + std::to_string(width) +
202 " does not fit in " + std::to_string(sizeof(T) * 8) +
203 "-bit unsigned integer");
204 // Require closest-size match: reject if a smaller C++ type would suffice.
205 if (sizeof(T) > 1 && width <= (sizeof(T) / 2) * 8)
206 throw AcceleratorMismatchError("ESI type mismatch: bit width " +
207 std::to_string(width) +
208 " should use a smaller C++ type than " +
209 std::to_string(sizeof(T) * 8) + "-bit");
210 } else {
212 std::string("Cannot verify type compatibility for C++ type '") +
213 typeid(T).name() + "' against ESI port type '" +
214 portType->toString(/*oneLine=*/true) + "'");
215 }
216}
217
218//===----------------------------------------------------------------------===//
219// TypedWritePort<T, SkipTypeCheck = false>
220//
221// When SkipTypeCheck is false, the `connect` method runs the type check via
222// `verifyTypeCompatibility<T>()`. When SkipTypeCheck is true, `connect`
223// skips that verification.
224//===----------------------------------------------------------------------===//
225
226template <typename T, bool SkipTypeCheck = false>
228public:
229 explicit TypedWritePort(WriteChannelPort &port) : inner(&port) {}
230 // NOLINTNEXTLINE(google-explicit-constructor)
232
233 void connect(const ChannelPort::ConnectOptions &opts = {}) {
234 if (!inner)
235 throw AcceleratorMismatchError("TypedWritePort: null port pointer");
236 if (!SkipTypeCheck)
237 verifyTypeCompatibility<T>(inner->getType());
239 inner->connect(opts);
240 }
241
242 void write(const T &data) { inner->write(toMessageData(data, wireInfo_)); }
243
244 /// Write by taking ownership. If T is a SegmentedMessageData, this hands
245 /// the message directly to the port's segmented write path.
246 void write(std::unique_ptr<T> &data) {
247 if (!data)
248 throw std::runtime_error("TypedWritePort::write: null unique_ptr");
249 if constexpr (std::is_base_of_v<SegmentedMessageData, T>) {
250 inner->write(std::move(data));
251 } else {
252 write(*data);
253 data.reset();
254 }
255 }
256
257 bool tryWrite(const T &data) {
258 return inner->tryWrite(toMessageData(data, wireInfo_));
259 }
260
261 bool flush() { return inner->flush(); }
263 bool isConnected() const { return inner && inner->isConnected(); }
264
265 WriteChannelPort &raw() { return *inner; }
266 const WriteChannelPort &raw() const { return *inner; }
267
268private:
271};
272
273/// Specialization for void — write takes no data argument.
274template <>
275class TypedWritePort<void> {
276public:
277 explicit TypedWritePort(WriteChannelPort &port) : inner(&port) {}
278 // NOLINTNEXTLINE(google-explicit-constructor)
280
281 void connect(const ChannelPort::ConnectOptions &opts = {}) {
282 if (!inner)
283 throw AcceleratorMismatchError("TypedWritePort: null port pointer");
284 verifyTypeCompatibility<void>(inner->getType());
285 inner->connect(opts);
286 }
287
288 void write() {
289 uint8_t zero = 0;
290 inner->write(MessageData(&zero, 1));
291 }
292
293 bool tryWrite() {
294 uint8_t zero = 0;
295 return inner->tryWrite(MessageData(&zero, 1));
296 }
297
298 bool flush() { return inner->flush(); }
300 bool isConnected() const { return inner && inner->isConnected(); }
301
302 WriteChannelPort &raw() { return *inner; }
303 const WriteChannelPort &raw() const { return *inner; }
304
305private:
307};
308
309//===----------------------------------------------------------------------===//
310// TypedReadPort<T>
311//===----------------------------------------------------------------------===//
312
313template <typename T>
315public:
316 explicit TypedReadPort(ReadChannelPort &port) : inner(&port) {}
317 // NOLINTNEXTLINE(google-explicit-constructor)
319
320 void connect(const ChannelPort::ConnectOptions &opts = {}) {
321 if (!inner)
322 throw AcceleratorMismatchError("TypedReadPort: null port pointer");
323 verifyTypeCompatibility<T>(inner->getType());
325 inner->connect(opts);
326 }
327
328 void connect(std::function<bool(const T &)> callback,
329 const ChannelPort::ConnectOptions &opts = {}) {
330 if (!inner)
331 throw AcceleratorMismatchError("TypedReadPort: null port pointer");
332 verifyTypeCompatibility<T>(inner->getType());
334 WireInfo wb = wireInfo_;
335 inner->connect(
336 [cb = std::move(callback), wb](MessageData data) -> bool {
337 return cb(fromMessageData<T>(data, wb));
338 },
339 opts);
340 }
341
342 T read() {
343 MessageData outData;
344 inner->read(outData);
345 return fromMessageData<T>(outData, wireInfo_);
346 }
347
348 std::future<T> readAsync() {
349 WireInfo wb = wireInfo_;
350 auto innerFuture = inner->readAsync();
351 return std::async(std::launch::deferred,
352 [f = std::move(innerFuture), wb]() mutable -> T {
353 MessageData data = f.get();
354 return fromMessageData<T>(data, wb);
355 });
356 }
357
359 bool isConnected() const { return inner && inner->isConnected(); }
360
361 ReadChannelPort &raw() { return *inner; }
362 const ReadChannelPort &raw() const { return *inner; }
363
364private:
367};
368
369/// Specialization for void — read discards data and returns nothing.
370template <>
371class TypedReadPort<void> {
372public:
373 explicit TypedReadPort(ReadChannelPort &port) : inner(&port) {}
374 // NOLINTNEXTLINE(google-explicit-constructor)
376
377 void connect(const ChannelPort::ConnectOptions &opts = {}) {
378 if (!inner)
379 throw AcceleratorMismatchError("TypedReadPort: null port pointer");
380 verifyTypeCompatibility<void>(inner->getType());
381 inner->connect(opts);
382 }
383
384 void connect(std::function<bool()> callback,
385 const ChannelPort::ConnectOptions &opts = {}) {
386 if (!inner)
387 throw AcceleratorMismatchError("TypedReadPort: null port pointer");
388 verifyTypeCompatibility<void>(inner->getType());
389 inner->connect(
390 [cb = std::move(callback)](MessageData) -> bool { return cb(); }, opts);
391 }
392
393 void read() {
394 MessageData outData;
395 inner->read(outData);
396 }
397
398 std::future<void> readAsync() {
399 auto innerFuture = inner->readAsync();
400 return std::async(
401 std::launch::deferred,
402 [f = std::move(innerFuture)]() mutable -> void { f.get(); });
403 }
404
406 bool isConnected() const { return inner && inner->isConnected(); }
407
408 ReadChannelPort &raw() { return *inner; }
409 const ReadChannelPort &raw() const { return *inner; }
410
411private:
413};
414
415//===----------------------------------------------------------------------===//
416// TypedFunction<ArgT, ResultT>
417//
418// Non-owning wrapper around FuncService::Function that provides strongly-typed
419// call() and connect() APIs. Implicitly constructible from Function* (the
420// return type of BundlePort::getAs<FuncService::Function>()).
421//===----------------------------------------------------------------------===//
422
423template <typename ArgT, typename ResultT, bool SkipTypeCheck = false>
425public:
426 /// Implicit conversion from Function* (returned by getAs<>()).
427 // NOLINTNEXTLINE(google-explicit-constructor)
429
430 void connect() {
431 if (!inner)
433 "TypedFunction: null Function pointer (getAs failed or wrong type)");
434 if constexpr (!SkipTypeCheck) {
435 verifyTypeCompatibility<ArgT>(inner->getArgType());
436 verifyTypeCompatibility<ResultT>(inner->getResultType());
437 }
440 inner->connect(ChannelPort::ConnectOptions(/*bufferSize=*/std::nullopt,
441 /*translateMessage=*/false));
442 }
443
444 std::future<ResultT> call(const ArgT &arg) {
446 auto f = inner->call(toMessageData(arg, argWireInfo_));
447 return std::async(std::launch::deferred,
448 [fut = std::move(f), rwb]() mutable -> ResultT {
449 MessageData data = fut.get();
450 return fromMessageData<ResultT>(data, rwb);
451 });
452 }
453
455 const services::FuncService::Function &raw() const { return *inner; }
456
457private:
461};
462
463/// Partial specialization: void argument, typed result.
464template <typename ResultT, bool SkipTypeCheck>
465class TypedFunction<void, ResultT, SkipTypeCheck> {
466public:
467 // NOLINTNEXTLINE(google-explicit-constructor)
469
470 void connect() {
471 if (!inner)
473 "TypedFunction: null Function pointer (getAs failed or wrong type)");
474 if constexpr (!SkipTypeCheck) {
475 verifyTypeCompatibility<void>(inner->getArgType());
476 verifyTypeCompatibility<ResultT>(inner->getResultType());
477 }
478 inner->connect(ChannelPort::ConnectOptions(/*bufferSize=*/std::nullopt,
479 /*translateMessage=*/false));
480 }
481
482 std::future<ResultT> call() {
483 uint8_t zero = 0;
484 const Type *resType = inner->getResultType();
485 auto f = inner->call(MessageData(&zero, 1));
486 return std::async(std::launch::deferred,
487 [fut = std::move(f), resType]() mutable -> ResultT {
488 MessageData data = fut.get();
489 return fromMessageData<ResultT>(data, resType);
490 });
491 }
492
494 const services::FuncService::Function &raw() const { return *inner; }
495
496private:
498};
499
500/// Partial specialization: typed argument, void result.
501template <typename ArgT, bool SkipTypeCheck>
502class TypedFunction<ArgT, void, SkipTypeCheck> {
503public:
504 // NOLINTNEXTLINE(google-explicit-constructor)
506
507 void connect() {
508 if (!inner)
510 "TypedFunction: null Function pointer (getAs failed or wrong type)");
511 if constexpr (!SkipTypeCheck) {
512 verifyTypeCompatibility<ArgT>(inner->getArgType());
513 verifyTypeCompatibility<void>(inner->getResultType());
514 }
516 inner->connect(ChannelPort::ConnectOptions(/*bufferSize=*/std::nullopt,
517 /*translateMessage=*/false));
518 }
519
520 std::future<void> call(const ArgT &arg) {
521 auto f = inner->call(toMessageData(arg, argWireInfo_));
522 return std::async(std::launch::deferred,
523 [fut = std::move(f)]() mutable -> void { fut.get(); });
524 }
525
527 const services::FuncService::Function &raw() const { return *inner; }
528
529private:
532};
533
534/// Full specialization: void argument, void result.
535template <bool SkipTypeCheck>
536class TypedFunction<void, void, SkipTypeCheck> {
537public:
538 // NOLINTNEXTLINE(google-explicit-constructor)
540
541 void connect() {
542 if (!inner)
544 "TypedFunction: null Function pointer (getAs failed or wrong type)");
545 if constexpr (!SkipTypeCheck) {
546 verifyTypeCompatibility<void>(inner->getArgType());
547 verifyTypeCompatibility<void>(inner->getResultType());
548 }
549 inner->connect(ChannelPort::ConnectOptions(/*bufferSize=*/std::nullopt,
550 /*translateMessage=*/false));
551 }
552
553 std::future<void> call() {
554 uint8_t zero = 0;
555 auto f = inner->call(MessageData(&zero, 1));
556 return std::async(std::launch::deferred,
557 [fut = std::move(f)]() mutable -> void { fut.get(); });
558 }
559
561 const services::FuncService::Function &raw() const { return *inner; }
562
563private:
565};
566
567//===----------------------------------------------------------------------===//
568// TypedCallback<ArgT, ResultT>
569//
570// Non-owning wrapper around CallService::Callback that provides strongly-typed
571// connect() and automatic MessageData conversion. Implicitly constructible
572// from Callback* (the return type of BundlePort::getAs<Callback>()).
573//===----------------------------------------------------------------------===//
574
575template <typename ArgT, typename ResultT, bool SkipTypeCheck = false>
577public:
578 // NOLINTNEXTLINE(google-explicit-constructor)
580
581 void connect(std::function<ResultT(const ArgT &)> callback,
582 bool quick = false) {
583 if (!inner)
585 "TypedCallback: null Callback pointer (getAs failed or wrong type)");
586 if constexpr (!SkipTypeCheck) {
587 verifyTypeCompatibility<ArgT>(inner->getArgType());
588 verifyTypeCompatibility<ResultT>(inner->getResultType());
589 }
590 inner->connect(
591 [cb = std::move(callback), argType = inner->getArgType(),
592 resType = inner->getResultType()](
593 const MessageData &argData) -> MessageData {
594 ResultT result = cb(fromMessageData<ArgT>(argData, argType));
595 return toMessageData(result, resType);
596 },
597 quick,
598 ChannelPort::ConnectOptions(/*bufferSize=*/std::nullopt,
599 /*translateMessage=*/false));
600 }
601
603 const services::CallService::Callback &raw() const { return *inner; }
604
605private:
607};
608
609/// Partial specialization: void argument, typed result.
610template <typename ResultT, bool SkipTypeCheck>
611class TypedCallback<void, ResultT, SkipTypeCheck> {
612public:
613 // NOLINTNEXTLINE(google-explicit-constructor)
615
616 void connect(std::function<ResultT()> callback, bool quick = false) {
617 if (!inner)
619 "TypedCallback: null Callback pointer (getAs failed or wrong type)");
620 if constexpr (!SkipTypeCheck) {
621 verifyTypeCompatibility<void>(inner->getArgType());
622 verifyTypeCompatibility<ResultT>(inner->getResultType());
623 }
625 inner->connect(
626 [cb = std::move(callback), rwb](const MessageData &) -> MessageData {
627 ResultT result = cb();
628 return toMessageData(result, rwb);
629 },
630 quick,
631 ChannelPort::ConnectOptions(/*bufferSize=*/std::nullopt,
632 /*translateMessage=*/false));
633 }
634
636 const services::CallService::Callback &raw() const { return *inner; }
637
638private:
640};
641
642/// Partial specialization: typed argument, void result.
643template <typename ArgT, bool SkipTypeCheck>
644class TypedCallback<ArgT, void, SkipTypeCheck> {
645public:
646 // NOLINTNEXTLINE(google-explicit-constructor)
648
649 void connect(std::function<void(const ArgT &)> callback, bool quick = false) {
650 if (!inner)
652 "TypedCallback: null Callback pointer (getAs failed or wrong type)");
653 if constexpr (!SkipTypeCheck) {
654 verifyTypeCompatibility<ArgT>(inner->getArgType());
655 verifyTypeCompatibility<void>(inner->getResultType());
656 }
657 inner->connect(
658 [cb = std::move(callback), argType = inner->getArgType()](
659 const MessageData &argData) -> MessageData {
660 cb(fromMessageData<ArgT>(argData, argType));
661 uint8_t zero = 0;
662 return MessageData(&zero, 1);
663 },
664 quick,
665 ChannelPort::ConnectOptions(/*bufferSize=*/std::nullopt,
666 /*translateMessage=*/false));
667 }
668
670 const services::CallService::Callback &raw() const { return *inner; }
671
672private:
674};
675
676/// Full specialization: void argument, void result.
677template <bool SkipTypeCheck>
678class TypedCallback<void, void, SkipTypeCheck> {
679public:
680 // NOLINTNEXTLINE(google-explicit-constructor)
682
683 void connect(std::function<void()> callback, bool quick = false) {
684 if (!inner)
686 "TypedCallback: null Callback pointer (getAs failed or wrong type)");
687 if constexpr (!SkipTypeCheck) {
688 verifyTypeCompatibility<void>(inner->getArgType());
689 verifyTypeCompatibility<void>(inner->getResultType());
690 }
691 inner->connect(
692 [cb = std::move(callback)](const MessageData &) -> MessageData {
693 cb();
694 uint8_t zero = 0;
695 return MessageData(&zero, 1);
696 },
697 quick,
698 ChannelPort::ConnectOptions(/*bufferSize=*/std::nullopt,
699 /*translateMessage=*/false));
700 }
701
703 const services::CallService::Callback &raw() const { return *inner; }
704
705private:
707};
708
709} // namespace esi
710
711#endif // ESI_TYPED_PORTS_H
Bit vectors include signed, unsigned, and signless integers.
Definition Types.h:191
Bits are just an array of bits.
Definition Types.h:204
const Type * getType() const
Definition Ports.h:137
A logical chunk of data representing serialized data.
Definition Common.h:113
const uint8_t * getBytes() const
Definition Common.h:124
const T * as() const
Cast to a type.
Definition Common.h:148
size_t getSize() const
Get the size of the data in bytes.
Definition Common.h:138
A ChannelPort which reads data from the accelerator.
Definition Ports.h:341
virtual std::future< MessageData > readAsync()
Asynchronous read.
Definition Ports.cpp:126
virtual bool isConnected() const override
Definition Ports.h:347
virtual void connect(std::function< bool(MessageData)> callback, const ConnectOptions &options={})
Definition Ports.cpp:69
virtual void disconnect() override
Definition Ports.h:346
virtual void read(MessageData &outData)
Specify a buffer to read into.
Definition Ports.h:381
Signed integer.
Definition Types.h:222
Type aliases provide a named type which forwards to an inner type.
Definition Types.h:164
Root class of the ESI type system.
Definition Types.h:36
std::string toString(bool oneLine=false) const
Definition Types.cpp:120
ID getID() const
Definition Types.h:42
services::CallService::Callback * inner
Definition TypedPorts.h:673
const services::CallService::Callback & raw() const
Definition TypedPorts.h:670
void connect(std::function< void(const ArgT &)> callback, bool quick=false)
Definition TypedPorts.h:649
services::CallService::Callback & raw()
Definition TypedPorts.h:669
TypedCallback(services::CallService::Callback *cb)
Definition TypedPorts.h:647
services::CallService::Callback & raw()
Definition TypedPorts.h:635
void connect(std::function< ResultT()> callback, bool quick=false)
Definition TypedPorts.h:616
TypedCallback(services::CallService::Callback *cb)
Definition TypedPorts.h:614
const services::CallService::Callback & raw() const
Definition TypedPorts.h:636
services::CallService::Callback * inner
Definition TypedPorts.h:639
TypedCallback(services::CallService::Callback *cb)
Definition TypedPorts.h:681
services::CallService::Callback & raw()
Definition TypedPorts.h:702
void connect(std::function< void()> callback, bool quick=false)
Definition TypedPorts.h:683
const services::CallService::Callback & raw() const
Definition TypedPorts.h:703
services::CallService::Callback * inner
Definition TypedPorts.h:706
services::CallService::Callback * inner
Definition TypedPorts.h:606
services::CallService::Callback & raw()
Definition TypedPorts.h:602
void connect(std::function< ResultT(const ArgT &)> callback, bool quick=false)
Definition TypedPorts.h:581
TypedCallback(services::CallService::Callback *cb)
Definition TypedPorts.h:579
const services::CallService::Callback & raw() const
Definition TypedPorts.h:603
const services::FuncService::Function & raw() const
Definition TypedPorts.h:527
services::FuncService::Function & raw()
Definition TypedPorts.h:526
std::future< void > call(const ArgT &arg)
Definition TypedPorts.h:520
services::FuncService::Function * inner
Definition TypedPorts.h:530
TypedFunction(services::FuncService::Function *func)
Definition TypedPorts.h:505
services::FuncService::Function & raw()
Definition TypedPorts.h:493
services::FuncService::Function * inner
Definition TypedPorts.h:497
const services::FuncService::Function & raw() const
Definition TypedPorts.h:494
TypedFunction(services::FuncService::Function *func)
Definition TypedPorts.h:468
const services::FuncService::Function & raw() const
Definition TypedPorts.h:561
services::FuncService::Function * inner
Definition TypedPorts.h:564
TypedFunction(services::FuncService::Function *func)
Definition TypedPorts.h:539
services::FuncService::Function & raw()
Definition TypedPorts.h:560
services::FuncService::Function & raw()
Definition TypedPorts.h:454
WireInfo resWireInfo_
Definition TypedPorts.h:460
std::future< ResultT > call(const ArgT &arg)
Definition TypedPorts.h:444
WireInfo argWireInfo_
Definition TypedPorts.h:459
const services::FuncService::Function & raw() const
Definition TypedPorts.h:455
TypedFunction(services::FuncService::Function *func)
Implicit conversion from Function* (returned by getAs<>()).
Definition TypedPorts.h:428
services::FuncService::Function * inner
Definition TypedPorts.h:458
ReadChannelPort * inner
Definition TypedPorts.h:412
TypedReadPort(ReadChannelPort &port)
Definition TypedPorts.h:373
void connect(const ChannelPort::ConnectOptions &opts={})
Definition TypedPorts.h:377
TypedReadPort(ReadChannelPort *port)
Definition TypedPorts.h:375
std::future< void > readAsync()
Definition TypedPorts.h:398
ReadChannelPort & raw()
Definition TypedPorts.h:408
const ReadChannelPort & raw() const
Definition TypedPorts.h:409
void connect(std::function< bool()> callback, const ChannelPort::ConnectOptions &opts={})
Definition TypedPorts.h:384
bool isConnected() const
Definition TypedPorts.h:359
TypedReadPort(ReadChannelPort &port)
Definition TypedPorts.h:316
ReadChannelPort & raw()
Definition TypedPorts.h:361
TypedReadPort(ReadChannelPort *port)
Definition TypedPorts.h:318
std::future< T > readAsync()
Definition TypedPorts.h:348
void connect(const ChannelPort::ConnectOptions &opts={})
Definition TypedPorts.h:320
const ReadChannelPort & raw() const
Definition TypedPorts.h:362
void connect(std::function< bool(const T &)> callback, const ChannelPort::ConnectOptions &opts={})
Definition TypedPorts.h:328
ReadChannelPort * inner
Definition TypedPorts.h:365
WriteChannelPort * inner
Definition TypedPorts.h:306
void connect(const ChannelPort::ConnectOptions &opts={})
Definition TypedPorts.h:281
TypedWritePort(WriteChannelPort &port)
Definition TypedPorts.h:277
TypedWritePort(WriteChannelPort *port)
Definition TypedPorts.h:279
WriteChannelPort & raw()
Definition TypedPorts.h:302
const WriteChannelPort & raw() const
Definition TypedPorts.h:303
const WriteChannelPort & raw() const
Definition TypedPorts.h:266
WriteChannelPort & raw()
Definition TypedPorts.h:265
void write(std::unique_ptr< T > &data)
Write by taking ownership.
Definition TypedPorts.h:246
bool tryWrite(const T &data)
Definition TypedPorts.h:257
bool isConnected() const
Definition TypedPorts.h:263
void connect(const ChannelPort::ConnectOptions &opts={})
Definition TypedPorts.h:233
TypedWritePort(WriteChannelPort &port)
Definition TypedPorts.h:229
void write(const T &data)
Definition TypedPorts.h:242
TypedWritePort(WriteChannelPort *port)
Definition TypedPorts.h:231
WriteChannelPort * inner
Definition TypedPorts.h:269
Unsigned integer.
Definition Types.h:233
The "void" type is a special type which can be used to represent no type.
Definition Types.h:141
A ChannelPort which sends data to the accelerator.
Definition Ports.h:215
virtual bool isConnected() const override
Definition Ports.h:227
virtual void disconnect() override
Definition Ports.h:226
void write(const MessageData &data)
A very basic blocking write API.
Definition Ports.h:231
bool flush()
Flush any buffered data.
Definition Ports.h:279
bool tryWrite(const MessageData &data)
A basic non-blocking write API.
Definition Ports.h:261
virtual void connect(const ConnectOptions &options={}) override
Set up a connection to the accelerator.
Definition Ports.h:219
A function call which gets attached to a service port.
Definition Services.h:405
const esi::Type * getArgType() const
Definition Services.h:423
const esi::Type * getResultType() const
Definition Services.h:428
void connect(std::function< MessageData(const MessageData &)> callback, bool quick=false, const ChannelPort::ConnectOptions &options={})
Connect a callback to code which will be executed when the accelerator invokes the callback.
Definition Services.cpp:343
A function call which gets attached to a service port.
Definition Services.h:353
const esi::Type * getArgType() const
Definition Services.h:364
const esi::Type * getResultType() const
Definition Services.h:369
std::future< MessageData > call(const MessageData &arg)
Definition Services.cpp:308
void connect(const ChannelPort::ConnectOptions &options={})
Definition Services.cpp:294
Definition esi.py:1
void verifyTypeCompatibility(const Type *portType)
Definition TypedPorts.h:143
MessageData toMessageData(const T &data, WireInfo wi)
Pack a C++ integral value into a MessageData with the given wire byte count.
Definition TypedPorts.h:79
WireInfo getWireInfo(const Type *portType)
Definition TypedPorts.h:69
constexpr bool has_esi_id_v
Definition TypedPorts.h:133
const Type * unwrapTypeAlias(const Type *t)
Unwrap TypeAliasType (possibly recursively) to get the underlying type.
Definition TypedPorts.h:55
T fromMessageData(const MessageData &msg, WireInfo wi)
Unpack a MessageData into a C++ integral value with the given wire info.
Definition TypedPorts.h:97
Compute the wire byte count for a port type.
Definition TypedPorts.h:64
size_t bitWidth
Definition TypedPorts.h:66