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 
38 //===----------------------------------------------------------------------===//
39 // Constants used by low-level APIs.
40 //===----------------------------------------------------------------------===//
41 
42 constexpr uint32_t MetadataOffset = 8;
43 constexpr uint32_t MagicNumberLo = 0xE5100E51;
44 constexpr uint32_t MagicNumberHi = 0x207D98E5;
45 constexpr uint32_t ExpectedVersionNumber = 0;
46 
47 //===----------------------------------------------------------------------===//
48 // Accelerator design hierarchy root.
49 //===----------------------------------------------------------------------===//
50 
51 /// Top level accelerator class. Maintains a shared pointer to the manifest,
52 /// which owns objects used in the design hierarchy owned by this class. Since
53 /// this class owns the entire design hierarchy, when it gets destroyed the
54 /// entire design hierarchy gets destroyed so all of the instances, ports, etc.
55 /// are no longer valid pointers.
56 class Accelerator : public HWModule {
57 public:
58  Accelerator() = delete;
59  Accelerator(const Accelerator &) = delete;
60  ~Accelerator() = default;
61  Accelerator(std::optional<ModuleInfo> info,
62  std::vector<std::unique_ptr<Instance>> children,
63  std::vector<services::Service *> services,
64  std::vector<std::unique_ptr<BundlePort>> &ports)
65  : HWModule(info, std::move(children), services, ports) {}
66 };
67 
68 //===----------------------------------------------------------------------===//
69 // Connection to the accelerator and its services.
70 //===----------------------------------------------------------------------===//
71 
72 /// Abstract class representing a connection to an accelerator. Actual
73 /// connections (e.g. to a co-simulation or actual device) are implemented by
74 /// subclasses.
76 public:
78 
79  virtual ~AcceleratorConnection() = default;
80  Context &getCtxt() const { return ctxt; }
81 
82  /// Request the host side channel ports for a particular instance (identified
83  /// by the AppID path). For convenience, provide the bundle type.
84  virtual std::map<std::string, ChannelPort &>
86 
88  /// Get a typed reference to a particular service type. Caller does *not* take
89  /// ownership of the returned pointer -- the Accelerator object owns it.
90  /// Pointer lifetime ends with the Accelerator lifetime.
91  template <typename ServiceClass>
92  ServiceClass *getService(AppIDPath id = {}, std::string implName = {},
93  ServiceImplDetails details = {},
94  HWClientDetails clients = {}) {
95  return dynamic_cast<ServiceClass *>(
96  getService(typeid(ServiceClass), id, implName, details, clients));
97  }
98  /// Calls `createService` and caches the result. Subclasses can override if
99  /// they want to use their own caching mechanism.
100  virtual Service *getService(Service::Type service, AppIDPath id = {},
101  std::string implName = {},
102  ServiceImplDetails details = {},
103  HWClientDetails clients = {});
104 
105 protected:
106  /// Called by `getServiceImpl` exclusively. It wraps the pointer returned by
107  /// this in a unique_ptr and caches it. Separate this from the
108  /// wrapping/caching since wrapping/caching is an implementation detail.
109  virtual Service *createService(Service::Type service, AppIDPath idPath,
110  std::string implName,
111  const ServiceImplDetails &details,
112  const HWClientDetails &clients) = 0;
113 
114 private:
115  /// Cache services via a unique_ptr so they get free'd automatically when
116  /// Accelerator objects get deconstructed.
117  using ServiceCacheKey = std::tuple<const std::type_info *, AppIDPath>;
118  std::map<ServiceCacheKey, std::unique_ptr<Service>> serviceCache;
119 
120  /// ESI accelerator context.
122 };
123 
124 namespace registry {
125 
126 // Connect to an ESI accelerator given a backend name and connection specifier.
127 // Alternatively, instantiate the backend directly (if you're using C++).
128 std::unique_ptr<AcceleratorConnection>
129 connect(Context &ctxt, std::string backend, std::string connection);
130 
131 namespace internal {
132 
133 /// Backends can register themselves to be connected via a connection string.
134 using BackendCreate = std::function<std::unique_ptr<AcceleratorConnection>(
135  Context &, std::string)>;
136 void registerBackend(std::string name, BackendCreate create);
137 
138 // Helper struct to
139 template <typename TAccelerator>
141  RegisterAccelerator(const char *name) {
143  }
144 };
145 
146 #define REGISTER_ACCELERATOR(Name, TAccelerator) \
147  static ::esi::registry::internal::RegisterAccelerator<TAccelerator> \
148  __register_accel____LINE__(Name)
149 
150 } // namespace internal
151 } // namespace registry
152 } // namespace esi
153 
154 #endif // ESI_ACCELERATOR_H
Abstract class representing a connection to an accelerator.
Definition: Accelerator.h:75
Context & getCtxt() const
Definition: Accelerator.h:80
services::Service Service
Definition: Accelerator.h:87
ServiceClass * getService(AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={})
Get a typed reference to a particular service type.
Definition: Accelerator.h:92
Context & ctxt
ESI accelerator context.
Definition: Accelerator.h:121
std::map< ServiceCacheKey, std::unique_ptr< Service > > serviceCache
Definition: Accelerator.h:118
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:117
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.h:77
virtual ~AcceleratorConnection()=default
Top level accelerator class.
Definition: Accelerator.h:56
~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:61
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
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:135
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:80
constexpr uint32_t MagicNumberLo
Definition: Accelerator.h:43
constexpr uint32_t ExpectedVersionNumber
Definition: Accelerator.h:45
constexpr uint32_t MetadataOffset
Definition: Accelerator.h:42
constexpr uint32_t MagicNumberHi
Definition: Accelerator.h:44
std::vector< HWClientDetail > HWClientDetails
Definition: Common.h:79