10#include "gtest/gtest.h"
20TEST(TypedPortsTest, VoidTypeCompatibility) {
22 EXPECT_NO_THROW(verifyTypeCompatibility<void>(&voidType));
29 EXPECT_THROW(verifyTypeCompatibility<void>(&sint32),
33TEST(TypedPortsTest, BoolTypeCompatibility) {
35 EXPECT_NO_THROW(verifyTypeCompatibility<bool>(&bits1));
46TEST(TypedPortsTest, SignedIntTypeCompatibility) {
49 EXPECT_NO_THROW(verifyTypeCompatibility<int32_t>(&sint17));
53 EXPECT_NO_THROW(verifyTypeCompatibility<int32_t>(&sint32));
57 EXPECT_THROW(verifyTypeCompatibility<int32_t>(&sint33),
62 EXPECT_THROW(verifyTypeCompatibility<int32_t>(&sint16),
67 EXPECT_THROW(verifyTypeCompatibility<int32_t>(&sint8),
71 EXPECT_NO_THROW(verifyTypeCompatibility<int8_t>(&sint8));
75 EXPECT_THROW(verifyTypeCompatibility<int32_t>(&uint31),
80 EXPECT_NO_THROW(verifyTypeCompatibility<int64_t>(&sint33b));
84 EXPECT_NO_THROW(verifyTypeCompatibility<int64_t>(&sint64));
88 EXPECT_THROW(verifyTypeCompatibility<int64_t>(&sint65),
92 EXPECT_THROW(verifyTypeCompatibility<int64_t>(&sint32),
96TEST(TypedPortsTest, UnsignedIntTypeCompatibility) {
99 EXPECT_NO_THROW(verifyTypeCompatibility<uint32_t>(&uint17));
103 EXPECT_NO_THROW(verifyTypeCompatibility<uint32_t>(&uint32_t_));
107 EXPECT_THROW(verifyTypeCompatibility<uint32_t>(&uint33),
112 EXPECT_THROW(verifyTypeCompatibility<uint32_t>(&uint16_),
116 EXPECT_NO_THROW(verifyTypeCompatibility<uint16_t>(&uint16_));
120 EXPECT_NO_THROW(verifyTypeCompatibility<uint32_t>(&bits17));
124 EXPECT_NO_THROW(verifyTypeCompatibility<uint32_t>(&bits32));
128 EXPECT_THROW(verifyTypeCompatibility<uint32_t>(&bits33),
133 EXPECT_THROW(verifyTypeCompatibility<uint32_t>(&bits8),
135 EXPECT_NO_THROW(verifyTypeCompatibility<uint8_t>(&bits8));
139 EXPECT_NO_THROW(verifyTypeCompatibility<uint64_t>(&uint33b));
143 EXPECT_NO_THROW(verifyTypeCompatibility<uint64_t>(&uint64_t_));
147 EXPECT_THROW(verifyTypeCompatibility<uint64_t>(&uint65),
151 EXPECT_THROW(verifyTypeCompatibility<uint64_t>(&uint32_t_),
156 EXPECT_THROW(verifyTypeCompatibility<uint32_t>(&sint31),
162 static constexpr std::string_view _ESI_ID =
"MyModule.TestStruct";
167TEST(TypedPortsTest, ESIIDTypeCompatibility) {
169 StructType matchType(
"MyModule.TestStruct", {});
170 EXPECT_NO_THROW(verifyTypeCompatibility<TestStruct>(&matchType));
173 StructType mismatchType(
"OtherModule.OtherStruct", {});
174 EXPECT_THROW(verifyTypeCompatibility<TestStruct>(&mismatchType),
178 UIntType uintWithMatchingID(
"MyModule.TestStruct", 32);
179 EXPECT_NO_THROW(verifyTypeCompatibility<TestStruct>(&uintWithMatchingID));
182TEST(TypedPortsTest, NullPortTypeThrows) {
183 EXPECT_THROW(verifyTypeCompatibility<int32_t>(
nullptr),
185 EXPECT_THROW(verifyTypeCompatibility<void>(
nullptr),
190struct UnknownCppType {
194TEST(TypedPortsTest, FallbackThrows) {
196 EXPECT_THROW(verifyTypeCompatibility<UnknownCppType>(&uint32),
210 void connect(
const ConnectOptions &opts = {})
override {
214 void disconnect()
override { connected =
false; }
227 bool connected =
false;
230TEST(TypedPortsTest, TypedWritePortConnectThrowsOnMismatch) {
232 MockWritePort mock(&uint32);
237TEST(TypedPortsTest, TypedWritePortConnectSucceeds) {
239 MockWritePort mock(&sint31);
241 EXPECT_NO_THROW(typed.connect());
242 EXPECT_TRUE(typed.isConnected());
245TEST(TypedPortsTest, TypedWritePortRoundTrip) {
247 MockWritePort mock(&sint15);
255 ASSERT_EQ(mock.lastWritten.getSize(), 2u);
258TEST(TypedPortsTest, SignExtensionNonByteAligned) {
264 EXPECT_EQ(wi.
bytes, 1u);
268 int32_t val = fromMessageData<int32_t>(msg, wi);
277 int32_t val = fromMessageData<int32_t>(msg, wi);
285 EXPECT_EQ(wi.
bytes, 3u);
286 uint8_t wire[3] = {0xFF, 0xFF, 0x3F};
288 int32_t val = fromMessageData<int32_t>(msg, wi);
295 uint8_t wire[3] = {0xFF, 0xFF, 0x1F};
297 int32_t val = fromMessageData<int32_t>(msg, wi);
298 EXPECT_EQ(val, 0x1FFFFF);
302TEST(TypedPortsTest, TypedWritePortVoid) {
304 MockWritePort mock(&voidType);
306 EXPECT_NO_THROW(typed.connect());
309 ASSERT_EQ(mock.lastWritten.getSize(), 1u);
310 EXPECT_EQ(mock.lastWritten.getData()[0], 0);
323 const ConnectOptions & = {})
override {
329 std::future<MessageData>
readAsync()
override {
330 std::promise<MessageData> p;
331 p.set_value(nextResponse);
332 return p.get_future();
342TEST(TypedPortsTest, TypedFunctionNullThrowsAtConnect) {
348TEST(TypedPortsTest, TypedFunctionConnectVerifiesTypes) {
351 ChannelType argChanType(
"channel<si24>", &argInner);
353 ChannelType resultChanType(
"channel<ui15>", &resultInner);
356 {
"arg", BundleType::Direction::To, &argChanType},
357 {
"result", BundleType::Direction::From, &resultChanType},
359 BundleType bundleType(
"func_bundle", channels);
361 MockWritePort mockWrite(&argInner);
362 MockReadPort mockRead(&resultInner);
365 mockWrite, mockRead);
370 EXPECT_NO_THROW(typed.connect());
374TEST(TypedPortsTest, TypedFunctionConnectRejectsArgMismatch) {
376 ChannelType argChanType(
"channel<ui24>", &argInner);
378 ChannelType resultChanType(
"channel<ui15>", &resultInner);
381 {
"arg", BundleType::Direction::To, &argChanType},
382 {
"result", BundleType::Direction::From, &resultChanType},
384 BundleType bundleType(
"func_bundle", channels);
386 MockWritePort mockWrite(&argInner);
387 MockReadPort mockRead(&resultInner);
390 mockWrite, mockRead);
398TEST(TypedPortsTest, TypedFunctionCallRoundTrip) {
400 ChannelType argChanType(
"channel<si24>", &argInner);
402 ChannelType resultChanType(
"channel<ui15>", &resultInner);
405 {
"arg", BundleType::Direction::To, &argChanType},
406 {
"result", BundleType::Direction::From, &resultChanType},
408 BundleType bundleType(
"func_bundle", channels);
410 MockWritePort mockWrite(&argInner);
411 MockReadPort mockRead(&resultInner);
418 mockWrite, mockRead);
424 uint16_t result = typed.call(arg).get();
425 EXPECT_EQ(result, 42);
428 ASSERT_EQ(mockWrite.lastWritten.getSize(), 3u);
446 std::vector<uint32_t> items;
451 return {
reinterpret_cast<const uint8_t *
>(&header),
sizeof(Header)};
452 return {
reinterpret_cast<const uint8_t *
>(items.data()),
453 items.
size() *
sizeof(uint32_t)};
457TEST(TypedPortsTest, TypedWritePortSegmentedMessageData) {
460 MockWritePort mock(&uint32);
466 msg.header.a = 0x12345678;
467 msg.header.b = 0xABCD;
468 msg.items = {1, 2, 3};
474 EXPECT_EQ(mock.lastWritten.getSize(), 18u);
477 const uint8_t *bytes = mock.lastWritten.getBytes();
480 std::memcpy(&gotA, bytes, 4);
481 std::memcpy(&gotB, bytes + 4, 2);
482 EXPECT_EQ(gotA, 0x12345678u);
483 EXPECT_EQ(gotB, 0xABCDu);
486 uint32_t gotItems[3];
487 std::memcpy(gotItems, bytes + 6, 12);
488 EXPECT_EQ(gotItems[0], 1u);
489 EXPECT_EQ(gotItems[1], 2u);
490 EXPECT_EQ(gotItems[2], 3u);
493TEST(TypedPortsTest, TypedWritePortSegmentedNoTypeCheck) {
497 MockWritePort mock(&sint8);
500 EXPECT_NO_THROW(typed.connect());
509 EXPECT_EQ(mock.lastWritten.getSize(), 10u);
512TEST(TypedPortsTest, TypedFunctionSegmentedArg) {
516 ChannelType argChanType(
"channel<ui32>", &argInner);
518 ChannelType resultChanType(
"channel<ui16>", &resultInner);
521 {
"arg", BundleType::Direction::To, &argChanType},
522 {
"result", BundleType::Direction::From, &resultChanType},
524 BundleType bundleType(
"func_bundle", channels);
526 MockWritePort mockWrite(&argInner);
527 MockReadPort mockRead(&resultInner);
534 mockWrite, mockRead);
540 arg.header.a = 0xDEAD;
542 arg.items = {10, 20};
544 uint16_t result = typed.call(arg).get();
545 EXPECT_EQ(result, 99u);
548 EXPECT_EQ(mockWrite.lastWritten.getSize(), 14u);
550 const uint8_t *bytes = mockWrite.lastWritten.getBytes();
552 std::memcpy(&gotA, bytes, 4);
553 EXPECT_EQ(gotA, 0xDEADu);
555 uint32_t gotItem0, gotItem1;
556 std::memcpy(&gotItem0, bytes + 6, 4);
557 std::memcpy(&gotItem1, bytes + 10, 4);
558 EXPECT_EQ(gotItem0, 10u);
559 EXPECT_EQ(gotItem1, 20u);
565struct UnrecognizedCppType {
570TEST(TypedPortsTest, VerifyTypeCompatibilityThrowsForUnsupportedType) {
572 EXPECT_THROW(verifyTypeCompatibility<UnrecognizedCppType>(&uint32),
576 EXPECT_THROW(verifyTypeCompatibility<UnrecognizedCppType>(&sint16),
Bits are just an array of bits.
Bundles represent a collection of channels.
std::vector< std::tuple< std::string, Direction, const Type * > > ChannelVector
virtual void connectImpl(const ConnectOptions &options)
Called by all connect methods to let backends initiate the underlying connections.
Channels are the basic communication primitives.
A logical chunk of data representing serialized data.
static MessageData from(T &t)
Cast from a type to its raw bytes.
A ChannelPort which reads data from the accelerator.
virtual std::future< MessageData > readAsync()
Asynchronous read.
virtual void connect(std::function< bool(MessageData)> callback, const ConnectOptions &options={})
virtual void read(MessageData &outData)
Specify a buffer to read into.
Abstract multi-segment message.
virtual Segment segment(size_t idx) const =0
Get a segment by index.
virtual size_t numSegments() const =0
Number of segments in the message.
Structs are an ordered collection of fields, each with a name and a type.
Root class of the ESI type system.
The "void" type is a special type which can be used to represent no type.
A ChannelPort which sends data to the accelerator.
virtual bool isConnected() const override
virtual void disconnect() override
virtual bool tryWriteImpl(const MessageData &data)=0
Implementation for tryWrite(). Subclasses must implement this.
virtual void connect(const ConnectOptions &options={}) override
Set up a connection to the accelerator.
virtual void writeImpl(const MessageData &)=0
Implementation for write(). Subclasses must implement this.
static Function * get(AppID id, BundleType *type, WriteChannelPort &arg, ReadChannelPort &result)
WireInfo getWireInfo(const Type *portType)
A contiguous, non-owning view of bytes within a SegmentedMessageData.
Compute the wire byte count for a port type.