PathManager.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
19 #include "art/Utilities/Globals.h"
27 #include "cetlib/HorizontalRule.h"
28 #include "cetlib/LibraryManager.h"
29 #include "cetlib/bold_fontify.h"
32 #include "cetlib/ostream_handle.h"
33 #include "fhiclcpp/ParameterSet.h"
37 
38 #include <algorithm>
39 #include <cassert>
40 #include <map>
41 #include <memory>
42 #include <regex>
43 #include <set>
44 #include <sstream>
45 #include <string>
46 #include <utility>
47 #include <vector>
48 
49 using namespace std;
50 using namespace std::string_literals;
51 
53 
54 namespace art {
55 
56  namespace {
57  std::vector<std::string>
58  sorted_module_labels(std::vector<WorkerInPath::ConfigInfo> const& wcis)
59  {
60  std::vector<std::string> sorted_modules;
62  wcis, back_inserter(sorted_modules), [](auto const& wci) {
63  return wci.moduleConfigInfo->modDescription.moduleLabel();
64  });
65  std::sort(begin(sorted_modules), end(sorted_modules));
66  return sorted_modules;
67  }
68  } // anonymous namespace
69 
70  PathManager::PathManager(ParameterSet const& procPS,
71  UpdateOutputCallbacks& outputCallbacks,
72  ProductDescriptions& productsToProduce,
73  ActionTable const& exceptActions,
74  ActivityRegistry const& actReg,
75  detail::EnabledModules const& enabled_modules)
76  : outputCallbacks_{outputCallbacks}
77  , exceptActions_{exceptActions}
78  , actReg_{actReg}
79  , procPS_{procPS}
80  , triggerPathSpecs_{enabled_modules.trigger_path_specs()}
82  , endPathInfo_(Globals::instance()->nschedules())
83  , productsToProduce_{productsToProduce}
84  , processName_{procPS.get<string>("process_name"s, {})}
85  {
86  allModules_ = moduleInformation_(enabled_modules);
87 
88  // Trigger paths
89  auto const& trigger_path_specs = enabled_modules.trigger_path_specs();
90  protoTrigPathLabels_.reserve(trigger_path_specs.size());
91  std::set<std::string> recorded_path_name;
92  for (auto const& [path_spec, entries] : trigger_path_specs) {
93  if (not recorded_path_name.insert(path_spec.name).second)
94  continue;
95 
96  if (entries.empty())
97  continue;
98 
99  art::detail::configs_t worker_config_infos{};
100  for (auto const& [label, action] : entries) {
101  auto const& mci = allModules_.at(label);
102  auto const mci_p = cet::make_exempt_ptr(&mci);
103  worker_config_infos.emplace_back(mci_p, action);
104  }
105  protoTrigPathLabels_.emplace_back(path_spec,
106  std::move(worker_config_infos));
107  }
108 
109  // Finalize trigger path names and make available in Globals
111 
112  ParameterSet triggerPSet;
113  triggerPSet.put("trigger_paths", prependedTriggerPathNames_());
115  Globals::instance()->setTriggerPSet(triggerPSet);
117 
118  // End path(s)
119  auto const& end_paths = enabled_modules.end_paths();
120  protoEndPathLabels_.reserve(end_paths.size());
121  for (auto const& [path_spec, entries] : end_paths) {
122  if (not recorded_path_name.insert(path_spec.name).second)
123  continue;
124 
125  if (entries.empty())
126  continue;
127 
128  for (auto const& [label, action] : entries) {
130  auto const& mci = allModules_.at(label);
131  auto const mci_p = cet::make_exempt_ptr(&mci);
132  protoEndPathLabels_.emplace_back(mci_p, action);
133  }
134  }
135 
136  if (size(end_paths) > 1u) {
137  mf::LogInfo("PathConfiguration")
138  << "Multiple end paths have been combined into one end path,\n"
139  << "\"end_path\" since order is irrelevant.";
140  }
141  }
142 
143  std::vector<PathSpec>
145  {
146  std::vector<PathSpec> result;
147  result.reserve(size(triggerPathSpecs_));
148  for (auto const& pr : triggerPathSpecs_) {
149  result.push_back(pr.first);
150  }
151  return result;
152  }
153 
154  std::vector<std::string>
156  {
157  std::vector<std::string> result;
158  result.reserve(size(triggerPathSpecs_));
159  for (auto const& pr : triggerPathSpecs_) {
160  result.push_back(pr.first.name);
161  }
162  return result;
163  }
164 
165  std::vector<std::string>
167  {
168  std::vector<std::string> result;
169  result.reserve(size(triggerPathSpecs_));
170  for (auto const& pr : triggerPathSpecs_) {
171  result.push_back(to_string(pr.first));
172  }
173  return result;
174  }
175 
176  void
178  GlobalTaskGroup& task_group,
179  detail::SharedResources& resources,
180  std::vector<std::string> const& producing_services)
181  {
182  // For each configured schedule, create the trigger paths and the
183  // workers on each path.
184  auto const nschedules =
186 
187  // The modules created are managed by shared_ptrs. Once the
188  // workers claim (co-)ownership of the modules, the 'modules'
189  // object can be destroyed.
190  auto modules = makeModules_(nschedules);
191 
192  // FIXME: THE PATHS INFO OBJECTS SHOULD BECOME OWNERS OF THE WORKERS
193  // I IMAGINE AN API LIKE:
194  //
195  // pinfo.fillWorkers(pc, worker_config_infos, task_group, resources);
196  // pinfo.add_path(...);
197  //
198  // PERHAPS WOULD BE BETTER SOMETHING LIKE:
199  //
200  // Paths;
201  // wp.add_path(....);
202 
203  for (ScheduleID::size_type i = 0; i != nschedules; ++i) {
204  ScheduleID const sid{i};
205  auto& pinfo = triggerPathsInfo_[sid];
206  ScheduleContext const sc{sid};
207  for (auto const& [path_spec, worker_config_infos] :
209 
210  PathContext const pc{
211  sc, path_spec, sorted_module_labels(worker_config_infos)};
212  auto wips = fillWorkers_(pc,
213  worker_config_infos,
214  modules,
215  pinfo.workers(),
216  task_group,
217  resources);
218  pinfo.add_path(exceptActions_, actReg_, pc, move(wips), task_group);
219  }
220 
221  if (protoEndPathLabels_.empty()) {
222  continue;
223  }
224 
225  // Create the end path and the workers on it.
226  auto& einfo = endPathInfo_[sid];
227  PathContext const pc{sc,
229  sorted_module_labels(protoEndPathLabels_)};
230  auto wips = fillWorkers_(pc,
232  modules,
233  einfo.workers(),
234  task_group,
235  resources);
236  einfo.add_path(exceptActions_, actReg_, pc, move(wips), task_group);
237  };
238 
239  using namespace detail;
240  auto const graph_info_collection =
241  getModuleGraphInfoCollection_(producing_services);
242  ModuleGraphInfoMap const modInfos{graph_info_collection};
243  auto const module_graph =
245  auto const graph_filename =
246  procPS_.get<string>("services.scheduler.dataDependencyGraph", {});
247  if (!graph_filename.empty()) {
248  cet::ostream_handle osh{graph_filename};
249  print_module_graph(osh, modInfos, module_graph.first);
250  cerr << "Generated data-dependency graph file: " << graph_filename
251  << '\n';
252  }
253  auto const& err = module_graph.second;
254  if (!err.empty()) {
255  throw Exception{errors::Configuration} << err << '\n';
256  }
257 
258  // No longer need worker/module config objects.
259  protoTrigPathLabels_.clear();
260  protoEndPathLabels_.clear();
261  allModules_.clear();
262  }
263 
264  PathsInfo&
266  {
267  return triggerPathsInfo_.at(sid);
268  }
269 
272  {
273  return triggerPathsInfo_;
274  }
275 
276  PathsInfo&
278  {
279  return endPathInfo_.at(sid);
280  }
281 
284  {
285  return endPathInfo_;
286  }
287 
288  std::map<std::string, detail::ModuleConfigInfo>
290  detail::EnabledModules const& enabled_modules) const
291  {
292  std::map<std::string, detail::ModuleConfigInfo> result{};
293  ostringstream es;
294  for (auto const& [module_label, key_and_type] : enabled_modules.modules()) {
295  try {
296  auto const& [key, module_type] = key_and_type;
297  auto const module_pset = procPS_.get<fhicl::ParameterSet>(key);
298  auto const lib_spec = module_pset.get<string>("module_type");
299  if (auto const actual_mod_type = loadModuleType_(lib_spec);
300  actual_mod_type != module_type) {
301  es << " ERROR: Module with label " << module_label << " of type "
302  << lib_spec << " is configured as a " << to_string(module_type)
303  << " but defined in code as a " << to_string(actual_mod_type)
304  << ".\n";
305  continue;
306  }
307 
308  ModuleDescription const md{module_pset.id(),
309  lib_spec,
310  module_label,
311  loadModuleThreadingType_(lib_spec),
313  procPS_.id(),
314  getReleaseVersion()}};
315  detail::ModuleConfigInfo mci{md, std::move(module_pset), module_type};
316  result.emplace(module_label, move(mci));
317  }
318  catch (exception const& e) {
319  es << " ERROR: Configuration of module with label " << module_label
320  << " encountered the following error:\n"
321  << e.what();
322  }
323  }
324  if (auto err_msg = es.str(); not empty(err_msg)) {
326  << "The following were encountered while processing the module "
327  "configurations:\n"
328  << err_msg;
329  }
330  return result;
331  }
332 
335  {
336  ModulesByThreadingType modules{};
337  vector<string> configErrMsgs;
338  for (auto const& [module_label, mci] : allModules_) {
339  auto const& modPS = mci.modPS;
340  auto const& md = mci.modDescription;
341  auto const module_type = md.moduleName();
342  auto const module_threading_type = md.moduleThreadingType();
343 
344  // FIXME: provide context information?
346 
347  auto sid = ScheduleID::first();
348  auto mod = makeModule_(modPS, md, sid);
349  if (auto err_msg = get_if<std::string>(&mod)) {
350  configErrMsgs.push_back(*err_msg);
351  continue;
352  }
353 
354  assert(std::holds_alternative<ModuleBase*>(mod));
355  auto module = std::get<ModuleBase*>(mod);
356 
357  if (module_threading_type == ModuleThreadingType::shared ||
358  module_threading_type == ModuleThreadingType::legacy) {
359  modules.shared.emplace(module_label,
360  std::shared_ptr<ModuleBase>{module});
361  } else {
363  nschedules);
364  replicated_modules[sid].reset(module);
365  ScheduleIteration schedule_iteration{sid.next(),
366  ScheduleID(nschedules)};
367 
368  auto fill_replicated_module = [&, this](ScheduleID const sid) {
369  auto repl_mod = makeModule_(modPS, md, sid);
370  if (auto mod_ptr = get_if<ModuleBase*>(&repl_mod)) {
371  replicated_modules[sid].reset(*mod_ptr);
372  }
373  };
374  schedule_iteration.for_each_schedule(fill_replicated_module);
375  modules.replicated.emplace(module_label, replicated_modules);
376  }
377 
379 
380  // Since we store consumes information per module label, we only
381  // sort and collect it for one of the replicated-module copies.
382  // The only way this would be a problem is if someone decided to
383  // provided conditional consumes calls based on the ScheduleID
384  // presented to the replicated-module constructor.
385  module->sortConsumables(processName_);
386  ConsumesInfo::instance()->collectConsumes(module_label,
387  module->getConsumables());
388  }
389 
390  if (!configErrMsgs.empty()) {
391  constexpr cet::HorizontalRule rule{100};
392  ostringstream msg;
393  msg << "\n"
394  << rule('=') << "\n\n"
395  << "!! The following modules have been misconfigured: !!"
396  << "\n";
397  for (auto const& err : configErrMsgs) {
398  msg << "\n" << rule('-') << "\n" << err;
399  }
400  msg << "\n" << rule('=') << "\n\n";
401  throw Exception(errors::Configuration) << msg.str();
402  }
403  return modules;
404  }
405 
408  ModuleDescription const& md,
409  ScheduleID const sid) const
410  {
411  auto const& module_type = md.moduleName();
412  try {
413  detail::ModuleMaker_t* module_factory_func{nullptr};
414  try {
415  lm_.getSymbolByLibspec(module_type, "make_module", module_factory_func);
416  }
417  catch (Exception& e) {
419  e, "Module", module_type, getReleaseVersion());
420  }
421  if (module_factory_func == nullptr) {
422  throw Exception(errors::Configuration, "BadPluginLibrary: ")
423  << "Module " << module_type << " with version " << getReleaseVersion()
424  << " has internal symbol definition problems: consult an "
425  "expert.";
426  }
427  auto mod = module_factory_func(modPS, art::ProcessingFrame{sid});
428  mod->setModuleDescription(md);
429  return mod;
430  }
431  catch (fhicl::detail::validationException const& e) {
432  ostringstream es;
433  es << "\n\nModule label: " << cet::bold_fontify(md.moduleLabel())
434  << "\nmodule_type : " << cet::bold_fontify(module_type) << "\n\n"
435  << e.what();
436  return es.str();
437  }
438  assert(false); // Unreachable
439  return {};
440  }
441 
442  vector<WorkerInPath>
444  vector<WorkerInPath::ConfigInfo> const& wci_list,
445  ModulesByThreadingType const& modules,
446  map<string, std::shared_ptr<Worker>>& workers,
447  GlobalTaskGroup& task_group,
448  detail::SharedResources& resources)
449  {
450  auto const sid = pc.scheduleID();
451  auto const pi = pc.pathID();
452  vector<WorkerInPath> wips;
453  for (auto const& wci : wci_list) {
454  auto const& mci = *wci.moduleConfigInfo;
455  auto const filterAction = wci.filterAction;
456  auto const& module_label = mci.modDescription.moduleLabel();
457 
458  auto const& md = mci.modDescription;
459  std::shared_ptr<Worker> worker{nullptr};
460  // Workers present on multiple paths are shared so that their
461  // work is only done once per schedule.
462  if (auto it = workers.find(module_label); it != workers.end()) {
463  TDEBUG_FUNC_SI(5, sid)
464  << "Reusing worker " << hex << it->second << dec
465  << " path: " << to_string(pi) << " type: " << md.moduleName()
466  << " label: " << module_label;
467  worker = it->second;
468  } else {
471  actReg_,
473  sid,
474  task_group.native_group(),
475  resources};
476  worker = makeWorker_(modules, mci.modDescription, wp);
477  TDEBUG(5) << "Made worker " << hex << worker << dec << " (" << sid
478  << ") path: " << to_string(pi) << " type: " << md.moduleName()
479  << " label: " << module_label << "\n";
480  }
481 
482  assert(worker);
483  workers.emplace(module_label, worker);
484  wips.emplace_back(cet::make_exempt_ptr(worker.get()),
485  filterAction,
486  ModuleContext{pc, worker->description()},
487  task_group);
488  }
489  return wips;
490  }
491 
492  std::shared_ptr<Worker>
494  ModuleDescription const& md,
495  WorkerParams const& wp)
496  {
497  auto get_module =
498  [&modules](std::string const& module_label,
499  ModuleThreadingType const module_threading_type,
500  ScheduleID const sid) {
501  if (module_threading_type == ModuleThreadingType::shared ||
502  module_threading_type == ModuleThreadingType::legacy) {
503  return modules.shared.at(module_label);
504  }
505  return modules.replicated.at(module_label)[sid];
506  };
507 
508  detail::WorkerFromModuleMaker_t* worker_from_module_factory_func = nullptr;
509  try {
511  "make_worker_from_module",
512  worker_from_module_factory_func);
513  }
514  catch (Exception& e) {
516  e, "Module", md.moduleName(), getReleaseVersion());
517  }
518  if (worker_from_module_factory_func == nullptr) {
519  throw Exception(errors::Configuration, "BadPluginLibrary: ")
520  << "Module " << md.moduleName() << " with version "
521  << getReleaseVersion()
522  << " has internal symbol definition problems: consult an expert.";
523  }
524 
525  auto module =
526  get_module(md.moduleLabel(), md.moduleThreadingType(), wp.scheduleID_);
527  return std::shared_ptr<Worker>{
528  worker_from_module_factory_func(module, md, wp)};
529  }
530 
531  ModuleType
532  PathManager::loadModuleType_(string const& lib_spec) const
533  {
534  detail::ModuleTypeFunc_t* mod_type_func{nullptr};
535  try {
536  lm_.getSymbolByLibspec(lib_spec, "moduleType", mod_type_func);
537  }
538  catch (Exception& e) {
540  e, "Module", lib_spec, getReleaseVersion());
541  }
542  if (mod_type_func == nullptr) {
543  throw Exception(errors::Configuration, "BadPluginLibrary")
544  << "Module " << lib_spec << " with version " << getReleaseVersion()
545  << " has internal symbol definition problems: consult an expert.";
546  }
547  return mod_type_func();
548  }
549 
551  PathManager::loadModuleThreadingType_(string const& lib_spec) const
552  {
553  detail::ModuleThreadingTypeFunc_t* mod_threading_type_func{nullptr};
554  try {
556  lib_spec, "moduleThreadingType", mod_threading_type_func);
557  }
558  catch (Exception& e) {
560  e, "Module", lib_spec, getReleaseVersion());
561  }
562  if (mod_threading_type_func == nullptr) {
563  throw Exception(errors::Configuration, "BadPluginLibrary")
564  << "Module " << lib_spec << " with version " << getReleaseVersion()
565  << " has internal symbol definition problems: consult an expert.";
566  }
567  return mod_threading_type_func();
568  }
569 
570  // Module-graph implementation below
571  using namespace detail;
572 
575  std::vector<std::string> const& producing_services)
576  {
578  auto& source_info = result["input_source"];
579  if (!protoTrigPathLabels_.empty()) {
580  set<string> path_names;
581  for (auto const& pr : triggerPathSpecs_) {
582  path_names.insert(pr.first.name);
583  }
584  source_info.paths = path_names;
585  result["TriggerResults"] = ModuleGraphInfo{ModuleType::producer};
586  } else if (!protoEndPathLabels_.empty()) {
587  source_info.paths = {"end_path"};
588  }
589 
590  // Prepare information for produced and viewable products
591  std::map<std::string, std::set<ProductInfo>> produced_products_per_module;
592  std::map<std::string, std::set<std::string>> viewable_products_per_module;
593  for (auto const& pd : productsToProduce_) {
594  auto const& module_name = pd.moduleLabel();
595  produced_products_per_module[module_name].emplace(
597  pd.friendlyClassName(),
598  pd.moduleLabel(),
599  pd.productInstanceName(),
600  ProcessTag{pd.processName(), pd.processName()});
601  if (pd.supportsView()) {
602  // We do not do any type-checking here due to lack of
603  // introspection abilities. That will be performed during the
604  // actual product lookup.
605  viewable_products_per_module[module_name].insert(
606  pd.productInstanceName());
607  }
608  }
609 
610  // Handle producing services, which do not currently support 'consumes'.
611  for (auto const& service_name : producing_services) {
612  auto& graph_info = result[service_name];
613  graph_info.module_type = ModuleType::producing_service;
614 
615  auto found = produced_products_per_module.find(service_name);
616  if (found == cend(produced_products_per_module)) {
617  continue;
618  }
619 
620  graph_info.produced_products = found->second;
621  }
622 
623  for (auto const& [path_spec, module_labels] : protoTrigPathLabels_) {
625  module_labels,
626  produced_products_per_module,
627  viewable_products_per_module,
628  result);
629  }
632  produced_products_per_module,
633  viewable_products_per_module,
634  result);
636  return result;
637  }
638 
639  void
641  string const& path_name,
642  configs_t const& worker_configs,
643  std::map<std::string, std::set<ProductInfo>> const& produced_products,
644  std::map<std::string, std::set<std::string>> const& viewable_products,
645  collection_map_t& info_collection) const
646  {
647  auto const worker_config_begin = cbegin(worker_configs);
648 
649  for (auto it = worker_config_begin, end = cend(worker_configs); it != end;
650  ++it) {
651  auto const& mci = *it->moduleConfigInfo;
652  auto const& module_name = mci.modDescription.moduleLabel();
653  auto& graph_info = info_collection[module_name];
654  graph_info.paths.insert(path_name);
655  graph_info.module_type = mci.moduleType;
656 
657  auto found = produced_products.find(module_name);
658  if (found != cend(produced_products)) {
659  graph_info.produced_products = found->second;
660  }
661 
662  auto const& consumables =
663  ConsumesInfo::instance()->consumables(module_name);
664  graph_info.consumed_products =
666  consumables,
667  produced_products,
668  viewable_products,
669  worker_config_begin,
670  it);
671  }
672  }
673 
674  namespace {
675  // The allowed path-specification is more restricted than what we
676  // formulate here--i.e. a path name cannot begin with a digit.
677  // However, because the FHiCL language does not allow parameter
678  // names to begin with a digit, we do not worry about the overly
679  // permissive regex below.
680  string const allowed_path_spec{R"([\w\*\?]+)"};
681  regex const regex{"(\\w+:)?(!|exception@)?(" + allowed_path_spec +
682  ")(&noexception)?"};
683  }
684 
685  void
687  collection_map_t& info_collection) const
688  {
689  for (auto const& worker_config : worker_configs) {
690  auto const& mci = *worker_config.moduleConfigInfo;
691  auto const& module_name = mci.modDescription.moduleLabel();
692  auto const& ps = mci.modPS;
693  auto& graph_info = info_collection[module_name];
694  assert(is_observer(graph_info.module_type));
695  auto path_specs = ps.get<vector<string>>("SelectEvents", {});
696  for (auto& path_spec : path_specs) {
698 
699  smatch matches;
700  regex_match(path_spec, matches, regex);
701  // By the time we have gotten here, all modules have been
702  // constructed, and it is guaranteed that the specified paths
703  // are in accord with the above regex.
704  // 0: Full match
705  // 1: Optional process name
706  // 2: Optional '!' or 'exception@'
707  // 3: Required path specification
708  // 4: Optional '&noexception'
709  assert(matches.size() == 5);
710  graph_info.select_events.insert(matches[3]);
711  }
712  }
713  }
714 
715 } // namespace art
consumables_t::mapped_type const & consumables(std::string const &module_label) const
Definition: ConsumesInfo.h:110
std::map< module_label_t, PerScheduleContainer< std::shared_ptr< ModuleBase > > > replicated
Definition: PathManager.h:80
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void collectConsumes(std::string const &module_label, consumables_t::mapped_type const &consumables)
Definition: ConsumesInfo.cc:99
ProductDescriptions & productsToProduce_
Definition: PathManager.h:128
void setProcessName(std::string const &)
Definition: Globals.cc:54
static std::string end_path()
Definition: PathContext.h:14
static ParameterSetID const & put(ParameterSet const &ps)
ModuleBase *(fhicl::ParameterSet const &, ProcessingFrame const &) ModuleMaker_t
Definition: ModuleMacros.h:33
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:87
static QCString result
keytype_for_name_t const & modules() const noexcept
std::shared_ptr< Worker > makeWorker_(ModulesByThreadingType const &modules, ModuleDescription const &md, WorkerParams const &wp)
Definition: PathManager.cc:493
static ConsumesInfo * instance()
Definition: ConsumesInfo.cc:24
void msg(const char *fmt,...)
Definition: message.cpp:107
void fillModuleOnlyDeps_(std::string const &path_name, detail::configs_t const &worker_configs, std::map< std::string, std::set< ProductInfo >> const &produced_products, std::map< std::string, std::set< std::string >> const &viewable_products, detail::collection_map_t &info_collection) const
Definition: PathManager.cc:640
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
GlobalSignal< detail::SignalResponseType::FIFO, void(ModuleDescription const &)> sPreModuleConstruction
std::string const & moduleLabel() const
std::map< module_name_t, ModuleGraphInfo > collection_map_t
std::vector< std::string > triggerPathNames_() const
Definition: PathManager.cc:155
static constexpr ScheduleID first()
Definition: ScheduleID.h:50
STL namespace.
art::detail::paths_to_modules_t protoTrigPathLabels_
Definition: PathManager.h:137
void setTriggerPSet(fhicl::ParameterSet const &)
Definition: Globals.cc:66
std::string processName_
Definition: PathManager.h:135
std::vector< BranchDescription > ProductDescriptions
ModuleType module_type(std::string const &full_key)
QTextStream & hex(QTextStream &s)
GlobalSignal< detail::SignalResponseType::LIFO, void(ModuleDescription const &)> sPostModuleConstruction
auto scheduleID() const
Definition: PathContext.h:52
maybe_module_t makeModule_(fhicl::ParameterSet const &module_pset, ModuleDescription const &md, ScheduleID) const
Definition: PathManager.cc:407
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
T getSymbolByLibspec(std::string const &libspec, std::string const &sym_name) const
std::string const & moduleName() const
const double e
PerScheduleContainer< PathsInfo > triggerPathsInfo_
Definition: PathManager.h:126
std::vector< WorkerInPath::ConfigInfo > configs_t
std::vector< PathSpec > path_specs(std::vector< std::string > const &path_spec_strs)
Definition: PathSpec.cc:34
std::variant< ModuleBase *, std::string > maybe_module_t
Definition: PathManager.h:87
ScheduleID::size_type nschedules() const
Definition: Globals.cc:24
def key(type, name=None)
Definition: graph.py:13
std::vector< std::string > prependedTriggerPathNames_() const
Definition: PathManager.cc:166
def move(depos, offset)
Definition: depos.py:107
T get(std::string const &key) const
Definition: ParameterSet.h:271
constexpr exempt_ptr< E > make_exempt_ptr(E *) noexcept
std::string const & getReleaseVersion()
PerScheduleContainer< PathsInfo > endPathInfo_
Definition: PathManager.h:127
std::string bold_fontify(std::string const &s)
Definition: bold_fontify.h:8
ScheduleID scheduleID_
Definition: WorkerParams.h:29
ModuleThreadingType loadModuleThreadingType_(std::string const &lib_spec) const
Definition: PathManager.cc:551
std::map< std::string, detail::ModuleConfigInfo > allModules_
Definition: PathManager.h:136
#define TDEBUG_FUNC_SI(LEVEL, SI)
void print_module_graph(std::ostream &os, ModuleGraphInfoMap const &modInfos, ModuleGraph const &graph)
ModulesByThreadingType makeModules_(ScheduleID::size_type n)
Definition: PathManager.cc:334
ModuleType( ModuleTypeFunc_t)
Definition: ModuleMacros.h:38
static constexpr double ps
Definition: Units.h:99
std::string name
Definition: PathSpec.h:48
static auto end_path_spec()
Definition: PathContext.h:20
void fillSelectEventsDeps_(detail::configs_t const &worker_configs, detail::collection_map_t &info_collection) const
Definition: PathManager.cc:686
auto transform_all(Container &, OutputIt, UnaryOp)
void err(const char *fmt,...)
Definition: message.cpp:226
cet::LibraryManager lm_
Definition: PathManager.h:130
QTextStream & dec(QTextStream &s)
ParameterSetID id() const
std::vector< PathSpec > triggerPathSpecs() const
Definition: PathManager.cc:144
ModuleThreadingType moduleThreadingType() const
std::map< std::string, detail::ModuleConfigInfo > moduleInformation_(detail::EnabledModules const &enabled_modules) const
Definition: PathManager.cc:289
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
#define TDEBUG(LEVEL)
UpdateOutputCallbacks & outputCallbacks_
Definition: PathManager.h:121
ActionTable const & exceptActions_
Definition: PathManager.h:122
char const * what() const noexcept override
std::vector< WorkerInPath > fillWorkers_(PathContext const &pc, std::vector< WorkerInPath::ConfigInfo > const &wci_list, ModulesByThreadingType const &modules, std::map< std::string, std::shared_ptr< Worker >> &workers, GlobalTaskGroup &task_group, detail::SharedResources &resources)
Definition: PathManager.cc:443
id_type size_type
Definition: ScheduleID.h:25
PathID pathID() const noexcept
Definition: PathContext.h:68
std::map< module_label_t, std::shared_ptr< ModuleBase > > shared
Definition: PathManager.h:77
ModuleThreadingType
Definition: ModuleType.h:19
void remove_whitespace(std::string &str)
detail::collection_map_t getModuleGraphInfoCollection_(std::vector< std::string > const &producing_services)
Definition: PathManager.cc:574
art::detail::module_entries_for_ordered_path_t triggerPathSpecs_
Definition: PathManager.h:125
void setTriggerPathNames(std::vector< std::string > const &)
Definition: Globals.cc:78
tbb::task_group & native_group()
std::set< ProductInfo > consumed_products_for_module(std::string const &current_process, ConsumesInfo::consumables_t::mapped_type const &consumables, std::map< std::string, std::set< ProductInfo >> const &produced_products, std::map< std::string, std::set< std::string >> const &viewable_products, config_const_iterator const config_begin, config_const_iterator const config_it)
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:82
void createModulesAndWorkers(GlobalTaskGroup &task_group, detail::SharedResources &resources, std::vector< std::string > const &producing_services)
Definition: PathManager.cc:177
ModuleThreadingType( ModuleThreadingTypeFunc_t)
Definition: ModuleMacros.h:39
PathSpec path_spec(std::string const &path_spec)
Definition: PathSpec.cc:22
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
float pi
Definition: units.py:11
bool is_observer(ModuleType const mt)
Definition: ModuleType.h:28
art::detail::configs_t protoEndPathLabels_
Definition: PathManager.h:138
PerScheduleContainer< PathsInfo > & triggerPathsInfo()
Definition: PathManager.cc:271
static Globals * instance()
Definition: Globals.cc:17
PerScheduleContainer< PathsInfo > & endPathInfo()
Definition: PathManager.cc:283
Worker *(std::shared_ptr< ModuleBase >, ModuleDescription const &, WorkerParams const &) WorkerFromModuleMaker_t
Definition: ModuleMacros.h:36
ActivityRegistry const & actReg_
Definition: PathManager.h:123
workers
Definition: train.py:479
ModuleType loadModuleType_(std::string const &lib_spec) const
Definition: PathManager.cc:532
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
static QCString * s
Definition: config.cpp:1042
fhicl::ParameterSet procPS_
Definition: PathManager.h:124
void put(std::string const &key)
void wrapLibraryManagerException(cet::exception const &e, std::string const &item_type, std::string const &libspec, std::string const &release)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
ModuleType
Definition: ModuleType.h:11
std::pair< ModuleGraph, std::string > make_module_graph(ModuleGraphInfoMap const &modInfos, paths_to_modules_t const &trigger_paths, configs_t const &end_path)