CIRCT  19.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 uint32_t MagicNumberLo = 0xE5100E51;
46 constexpr uint32_t MagicNumberHi = 0x207D98E5;
47 constexpr uint32_t ExpectedVersionNumber = 0;
48 
49 //===----------------------------------------------------------------------===//
50 // Accelerator design hierarchy root.
51 //===----------------------------------------------------------------------===//
52 
53 /// Top level accelerator class. Maintains a shared pointer to the manifest,
54 /// which owns objects used in the design hierarchy owned by this class. Since
55 /// this class owns the entire design hierarchy, when it gets destroyed the
56 /// entire design hierarchy gets destroyed so all of the instances, ports, etc.
57 /// are no longer valid pointers.
58 class Accelerator : public HWModule {
59 public:
60  Accelerator() = delete;
61  Accelerator(const Accelerator &) = delete;
62  ~Accelerator() = default;
63  Accelerator(std::optional<ModuleInfo> info,
64  std::vector<std::unique_ptr<Instance>> children,
65  std::vector<services::Service *> services,
66  std::vector<std::unique_ptr<BundlePort>> &ports)
67  : HWModule(info, std::move(children), services, ports) {}
68 };
69 
70 //===----------------------------------------------------------------------===//
71 // Connection to the accelerator and its services.
72 //===----------------------------------------------------------------------===//
73 
74 /// Abstract class representing a connection to an accelerator. Actual
75 /// connections (e.g. to a co-simulation or actual device) are implemented by
76 /// subclasses.
78 public:
80  virtual ~AcceleratorConnection() = default;
81  Context &getCtxt() const { return ctxt; }
82 
83  /// Disconnect from the accelerator cleanly.
84  void disconnect();
85 
86  /// Request the host side channel ports for a particular instance (identified
87  /// by the AppID path). For convenience, provide the bundle type.
88  virtual std::map<std::string, ChannelPort &>
90 
92 
94  /// Get a typed reference to a particular service type. Caller does *not* take
95  /// ownership of the returned pointer -- the Accelerator object owns it.
96  /// Pointer lifetime ends with the Accelerator lifetime.
97  template <typename ServiceClass>
98  ServiceClass *getService(AppIDPath id = {}, std::string implName = {},
99  ServiceImplDetails details = {},
100  HWClientDetails clients = {}) {
101  return dynamic_cast<ServiceClass *>(
102  getService(typeid(ServiceClass), id, implName, details, clients));
103  }
104  /// Calls `createService` and caches the result. Subclasses can override if
105  /// they want to use their own caching mechanism.
106  virtual Service *getService(Service::Type service, AppIDPath id = {},
107  std::string implName = {},
108  ServiceImplDetails details = {},
109  HWClientDetails clients = {});
110 
111 protected:
112  /// Called by `getServiceImpl` exclusively. It wraps the pointer returned by
113  /// this in a unique_ptr and caches it. Separate this from the
114  /// wrapping/caching since wrapping/caching is an implementation detail.
115  virtual Service *createService(Service::Type service, AppIDPath idPath,
116  std::string implName,
117  const ServiceImplDetails &details,
118  const HWClientDetails &clients) = 0;
119 
120 private:
121  /// ESI accelerator context.
123 
124  /// Cache services via a unique_ptr so they get free'd automatically when
125  /// Accelerator objects get deconstructed.
126  using ServiceCacheKey = std::tuple<const std::type_info *, AppIDPath>;
127  std::map<ServiceCacheKey, std::unique_ptr<Service>> serviceCache;
128 
129  std::unique_ptr<AcceleratorServiceThread> serviceThread;
130 };
131 
132 namespace registry {
133 
134 // Connect to an ESI accelerator given a backend name and connection specifier.
135 // Alternatively, instantiate the backend directly (if you're using C++).
136 std::unique_ptr<AcceleratorConnection>
137 connect(Context &ctxt, std::string backend, std::string connection);
138 
139 namespace internal {
140 
141 /// Backends can register themselves to be connected via a connection string.
142 using BackendCreate = std::function<std::unique_ptr<AcceleratorConnection>(
143  Context &, std::string)>;
144 void registerBackend(std::string name, BackendCreate create);
145 
146 // Helper struct to
147 template <typename TAccelerator>
149  RegisterAccelerator(const char *name) {
151  }
152 };
153 
154 #define REGISTER_ACCELERATOR(Name, TAccelerator) \
155  static ::esi::registry::internal::RegisterAccelerator<TAccelerator> \
156  __register_accel____LINE__(Name)
157 
158 } // namespace internal
159 } // namespace registry
160 
161 /// Background thread which services various requests. Currently, it listens on
162 /// ports and calls callbacks for incoming messages on said ports.
164 public:
167 
168  /// When there's data on any of the listenPorts, call the callback. Callable
169  /// from any thread.
170  void
171  addListener(std::initializer_list<ReadChannelPort *> listenPorts,
172  std::function<void(ReadChannelPort *, MessageData)> callback);
173 
174  /// Instruct the service thread to stop running.
175  void stop();
176 
177 private:
178  struct Impl;
179  std::unique_ptr<Impl> impl;
180 };
181 } // namespace esi
182 
183 #endif // ESI_ACCELERATOR_H
Abstract class representing a connection to an accelerator.
Definition: Accelerator.h:77
Context & getCtxt() const
Definition: Accelerator.h:81
void disconnect()
Disconnect from the accelerator cleanly.
services::Service Service
Definition: Accelerator.h:93
ServiceClass * getService(AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={})
Get a typed reference to a particular service type.
Definition: Accelerator.h:98
Context & ctxt
ESI accelerator context.
Definition: Accelerator.h:122
std::map< ServiceCacheKey, std::unique_ptr< Service > > serviceCache
Definition: Accelerator.h:127
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:126
std::unique_ptr< AcceleratorServiceThread > serviceThread
Definition: Accelerator.h:129
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).
AcceleratorConnection(Context &ctxt)
Definition: Accelerator.cpp:27
virtual ~AcceleratorConnection()=default
AcceleratorServiceThread * getServiceThread()
Definition: Accelerator.h:91
Background thread which services various requests.
Definition: Accelerator.h:163
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:178
Top level accelerator class.
Definition: Accelerator.h:58
~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:63
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:30
Represents either the top level or an instance of a hardware module.
Definition: Design.h:47
const std::optional< ModuleInfo > info
Definition: Design.h:81
const std::vector< std::unique_ptr< BundlePort > > ports
Definition: Design.h:85
const std::vector< std::unique_ptr< Instance > > children
Definition: Design.h:82
const std::vector< services::Service * > services
Definition: Design.h:84
A logical chunk of data representing serialized data.
Definition: Common.h:86
A ChannelPort which reads data from the accelerator.
Definition: Ports.h:55
Parent class of all APIs modeled as 'services'.
Definition: Services.h:42
const std::type_info & Type
Definition: Services.h:44
void registerBackend(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:143
std::unique_ptr< AcceleratorConnection > connect(Context &ctxt, std::string backend, std::string connection)
Definition: esi.py:1
std::map< std::string, std::any > ServiceImplDetails
Definition: Common.h:81
constexpr uint32_t MagicNumberLo
Definition: Accelerator.h:45
constexpr uint32_t ExpectedVersionNumber
Definition: Accelerator.h:47
constexpr uint32_t MetadataOffset
Definition: Accelerator.h:44
constexpr uint32_t MagicNumberHi
Definition: Accelerator.h:46
std::vector< HWClientDetail > HWClientDetails
Definition: Common.h:80