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