CIRCT  19.0.0git
Manifest.cpp
Go to the documentation of this file.
1 //===- Manifest.cpp - Metadata on the accelerator -------------------------===//
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 // DO NOT EDIT!
10 // This file is distributed as part of an ESI package. The source for this file
11 // should always be modified within CIRCT (lib/dialect/ESI/runtime/cpp/).
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "esi/Manifest.h"
16 #include "esi/Accelerator.h"
17 #include "esi/Services.h"
18 
19 #include <nlohmann/json.hpp>
20 #include <sstream>
21 
22 using namespace esi;
23 
24 // While building the design, keep around a std::map of active services indexed
25 // by the service name. When a new service is encountered during descent, add it
26 // to the table (perhaps overwriting one). Modifications to the table only apply
27 // to the current branch, so copy this and update it at each level of the tree.
28 using ServiceTable = std::map<std::string, services::Service *>;
29 
30 // This is a proxy class to the manifest JSON. It is used to avoid having to
31 // include the JSON parser in the header. Forward references don't work since
32 // nlohmann::json is a rather complex template.
33 //
34 // Plus, it allows us to hide some implementation functions from the header
35 // file.
37  friend class ::esi::Manifest;
38 
39 public:
40  Impl(Context &ctxt, const std::string &jsonManifest);
41 
42  auto at(const std::string &key) const { return manifestJson.at(key); }
43 
44  // Get the module info (if any) for the module instance in 'json'.
45  std::optional<ModuleInfo> getModInfo(const nlohmann::json &) const;
46 
47  /// Go through the "service_decls" section of the manifest and populate the
48  /// services table as appropriate.
49  void scanServiceDecls(AcceleratorConnection &, const nlohmann::json &,
50  ServiceTable &) const;
51 
52  /// Get a Service for the service specified in 'json'. Update the
53  /// activeServices table.
55  const nlohmann::json &,
56  ServiceTable &activeServices) const;
57 
58  /// Get all the services in the description of an instance. Update the active
59  /// services table.
60  std::vector<services::Service *>
61  getServices(AppIDPath idPath, AcceleratorConnection &, const nlohmann::json &,
62  ServiceTable &activeServices) const;
63 
64  /// Get the bundle ports for the instance at 'idPath' and specified in
65  /// 'instJson'. Look them up in 'activeServies'.
66  std::vector<std::unique_ptr<BundlePort>>
68  const ServiceTable &activeServices,
69  const nlohmann::json &instJson) const;
70 
71  /// Build the set of child instances (recursively) for the module instance
72  /// description.
73  std::vector<std::unique_ptr<Instance>>
75  const ServiceTable &activeServices,
76  const nlohmann::json &instJson) const;
77 
78  /// Get a single child instance. Implicitly copy the active services table so
79  /// that it can be safely updated for the child's branch of the tree.
80  std::unique_ptr<Instance>
82  ServiceTable activeServices,
83  const nlohmann::json &childJson) const;
84 
85  /// Parse all the types and populate the types table.
86  void populateTypes(const nlohmann::json &typesJson);
87 
88  /// Get the ordered list of types from the manifest.
89  const std::vector<const Type *> &getTypeTable() const { return _typeTable; }
90 
91  /// Build a dynamic API for the Accelerator connection 'acc' based on the
92  /// manifest stored herein.
93  std::unique_ptr<Accelerator>
95 
96  const Type *parseType(const nlohmann::json &typeJson);
97 
98 private:
100  std::vector<const Type *> _typeTable;
101 
102  std::optional<const Type *> getType(Type::ID id) const {
103  return ctxt.getType(id);
104  }
105 
106  // The parsed json.
107  nlohmann::json manifestJson;
108  // Cache the module info for each symbol.
109  std::map<std::string, ModuleInfo> symbolInfoCache;
110 };
111 
112 //===----------------------------------------------------------------------===//
113 // Simple JSON -> object parsers.
114 //===----------------------------------------------------------------------===//
115 
116 static AppID parseID(const nlohmann::json &jsonID) {
117  std::optional<uint32_t> idx;
118  if (jsonID.contains("index"))
119  idx = jsonID.at("index").get<uint32_t>();
120  return AppID(jsonID.at("name").get<std::string>(), idx);
121 }
122 
123 static AppIDPath parseIDPath(const nlohmann::json &jsonIDPath) {
124  AppIDPath ret;
125  for (auto &id : jsonIDPath)
126  ret.push_back(parseID(id));
127  return ret;
128 }
129 
130 static ServicePortDesc parseServicePort(const nlohmann::json &jsonPort) {
131  return ServicePortDesc{jsonPort.at("outer_sym").get<std::string>(),
132  jsonPort.at("inner").get<std::string>()};
133 }
134 
135 /// Convert the json value to a 'std::any', which can be exposed outside of this
136 /// file.
137 static std::any getAny(const nlohmann::json &value) {
138  auto getObject = [](const nlohmann::json &json) {
139  std::map<std::string, std::any> ret;
140  for (auto &e : json.items())
141  ret[e.key()] = getAny(e.value());
142  return ret;
143  };
144 
145  auto getArray = [](const nlohmann::json &json) {
146  std::vector<std::any> ret;
147  for (auto &e : json)
148  ret.push_back(getAny(e));
149  return ret;
150  };
151 
152  if (value.is_string())
153  return value.get<std::string>();
154  else if (value.is_number_integer())
155  return value.get<int64_t>();
156  else if (value.is_number_unsigned())
157  return value.get<uint64_t>();
158  else if (value.is_number_float())
159  return value.get<double>();
160  else if (value.is_boolean())
161  return value.get<bool>();
162  else if (value.is_null())
163  return value.get<std::nullptr_t>();
164  else if (value.is_object())
165  return getObject(value);
166  else if (value.is_array())
167  return getArray(value);
168  else
169  throw std::runtime_error("Unknown type in manifest: " + value.dump(2));
170 }
171 
172 static ModuleInfo parseModuleInfo(const nlohmann::json &mod) {
173 
174  std::map<std::string, std::any> extras;
175  for (auto &extra : mod.items())
176  if (extra.key() != "name" && extra.key() != "summary" &&
177  extra.key() != "version" && extra.key() != "repo" &&
178  extra.key() != "commitHash" && extra.key() != "symbolRef")
179  extras[extra.key()] = getAny(extra.value());
180 
181  auto value = [&](const std::string &key) -> std::optional<std::string> {
182  auto f = mod.find(key);
183  if (f == mod.end())
184  return std::nullopt;
185  return f.value();
186  };
187  return ModuleInfo{value("name"), value("summary"), value("version"),
188  value("repo"), value("commitHash"), extras};
189 }
190 
191 //===----------------------------------------------------------------------===//
192 // Manifest::Impl class implementation.
193 //===----------------------------------------------------------------------===//
194 
195 Manifest::Impl::Impl(Context &ctxt, const std::string &manifestStr)
196  : ctxt(ctxt) {
197  manifestJson = nlohmann::ordered_json::parse(manifestStr);
198 
199  for (auto &mod : manifestJson.at("symbols"))
200  symbolInfoCache.insert(
201  make_pair(mod.at("symbolRef"), parseModuleInfo(mod)));
202  populateTypes(manifestJson.at("types"));
203 }
204 
205 std::unique_ptr<Accelerator>
207  ServiceTable activeSvcs;
208 
209  // Get the initial active services table. Update it as we descend down.
210  auto svcDecls = manifestJson.at("service_decls");
211  scanServiceDecls(acc, svcDecls, activeSvcs);
212 
213  // Get the services instantiated at the top level.
214  auto designJson = manifestJson.at("design");
215  std::vector<services::Service *> services =
216  getServices({}, acc, designJson, activeSvcs);
217 
218  // Get the ports at the top level.
219  auto ports = getBundlePorts(acc, {}, activeSvcs, designJson);
220 
221  return make_unique<Accelerator>(
222  getModInfo(designJson),
223  getChildInstances({}, acc, activeSvcs, designJson), services, ports);
224 }
225 
226 std::optional<ModuleInfo>
227 Manifest::Impl::getModInfo(const nlohmann::json &json) const {
228  auto instOfIter = json.find("inst_of");
229  if (instOfIter == json.end())
230  return std::nullopt;
231  auto f = symbolInfoCache.find(instOfIter.value());
232  if (f != symbolInfoCache.end())
233  return f->second;
234  return std::nullopt;
235 }
236 
238  const nlohmann::json &svcDecls,
239  ServiceTable &activeServices) const {
240  for (auto &svcDecl : svcDecls) {
241  if (auto f = svcDecl.find("type_name"); f != svcDecl.end()) {
242  // Get the implementation details.
243  ServiceImplDetails svcDetails;
244  for (auto &detail : svcDecl.items())
245  svcDetails[detail.key()] = getAny(detail.value());
246 
247  // Create the service.
249  services::ServiceRegistry::lookupServiceType(f.value());
250  auto svc = acc.getService(svcId, /*id=*/{}, /*implName=*/"",
251  /*details=*/svcDetails, /*clients=*/{});
252  if (svc)
253  activeServices[svcDecl.at("symbol")] = svc;
254  }
255  }
256 }
257 
258 std::vector<std::unique_ptr<Instance>>
260  const ServiceTable &activeServices,
261  const nlohmann::json &instJson) const {
262  std::vector<std::unique_ptr<Instance>> ret;
263  auto childrenIter = instJson.find("children");
264  if (childrenIter == instJson.end())
265  return ret;
266  for (auto &child : childrenIter.value())
267  ret.emplace_back(getChildInstance(idPath, acc, activeServices, child));
268  return ret;
269 }
270 
271 std::unique_ptr<Instance>
273  ServiceTable activeServices,
274  const nlohmann::json &child) const {
275  AppID childID = parseID(child.at("app_id"));
276  idPath.push_back(childID);
277 
278  std::vector<services::Service *> services =
279  getServices(idPath, acc, child, activeServices);
280 
281  auto children = getChildInstances(idPath, acc, activeServices, child);
282  auto ports = getBundlePorts(acc, idPath, activeServices, child);
283  return make_unique<Instance>(parseID(child.at("app_id")), getModInfo(child),
284  std::move(children), services, ports);
285 }
286 
289  const nlohmann::json &svcJson,
290  ServiceTable &activeServices) const {
291 
292  AppID id = parseID(svcJson.at("appID"));
293  idPath.push_back(id);
294 
295  // Get all the client info, including the implementation details.
296  HWClientDetails clientDetails;
297  for (auto &client : svcJson.at("client_details")) {
298  HWClientDetail clientDetail;
299  for (auto &detail : client.items()) {
300  if (detail.key() == "relAppIDPath")
301  clientDetail.relPath = parseIDPath(detail.value());
302  else if (detail.key() == "port")
303  clientDetail.port = parseServicePort(detail.value());
304  else
305  clientDetail.implOptions[detail.key()] = getAny(detail.value());
306  }
307  clientDetails.push_back(clientDetail);
308  }
309 
310  // Get the implementation details.
311  ServiceImplDetails svcDetails;
312  std::string implName;
313  std::string service;
314  for (auto &detail : svcJson.items()) {
315  if (detail.key() == "appID" || detail.key() == "client_details")
316  continue;
317  if (detail.key() == "serviceImplName")
318  implName = detail.value();
319  else if (detail.key() == "service")
320  service = detail.value().get<std::string>().substr(1);
321  else
322  svcDetails[detail.key()] = getAny(detail.value());
323  }
324 
325  // Create the service.
326  // TODO: Add support for 'standard' services.
327  services::Service::Type svcType =
328  services::ServiceRegistry::lookupServiceType(service);
329  services::Service *svc =
330  acc.getService(svcType, idPath, implName, svcDetails, clientDetails);
331  if (svc)
332  // Update the active services table.
333  activeServices[service] = svc;
334  return svc;
335 }
336 
337 std::vector<services::Service *>
339  const nlohmann::json &svcsJson,
340  ServiceTable &activeServices) const {
341  std::vector<services::Service *> ret;
342  auto contentsIter = svcsJson.find("contents");
343  if (contentsIter == svcsJson.end())
344  return ret;
345 
346  for (auto &content : contentsIter.value())
347  if (content.at("class") == "service")
348  ret.emplace_back(getService(idPath, acc, content, activeServices));
349  return ret;
350 }
351 
352 std::vector<std::unique_ptr<BundlePort>>
354  const ServiceTable &activeServices,
355  const nlohmann::json &instJson) const {
356  std::vector<std::unique_ptr<BundlePort>> ret;
357  auto contentsIter = instJson.find("contents");
358  if (contentsIter == instJson.end())
359  return ret;
360 
361  for (auto &content : contentsIter.value()) {
362  if (content.at("class") != "client_port")
363  continue;
364 
365  // Lookup the requested service in the active services table.
366  std::string serviceName = "";
367  if (auto f = content.find("servicePort"); f != content.end())
368  serviceName = parseServicePort(f.value()).name;
369  auto svcIter = activeServices.find(serviceName);
370  if (svcIter == activeServices.end()) {
371  // If a specific service isn't found, search for the default service
372  // (typically provided by a BSP).
373  if (svcIter = activeServices.find(""); svcIter == activeServices.end())
374  throw std::runtime_error(
375  "Malformed manifest: could not find active service '" +
376  serviceName + "'");
377  }
378  services::Service *svc = svcIter->second;
379 
380  std::string typeName = content.at("bundleType").at("circt_name");
381  auto type = getType(typeName);
382  if (!type)
383  throw std::runtime_error(
384  "Malformed manifest: could not find port type '" + typeName + "'");
385  const BundleType *bundleType = dynamic_cast<const BundleType *>(*type);
386  if (!bundleType)
387  throw std::runtime_error("Malformed manifest: type '" + typeName +
388  "' is not a bundle type");
389 
390  idPath.push_back(parseID(content.at("appID")));
391  std::map<std::string, ChannelPort &> portChannels =
392  acc.requestChannelsFor(idPath, bundleType);
393 
394  services::ServicePort *svcPort =
395  svc->getPort(idPath, bundleType, portChannels, acc);
396  if (svcPort)
397  ret.emplace_back(svcPort);
398  else
399  ret.emplace_back(new BundlePort(idPath.back(), portChannels));
400  // Since we share idPath between iterations, pop the last element before the
401  // next iteration.
402  idPath.pop_back();
403  }
404  return ret;
405 }
406 
407 namespace {
408 const Type *parseType(const nlohmann::json &typeJson, Context &ctxt);
409 
410 BundleType *parseBundleType(const nlohmann::json &typeJson, Context &cache) {
411  assert(typeJson.at("mnemonic") == "bundle");
412 
413  std::vector<std::tuple<std::string, BundleType::Direction, const Type *>>
414  channels;
415  for (auto &chanJson : typeJson["channels"]) {
416  std::string dirStr = chanJson.at("direction");
418  if (dirStr == "to")
419  dir = BundleType::Direction::To;
420  else if (dirStr == "from")
421  dir = BundleType::Direction::From;
422  else
423  throw std::runtime_error("Malformed manifest: unknown direction '" +
424  dirStr + "'");
425  channels.emplace_back(chanJson.at("name"), dir,
426  parseType(chanJson["type"], cache));
427  }
428  return new BundleType(typeJson.at("circt_name"), channels);
429 }
430 
431 ChannelType *parseChannelType(const nlohmann::json &typeJson, Context &cache) {
432  assert(typeJson.at("mnemonic") == "channel");
433  return new ChannelType(typeJson.at("circt_name"),
434  parseType(typeJson.at("inner"), cache));
435 }
436 
437 Type *parseInt(const nlohmann::json &typeJson, Context &cache) {
438  assert(typeJson.at("mnemonic") == "int");
439  std::string sign = typeJson.at("signedness");
440  uint64_t width = typeJson.at("hw_bitwidth");
441  Type::ID id = typeJson.at("circt_name");
442 
443  if (sign == "signed")
444  return new SIntType(id, width);
445  else if (sign == "unsigned")
446  return new UIntType(id, width);
447  else if (sign == "signless" && width == 0)
448  // By convention, a zero-width signless integer is a void type.
449  return new VoidType(id);
450  else if (sign == "signless" && width > 0)
451  return new BitsType(id, width);
452  else
453  throw std::runtime_error("Malformed manifest: unknown sign '" + sign + "'");
454 }
455 
456 StructType *parseStruct(const nlohmann::json &typeJson, Context &cache) {
457  assert(typeJson.at("mnemonic") == "struct");
458  std::vector<std::pair<std::string, const Type *>> fields;
459  for (auto &fieldJson : typeJson["fields"])
460  fields.emplace_back(fieldJson.at("name"),
461  parseType(fieldJson["type"], cache));
462  return new StructType(typeJson.at("circt_name"), fields);
463 }
464 
465 ArrayType *parseArray(const nlohmann::json &typeJson, Context &cache) {
466  assert(typeJson.at("mnemonic") == "array");
467  uint64_t size = typeJson.at("size");
468  return new ArrayType(typeJson.at("circt_name"),
469  parseType(typeJson.at("element"), cache), size);
470 }
471 
472 using TypeParser = std::function<Type *(const nlohmann::json &, Context &)>;
473 const std::map<std::string_view, TypeParser> typeParsers = {
474  {"bundle", parseBundleType},
475  {"channel", parseChannelType},
476  {"std::any",
477  [](const nlohmann::json &typeJson, Context &cache) {
478  return new AnyType(typeJson.at("circt_name"));
479  }},
480  {"int", parseInt},
481  {"struct", parseStruct},
482  {"array", parseArray},
483 
484 };
485 
486 // Parse a type if it doesn't already exist in the cache.
487 const Type *parseType(const nlohmann::json &typeJson, Context &cache) {
488  // We use the circt type string as a unique ID.
489  std::string circt_name = typeJson.at("circt_name");
490  if (std::optional<const Type *> t = cache.getType(circt_name))
491  return *t;
492 
493  std::string mnemonic = typeJson.at("mnemonic");
494  Type *t;
495  auto f = typeParsers.find(mnemonic);
496  if (f != typeParsers.end())
497  t = f->second(typeJson, cache);
498  else
499  // Types we don't know about are opaque.
500  t = new Type(circt_name);
501 
502  // Insert into the cache.
503  cache.registerType(t);
504  return t;
505 }
506 } // namespace
507 
508 const Type *Manifest::Impl::parseType(const nlohmann::json &typeJson) {
509  return ::parseType(typeJson, ctxt);
510 }
511 
512 void Manifest::Impl::populateTypes(const nlohmann::json &typesJson) {
513  for (auto &typeJson : typesJson)
514  _typeTable.push_back(parseType(typeJson));
515 }
516 
517 //===----------------------------------------------------------------------===//
518 // Manifest class implementation.
519 //===----------------------------------------------------------------------===//
520 
521 Manifest::Manifest(Context &ctxt, const std::string &jsonManifest)
522  : impl(new Impl(ctxt, jsonManifest)) {}
523 
525 
526 uint32_t Manifest::getApiVersion() const {
527  return impl->at("api_version").get<uint32_t>();
528 }
529 
530 std::vector<ModuleInfo> Manifest::getModuleInfos() const {
531  std::vector<ModuleInfo> ret;
532  for (auto &mod : impl->at("symbols"))
533  ret.push_back(parseModuleInfo(mod));
534  return ret;
535 }
536 
537 std::unique_ptr<Accelerator>
539  return impl->buildAccelerator(acc);
540 }
541 
542 const std::vector<const Type *> &Manifest::getTypeTable() const {
543  return impl->getTypeTable();
544 }
545 
546 //===----------------------------------------------------------------------===//
547 // POCO helpers.
548 //===----------------------------------------------------------------------===//
549 
550 // Print a module info, including the extra metadata.
551 std::ostream &operator<<(std::ostream &os, const ModuleInfo &m) {
552  auto printAny = [&os](std::any a) {
553  const std::type_info &t = a.type();
554  if (t == typeid(std::string))
555  os << std::any_cast<std::string>(a);
556  else if (t == typeid(int64_t))
557  os << std::any_cast<int64_t>(a);
558  else if (t == typeid(uint64_t))
559  os << std::any_cast<uint64_t>(a);
560  else if (t == typeid(double))
561  os << std::any_cast<double>(a);
562  else if (t == typeid(bool))
563  os << std::any_cast<bool>(a);
564  else if (t == typeid(std::nullptr_t))
565  os << "null";
566  else
567  os << "unknown";
568  };
569 
570  if (m.name)
571  os << *m.name << " ";
572  if (m.version)
573  os << *m.version << " ";
574  if (m.repo || m.commitHash) {
575  os << "(";
576  if (m.repo)
577  os << *m.repo;
578  if (m.commitHash)
579  os << "@" << *m.commitHash;
580  os << ")";
581  }
582  if (m.summary)
583  os << ": " << *m.summary;
584  os << "\n";
585 
586  if (!m.extra.empty()) {
587  os << " Extra metadata:\n";
588  for (auto &e : m.extra) {
589  os << " " << e.first << ": ";
590  printAny(e.second);
591  os << "\n";
592  }
593  }
594  return os;
595 }
596 
597 namespace esi {
599  AppIDPath ret = *this;
600  ret.insert(ret.end(), b.begin(), b.end());
601  return ret;
602 }
603 
604 std::string AppIDPath::toStr() const {
605  std::ostringstream os;
606  os << *this;
607  return os.str();
608 }
609 
610 bool operator<(const AppID &a, const AppID &b) {
611  if (a.name != b.name)
612  return a.name < b.name;
613  return a.idx < b.idx;
614 }
615 bool operator<(const AppIDPath &a, const AppIDPath &b) {
616  if (a.size() != b.size())
617  return a.size() < b.size();
618  for (size_t i = 0, e = a.size(); i < e; ++i)
619  if (a[i] != b[i])
620  return a[i] < b[i];
621  return false;
622 }
623 } // namespace esi
624 
625 std::ostream &operator<<(std::ostream &os, const AppID &id) {
626  os << id.name;
627  if (id.idx)
628  os << "[" << *id.idx << "]";
629  return os;
630 }
631 std::ostream &operator<<(std::ostream &os, const AppIDPath &path) {
632  for (size_t i = 0, e = path.size(); i < e; ++i) {
633  if (i > 0)
634  os << '.';
635  os << path[i];
636  }
637  return os;
638 }
assert(baseType &&"element must be base type")
static ParseResult parseType(Type &result, StringRef name, AsmParser &parser)
Parse a type defined by this dialect.
int32_t width
Definition: FIRRTL.cpp:36
std::map< std::string, services::Service * > ServiceTable
Definition: Manifest.cpp:28
static AppIDPath parseIDPath(const nlohmann::json &jsonIDPath)
Definition: Manifest.cpp:123
static std::any getAny(const nlohmann::json &value)
Convert the json value to a 'std::any', which can be exposed outside of this file.
Definition: Manifest.cpp:137
std::ostream & operator<<(std::ostream &os, const ModuleInfo &m)
Definition: Manifest.cpp:551
static ModuleInfo parseModuleInfo(const nlohmann::json &mod)
Definition: Manifest.cpp:172
static ServicePortDesc parseServicePort(const nlohmann::json &jsonPort)
Definition: Manifest.cpp:130
static AppID parseID(const nlohmann::json &jsonID)
Definition: Manifest.cpp:116
auto at(const std::string &key) const
Definition: Manifest.cpp:42
nlohmann::json manifestJson
Definition: Manifest.cpp:107
const Type * parseType(const nlohmann::json &typeJson)
Definition: Manifest.cpp:508
std::vector< const Type * > _typeTable
Definition: Manifest.cpp:100
services::Service * getService(AppIDPath idPath, AcceleratorConnection &, const nlohmann::json &, ServiceTable &activeServices) const
Get a Service for the service specified in 'json'.
Definition: Manifest.cpp:288
std::vector< std::unique_ptr< Instance > > getChildInstances(AppIDPath idPath, AcceleratorConnection &acc, const ServiceTable &activeServices, const nlohmann::json &instJson) const
Build the set of child instances (recursively) for the module instance description.
Definition: Manifest.cpp:259
std::optional< ModuleInfo > getModInfo(const nlohmann::json &) const
Definition: Manifest.cpp:227
const std::vector< const Type * > & getTypeTable() const
Get the ordered list of types from the manifest.
Definition: Manifest.cpp:89
void scanServiceDecls(AcceleratorConnection &, const nlohmann::json &, ServiceTable &) const
Go through the "service_decls" section of the manifest and populate the services table as appropriate...
Definition: Manifest.cpp:237
Impl(Context &ctxt, const std::string &jsonManifest)
Definition: Manifest.cpp:195
std::optional< const Type * > getType(Type::ID id) const
Definition: Manifest.cpp:102
std::unique_ptr< Accelerator > buildAccelerator(AcceleratorConnection &acc) const
Build a dynamic API for the Accelerator connection 'acc' based on the manifest stored herein.
Definition: Manifest.cpp:206
std::vector< std::unique_ptr< BundlePort > > getBundlePorts(AcceleratorConnection &acc, AppIDPath idPath, const ServiceTable &activeServices, const nlohmann::json &instJson) const
Get the bundle ports for the instance at 'idPath' and specified in 'instJson'.
Definition: Manifest.cpp:353
std::map< std::string, ModuleInfo > symbolInfoCache
Definition: Manifest.cpp:109
void populateTypes(const nlohmann::json &typesJson)
Parse all the types and populate the types table.
Definition: Manifest.cpp:512
std::unique_ptr< Instance > getChildInstance(AppIDPath idPath, AcceleratorConnection &acc, ServiceTable activeServices, const nlohmann::json &childJson) const
Get a single child instance.
Definition: Manifest.cpp:272
std::vector< services::Service * > getServices(AppIDPath idPath, AcceleratorConnection &, const nlohmann::json &, ServiceTable &activeServices) const
Get all the services in the description of an instance.
Definition: Manifest.cpp:338
Abstract class representing a connection to an accelerator.
Definition: Accelerator.h:78
ServiceClass * getService(AppIDPath id={}, std::string implName={}, ServiceImplDetails details={}, HWClientDetails clients={})
Get a typed reference to a particular service type.
Definition: Accelerator.h:99
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).
The "any" type is a special type which can be used to represent any type, as identified by the type i...
Definition: Types.h:85
std::string toStr() const
Definition: Manifest.cpp:604
AppIDPath operator+(const AppIDPath &b)
Definition: Manifest.cpp:598
Arrays have a compile time specified (static) size and an element type.
Definition: Types.h:154
Bits are just an array of bits.
Definition: Types.h:105
Services provide connections to 'bundles' – collections of named, unidirectional communication channe...
Definition: Ports.h:147
Bundles represent a collection of channels.
Definition: Types.h:44
Channels are the basic communication primitives.
Definition: Types.h:63
AcceleratorConnections, Accelerators, and Manifests must all share a context.
Definition: Context.h:30
std::optional< const Type * > getType(Type::ID id) const
Resolve a type id to the type.
Definition: Context.h:34
void registerType(Type *type)
Register a type with the context. Takes ownership of the pointer type.
Definition: Context.cpp:20
std::unique_ptr< Accelerator > buildAccelerator(AcceleratorConnection &acc) const
Definition: Manifest.cpp:538
std::vector< ModuleInfo > getModuleInfos() const
Definition: Manifest.cpp:530
uint32_t getApiVersion() const
Definition: Manifest.cpp:526
const std::vector< const Type * > & getTypeTable() const
The Type Table is an ordered list of types.
Definition: Manifest.cpp:542
Impl * impl
Definition: Manifest.h:62
Signed integer.
Definition: Types.h:118
Structs are an ordered collection of fields, each with a name and a type.
Definition: Types.h:130
Root class of the ESI type system.
Definition: Types.h:27
std::string ID
Definition: Types.h:29
Unsigned integer.
Definition: Types.h:124
The "void" type is a special type which can be used to represent no type.
Definition: Types.h:74
Add a custom interface to a service client at a particular point in the design hierarchy.
Definition: Services.h:34
Parent class of all APIs modeled as 'services'.
Definition: Services.h:42
const std::type_info & Type
Definition: Services.h:44
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:51
Definition: esi.py:1
std::map< std::string, std::any > ServiceImplDetails
Definition: Common.h:81
bool operator<(const AppID &a, const AppID &b)
Definition: Manifest.cpp:610
std::vector< HWClientDetail > HWClientDetails
Definition: Common.h:80
std::string name
Definition: Common.h:34
std::optional< uint32_t > idx
Definition: Common.h:35
A description of a hardware client.
Definition: Common.h:75
std::map< std::string, std::any > implOptions
Definition: Common.h:78
AppIDPath relPath
Definition: Common.h:76
ServicePortDesc port
Definition: Common.h:77
const std::optional< std::string > commitHash
Definition: Common.h:62
const std::optional< std::string > repo
Definition: Common.h:61
const std::optional< std::string > version
Definition: Common.h:60
const std::optional< std::string > summary
Definition: Common.h:59
const std::map< std::string, std::any > extra
Definition: Common.h:63
const std::optional< std::string > name
Definition: Common.h:58
A description of a service port.
Definition: Common.h:68
std::string name
Definition: Common.h:69