Skip to content

Commit

Permalink
[ESI][Runtime] Throw unknown engine error lazily (#8205)
Browse files Browse the repository at this point in the history
When an engine is unknown, throw the error when the user tries to
connect rather than during manifest parsing.
  • Loading branch information
teqdruid authored Feb 7, 2025
1 parent 5fc33be commit ab69d42
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
39 changes: 39 additions & 0 deletions lib/Dialect/ESI/runtime/cpp/include/esi/Ports.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ class WriteChannelPort : public ChannelPort {
volatile bool connected = false;
};

/// Instantiated when a backend does not know how to create a write channel.
class UnknownWriteChannelPort : public WriteChannelPort {
public:
UnknownWriteChannelPort(const Type *type, std::string errmsg)
: WriteChannelPort(type), errmsg(errmsg) {}

void connect(std::optional<unsigned> bufferSize = std::nullopt) override {
throw std::runtime_error(errmsg);
}
void write(const MessageData &) override { throw std::runtime_error(errmsg); }
bool tryWrite(const MessageData &) override {
throw std::runtime_error(errmsg);
}

protected:
std::string errmsg;
};

/// A ChannelPort which reads data from the accelerator. It has two modes:
/// Callback and Polling which cannot be used at the same time. The mode is set
/// at connect() time. To change the mode, disconnect() and then connect()
Expand Down Expand Up @@ -181,6 +199,27 @@ class ReadChannelPort : public ChannelPort {
std::queue<std::promise<MessageData>> promiseQueue;
};

/// Instantiated when a backend does not know how to create a read channel.
class UnknownReadChannelPort : public ReadChannelPort {
public:
UnknownReadChannelPort(const Type *type, std::string errmsg)
: ReadChannelPort(type), errmsg(errmsg) {}

void connect(std::function<bool(MessageData)> callback,
std::optional<unsigned> bufferSize = std::nullopt) override {
throw std::runtime_error(errmsg);
}
void connect(std::optional<unsigned> bufferSize = std::nullopt) override {
throw std::runtime_error(errmsg);
}
std::future<MessageData> readAsync() override {
throw std::runtime_error(errmsg);
}

protected:
std::string errmsg;
};

/// Services provide connections to 'bundles' -- collections of named,
/// unidirectional communication channels. This class provides access to those
/// ChannelPorts.
Expand Down
32 changes: 31 additions & 1 deletion lib/Dialect/ESI/runtime/cpp/lib/Engines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,36 @@

using namespace esi;

namespace {
/// Created by default when the DMA engine cannot be resolved. Throws the error
/// upon trying to connect and creates ports which throw errors on their
/// connection attempts.
class UnknownEngine : public Engine {
public:
UnknownEngine(AcceleratorConnection &conn, std::string engineName)
: engineName(engineName) {}
void connect() override {
throw std::runtime_error("Unknown engine '" + engineName + "'");
}

std::unique_ptr<ChannelPort> createPort(AppIDPath idPath,
const std::string &channelName,
BundleType::Direction dir,
const Type *type) override {
if (BundlePort::isWrite(dir))
return std::make_unique<UnknownWriteChannelPort>(
type,
"Unknown engine '" + engineName + "': cannot create write port");
else
return std::make_unique<UnknownReadChannelPort>(
type, "Unknown engine '" + engineName + "': cannot create read port");
}

protected:
std::string engineName;
};
} // namespace

ChannelPort &Engine::requestPort(AppIDPath idPath,
const std::string &channelName,
BundleType::Direction dir, const Type *type) {
Expand Down Expand Up @@ -61,7 +91,7 @@ registry::createEngine(AcceleratorConnection &conn,
const HWClientDetails &clients) {
auto it = engineRegistry.find(dmaEngineName);
if (it == engineRegistry.end())
throw std::runtime_error("Unknown engine: " + dmaEngineName);
return std::make_unique<UnknownEngine>(conn, dmaEngineName);
return it->second(conn, idPath, details, clients);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/Dialect/ESI/runtime/cpp/tools/esitester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ int main(int argc, const char *argv[]) {
Accelerator *accel = manifest.buildAccelerator(*acc);
acc->getServiceThread()->addPoll(*accel);

registerCallbacks(acc.get(), accel);

if (cmd == "loop") {
registerCallbacks(acc.get(), accel);
while (true) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
} else if (cmd == "wait") {
registerCallbacks(acc.get(), accel);
std::this_thread::sleep_for(std::chrono::seconds(1));
} else if (cmd == "dmatest") {
dmaTest(acc.get(), accel, true, true);
Expand Down

0 comments on commit ab69d42

Please sign in to comment.