23class UnknownEngine :
public Engine {
26 : engineName(engineName) {}
28 throw std::runtime_error(
"Unknown engine '" + engineName +
"'");
32 const std::string &channelName,
34 const Type *type)
override {
35 if (BundlePort::isWrite(dir))
36 return std::make_unique<UnknownWriteChannelPort>(
38 "Unknown engine '" + engineName +
"': cannot create write port");
40 return std::make_unique<UnknownReadChannelPort>(
41 type,
"Unknown engine '" + engineName +
"': cannot create read port");
45 std::string engineName;
50 const std::string &channelName,
52 auto portIter =
ownedPorts.find(std::make_pair(idPath, channelName));
54 return *portIter->second;
55 std::unique_ptr<ChannelPort> port =
58 ownedPorts.emplace(std::make_pair(idPath, channelName), std::move(port));
65 for (
auto [channelName, dir, type] : bundleType->
getChannels()) {
70 ports.emplace(channelName, engineIter->second->requestPort(
71 idPath, channelName, dir, type));
80 throw std::runtime_error(
"Channel already exists in engine map");
89 static std::map<std::string, registry::internal::EngineCreate> &get() {
90 static EngineRegistry instance;
91 return instance.engineRegistry;
95 std::map<std::string, registry::internal::EngineCreate> engineRegistry;
99std::unique_ptr<Engine>
101 const std::string &dmaEngineName,
AppIDPath idPath,
104 auto ® = EngineRegistry::get();
105 auto it = reg.find(dmaEngineName);
107 return std::make_unique<UnknownEngine>(conn, dmaEngineName);
108 return it->second(conn, idPath, details, clients);
113 auto tried = EngineRegistry::get().try_emplace(name, create);
115 throw std::runtime_error(
"Engine already exists in registry");
Abstract class representing a connection to an accelerator.
PortMap requestPorts(const AppIDPath &idPath, const BundleType *bundleType) const
Request ports for all the channels in a bundle.
std::map< std::string, Engine * > bundleEngineMap
void setEngine(const std::string &channelName, Engine *engine)
Set a particlar engine for a particular channel.
Bundles represent a collection of channels.
const ChannelVector & getChannels() const
Unidirectional channels are the basic communication primitive between the host and accelerator.
Engines implement the actual channel communication between the host and the accelerator.
virtual void connect()
Start the engine, if applicable.
virtual ChannelPort & requestPort(AppIDPath idPath, const std::string &channelName, BundleType::Direction dir, const Type *type)
Get a port for a channel, from the cache if it exists or create it.
virtual std::unique_ptr< ChannelPort > createPort(AppIDPath idPath, const std::string &channelName, BundleType::Direction dir, const Type *type)=0
Each engine needs to know how to create a ports.
std::map< std::pair< AppIDPath, std::string >, std::unique_ptr< ChannelPort > > ownedPorts
Root class of the ESI type system.
std::function< std::unique_ptr< Engine >(AcceleratorConnection &conn, AppIDPath idPath, const ServiceImplDetails &details, const HWClientDetails &clients)> EngineCreate
Engines can register themselves for pluggable functionality.
void registerEngine(const std::string &name, EngineCreate create)
std::unique_ptr< Engine > createEngine(AcceleratorConnection &conn, const std::string &dmaEngineName, AppIDPath idPath, const ServiceImplDetails &details, const HWClientDetails &clients)
Create an engine by name.
std::map< std::string, std::any > ServiceImplDetails
std::map< std::string, ChannelPort & > PortMap
std::vector< HWClientDetail > HWClientDetails