CIRCT 22.0.0git
Loading...
Searching...
No Matches
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#include <list>
29
30namespace esi {
31class AcceleratorConnection;
32class Engine;
33namespace services {
34class Service;
35}
36
37// While building the design, keep around a std::map of active services indexed
38// by the service name. When a new service is encountered during descent, add it
39// to the table (perhaps overwriting one). Modifications to the table only apply
40// to the current branch, so copy this and update it at each level of the tree.
41using ServiceTable = std::map<std::string, services::Service *>;
42
43namespace services {
44
45/// Add a custom interface to a service client at a particular point in the
46/// design hierarchy.
47class ServicePort : public BundlePort {
48public:
50 virtual ~ServicePort() = default;
51 // Get a description of the service port.
52 virtual std::optional<std::string> toString() const { return std::nullopt; }
53};
54
55/// Parent class of all APIs modeled as 'services'. May or may not map to a
56/// hardware side 'service'.
57class Service {
58public:
59 using Type = const std::type_info &;
61 virtual ~Service() = default;
62
63 virtual std::string getServiceSymbol() const = 0;
64
65 /// Create a "child" service of this service. Does not have to be the same
66 /// service type, but typically is. Used when a service already exists in the
67 /// active services table, but a new one wants to replace it. Useful for cases
68 /// where the child service needs to use the parent service. Defaults to
69 /// calling the `getService` method on `AcceleratorConnection` to get the
70 /// global service, implying that the child service does not need to use the
71 /// service it is replacing.
72 virtual Service *getChildService(Service::Type service, AppIDPath id = {},
73 std::string implName = {},
74 ServiceImplDetails details = {},
75 HWClientDetails clients = {});
76
77 /// Get specialized port for this service to attach to the given appid path.
78 /// Null returns mean nothing to attach.
79 virtual BundlePort *getPort(AppIDPath id, const BundleType *type) const {
80 return nullptr;
81 }
82
84
85protected:
87};
88
89/// A service for which there are no standard services registered. Requires
90/// ports be added to the design hierarchy instead of high level interfaces like
91/// the ones in StdServices.h.
92class CustomService : public Service {
93public:
95 const ServiceImplDetails &details,
96 const HWClientDetails &clients);
97 virtual ~CustomService() = default;
98
99 virtual std::string getServiceSymbol() const override {
100 return serviceSymbol;
101 }
102 virtual BundlePort *getPort(AppIDPath id,
103 const BundleType *type) const override;
104
105protected:
106 std::string serviceSymbol;
108};
109
110/// Information about the Accelerator system.
111class SysInfo : public Service {
112public:
113 using Service::Service;
114 virtual ~SysInfo() = default;
115
116 virtual std::string getServiceSymbol() const override;
117
118 /// Get the ESI version number to check version compatibility.
119 virtual uint32_t getEsiVersion() const = 0;
120
121 /// Return the JSON-formatted system manifest.
122 virtual std::string getJsonManifest() const;
123
124 /// Return the zlib compressed JSON system manifest.
125 virtual std::vector<uint8_t> getCompressedManifest() const = 0;
126};
127
128class MMIO : public Service {
129public:
130 static constexpr std::string_view StdName = "esi.service.std.mmio";
131
132 /// Describe a region (slice) of MMIO space.
134 uint32_t base;
135 uint32_t size;
136 };
137
138 MMIO(AcceleratorConnection &, const AppIDPath &idPath,
139 const HWClientDetails &clients);
140 virtual ~MMIO() = default;
141
142 /// Read a 64-bit value from the global MMIO space.
143 virtual uint64_t read(uint32_t addr) const = 0;
144 /// Write a 64-bit value to the global MMIO space.
145 virtual void write(uint32_t addr, uint64_t data) = 0;
146 /// Get the regions of MMIO space that this service manages. Otherwise known
147 /// as the base address table.
148 const std::map<AppIDPath, RegionDescriptor> &getRegions() const {
149 return regions;
150 }
151
152 /// If the service is a MMIO service, return a region of the MMIO space which
153 /// peers into ours.
154 virtual Service *getChildService(Service::Type service, AppIDPath id = {},
155 std::string implName = {},
156 ServiceImplDetails details = {},
157 HWClientDetails clients = {}) override;
158
159 virtual std::string getServiceSymbol() const override;
160
161 /// Get a MMIO region port for a particular region descriptor.
162 virtual BundlePort *getPort(AppIDPath id,
163 const BundleType *type) const override;
164
165private:
166 /// MMIO base address table.
167 std::map<AppIDPath, RegionDescriptor> regions;
168
169public:
170 /// A "slice" of some parent MMIO space.
171 class MMIORegion : public ServicePort {
172 friend class MMIO;
174
175 public:
176 /// Get the offset (and size) of the region in the parent (usually global)
177 /// MMIO address space.
178 virtual RegionDescriptor getDescriptor() const { return desc; };
179 /// Read a 64-bit value from this region, not the global address space.
180 virtual uint64_t read(uint32_t addr) const;
181 /// Write a 64-bit value to this region, not the global address space.
182 virtual void write(uint32_t addr, uint64_t data);
183
184 virtual std::optional<std::string> toString() const override {
185 return "MMIO region " + toHex(desc.base) + " - " +
187 }
188
189 private:
192 };
193};
194
195/// Implement the SysInfo API for a standard MMIO protocol.
196class MMIOSysInfo final : public SysInfo {
197public:
198 MMIOSysInfo(const MMIO *);
199
200 /// Get the ESI version number to check version compatibility.
201 uint32_t getEsiVersion() const override;
202
203 /// Return the zlib compressed JSON system manifest.
204 virtual std::vector<uint8_t> getCompressedManifest() const override;
205
206private:
207 const MMIO *mmio;
208};
209
210class HostMem : public Service {
211public:
212 static constexpr std::string_view StdName = "esi.service.std.hostmem";
213
214 using Service::Service;
215 virtual ~HostMem() = default;
216 virtual std::string getServiceSymbol() const override;
217
218 /// RAII memory region for host memory. Automatically frees the memory when
219 /// deconstructed.
221 virtual ~HostMemRegion() = default;
222 /// Get a pointer to the host memory.
223 virtual void *getPtr() const = 0;
224 /// Sometimes the pointer the device sees is different from the pointer the
225 /// host sees. Call this functon to get the device pointer.
226 virtual void *getDevicePtr() const { return getPtr(); }
227 operator void *() const { return getPtr(); }
228 virtual std::size_t getSize() const = 0;
229 /// Flush the memory region to ensure that the device sees the latest
230 /// contents. Because some platforms require it before DMA transactions, it
231 /// is recommended to call this before any DMA on all platforms. On
232 /// platforms which don't require it, it is a cheap no-op virtual method
233 /// call.
234 virtual void flush() {}
235 };
236
237 /// Options for allocating host memory.
238 struct Options {
239 bool writeable = false;
240 bool useLargePages = false;
241 };
242
243 /// In cases where necessary, enable host memory services.
244 virtual void start() {}
245
246 /// Allocate a region of host memory in accelerator accessible address space.
247 virtual std::unique_ptr<HostMemRegion> allocate(std::size_t size,
248 Options opts) const = 0;
249
250 /// Try to make a region of host memory accessible to the accelerator. Returns
251 /// 'false' on failure. It is optional for an accelerator backend to implement
252 /// this, so client code needs to have a fallback for when this returns
253 /// 'false'. On success, it is the client's responsibility to ensure that the
254 /// memory eventually gets unmapped.
255 virtual bool mapMemory(void *ptr, std::size_t size, Options opts) const {
256 return false;
257 }
258 /// Unmap memory which was previously mapped with 'mapMemory'. Undefined
259 /// behavior when called with a pointer which was not previously mapped.
260 virtual void unmapMemory(void *ptr) const {}
261};
262
263/// Service for calling functions.
264class FuncService : public Service {
265public:
267 HWClientDetails clients);
268
269 virtual std::string getServiceSymbol() const override;
270 virtual BundlePort *getPort(AppIDPath id,
271 const BundleType *type) const override;
272
273 /// A function call which gets attached to a service port.
274 class Function : public ServicePort {
275 friend class FuncService;
276 using ServicePort::ServicePort;
277
278 public:
281
282 void connect();
283 std::future<MessageData> call(const MessageData &arg);
284
285 const esi::Type *getArgType() const {
286 return dynamic_cast<const ChannelType *>(type->findChannel("arg").first)
287 ->getInner();
288 }
289
290 const esi::Type *getResultType() const {
291 return dynamic_cast<const ChannelType *>(
292 type->findChannel("result").first)
293 ->getInner();
294 }
295
296 virtual std::optional<std::string> toString() const override {
297 const esi::Type *argType = getArgType();
298 const esi::Type *resultType = getResultType();
299 return "function " + resultType->getID() + "(" + argType->getID() + ")";
300 }
301
302 private:
303 std::mutex callMutex;
306 bool connected = false;
307 };
308
309private:
310 std::string symbol;
311};
312
313/// Service for servicing function calls from the accelerator.
314class CallService : public Service {
315public:
317 ServiceImplDetails details);
318
319 virtual std::string getServiceSymbol() const override;
320 virtual BundlePort *getPort(AppIDPath id,
321 const BundleType *type) const override;
322
323 /// A function call which gets attached to a service port.
324 class Callback : public ServicePort {
325 friend class CallService;
328
329 public:
333
334 /// Connect a callback to code which will be executed when the accelerator
335 /// invokes the callback. The 'quick' flag indicates that the callback is
336 /// sufficiently fast that it could be called in the same thread as the
337 /// port callback.
338 void connect(std::function<MessageData(const MessageData &)> callback,
339 bool quick = false);
340
341 const esi::Type *getArgType() const {
342 return dynamic_cast<const ChannelType *>(type->findChannel("arg").first)
343 ->getInner();
344 }
345
346 const esi::Type *getResultType() const {
347 return dynamic_cast<const ChannelType *>(
348 type->findChannel("result").first)
349 ->getInner();
350 }
351
352 virtual std::optional<std::string> toString() const override {
353 const esi::Type *argType = getArgType();
354 const esi::Type *resultType = getResultType();
355 return "callback " + resultType->getID() + "(" + argType->getID() + ")";
356 }
357
358 private:
362 };
363
364private:
365 std::string symbol;
366};
367
368/// Service for retrieving telemetry data from the accelerator.
369class TelemetryService : public Service {
370public:
371 static constexpr std::string_view StdName = "esi.service.std.telemetry";
372
374 ServiceImplDetails details, HWClientDetails clients);
375
376 virtual std::string getServiceSymbol() const override;
377 virtual BundlePort *getPort(AppIDPath id,
378 const BundleType *type) const override;
379 virtual Service *getChildService(Service::Type service, AppIDPath id = {},
380 std::string implName = {},
381 ServiceImplDetails details = {},
382 HWClientDetails clients = {}) override;
383 MMIO::MMIORegion *getMMIORegion() const;
384
385 /// A telemetry port which gets attached to a service port.
386 class Metric : public ServicePort {
387 friend class TelemetryService;
390 std::optional<uint64_t> offset);
391
392 public:
393 void connect();
394 std::future<MessageData> read();
395 uint64_t readInt();
396
397 virtual std::optional<std::string> toString() const override {
398 const esi::Type *dataType =
399 dynamic_cast<const ChannelType *>(type->findChannel("data").first)
400 ->getInner();
401 return "telemetry " + dataType->getID();
402 }
403
404 private:
407 std::optional<uint64_t> offset;
408 };
409
410 std::map<AppIDPath, Metric *> getTelemetryPorts() {
411 std::map<AppIDPath, Metric *> ports;
412 getTelemetryPorts(ports);
413 return ports;
414 }
415 void getTelemetryPorts(std::map<AppIDPath, Metric *> &ports);
416
417private:
420 std::map<AppIDPath, uint64_t> portAddressAssignments;
421 mutable std::map<AppIDPath, Metric *> telemetryPorts;
422 std::list<TelemetryService *> children;
423};
424
425/// Registry of services which can be instantiated directly by the Accelerator
426/// class if the backend doesn't do anything special with a service.
428public:
429 /// Create a service instance from the given details. Returns nullptr if
430 /// 'svcType' isn't registered.
432 Service::Type svcType, AppIDPath id,
433 std::string implName,
434 ServiceImplDetails details,
435 HWClientDetails clients);
436
437 /// Resolve a service type from a string. If the string isn't recognized,
438 /// default to CustomService.
439 static Service::Type lookupServiceType(const std::string &);
440};
441
442} // namespace services
443} // namespace esi
444
445#endif // ESI_RUNTIME_SERVICES_H
Abstract class representing a connection to an accelerator.
Definition Accelerator.h:79
Services provide connections to 'bundles' – collections of named, unidirectional communication channe...
Definition Ports.h:226
PortMap channels
Definition Ports.h:270
const BundleType * type
Definition Ports.h:269
BundlePort(AppID id, const BundleType *type, PortMap channels)
Construct a port.
Definition Ports.cpp:22
Bundles represent a collection of channels.
Definition Types.h:97
std::pair< const Type *, Direction > findChannel(std::string name) const
Definition Types.cpp:78
Channels are the basic communication primitives.
Definition Types.h:118
A logical chunk of data representing serialized data.
Definition Common.h:113
A ChannelPort which reads data from the accelerator.
Definition Ports.h:124
Root class of the ESI type system.
Definition Types.h:34
ID getID() const
Definition Types.h:40
A ChannelPort which sends data to the accelerator.
Definition Ports.h:77
A function call which gets attached to a service port.
Definition Services.h:324
static Callback * get(AcceleratorConnection &acc, AppID id, const BundleType *type, WriteChannelPort &result, ReadChannelPort &arg)
Definition Services.cpp:255
virtual std::optional< std::string > toString() const override
Definition Services.h:352
const esi::Type * getArgType() const
Definition Services.h:341
const esi::Type * getResultType() const
Definition Services.h:346
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:263
AcceleratorConnection & acc
Definition Services.h:361
Service for servicing function calls from the accelerator.
Definition Services.h:314
virtual std::string getServiceSymbol() const override
Definition Services.cpp:244
virtual BundlePort * getPort(AppIDPath id, const BundleType *type) const override
Get specialized port for this service to attach to the given appid path.
Definition Services.cpp:246
A service for which there are no standard services registered.
Definition Services.h:92
virtual BundlePort * getPort(AppIDPath id, const BundleType *type) const override
Get specialized port for this service to attach to the given appid path.
Definition Services.cpp:186
virtual ~CustomService()=default
virtual std::string getServiceSymbol() const override
Definition Services.h:99
A function call which gets attached to a service port.
Definition Services.h:274
const esi::Type * getArgType() const
Definition Services.h:285
const esi::Type * getResultType() const
Definition Services.h:290
std::future< MessageData > call(const MessageData &arg)
Definition Services.cpp:228
virtual std::optional< std::string > toString() const override
Definition Services.h:296
static Function * get(AppID id, BundleType *type, WriteChannelPort &arg, ReadChannelPort &result)
Definition Services.cpp:207
Service for calling functions.
Definition Services.h:264
virtual std::string getServiceSymbol() const override
Definition Services.cpp:200
virtual BundlePort * getPort(AppIDPath id, const BundleType *type) const override
Get specialized port for this service to attach to the given appid path.
Definition Services.cpp:202
virtual ~HostMem()=default
virtual std::string getServiceSymbol() const override
Definition Services.cpp:173
virtual void start()
In cases where necessary, enable host memory services.
Definition Services.h:244
static constexpr std::string_view StdName
Definition Services.h:212
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:260
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:255
Implement the SysInfo API for a standard MMIO protocol.
Definition Services.h:196
virtual std::vector< uint8_t > getCompressedManifest() const override
Return the zlib compressed JSON system manifest.
Definition Services.cpp:153
uint32_t getEsiVersion() const override
Get the ESI version number to check version compatibility.
Definition Services.cpp:146
A "slice" of some parent MMIO space.
Definition Services.h:171
virtual uint64_t read(uint32_t addr) const
Read a 64-bit value from this region, not the global address space.
Definition Services.cpp:132
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:137
virtual RegionDescriptor getDescriptor() const
Get the offset (and size) of the region in the parent (usually global) MMIO address space.
Definition Services.h:178
virtual std::optional< std::string > toString() const override
Definition Services.h:184
virtual uint64_t read(uint32_t addr) const =0
Read a 64-bit value from the global MMIO space.
virtual ~MMIO()=default
virtual void write(uint32_t addr, uint64_t data)=0
Write a 64-bit value to the global MMIO space.
virtual BundlePort * getPort(AppIDPath id, const BundleType *type) const override
Get a MMIO region port for a particular region descriptor.
Definition Services.cpp:94
std::map< AppIDPath, RegionDescriptor > regions
MMIO base address table.
Definition Services.h:167
static constexpr std::string_view StdName
Definition Services.h:130
virtual Service * getChildService(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:118
const std::map< AppIDPath, RegionDescriptor > & getRegions() const
Get the regions of MMIO space that this service manages.
Definition Services.h:148
virtual std::string getServiceSymbol() const override
Definition Services.cpp:91
Add a custom interface to a service client at a particular point in the design hierarchy.
Definition Services.h:47
virtual ~ServicePort()=default
virtual std::optional< std::string > toString() const
Definition Services.h:52
Registry of services which can be instantiated directly by the Accelerator class if the backend doesn...
Definition Services.h:427
static Service::Type lookupServiceType(const std::string &)
Resolve a service type from a string.
Definition Services.cpp:423
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:406
Parent class of all APIs modeled as 'services'.
Definition Services.h:57
virtual BundlePort * getPort(AppIDPath id, const BundleType *type) const
Get specialized port for this service to attach to the given appid path.
Definition Services.h:79
virtual std::string getServiceSymbol() const =0
AcceleratorConnection & getConnection() const
Definition Services.h:83
const std::type_info & Type
Definition Services.h:59
virtual Service * getChildService(Service::Type service, AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={})
Create a "child" service of this service.
Definition Services.cpp:28
Service(AcceleratorConnection &conn)
Definition Services.h:60
virtual ~Service()=default
AcceleratorConnection & conn
Definition Services.h:86
Information about the Accelerator system.
Definition Services.h:111
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
A telemetry port which gets attached to a service port.
Definition Services.h:386
std::optional< uint64_t > offset
Definition Services.h:407
virtual std::optional< std::string > toString() const override
Definition Services.h:397
void connect()
Connect to a particular telemetry port. Offset should be non-nullopt.
Definition Services.cpp:378
std::future< MessageData > read()
Definition Services.cpp:385
const TelemetryService * telemetryService
Definition Services.h:405
Service for retrieving telemetry data from the accelerator.
Definition Services.h:369
std::list< TelemetryService * > children
Definition Services.h:422
std::map< AppIDPath, Metric * > getTelemetryPorts()
Definition Services.h:410
MMIO::MMIORegion * mmio
Definition Services.h:419
MMIO::MMIORegion * getMMIORegion() const
Definition Services.cpp:331
std::map< AppIDPath, Metric * > telemetryPorts
Definition Services.h:421
std::map< AppIDPath, uint64_t > portAddressAssignments
Definition Services.h:420
static constexpr std::string_view StdName
Definition Services.h:371
virtual std::string getServiceSymbol() const override
Definition Services.cpp:327
virtual BundlePort * getPort(AppIDPath id, const BundleType *type) const override
Get specialized port for this service to attach to the given appid path.
Definition Services.cpp:350
virtual Service * getChildService(Service::Type service, AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={}) override
Create a "child" service of this service.
Definition Services.cpp:361
Definition esi.py:1
std::map< std::string, std::any > ServiceImplDetails
Definition Common.h:108
std::string toHex(void *val)
Definition Common.cpp:37
std::map< std::string, ChannelPort & > PortMap
Definition Ports.h:29
std::map< std::string, services::Service * > ServiceTable
Definition Services.h:41
std::vector< HWClientDetail > HWClientDetails
Definition Common.h:107
RAII memory region for host memory.
Definition Services.h:220
virtual void * getDevicePtr() const
Sometimes the pointer the device sees is different from the pointer the host sees.
Definition Services.h:226
virtual void * getPtr() const =0
Get a pointer to the host memory.
virtual void flush()
Flush the memory region to ensure that the device sees the latest contents.
Definition Services.h:234
virtual std::size_t getSize() const =0
Options for allocating host memory.
Definition Services.h:238
Describe a region (slice) of MMIO space.
Definition Services.h:133