consumed_products.cc
Go to the documentation of this file.
5 
6 using namespace art;
8 
9 namespace {
10  auto
11  product_from_input_source(art::ProductInfo info)
12  {
13  info.label = "input_source";
14  return info;
15  }
16 
17  bool
18  product_match_found(
19  std::map<std::string, std::set<ProductInfo>> const& produced_products,
20  ProductInfo const& info)
21  {
22  auto found = produced_products.find(info.label);
23  if (found == cend(produced_products)) {
24  return false;
25  }
26  // Do not use ProductInfo::operator< for the comparator as that
27  // includes that process name, which is not required when
28  // checking for a match in the current process. If it were,
29  // then only those consumes statements that included the current
30  // process name (or 'current_process') would result in a match.
31  return std::binary_search(
32  cbegin(found->second),
33  cend(found->second),
34  info,
35  [](auto const& a, auto const& b) {
36  auto const& boundA = std::tie(a.friendlyClassName, a.label, a.instance);
37  auto const& boundB = std::tie(b.friendlyClassName, b.label, b.instance);
38  return boundA < boundB;
39  });
40  }
41 
43  consumes_dependency(
44  config_const_iterator const firstModuleOnPath,
45  config_const_iterator const moduleConfig,
46  ProductInfo const& prod_info,
47  std::string const& current_process,
48  std::map<std::string, std::set<ProductInfo>> const& produced_products)
49  {
50  assert(prod_info.consumableType == ProductInfo::ConsumableType::Product);
51 
52  auto const mci = moduleConfig->moduleConfigInfo;
53  assert(mci);
54 
55  // User has not specified the process name.
56  if (prod_info.process.name().empty()) {
57  if (!product_match_found(produced_products, prod_info)) {
58  return product_from_input_source(prod_info);
59  }
60 
61  // This is a necessary requirement if the consumes clause is on a
62  // trigger path.
63  if (is_modifier(mci->moduleType)) {
64  auto found_on_path = std::find_if(
65  firstModuleOnPath, moduleConfig, [&prod_info](auto const& config) {
66  return config.moduleConfigInfo->modDescription.moduleLabel() ==
67  prod_info.label;
68  });
69  if (found_on_path == moduleConfig) {
70  return product_from_input_source(prod_info);
71  }
72  }
73  return prod_info;
74  }
75 
76  // If we get here, the user has specified a process name.
77  if (prod_info.process.name() != current_process) {
78  return product_from_input_source(prod_info);
79  }
80 
81  // The user has specified the current process name.
82  if (product_match_found(produced_products, prod_info)) {
83  return prod_info;
84  }
85 
87  << "Module "
88  << moduleConfig->moduleConfigInfo->modDescription.moduleLabel()
89  << " expects to consume a product from module " << prod_info.label
90  << " with the signature:\n"
91  << " Friendly class name: " << prod_info.friendlyClassName << '\n'
92  << " Instance name: " << prod_info.instance << '\n'
93  << " Process name: " << prod_info.process.name() << '\n'
94  << "However, no product of that signature is provided by module "
95  << prod_info.label << ".\n";
96  }
97 
99  consumes_view_dependency(
100  ProductInfo const& prod_info,
101  std::string const& module_name,
102  std::string const& current_process,
103  std::map<std::string, std::set<std::string>> const& viewable_products)
104  {
105  assert(prod_info.consumableType ==
107 
108  // User has not specified the process name
109  if (prod_info.process.name().empty()) {
110  auto ml_found = viewable_products.find(prod_info.label);
111  if (ml_found == cend(viewable_products)) {
112  return product_from_input_source(prod_info);
113  }
114 
115  auto prod_found = ml_found->second.find(prod_info.instance);
116  if (prod_found == cend(ml_found->second)) {
117  return product_from_input_source(prod_info);
118  }
119 
120  // The correct module has been found for which a view can be
121  // formed.
122  return prod_info;
123  }
124 
125  // If we get here, the user has specified a process name.
126  if (prod_info.process.name() != current_process) {
127  return product_from_input_source(prod_info);
128  }
129 
130  // Current process
132  "An error occurred while checking data-product dependencies "
133  "for this job.\n"};
134  auto ml_found = viewable_products.find(prod_info.label);
135  if (ml_found == cend(viewable_products)) {
136  throw e << "Module " << module_name
137  << " expects to consume a view of type from module "
138  << prod_info.label << ".\n"
139  << "However, module " << prod_info.label
140  << " does not produce a product\n"
141  << "for which a view can be formed.\n";
142  }
143 
144  auto prod_found = ml_found->second.find(prod_info.instance);
145  if (prod_found == cend(ml_found->second)) {
146  throw e << "Module " << module_name
147  << " expects to consume a view with the following signature:\n"
148  << " Module label: " << prod_info.label << '\n'
149  << " Instance name: " << prod_info.instance << '\n'
150  << "However, module " << prod_info.label
151  << " does not produce a product for which such a view "
152  "can be formed.\n";
153  }
154  return prod_info;
155  }
156 }
157 
158 std::set<ProductInfo>
160  std::string const& current_process,
161  ConsumesInfo::consumables_t::mapped_type const& consumables,
162  std::map<std::string, std::set<ProductInfo>> const& produced_products,
163  std::map<std::string, std::set<std::string>> const& viewable_products,
164  config_const_iterator const config_begin,
165  config_const_iterator const config_it)
166 {
167  auto const& module_name =
168  config_it->moduleConfigInfo->modDescription.moduleLabel();
169  std::set<ProductInfo> result;
170  for (auto const& per_branch_type : consumables) {
171  for (auto const& prod_info : per_branch_type) {
172  switch (prod_info.consumableType) {
174  auto dep = consumes_dependency(config_begin,
175  config_it,
176  prod_info,
177  current_process,
178  produced_products);
179  result.insert(std::move(dep));
180  break;
181  }
183  // Loop through modules on this path, introducing
184  // product-lookup dependencies if the type of the product
185  // created by the module matches the type requested in the
186  // consumesMany call.
187  auto const& class_name = prod_info.friendlyClassName;
188  for (auto mit = config_begin; mit != config_it; ++mit) {
189  auto possible_products = produced_products.find(
190  mit->moduleConfigInfo->modDescription.moduleLabel());
191  if (possible_products == cend(produced_products)) {
192  continue;
193  }
194  cet::copy_if_all(possible_products->second,
195  inserter(result, begin(result)),
196  [&class_name](auto const& pi) {
197  return class_name == pi.friendlyClassName;
198  });
199  }
200  break;
201  }
203  auto dep = consumes_view_dependency(
204  prod_info, module_name, current_process, viewable_products);
205  result.insert(std::move(dep));
206  }
207  // No default case to allow compiler to warn.
208  }
209  }
210  }
211  return result;
212 }
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:87
static QCString result
auto copy_if_all(FwdCont &, FwdIter, Pred)
std::string string
Definition: nybbler.cc:12
const double e
static Config * config
Definition: config.cpp:1054
const double a
def move(depos, offset)
Definition: depos.py:107
bool is_modifier(ModuleType const mt)
Definition: ModuleType.h:22
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
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
static bool * b
Definition: config.cpp:1043
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
float pi
Definition: units.py:11
std::vector< WorkerInPath::ConfigInfo >::const_iterator config_const_iterator