CIRCT  20.0.0git
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 
36 namespace esi {
37 // Forward declarations.
38 class AcceleratorServiceThread;
39 
40 //===----------------------------------------------------------------------===//
41 // Constants used by low-level APIs.
42 //===----------------------------------------------------------------------===//
43 
44 constexpr uint32_t MetadataOffset = 8;
45 constexpr uint64_t MagicNumberLo = 0xE5100E51;
46 constexpr uint64_t MagicNumberHi = 0x207D98E5;
47 constexpr uint64_t MagicNumber = MagicNumberLo | (MagicNumberHi << 32);
48 constexpr 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.
59 class Accelerator : public HWModule {
60 public:
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.
79 public:
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  /// Request the host side channel ports for a particular instance (identified
89  /// by the AppID path). For convenience, provide the bundle type.
90  virtual std::map<std::string, ChannelPort &>
92 
93  /// Return a pointer to the accelerator 'service' thread (or threads). If the
94  /// thread(s) are not running, they will be started when this method is
95  /// called. `std::thread` is used. If users don't want the runtime to spin up
96  /// threads, don't call this method. `AcceleratorServiceThread` is owned by
97  /// AcceleratorConnection and governed by the lifetime of the this object.
99 
101  /// Get a typed reference to a particular service type. Caller does *not* take
102  /// ownership of the returned pointer -- the Accelerator object owns it.
103  /// Pointer lifetime ends with the Accelerator lifetime.
104  template <typename ServiceClass>
105  ServiceClass *getService(AppIDPath id = {}, std::string implName = {},
106  ServiceImplDetails details = {},
107  HWClientDetails clients = {}) {
108  return dynamic_cast<ServiceClass *>(
109  getService(typeid(ServiceClass), id, implName, details, clients));
110  }
111  /// Calls `createService` and caches the result. Subclasses can override if
112  /// they want to use their own caching mechanism.
113  virtual Service *getService(Service::Type service, AppIDPath id = {},
114  std::string implName = {},
115  ServiceImplDetails details = {},
116  HWClientDetails clients = {});
117 
118  /// Assume ownership of an accelerator object. Ties the lifetime of the
119  /// accelerator to this connection. Returns a raw pointer to the object.
120  Accelerator *takeOwnership(std::unique_ptr<Accelerator> accel);
121 
122 protected:
123  /// Called by `getServiceImpl` exclusively. It wraps the pointer returned by
124  /// this in a unique_ptr and caches it. Separate this from the
125  /// wrapping/caching since wrapping/caching is an implementation detail.
126  virtual Service *createService(Service::Type service, AppIDPath idPath,
127  std::string implName,
128  const ServiceImplDetails &details,
129  const HWClientDetails &clients) = 0;
130 
131 private:
132  /// ESI accelerator context.
134 
135  /// Cache services via a unique_ptr so they get free'd automatically when
136  /// Accelerator objects get deconstructed.
137  using ServiceCacheKey = std::tuple<const std::type_info *, AppIDPath>;
138  std::map<ServiceCacheKey, std::unique_ptr<Service>> serviceCache;
139 
140  std::unique_ptr<AcceleratorServiceThread> serviceThread;
141 
142  /// List of accelerator objects owned by this connection. These are destroyed
143  /// when the connection dies or is shutdown.
144  std::vector<std::unique_ptr<Accelerator>> ownedAccelerators;
145 };
146 
147 namespace registry {
148 
149 // Connect to an ESI accelerator given a backend name and connection specifier.
150 // Alternatively, instantiate the backend directly (if you're using C++).
151 std::unique_ptr<AcceleratorConnection> connect(Context &ctxt,
152  const std::string &backend,
153  const std::string &connection);
154 
155 namespace internal {
156 
157 /// Backends can register themselves to be connected via a connection string.
158 using BackendCreate = std::function<std::unique_ptr<AcceleratorConnection>(
159  Context &, std::string)>;
160 void registerBackend(const std::string &name, BackendCreate create);
161 
162 // Helper struct to
163 template <typename TAccelerator>
165  RegisterAccelerator(const char *name) {
167  }
168 };
169 
170 #define REGISTER_ACCELERATOR(Name, TAccelerator) \
171  static ::esi::registry::internal::RegisterAccelerator<TAccelerator> \
172  __register_accel____LINE__(Name)
173 
174 } // namespace internal
175 } // namespace registry
176 
177 /// Background thread which services various requests. Currently, it listens on
178 /// ports and calls callbacks for incoming messages on said ports.
180 public:
183 
184  /// When there's data on any of the listenPorts, call the callback. Callable
185  /// from any thread.
186  void
187  addListener(std::initializer_list<ReadChannelPort *> listenPorts,
188  std::function<void(ReadChannelPort *, MessageData)> callback);
189 
190  /// Poll this module.
191  void addPoll(HWModule &module);
192 
193  /// Instruct the service thread to stop running.
194  void stop();
195 
196 private:
197  struct Impl;
198  std::unique_ptr<Impl> impl;
199 };
200 } // namespace esi
201 
202 #endif // ESI_ACCELERATOR_H
Abstract class representing a connection to an accelerator.
Definition: Accelerator.h:78
Context & getCtxt() const
Definition: Accelerator.h:82
virtual void disconnect()
Disconnect from the accelerator cleanly.
Logger & getLogger() const
Definition: Accelerator.h:83
services::Service Service
Definition: Accelerator.h:100
ServiceClass * getService(AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={})
Get a typed reference to a particular service type.
Definition: Accelerator.h:105
Context & ctxt
ESI accelerator context.
Definition: Accelerator.h:133
std::map< ServiceCacheKey, std::unique_ptr< Service > > serviceCache
Definition: Accelerator.h:138
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...
Definition: Accelerator.h:137
std::unique_ptr< AcceleratorServiceThread > serviceThread
Definition: Accelerator.h:140
virtual Service * createService(Service::Type service, AppIDPath idPath, std::string implName, const ServiceImplDetails &details, const HWClientDetails &clients)=0
Called by getServiceImpl exclusively.
virtual std::map< std::string, ChannelPort & > requestChannelsFor(AppIDPath, const BundleType *)=0
Request the host side channel ports for a particular instance (identified by the AppID path).
std::vector< std::unique_ptr< Accelerator > > ownedAccelerators
List of accelerator objects owned by this connection.
Definition: Accelerator.h:144
AcceleratorServiceThread * getServiceThread()
Return a pointer to the accelerator 'service' thread (or threads).
Definition: Accelerator.cpp:40
AcceleratorConnection(Context &ctxt)
Definition: Accelerator.cpp:36
Accelerator * takeOwnership(std::unique_ptr< Accelerator > accel)
Assume ownership of an accelerator object.
Definition: Accelerator.cpp:65
Background thread which services various requests.
Definition: Accelerator.h:179
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
Definition: Accelerator.h:197
void addPoll(HWModule &module)
Poll this module.
Top level accelerator class.
Definition: Accelerator.h:59
~Accelerator()=default
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()=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:92
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.
Definition: Accelerator.h:159
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:87
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:86