CIRCT  20.0.0git
Services.h
Go to the documentation of this file.
1 //===- StdServices.h - ESI standard services C++ 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 // The APIs in this backend are all optionally implemented. The lower level
10 // ones, however, are strongly recommended. 'Services' here refers to ESI
11 // services. These are standard APIs into the standard ESI services.
12 //
13 // DO NOT EDIT!
14 // This file is distributed as part of an ESI package. The source for this file
15 // should always be modified within CIRCT.
16 //
17 //===----------------------------------------------------------------------===//
18 
19 // NOLINTNEXTLINE(llvm-header-guard)
20 #ifndef ESI_RUNTIME_SERVICES_H
21 #define ESI_RUNTIME_SERVICES_H
22 
23 #include "esi/Common.h"
24 #include "esi/Context.h"
25 #include "esi/Ports.h"
26 
27 #include <cstdint>
28 
29 namespace esi {
30 class AcceleratorConnection;
31 namespace services {
32 
33 /// Add a custom interface to a service client at a particular point in the
34 /// design hierarchy.
35 class ServicePort : public BundlePort {
36 public:
38  virtual ~ServicePort() = default;
39  // Get a description of the service port.
40  virtual std::optional<std::string> toString() const { return std::nullopt; }
41 };
42 
43 /// Parent class of all APIs modeled as 'services'. May or may not map to a
44 /// hardware side 'service'.
45 class Service {
46 public:
47  using Type = const std::type_info &;
48  virtual ~Service() = default;
49 
50  virtual std::string getServiceSymbol() const = 0;
51 
52  /// Create a "child" service of this service. Does not have to be the same
53  /// service type, but typically is. Used when a service already exists in the
54  /// active services table, but a new one wants to replace it. Useful for cases
55  /// where the child service needs to use the parent service. Defaults to
56  /// calling the `getService` method on `AcceleratorConnection` to get the
57  /// global service, implying that the child service does not need to use the
58  /// service it is replacing.
60  Service::Type service, AppIDPath id = {},
61  std::string implName = {},
62  ServiceImplDetails details = {},
63  HWClientDetails clients = {});
64 
65  /// Get specialized port for this service to attach to the given appid path.
66  /// Null returns mean nothing to attach.
67  virtual ServicePort *getPort(AppIDPath id, const BundleType *type,
68  const std::map<std::string, ChannelPort &> &,
69  AcceleratorConnection &) const {
70  return nullptr;
71  }
72 };
73 
74 /// A service for which there are no standard services registered. Requires
75 /// ports be added to the design hierarchy instead of high level interfaces like
76 /// the ones in StdServices.h.
77 class CustomService : public Service {
78 public:
79  CustomService(AppIDPath idPath, const ServiceImplDetails &details,
80  const HWClientDetails &clients);
81  virtual ~CustomService() = default;
82 
83  virtual std::string getServiceSymbol() const override {
84  return serviceSymbol;
85  }
86 
87 protected:
88  std::string serviceSymbol;
90 };
91 
92 /// Information about the Accelerator system.
93 class SysInfo : public Service {
94 public:
95  virtual ~SysInfo() = default;
96 
97  virtual std::string getServiceSymbol() const override;
98 
99  /// Get the ESI version number to check version compatibility.
100  virtual uint32_t getEsiVersion() const = 0;
101 
102  /// Return the JSON-formatted system manifest.
103  virtual std::string getJsonManifest() const;
104 
105  /// Return the zlib compressed JSON system manifest.
106  virtual std::vector<uint8_t> getCompressedManifest() const = 0;
107 };
108 
109 class MMIO : public Service {
110 public:
111  static constexpr std::string_view StdName = "esi.service.std.mmio";
112 
113  /// Describe a region (slice) of MMIO space.
115  uint32_t base;
116  uint32_t size;
117  };
118 
119  MMIO(Context &ctxt, AppIDPath idPath, std::string implName,
120  const ServiceImplDetails &details, const HWClientDetails &clients);
121  MMIO() = default;
122  virtual ~MMIO() = default;
123 
124  /// Read a 64-bit value from the global MMIO space.
125  virtual uint64_t read(uint32_t addr) const = 0;
126  /// Write a 64-bit value to the global MMIO space.
127  virtual void write(uint32_t addr, uint64_t data) = 0;
128  /// Get the regions of MMIO space that this service manages. Otherwise known
129  /// as the base address table.
130  const std::map<AppIDPath, RegionDescriptor> &getRegions() const {
131  return regions;
132  }
133 
134  /// If the service is a MMIO service, return a region of the MMIO space which
135  /// peers into ours.
137  Service::Type service, AppIDPath id = {},
138  std::string implName = {},
139  ServiceImplDetails details = {},
140  HWClientDetails clients = {}) override;
141 
142  virtual std::string getServiceSymbol() const override;
143 
144  /// Get a MMIO region port for a particular region descriptor.
145  virtual ServicePort *getPort(AppIDPath id, const BundleType *type,
146  const std::map<std::string, ChannelPort &> &,
147  AcceleratorConnection &) const override;
148 
149 private:
150  /// MMIO base address table.
151  std::map<AppIDPath, RegionDescriptor> regions;
152 
153 public:
154  /// A "slice" of some parent MMIO space.
155  class MMIORegion : public ServicePort {
156  friend class MMIO;
158 
159  public:
160  /// Get the offset (and size) of the region in the parent (usually global)
161  /// MMIO address space.
162  virtual RegionDescriptor getDescriptor() const { return desc; };
163  /// Read a 64-bit value from this region, not the global address space.
164  virtual uint64_t read(uint32_t addr) const;
165  /// Write a 64-bit value to this region, not the global address space.
166  virtual void write(uint32_t addr, uint64_t data);
167 
168  virtual std::optional<std::string> toString() const override {
169  return "MMIO region " + toHex(desc.base) + " - " +
170  toHex(desc.base + desc.size);
171  }
172 
173  private:
176  };
177 };
178 
179 /// Implement the SysInfo API for a standard MMIO protocol.
180 class MMIOSysInfo final : public SysInfo {
181 public:
182  MMIOSysInfo(const MMIO *);
183 
184  /// Get the ESI version number to check version compatibility.
185  uint32_t getEsiVersion() const override;
186 
187  /// Return the zlib compressed JSON system manifest.
188  virtual std::vector<uint8_t> getCompressedManifest() const override;
189 
190 private:
191  const MMIO *mmio;
192 };
193 
194 class HostMem : public Service {
195 public:
196  virtual ~HostMem() = default;
197  virtual std::string getServiceSymbol() const override;
198 
199  /// RAII memory region for host memory. Automatically frees the memory when
200  /// deconstructed.
201  struct HostMemRegion {
202  virtual ~HostMemRegion() = default;
203  virtual void *getPtr() const = 0;
204  operator void *() const { return getPtr(); }
205  virtual std::size_t getSize() const = 0;
206  };
207 
208  /// Options for allocating host memory.
209  struct Options {
210  bool writeable = false;
211  bool useLargePages = false;
212  };
213 
214  /// Allocate a region of host memory in accelerator accessible address space.
215  virtual std::unique_ptr<HostMemRegion> allocate(std::size_t size,
216  Options opts) const = 0;
217 
218  /// Try to make a region of host memory accessible to the accelerator. Returns
219  /// 'false' on failure. It is optional for an accelerator backend to implement
220  /// this, so client code needs to have a fallback for when this returns
221  /// 'false'. On success, it is the client's responsibility to ensure that the
222  /// memory eventually gets unmapped.
223  virtual bool mapMemory(void *ptr, std::size_t size, Options opts) const {
224  return false;
225  }
226  /// Unmap memory which was previously mapped with 'mapMemory'. Undefined
227  /// behavior when called with a pointer which was not previously mapped.
228  virtual void unmapMemory(void *ptr) const {}
229 };
230 
231 /// Service for calling functions.
232 class FuncService : public Service {
233 public:
235  const std::string &implName, ServiceImplDetails details,
236  HWClientDetails clients);
237 
238  virtual std::string getServiceSymbol() const override;
239  virtual ServicePort *getPort(AppIDPath id, const BundleType *type,
240  const std::map<std::string, ChannelPort &> &,
241  AcceleratorConnection &) const override;
242 
243  /// A function call which gets attached to a service port.
244  class Function : public ServicePort {
245  friend class FuncService;
246  Function(AppID id, const std::map<std::string, ChannelPort &> &channels);
247 
248  public:
249  static Function *get(AppID id, WriteChannelPort &arg,
251 
252  void connect();
253  std::future<MessageData> call(const MessageData &arg);
254 
255  virtual std::optional<std::string> toString() const override {
256  const esi::Type *argType =
257  dynamic_cast<const ChannelType *>(arg.getType())->getInner();
258  const esi::Type *resultType =
259  dynamic_cast<const ChannelType *>(result.getType())->getInner();
260  return "function " + resultType->getID() + "(" + argType->getID() + ")";
261  }
262 
263  private:
264  std::mutex callMutex;
267  };
268 
269 private:
270  std::string symbol;
271 };
272 
273 /// Service for servicing function calls from the accelerator.
274 class CallService : public Service {
275 public:
276  CallService(AcceleratorConnection *acc, AppIDPath id, std::string implName,
277  ServiceImplDetails details, HWClientDetails clients);
278 
279  virtual std::string getServiceSymbol() const override;
280  virtual ServicePort *getPort(AppIDPath id, const BundleType *type,
281  const std::map<std::string, ChannelPort &> &,
282  AcceleratorConnection &) const override;
283 
284  /// A function call which gets attached to a service port.
285  class Callback : public ServicePort {
286  friend class CallService;
288  const std::map<std::string, ChannelPort &> &channels);
289 
290  public:
291  /// Connect a callback to code which will be executed when the accelerator
292  /// invokes the callback. The 'quick' flag indicates that the callback is
293  /// sufficiently fast that it could be called in the same thread as the
294  /// port callback.
295  void connect(std::function<MessageData(const MessageData &)> callback,
296  bool quick = false);
297 
298  private:
302  };
303 
304 private:
305  std::string symbol;
306 };
307 
308 /// Registry of services which can be instantiated directly by the Accelerator
309 /// class if the backend doesn't do anything special with a service.
311 public:
312  /// Create a service instance from the given details. Returns nullptr if
313  /// 'svcType' isn't registered.
315  Service::Type svcType, AppIDPath id,
316  std::string implName,
317  ServiceImplDetails details,
318  HWClientDetails clients);
319 
320  /// Resolve a service type from a string. If the string isn't recognized,
321  /// default to CustomService.
322  static Service::Type lookupServiceType(const std::string &);
323 };
324 
325 } // namespace services
326 } // namespace esi
327 
328 #endif // ESI_RUNTIME_SERVICES_H
Abstract class representing a connection to an accelerator.
Definition: Accelerator.h:78
Services provide connections to 'bundles' – collections of named, unidirectional communication channe...
Definition: Ports.h:184
std::map< std::string, ChannelPort & > channels
Definition: Ports.h:229
BundlePort(AppID id, std::map< std::string, ChannelPort & > channels)
Construct a port.
Definition: Ports.cpp:22
Bundles represent a collection of channels.
Definition: Types.h:44
const Type * getType() const
Definition: Ports.h:59
Channels are the basic communication primitives.
Definition: Types.h:63
AcceleratorConnections, Accelerators, and Manifests must all share a context.
Definition: Context.h:31
A logical chunk of data representing serialized data.
Definition: Common.h:92
A ChannelPort which reads data from the accelerator.
Definition: Ports.h:103
Root class of the ESI type system.
Definition: Types.h:27
ID getID() const
Definition: Types.h:33
A ChannelPort which sends data to the accelerator.
Definition: Ports.h:74
A function call which gets attached to a service port.
Definition: Services.h:285
Callback(AcceleratorConnection &acc, AppID id, const std::map< std::string, ChannelPort & > &channels)
Definition: Services.cpp:255
void connect(std::function< MessageData(const MessageData &)> callback, bool quick=false)
Connect a callback to code which will be executed when the accelerator invokes the callback.
Definition: Services.cpp:264
AcceleratorConnection & acc
Definition: Services.h:301
Service for servicing function calls from the accelerator.
Definition: Services.h:274
CallService(AcceleratorConnection *acc, AppIDPath id, std::string implName, ServiceImplDetails details, HWClientDetails clients)
Definition: Services.cpp:222
virtual std::string getServiceSymbol() const override
Definition: Services.cpp:230
virtual ServicePort * getPort(AppIDPath id, const BundleType *type, const std::map< std::string, ChannelPort & > &, AcceleratorConnection &) const override
Get specialized port for this service to attach to the given appid path.
Definition: Services.cpp:233
A service for which there are no standard services registered.
Definition: Services.h:77
CustomService(AppIDPath idPath, const ServiceImplDetails &details, const HWClientDetails &clients)
Definition: Services.cpp:168
virtual ~CustomService()=default
virtual std::string getServiceSymbol() const override
Definition: Services.h:83
A function call which gets attached to a service port.
Definition: Services.h:244
std::future< MessageData > call(const MessageData &arg)
Definition: Services.cpp:216
virtual std::optional< std::string > toString() const override
Definition: Services.h:255
static Function * get(AppID id, WriteChannelPort &arg, ReadChannelPort &result)
Definition: Services.cpp:204
Function(AppID id, const std::map< std::string, ChannelPort & > &channels)
Definition: Services.cpp:196
Service for calling functions.
Definition: Services.h:232
virtual std::string getServiceSymbol() const override
Definition: Services.cpp:187
virtual ServicePort * getPort(AppIDPath id, const BundleType *type, const std::map< std::string, ChannelPort & > &, AcceleratorConnection &) const override
Get specialized port for this service to attach to the given appid path.
Definition: Services.cpp:190
FuncService(AcceleratorConnection *acc, AppIDPath id, const std::string &implName, ServiceImplDetails details, HWClientDetails clients)
Definition: Services.cpp:179
virtual ~HostMem()=default
virtual std::string getServiceSymbol() const override
Definition: Services.cpp:166
virtual std::unique_ptr< HostMemRegion > allocate(std::size_t size, Options opts) const =0
Allocate a region of host memory in accelerator accessible address space.
virtual void unmapMemory(void *ptr) const
Unmap memory which was previously mapped with 'mapMemory'.
Definition: Services.h:228
virtual bool mapMemory(void *ptr, std::size_t size, Options opts) const
Try to make a region of host memory accessible to the accelerator.
Definition: Services.h:223
Implement the SysInfo API for a standard MMIO protocol.
Definition: Services.h:180
virtual std::vector< uint8_t > getCompressedManifest() const override
Return the zlib compressed JSON system manifest.
Definition: Services.cpp:146
uint32_t getEsiVersion() const override
Get the ESI version number to check version compatibility.
Definition: Services.cpp:139
MMIOSysInfo(const MMIO *)
Definition: Services.cpp:137
A "slice" of some parent MMIO space.
Definition: Services.h:155
virtual uint64_t read(uint32_t addr) const
Read a 64-bit value from this region, not the global address space.
Definition: Services.cpp:126
MMIORegion(AppID id, MMIO *parent, RegionDescriptor desc)
Definition: Services.cpp:124
virtual void write(uint32_t addr, uint64_t data)
Write a 64-bit value to this region, not the global address space.
Definition: Services.cpp:131
virtual RegionDescriptor getDescriptor() const
Get the offset (and size) of the region in the parent (usually global) MMIO address space.
Definition: Services.h:162
virtual std::optional< std::string > toString() const override
Definition: Services.h:168
virtual uint64_t read(uint32_t addr) const =0
Read a 64-bit value from the global MMIO space.
virtual Service * getChildService(AcceleratorConnection *conn, Service::Type service, AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={}) override
If the service is a MMIO service, return a region of the MMIO space which peers into ours.
Definition: Services.cpp:109
virtual ~MMIO()=default
virtual void write(uint32_t addr, uint64_t data)=0
Write a 64-bit value to the global MMIO space.
std::map< AppIDPath, RegionDescriptor > regions
MMIO base address table.
Definition: Services.h:151
static constexpr std::string_view StdName
Definition: Services.h:111
const std::map< AppIDPath, RegionDescriptor > & getRegions() const
Get the regions of MMIO space that this service manages.
Definition: Services.h:130
virtual ServicePort * getPort(AppIDPath id, const BundleType *type, const std::map< std::string, ChannelPort & > &, AcceleratorConnection &) const override
Get a MMIO region port for a particular region descriptor.
Definition: Services.cpp:82
virtual std::string getServiceSymbol() const override
Definition: Services.cpp:79
Add a custom interface to a service client at a particular point in the design hierarchy.
Definition: Services.h:35
virtual ~ServicePort()=default
virtual std::optional< std::string > toString() const
Definition: Services.h:40
Registry of services which can be instantiated directly by the Accelerator class if the backend doesn...
Definition: Services.h:310
static Service::Type lookupServiceType(const std::string &)
Resolve a service type from a string.
Definition: Services.cpp:299
static Service * createService(AcceleratorConnection *acc, Service::Type svcType, AppIDPath id, std::string implName, ServiceImplDetails details, HWClientDetails clients)
Create a service instance from the given details.
Definition: Services.cpp:286
Parent class of all APIs modeled as 'services'.
Definition: Services.h:45
virtual std::string getServiceSymbol() const =0
const std::type_info & Type
Definition: Services.h:47
virtual ~Service()=default
virtual Service * getChildService(AcceleratorConnection *conn, Service::Type service, AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={})
Create a "child" service of this service.
Definition: Services.cpp:27
virtual ServicePort * getPort(AppIDPath id, const BundleType *type, const std::map< std::string, ChannelPort & > &, AcceleratorConnection &) const
Get specialized port for this service to attach to the given appid path.
Definition: Services.h:67
Information about the Accelerator system.
Definition: Services.h:93
virtual std::string getJsonManifest() const
Return the JSON-formatted system manifest.
Definition: Services.cpp:40
virtual uint32_t getEsiVersion() const =0
Get the ESI version number to check version compatibility.
virtual std::vector< uint8_t > getCompressedManifest() const =0
Return the zlib compressed JSON system manifest.
virtual std::string getServiceSymbol() const override
Definition: Services.cpp:35
virtual ~SysInfo()=default
Definition: esi.py:1
std::map< std::string, std::any > ServiceImplDetails
Definition: Common.h:87
std::string toHex(uint32_t val)
Definition: Common.cpp:37
std::vector< HWClientDetail > HWClientDetails
Definition: Common.h:86
RAII memory region for host memory.
Definition: Services.h:201
virtual void * getPtr() const =0
virtual std::size_t getSize() const =0
Options for allocating host memory.
Definition: Services.h:209
Describe a region (slice) of MMIO space.
Definition: Services.h:114