Functions
check_data_dependencies.cc File Reference
#include "art/Framework/Core/detail/ModuleConfigInfo.h"
#include "art/Framework/Core/detail/ModuleGraph.h"
#include "art/Framework/Core/detail/ModuleGraphInfoMap.h"
#include "art/Framework/Core/detail/consumed_products.h"
#include "art/Framework/Core/detail/graph_algorithms.h"
#include "art/Framework/Principal/ConsumesInfo.h"
#include "art/Persistency/Provenance/ModuleDescription.h"
#include "art/test/Framework/Core/data-dependencies/Configs.h"
#include "boost/graph/graph_utility.hpp"
#include "canvas/Utilities/Exception.h"
#include "fhiclcpp/ParameterSet.h"
#include "fhiclcpp/types/OptionalAtom.h"
#include "fhiclcpp/types/OptionalDelegatedParameter.h"
#include "fhiclcpp/types/OptionalSequence.h"
#include "fhiclcpp/types/OptionalTable.h"
#include "fhiclcpp/types/Table.h"
#include "fhiclcpp/types/TupleAs.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <regex>

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 366 of file check_data_dependencies.cc.

366  {
367  if (argc != 2)
368  return 1;
369 
370  string const filename{argv[1]};
372  auto const pset = fhicl::ParameterSet::make(filename, maker);
374  auto const& process_name = table().process_name();
375  auto const& test_properties = table().test_properties();
376 
377  ParameterSet physics;
378  if (!table().physics.get_if_present(physics)) {
379  return 0;
380  }
381 
382  // Form the paths
383  auto module_configs = get_module_configs(pset);
384  auto paths_to_modules = get_paths_to_modules(physics, module_configs);
385  auto const trigger_paths =
386  select_paths(pset, tables_with_modifiers, paths_to_modules);
387  auto end_paths = paths_to_modules;
388 
389  auto const end_path = merge_end_paths(end_paths);
390 
391  // Get modules
393 
394  auto& source_info = modules["input_source"];
395  if (!trigger_paths.empty()) {
396  source_info.paths = path_names(trigger_paths);
397  } else if (!end_path.empty()) {
398  source_info.paths = {"end_path"};
399  }
400 
401  // Assemble all the information for products to be produced.
402  std::map<std::string, std::set<art::ProductInfo>> produced_products{};
403  for (auto const& path : trigger_paths) {
404  fillProducesInfo(pset,
405  process_name,
406  path.first.name,
407  path.second,
408  produced_products,
409  modules);
410  }
411 
412  // Now go through and assemble the rest of the graph info objects,
413  // based on the consumes clauses. The reason this is separate from
414  // the filling of the produces information is that we want to allow
415  // users to specify consumes dependencies at this stage, checking
416  // for correct types, etc. *before* checking if the workflow is
417  // well-formed (i.e. no interpath dependencies, or intrapath
418  // circularities). This pattern mimics what is done in
419  // art::PathManager, where all produces information is filled first,
420  // and then the graph is assembled afterward.
421  std::string err_msg;
422  bool graph_failure{false};
423  try {
424  for (auto const& path : trigger_paths) {
425  fillModifierInfo(pset,
426  process_name,
427  path.first.name,
428  path.second,
429  produced_products,
430  modules);
431  }
432 
433  if (!trigger_paths.empty()) {
434  modules["TriggerResults"] = ModuleGraphInfo{art::ModuleType::producer};
435  }
436 
437  fillObserverInfo(
438  pset, process_name, "end_path", end_path, produced_products, modules);
439  }
440  catch (cet::exception const& e) {
441  err_msg += e.what();
442  graph_failure = true;
443  }
444 
445  // Build the graph only if there was no error in constructing the
446  // information it needs.
447  if (err_msg.empty()) {
448  ModuleGraphInfoMap const modInfos{modules};
449  auto const module_graph =
450  art::detail::make_module_graph(modInfos, trigger_paths, end_path);
451  auto const& err = module_graph.second;
452  if (!err.empty()) {
453  err_msg += err;
454  graph_failure = true;
455  }
456 
457  auto const pos = filename.find(".fcl");
458  string const basename =
459  (pos != string::npos) ? filename.substr(0, pos) : filename;
460  std::ofstream ofs{basename + ".dot"};
461  print_module_graph(ofs, modInfos, module_graph.first);
462  }
463 
464  // Check if test properties have been satisfied
465  int rc{};
466  bool const graph_failure_expected = test_properties.graph_failure_expected();
467  if (graph_failure && !graph_failure_expected) {
468  std::cerr << "Unexpected graph-construction failure.\n"
469  << "Error message:\n"
470  << err_msg << '\n';
471  rc = 1;
472  } else if (!graph_failure && graph_failure_expected) {
473  std::cerr << "Unexpected graph-construction success.\n";
474  rc = 1;
475  }
476  string expected_msg;
477  if (test_properties.error_message(expected_msg)) {
478  std::regex const re{expected_msg};
479  if (!std::regex_search(err_msg, re)) {
480  std::cerr << " The error message does not match what was expected:\n"
481  << " Actual: [" << err_msg << "]\n"
482  << " Expected: [" << expected_msg << "]\n";
483  rc = 3;
484  }
485  }
486  return rc;
487 }
488 catch (detail::validationException const& v) {
489  std::cerr << v.what();
490  return 1;
491 }
492 catch (std::exception const& e) {
493  std::cerr << e.what() << '\n';
494  return 1;
495 }
496 catch (...) {
497  std::cerr << "Job failed.\n";
498  return 1;
499 }
std::string string
Definition: nybbler.cc:12
static ParameterSet make(intermediate_table const &tbl)
Definition: ParameterSet.cc:68
std::map< module_name_t, ModuleGraphInfo > collection_map_t
string filename
Definition: train.py:213
const double e
void print_module_graph(std::ostream &os, ModuleGraphInfoMap const &modInfos, ModuleGraph const &graph)
void err(const char *fmt,...)
Definition: message.cpp:226
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
def maker(G, ac, typename)
Definition: apa.py:280
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::pair< ModuleGraph, std::string > make_module_graph(ModuleGraphInfoMap const &modInfos, paths_to_modules_t const &trigger_paths, configs_t const &end_path)