diff --git a/.github/ISSUE_TEMPLATE/gripe.yml b/.github/ISSUE_TEMPLATE/gripe.yml new file mode 100644 index 000000000..ceb3f1729 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/gripe.yml @@ -0,0 +1,16 @@ +name: Gripe +description: Describe a bug, problem, or annoyance that doesn't have a simple reproducer +labels: ["best effort"] +title: "[Gripe]: " +body: + - type: markdown + attributes: + value: | + * **If you are able to define a minimal reproducer for the issue, please use a different issue type.** + * **Gripes will be dealt with on a "best effort" basis only, and cannot be high priority.** + * **Multiple iterations may be necessary to understand your issue well enough to posit a remedy.** + - type: textarea + id: gripe-details + attributes: + label: Details + placeholder: Please describe your issue in as much detail as possible. diff --git a/CMakeLists.txt b/CMakeLists.txt index b14de6530..94f41442c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ cmake_minimum_required(VERSION 3.19 FATAL_ERROR) find_package(cetmodules 2.13.00 REQUIRED) -project(art VERSION 3.14.04 LANGUAGES CXX C) +project(art VERSION 3.15.00 LANGUAGES CXX C) include(CetCMakeEnv) cet_cmake_env() diff --git a/art/Framework/Core/Modifier.h b/art/Framework/Core/Modifier.h index b0e18d9dc..4643d5561 100644 --- a/art/Framework/Core/Modifier.h +++ b/art/Framework/Core/Modifier.h @@ -15,9 +15,9 @@ namespace art { class Modifier : public ModuleBase, private ProductRegistryHelper { public: - template + template using Table = - ProducerTable; + ProducerTable; ~Modifier() noexcept; Modifier(); diff --git a/art/Framework/Core/ProducerTable.h b/art/Framework/Core/ProducerTable.h index 2bc8774a5..a69fdbc51 100644 --- a/art/Framework/Core/ProducerTable.h +++ b/art/Framework/Core/ProducerTable.h @@ -12,10 +12,9 @@ #include namespace art { - template + typename... UserKeysToIgnore> class ProducerTable : public fhicl::ConfigurationTable { private: // TYPES template @@ -26,11 +25,9 @@ namespace art { fhicl::TableFragment user; }; - using KeysToIgnore_t = std::conditional_t< - std::is_void::value, - typename ImplicitConfig::IgnoreKeys, + using KeysToIgnore_t = fhicl::KeysToIgnore>; + UserKeysToIgnore...>; public: // MEMBER FUNCTIONS -- Special Member Functions explicit ProducerTable(fhicl::Name&& name) : fullConfig_{std::move(name)} {} diff --git a/art/Framework/Core/ResultsProducer.h b/art/Framework/Core/ResultsProducer.h index 530e2033e..e5e1384cd 100644 --- a/art/Framework/Core/ResultsProducer.h +++ b/art/Framework/Core/ResultsProducer.h @@ -98,8 +98,9 @@ namespace art { ResultsProducer() noexcept(false); - template - using Table = ProducerTable; + template + using Table = + ProducerTable; void doBeginJob(); void doEndJob(); diff --git a/art/Framework/Core/TriggerPathsExecutor.cc b/art/Framework/Core/TriggerPathsExecutor.cc index e4f7f6154..1bee416f7 100644 --- a/art/Framework/Core/TriggerPathsExecutor.cc +++ b/art/Framework/Core/TriggerPathsExecutor.cc @@ -232,7 +232,7 @@ namespace art { TDEBUG_END_FUNC_SI(4, scheduleID); return; } - auto pathsDoneTask = std::make_shared( + auto pathsDoneTask = make_waiting_task( PathsDoneTask{this, endPathTask, event_principal, taskGroup_}, triggerPathsInfo_.paths().size()); for (auto& path : triggerPathsInfo_.paths()) { diff --git a/art/Framework/Core/detail/Analyzer.h b/art/Framework/Core/detail/Analyzer.h index cc572175a..b9e25ef2f 100644 --- a/art/Framework/Core/detail/Analyzer.h +++ b/art/Framework/Core/detail/Analyzer.h @@ -33,7 +33,7 @@ namespace art { namespace art::detail { class Analyzer : public Observer { public: - template + template class Table : public fhicl::ConfigurationTable { template struct FullConfig { @@ -42,10 +42,9 @@ namespace art::detail { fhicl::TableFragment user; }; - using KeysToIgnore_t = std::conditional_t< - std::is_void::value, - ModuleConfig::IgnoreKeys, - fhicl::KeysToIgnore>; + using KeysToIgnore_t = + fhicl::KeysToIgnore; public: explicit Table(fhicl::Name&& name) : fullConfig_{std::move(name)} {} diff --git a/art/Framework/Core/detail/Producer.h b/art/Framework/Core/detail/Producer.h index f66eec3e4..116860874 100644 --- a/art/Framework/Core/detail/Producer.h +++ b/art/Framework/Core/detail/Producer.h @@ -22,8 +22,8 @@ namespace art::detail { class Producer : public Modifier { public: - template - using Table = Modifier::Table; + template + using Table = Modifier::Table; virtual ~Producer() noexcept; explicit Producer(fhicl::ParameterSet const&); diff --git a/art/Framework/IO/ProductMix/MixHelper.cc b/art/Framework/IO/ProductMix/MixHelper.cc index e701525f6..6d5f26395 100644 --- a/art/Framework/IO/ProductMix/MixHelper.cc +++ b/art/Framework/IO/ProductMix/MixHelper.cc @@ -131,14 +131,14 @@ art::operator<<(std::ostream& os, MixHelper::Mode const mode) switch (mode) { case MixHelper::Mode::SEQUENTIAL: return os << "SEQUENTIAL"; + case MixHelper::Mode::RANDOM_OFFSET: + return os << "RANDOM_OFFSET"; case MixHelper::Mode::RANDOM_REPLACE: return os << "RANDOM_REPLACE"; case MixHelper::Mode::RANDOM_LIM_REPLACE: return os << "RANDOM_LIM_REPLACE"; case MixHelper::Mode::RANDOM_NO_REPLACE: return os << "RANDOM_NO_REPLACE"; - case MixHelper::Mode::UNKNOWN: - return os << "UNKNOWN"; // No default so compiler can warn. } return os; @@ -189,6 +189,27 @@ art::MixHelper::createEngine(seed_t const seed, seed, kind_of_engine_to_make, engine_label); } +bool +art::MixHelper::overThreshold_(size_t const nSecondaries, + size_t const nEventsInFile) const +{ + switch (readMode_) { + case Mode::SEQUENTIAL: + [[fallthrough]]; + case Mode::RANDOM_OFFSET: + [[fallthrough]]; + case Mode::RANDOM_NO_REPLACE: + return nEventsReadThisFile_ + nSecondaries > nEventsInFile; + case Mode::RANDOM_REPLACE: + [[fallthrough]]; + case Mode::RANDOM_LIM_REPLACE: + return nEventsReadThisFile_ + nSecondaries > + nEventsInFile * coverageFraction_; + } + assert(false); // unreachable + return false; +} + bool art::MixHelper::generateEventSequence(size_t const nSecondaries, EntryNumberSequence& enSeq, @@ -201,12 +222,7 @@ art::MixHelper::generateEventSequence(size_t const nSecondaries, } auto const nEventsInFile = ioHandle_->nEventsInFile(); - bool const over_threshold = - (readMode_ == Mode::SEQUENTIAL || readMode_ == Mode::RANDOM_NO_REPLACE) ? - ((nEventsReadThisFile_ + nSecondaries) > nEventsInFile) : - ((nEventsReadThisFile_ + nSecondaries) > - (nEventsInFile * coverageFraction_)); - if (over_threshold) { + if (overThreshold_(nSecondaries, nEventsInFile)) { if (!providerFunc_) { ++nOpensOverThreshold_; if (nOpensOverThreshold_ > filenames_.size()) { @@ -215,11 +231,13 @@ art::MixHelper::generateEventSequence(size_t const nSecondaries, "the current event.\n"} << "The number of requested secondaries (" << nSecondaries << ") exceeds the number of events in any\n" - << "of the files specified for product mixing. For a read mode of '" + << "of the files specified for product mixing. For a read mode of " + "'" << readMode_ << "',\n" << "the framework does not currently allow product-mixing to span " "multiple secondary\n" - << "input files for a given event. Please contact artists@fnal.gov " + << "input files for a given event. Please contact " + "artists@fnal.gov " "for more information.\n"; } } @@ -233,13 +251,15 @@ art::MixHelper::generateEventSequence(size_t const nSecondaries, nOpensOverThreshold_ = {}; switch (readMode_) { case Mode::SEQUENTIAL: + [[fallthrough]]; + case Mode::RANDOM_OFFSET: enSeq.resize(nSecondaries); std::iota(begin(enSeq), end(enSeq), nEventsReadThisFile_); break; case Mode::RANDOM_REPLACE: std::generate_n( std::back_inserter(enSeq), nSecondaries, [this, nEventsInFile] { - return dist_.get()->fireInt(nEventsInFile); + return dist_->fireInt(nEventsInFile); }); std::sort(enSeq.begin(), enSeq.end()); break; @@ -250,7 +270,7 @@ art::MixHelper::generateEventSequence(size_t const nSecondaries, std::generate_n( std::inserter(entries, entries.begin()), nSecondaries - entries.size(), - [this, nEventsInFile] { return dist_.get()->fireInt(nEventsInFile); }); + [this, nEventsInFile] { return dist_->fireInt(nEventsInFile); }); } enSeq.assign(cbegin(entries), cend(entries)); std::sort(begin(enSeq), end(enSeq)); @@ -367,8 +387,9 @@ art::MixHelper::initReadMode_(std::string const& mode) const -> Mode { // These regexes must correspond by index to the valid Mode enumerator // values. - static std::regex const robjs[4]{ + static std::regex const robjs[5]{ std::regex("^seq", std::regex_constants::icase), + std::regex("^randomoffset$", std::regex_constants::icase), std::regex("^random(replace)?$", std::regex_constants::icase), std::regex("^randomlimreplace$", std::regex_constants::icase), std::regex("^randomnoreplace$", std::regex_constants::icase)}; @@ -384,11 +405,25 @@ art::MixHelper::initReadMode_(std::string const& mode) const -> Mode << "Unrecognized value of readMode parameter: \"" << mode << "\". Valid values are:\n" << " sequential,\n" + << " randomOffset,\n" << " randomReplace (random is accepted for reasons of legacy),\n" << " randomLimReplace,\n" << " randomNoReplace.\n"; } +size_t +art::MixHelper::eventOffset_(size_t nEventsInFile) +{ + if (readMode_ == Mode::SEQUENTIAL && eventsToSkip_) { + return eventsToSkip_(); + } + if (readMode_ == Mode::RANDOM_OFFSET and not randomOffsetUsed_) { + randomOffsetUsed_ = true; + return dist_->fireInt(nEventsInFile); + } + return 0; +} + bool art::MixHelper::openNextFile_() { @@ -416,10 +451,8 @@ art::MixHelper::openNextFile_() } filename = *fileIter_; } - nEventsReadThisFile_ = (readMode_ == Mode::SEQUENTIAL && eventsToSkip_) ? - eventsToSkip_() : - 0; // Reset for this file. ioHandle_->openAndReadMetaData(filename, mixOps_); + nEventsReadThisFile_ = eventOffset_(ioHandle_->nEventsInFile()); eventIDIndex_ = buildEventIDIndex(ioHandle_->fileIndex()); auto transMap = buildProductIDTransMap(mixOps_); diff --git a/art/Framework/IO/ProductMix/MixHelper.h b/art/Framework/IO/ProductMix/MixHelper.h index aaaddf132..bd948d4a4 100644 --- a/art/Framework/IO/ProductMix/MixHelper.h +++ b/art/Framework/IO/ProductMix/MixHelper.h @@ -26,6 +26,8 @@ // are: // // sequential -- read the secondary events in order +// randomOffset -- sequential but starting from a random location +// in the file // randomReplace -- random with replacement // randomLimReplace -- events unique within a primary event // randomNoReplace -- events guaranteed to be used once only. @@ -248,10 +250,10 @@ namespace art { public: enum class Mode { SEQUENTIAL = 0, + RANDOM_OFFSET, RANDOM_REPLACE, RANDOM_LIM_REPLACE, - RANDOM_NO_REPLACE, - UNKNOWN + RANDOM_NO_REPLACE }; struct Config { @@ -259,7 +261,23 @@ namespace art { fhicl::Atom compactMissingProducts{ fhicl::Name{"compactMissingProducts"}, false}; - fhicl::Atom readMode{fhicl::Name{"readMode"}, "sequential"}; + fhicl::Atom readMode{ + fhicl::Name{"readMode"}, + fhicl::Comment{R"(The readMode parameter specifies how secondary events +should be chosen from each file. Valid values are: + + - "sequential" (default) + read the secondary events in order + - "randomOffset" + sequential but starting from a random location in the file + - "randomReplace" + random with replacement + - "randomLimReplace" + events unique within a primary event + - "randomNoReplace" + events guaranteed to be used once only +)"}, + "sequential"}; fhicl::Atom coverageFraction{fhicl::Name{"coverageFraction"}, 1.0}; fhicl::Atom wrapFiles{fhicl::Name{"wrapFiles"}, false}; @@ -386,7 +404,9 @@ namespace art { cet::exempt_ptr engine) const; bool consistentRequest_(std::string const& kind_of_engine_to_make, label_t const& engine_label) const; + bool overThreshold_(size_t nSecondaries, size_t nEventsInFile) const; Mode initReadMode_(std::string const& mode) const; + size_t eventOffset_(size_t nEventsInFile); bool openNextFile_(); ProdToProdMapBuilder::ProductIDTransMap buildProductIDTransMap_( @@ -413,6 +433,7 @@ namespace art { EntryNumberSequence shuffledSequence_{}; // RANDOM_NO_REPLACE only. bool haveSubRunMixOps_{false}; bool haveRunMixOps_{false}; + bool randomOffsetUsed_{false}; // RANDOM_OFFSET only. EventIDIndex eventIDIndex_{}; std::unique_ptr ioHandle_{nullptr}; diff --git a/art/Framework/Services/Optional/detail/LinuxMallInfo.h b/art/Framework/Services/Optional/detail/LinuxMallInfo.h index 62aae88ac..eb1d35e93 100644 --- a/art/Framework/Services/Optional/detail/LinuxMallInfo.h +++ b/art/Framework/Services/Optional/detail/LinuxMallInfo.h @@ -36,7 +36,11 @@ namespace art { class LinuxMallInfo { public: +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + // FIXME: The 'mallinfo()' function is deprecated for AL9. LinuxMallInfo() : minfo_(mallinfo()) {} +#pragma GCC diagnostic pop struct mallinfo get() const diff --git a/art/Utilities/ToolConfigTable.h b/art/Utilities/ToolConfigTable.h index 77f20b5d8..e0a96b1aa 100644 --- a/art/Utilities/ToolConfigTable.h +++ b/art/Utilities/ToolConfigTable.h @@ -25,7 +25,7 @@ namespace art { }; }; - template + template class ToolConfigTable : public fhicl::ConfigurationTable { public: ToolConfigTable(fhicl::Name&& name) : fullConfig_{std::move(name)} {} @@ -56,10 +56,9 @@ namespace art { fhicl::TableFragment user; }; - using KeysToIgnore_t = std::conditional_t< - std::is_void::value, - MinimalToolConfig::KeysToIgnore, - fhicl::KeysToIgnore>; + using KeysToIgnore_t = + fhicl::KeysToIgnore; fhicl::Table, KeysToIgnore_t> fullConfig_; cet::exempt_ptr diff --git a/ups/product_deps b/ups/product_deps index 2fd2be229..e07140f9b 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -87,7 +87,7 @@ #> define_pythonpath #################################### parent art -defaultqual e20 +defaultqual e28 #################################### #################################### @@ -248,10 +248,10 @@ perllib product_dir # #################################### product version qual flags -canvas v3_16_04 -hep_concurrency v1_09_02 +canvas v3_17_00 +hep_concurrency v1_10_00 catch v3_3_2 - only_for_build -cetmodules v3_24_01 - only_for_build +cetmodules v3_25_00 - only_for_build range v3_0_12_0 - only_for_build end_product_list #################################### @@ -308,16 +308,6 @@ end_product_list # #################################### qualifier catch hep_concurrency canvas notes -c14:debug c14 c14:debug c14:debug -c14:prof c14 c14:prof c14:prof -c15:debug c15 c15:debug c15:debug -c15:prof c15 c15:prof c15:prof -e20:debug e20 e20:debug e20:debug -e20:prof e20 e20:prof e20:prof -e26:debug e26 e26:debug e26:debug -e26:prof e26 e26:prof e26:prof -e27:debug e27 e27:debug e27:debug -e27:prof e27 e27:prof e27:prof e28:debug e28 e28:debug e28:debug e28:prof e28 e28:prof e28:prof end_qualifier_list