CIRCT 20.0.0git
Loading...
Searching...
No Matches
Accelerator.h
Go to the documentation of this file.
1//===- Accelerator.h - Base ESI runtime API ---------------------*- 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// Basic ESI APIs. The 'Accelerator' class is the superclass for all accelerator
10// backends. It should (usually) provide enough functionality such that users do
11// not have to interact with the platform-specific backend implementation with
12// the exception of connecting to the accelerator.
13//
14// DO NOT EDIT!
15// This file is distributed as part of an ESI package. The source for this file
16// should always be modified within CIRCT.
17//
18//===----------------------------------------------------------------------===//
19
20// NOLINTNEXTLINE(llvm-header-guard)
21#ifndef ESI_ACCELERATOR_H
22#define ESI_ACCELERATOR_H
23
24#include "esi/Context.h"
25#include "esi/Design.h"
26#include "esi/Manifest.h"
27#include "esi/Ports.h"
28#include "esi/Services.h"
29
30#include <functional>
31#include <map>
32#include <memory>
33#include <string>
34#include <typeinfo>
35
36namespace esi {
37// Forward declarations.
38class AcceleratorServiceThread;
39
40//===----------------------------------------------------------------------===//
41// Constants used by low-level APIs.
42//===----------------------------------------------------------------------===//
43
44constexpr uint32_t MetadataOffset = 8;
45constexpr uint64_t MagicNumberLo = 0xE5100E51;
46constexpr uint64_t MagicNumberHi = 0x207D98E5;
47constexpr uint64_t MagicNumber = MagicNumberLo | (MagicNumberHi << 32);
48constexpr uint32_t ExpectedVersionNumber = 0;
49
50//===----------------------------------------------------------------------===//
51// Accelerator design hierarchy root.
52//===----------------------------------------------------------------------===//
53
54/// Top level accelerator class. Maintains a shared pointer to the manifest,
55/// which owns objects used in the design hierarchy owned by this class. Since
56/// this class owns the entire design hierarchy, when it gets destroyed the
57/// entire design hierarchy gets destroyed so all of the instances, ports, etc.
58/// are no longer valid pointers.
59class Accelerator : public HWModule {
60public:
61 Accelerator() = delete;
62 Accelerator(const Accelerator &) = delete;
63 ~Accelerator() = default;
64 Accelerator(std::optional<ModuleInfo> info,
65 std::vector<std::unique_ptr<Instance>> children,
66 std::vector<services::Service *> services,
67 std::vector<std::unique_ptr<BundlePort>> &ports)
68 : HWModule(info, std::move(children), services, ports) {}
69};
70
71//===----------------------------------------------------------------------===//
72// Connection to the accelerator and its services.
73//===----------------------------------------------------------------------===//
74
75/// Abstract class representing a connection to an accelerator. Actual
76/// connections (e.g. to a co-simulation or actual device) are implemented by
77/// subclasses. No methods in here are thread safe.
79public:
81 virtual ~AcceleratorConnection();
82 Context &getCtxt() const { return ctxt; }
83 Logger &getLogger() const { return ctxt.getLogger(); }
84
85 /// Disconnect from the accelerator cleanly.
86 virtual void disconnect();
87
88 // While building the design, keep around a std::map of active services
89 // indexed by the service name. When a new service is encountered during
90 // descent, add it to the table (perhaps overwriting one). Modifications to
91 // the table only apply to the current branch, so copy this and update it at
92 // each level of the tree.
93 using ServiceTable = std::map<std::string, services::Service *>;
94
95 /// Request the host side channel ports for a particular instance (identified
96 /// by the AppID path). For convenience, provide the bundle type.
97 virtual std::map<std::string, ChannelPort &>
99
100 /// Return a pointer to the accelerator 'service' thread (or threads). If the
101 /// thread(s) are not running, they will be started when this method is
102 /// called. `std::thread` is used. If users don't want the runtime to spin up
103 /// threads, don't call this method. `AcceleratorServiceThread` is owned by
104 /// AcceleratorConnection and governed by the lifetime of the this object.
106
108 /// Get a typed reference to a particular service type. Caller does *not* take
109 /// ownership of the returned pointer -- the Accelerator object owns it.
110 /// Pointer lifetime ends with the Accelerator lifetime.
111 template <typename ServiceClass>
112 ServiceClass *getService(AppIDPath id = {}, std::string implName = {},
113 ServiceImplDetails details = {},
114 HWClientDetails clients = {}) {
115 return dynamic_cast<ServiceClass *>(
116 getService(typeid(ServiceClass), id, implName, details, clients));
117 }
118 /// Calls `createService` and caches the result. Subclasses can override if
119 /// they want to use their own caching mechanism.
120 virtual Service *getService(Service::Type service, AppIDPath id = {},
121 std::string implName = {},
122 ServiceImplDetails details = {},
123 HWClientDetails clients = {});
124
125 /// Assume ownership of an accelerator object. Ties the lifetime of the
126 /// accelerator to this connection. Returns a raw pointer to the object.
127 Accelerator *takeOwnership(std::unique_ptr<Accelerator> accel);
128
129protected:
130 /// Called by `getServiceImpl` exclusively. It wraps the pointer returned by
131 /// this in a unique_ptr and caches it. Separate this from the
132 /// wrapping/caching since wrapping/caching is an implementation detail.
134 std::string implName,
135 const ServiceImplDetails &details,
136 const HWClientDetails &clients) = 0;
137
138private:
139 /// ESI accelerator context.
141
142 /// Cache services via a unique_ptr so they get free'd automatically when
143 /// Accelerator objects get deconstructed.
144 using ServiceCacheKey = std::tuple<const std::type_info *, AppIDPath>;
145 std::map<ServiceCacheKey, std::unique_ptr<Service>> serviceCache;
146
147 std::unique_ptr<AcceleratorServiceThread> serviceThread;
148
149 /// List of accelerator objects owned by this connection. These are destroyed
150 /// when the connection dies or is shutdown.
151 std::vector<std::unique_ptr<Accelerator>> ownedAccelerators;
152};
153
154namespace registry {
155
156// Connect to an ESI accelerator given a backend name and connection specifier.
157// Alternatively, instantiate the backend directly (if you're using C++).
158std::unique_ptr<AcceleratorConnection> connect(Context &ctxt,
159 const std::string &backend,
160 const std::string &connection);
161
162namespace internal {
163
164/// Backends can register themselves to be connected via a connection string.
165using BackendCreate = std::function<std::unique_ptr<AcceleratorConnection>(
166 Context &, std::string)>;
167void registerBackend(const std::string &name, BackendCreate create);
168
169// Helper struct to
170template <typename TAccelerator>
172 RegisterAccelerator(const char *name) {
173 registerBackend(name, &TAccelerator::connect);
174 }
175};
176
177#define REGISTER_ACCELERATOR(Name, TAccelerator) \
178 static ::esi::registry::internal::RegisterAccelerator<TAccelerator> \
179 __register_accel____LINE__(Name)
180
181} // namespace internal
182} // namespace registry
183
184/// Background thread which services various requests. Currently, it listens on
185/// ports and calls callbacks for incoming messages on said ports.
187public:
190
191 /// When there's data on any of the listenPorts, call the callback. Callable
192 /// from any thread.
193 void
194 addListener(std::initializer_list<ReadChannelPort *> listenPorts,
195 std::function<void(ReadChannelPort *, MessageData)> callback);
196
197 /// Poll this module.
198 void addPoll(HWModule &module);
199
200 /// Instruct the service thread to stop running.
201 void stop();
202
203private:
204 struct Impl;
205 std::unique_ptr<Impl> impl;
206};
207} // namespace esi
208
209#endif // ESI_ACCELERATOR_H
Abstract class representing a connection to an accelerator.
Definition Accelerator.h:78
virtual void disconnect()
Disconnect from the accelerator cleanly.
virtual Service * createService(Service::Type service, AppIDPath idPath, std::string implName, const ServiceImplDetails &details, const HWClientDetails &clients)=0
Called by getServiceImpl exclusively.
services::Service Service
ServiceClass * getService(AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={})
Get a typed reference to a particular service type.
Context & getCtxt() const
Definition Accelerator.h:82
std::map< std::string, services::Service * > ServiceTable
Definition Accelerator.h:93
Context & ctxt
ESI accelerator context.
std::map< ServiceCacheKey, std::unique_ptr< Service > > serviceCache
std::tuple< const std::type_info *, AppIDPath > ServiceCacheKey
Cache services via a unique_ptr so they get free'd automatically when Accelerator objects get deconst...
std::unique_ptr< AcceleratorServiceThread > serviceThread
std::vector< std::unique_ptr< Accelerator > > ownedAccelerators
List of accelerator objects owned by this connection.
Logger & getLogger() const
Definition Accelerator.h:83
virtual std::map< std::string, ChannelPort & > requestChannelsFor(AppIDPath, const BundleType *, const ServiceTable &)=0
Request the host side channel ports for a particular instance (identified by the AppID path).
AcceleratorServiceThread * getServiceThread()
Return a pointer to the accelerator 'service' thread (or threads).
Accelerator * takeOwnership(std::unique_ptr< Accelerator > accel)
Assume ownership of an accelerator object.
Background thread which services various requests.
void stop()
Instruct the service thread to stop running.
void addListener(std::initializer_list< ReadChannelPort * > listenPorts, std::function< void(ReadChannelPort *, MessageData)> callback)
When there's data on any of the listenPorts, call the callback.
std::unique_ptr< Impl > impl
void addPoll(HWModule &module)
Poll this module.
Top level accelerator class.
Definition Accelerator.h:59
Accelerator(std::optional< ModuleInfo > info, std::vector< std::unique_ptr< Instance > > children, std::vector< services::Service * > services, std::vector< std::unique_ptr< BundlePort > > &ports)
Definition Accelerator.h:64
~Accelerator()=default
Accelerator()=delete
Accelerator(const Accelerator &)=delete
Bundles represent a collection of channels.
Definition Types.h:44
AcceleratorConnections, Accelerators, and Manifests must all share a context.
Definition Context.h:31
Logger & getLogger()
Definition Context.h:62
Represents either the top level or an instance of a hardware module.
Definition Design.h:47
const std::optional< ModuleInfo > info
Definition Design.h:90
const std::vector< std::unique_ptr< BundlePort > > ports
Definition Design.h:94
const std::vector< std::unique_ptr< Instance > > children
Definition Design.h:91
const std::vector< services::Service * > services
Definition Design.h:93
A logical chunk of data representing serialized data.
Definition Common.h:103
A ChannelPort which reads data from the accelerator.
Definition Ports.h:103
Parent class of all APIs modeled as 'services'.
Definition Services.h:45
const std::type_info & Type
Definition Services.h:47
void registerBackend(const std::string &name, BackendCreate create)
std::function< std::unique_ptr< AcceleratorConnection >(Context &, std::string)> BackendCreate
Backends can register themselves to be connected via a connection string.
std::unique_ptr< AcceleratorConnection > connect(Context &ctxt, const std::string &backend, const std::string &connection)
Definition esi.py:1
constexpr uint64_t MagicNumber
Definition Accelerator.h:47
std::map< std::string, std::any > ServiceImplDetails
Definition Common.h:98
constexpr uint64_t MagicNumberHi
Definition Accelerator.h:46
constexpr uint32_t ExpectedVersionNumber
Definition Accelerator.h:48
constexpr uint32_t MetadataOffset
Definition Accelerator.h:44
constexpr uint64_t MagicNumberLo
Definition Accelerator.h:45
std::vector< HWClientDetail > HWClientDetails
Definition Common.h:97