From 6374d895834ddc540bb7d5a8366d621b4f7a8920 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 3 Jan 2025 00:44:51 +0100 Subject: [PATCH 1/3] DPL: drop unneeded ScopedExit helper (#13831) --- Framework/Core/src/DataProcessingDevice.cxx | 2 - Framework/Core/src/ScopedExit.h | 148 -------------------- 2 files changed, 150 deletions(-) delete mode 100644 Framework/Core/src/ScopedExit.h diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index da92c73e1e16a..8a3fbbcf5b2f1 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -52,8 +52,6 @@ #include "Headers/DataHeader.h" #include "Headers/DataHeaderHelpers.h" -#include "ScopedExit.h" - #include #include diff --git a/Framework/Core/src/ScopedExit.h b/Framework/Core/src/ScopedExit.h deleted file mode 100644 index aca3c1a19d8b1..0000000000000 --- a/Framework/Core/src/ScopedExit.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -#include -#include - -namespace o2::framework -{ -namespace detail -{ -// Original from https://github.com/ricab/scope_guard -// which is licensed to public domain -// Type trait determining whether a type is callable with no arguments -template -struct is_noarg_callable_t - : public std::false_type { -}; // in general, false - -template -struct is_noarg_callable_t()())> - : public std::true_type { -}; // only true when call expression valid - -// Type trait determining whether a no-argument callable returns void -template -struct returns_void_t - : public std::is_same()())> { -}; - -/* Type trait determining whether a no-arg callable is nothrow invocable if - required. This is where SG_REQUIRE_NOEXCEPT logic is encapsulated. */ -template -struct is_nothrow_invocable_if_required_t - : public std::is_nothrow_invocable /* Note: _r variants not enough to - confirm void return: any return can be - discarded so all returns are - compatible with void */ -{ -}; - -template -struct and_t : public and_t> { -}; - -template -struct and_t : public std::conditional::type { -}; - -template -struct is_proper_sg_callback_t - : public and_t, - returns_void_t, - is_nothrow_invocable_if_required_t, - std::is_nothrow_destructible> { -}; - -template ::value>::type> -class scope_guard; - -template -detail::scope_guard make_scope_guard(Callback&& callback) noexcept(std::is_nothrow_constructible::value); - -template -class scope_guard final -{ - public: - typedef Callback callback_type; - - scope_guard(scope_guard&& other) noexcept(std::is_nothrow_constructible::value); - - ~scope_guard() noexcept; // highlight noexcept dtor - - void dismiss() noexcept; - - public: - scope_guard() = delete; - scope_guard(const scope_guard&) = delete; - scope_guard& operator=(const scope_guard&) = delete; - scope_guard& operator=(scope_guard&&) = delete; - - private: - explicit scope_guard(Callback&& callback) noexcept(std::is_nothrow_constructible::value); /* - meant for friends only */ - - friend scope_guard make_scope_guard(Callback&&) noexcept(std::is_nothrow_constructible::value); /* - only make_scope_guard can create scope_guards from scratch (i.e. non-move) - */ - - private: - Callback mCallback; - bool mActive; -}; - -} // namespace detail - -using detail::make_scope_guard; // see comment on declaration above - -template -detail::scope_guard::scope_guard(Callback&& callback) noexcept(std::is_nothrow_constructible::value) - : mCallback(std::forward(callback)) /* use () instead of {} because - of DR 1467 (https://is.gd/WHmWuo), which still impacts older compilers - (e.g. GCC 4.x and clang <=3.6, see https://godbolt.org/g/TE9tPJ and - https://is.gd/Tsmh8G) */ - , - mActive{true} -{ -} - -template -detail::scope_guard::~scope_guard() noexcept -{ - if (mActive) { - mCallback(); - } -} - -template -detail::scope_guard::scope_guard(scope_guard&& other) noexcept(std::is_nothrow_constructible::value) - : mCallback(std::forward(other.mCallback)) // idem - , - mActive{std::move(other.mActive)} -{ - other.mActive = false; -} - -template -inline void detail::scope_guard::dismiss() noexcept -{ - mActive = false; -} - -template -inline auto detail::make_scope_guard(Callback&& callback) noexcept(std::is_nothrow_constructible::value) - -> detail::scope_guard -{ - return detail::scope_guard{std::forward(callback)}; -} - -} // namespace o2::framework From f5d37d2676f9bb3d8f77a3c15d86feeab03e73f4 Mon Sep 17 00:00:00 2001 From: shahoian Date: Sat, 28 Dec 2024 00:21:32 +0100 Subject: [PATCH 2/3] ITS/MFT decoder sends vector with certain errors details An output vector is added with information about ChipStat::RepeatingPixel error details (at the moment, other errors may be added). Each element of ErrorMessage is assigned as: errMsg.id = chipID errMsg.errType = ChipStat::RepeatingPixel (at the moment) errMsg.errInfo0 = row errMsg.errInfo1 = col --- .../ITSMFTReconstruction/DecodingStat.h | 8 ++++++ .../ITSMFTReconstruction/RUDecodeData.h | 2 ++ .../ITSMFTReconstruction/RawPixelDecoder.h | 27 ++++++++++++++----- .../src/ITSMFTReconstructionLinkDef.h | 3 +++ .../reconstruction/src/RUDecodeData.cxx | 8 ++++++ .../common/workflow/src/STFDecoderSpec.cxx | 4 ++- 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h index 9a57228ddce1e..012059749d995 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h @@ -290,6 +290,14 @@ struct GBTLinkDecodingStat { ClassDefNV(GBTLinkDecodingStat, 3); }; +struct ErrorMessage { + uint16_t id = -1; + uint16_t errType = 0; + uint16_t errInfo0 = 0; + uint16_t errInfo1 = 0; + ClassDefNV(ErrorMessage, 1) +}; + } // namespace itsmft } // namespace o2 #endif diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RUDecodeData.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RUDecodeData.h index 9e3b1daa00a26..85c6b39fdd1b5 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RUDecodeData.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RUDecodeData.h @@ -54,6 +54,8 @@ struct RUDecodeData { bool ROFRampUpStage = false; // flag that the data come from the ROF rate ramp-up stage GBTCalibData calibData{}; // calibration info from GBT calibration word std::unordered_map> chipErrorsTF{}; // vector of chip decoding errors seen in the given TF + std::vector errMsgVecTF; // Specific errors info collected for sending for the whole TF + const RUInfo* ruInfo = nullptr; RUDecodeData() diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h index 810bff1037513..3a53253da2b42 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h @@ -69,8 +69,8 @@ class RawPixelDecoder final : public PixelReader template void fillCalibData(CalibContainer& calib); - template - void collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors); + template + void collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors, ErrMsgs& errInfos); const RUDecodeData* getRUDecode(int ruSW) const { return mRUEntry[ruSW] < 0 ? nullptr : &mRUDecodeVec[mRUEntry[ruSW]]; } const GBTLink* getGBTLink(int i) const { return i < 0 ? nullptr : &mGBTLinks[i]; } @@ -267,8 +267,8 @@ void RawPixelDecoder::fillCalibData(CalibContainer& calib) ///______________________________________________________________________ template -template -void RawPixelDecoder::collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors) +template +void RawPixelDecoder::collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors, ErrMsgs& errInfos) { for (auto& lnk : mGBTLinks) { if (lnk.gbtErrStatUpadated) { @@ -276,11 +276,24 @@ void RawPixelDecoder::collectDecodingErrors(LinkErrors& linkErrors, Dec lnk.gbtErrStatUpadated = false; } } + size_t nerr = 0, nerrMsg = 0; for (auto& ru : mRUDecodeVec) { - for (const auto& err : ru.chipErrorsTF) { - decErrors.emplace_back(ChipError{err.first, err.second.first, err.second.second}); // id, nerrors, errorFlags + nerr += ru.chipErrorsTF.size(); + nerrMsg += ru.errMsgVecTF.size(); + } + if (nerr || nerrMsg) { + decErrors.reserve(nerr); + errInfos.reserve(nerrMsg); + for (auto& ru : mRUDecodeVec) { + for (const auto& err : ru.chipErrorsTF) { + decErrors.emplace_back(ChipError{err.first, err.second.first, err.second.second}); // id, nerrors, errorFlags + } + for (auto& err : ru.errMsgVecTF) { + errInfos.push_back(err); + } + ru.chipErrorsTF.clear(); + ru.errMsgVecTF.clear(); } - ru.chipErrorsTF.clear(); } } diff --git a/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h b/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h index e6785e4402f37..19f4ca06d0220 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h +++ b/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h @@ -55,4 +55,7 @@ #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::itsmft::ClustererParam < o2::detectors::DetID::ITS>> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::itsmft::ClustererParam < o2::detectors::DetID::MFT>> + ; +#pragma link C++ class o2::itsmft::ErrorMessage + ; +#pragma link C++ class std::vector < o2::itsmft::ErrorMessage> + ; + #endif diff --git a/Detectors/ITSMFT/common/reconstruction/src/RUDecodeData.cxx b/Detectors/ITSMFT/common/reconstruction/src/RUDecodeData.cxx index e81194666fcb8..a9ed2748ec004 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/RUDecodeData.cxx +++ b/Detectors/ITSMFT/common/reconstruction/src/RUDecodeData.cxx @@ -62,6 +62,14 @@ void RUDecodeData::fillChipStatistics(int icab, const ChipPixelData* chipData) auto& chErr = chipErrorsTF[compid]; chErr.first++; chErr.second |= chipData->getErrorFlags(); + + if (chipData->isErrorSet(ChipStat::RepeatingPixel)) { + auto& errMsg = errMsgVecTF.emplace_back(); + errMsg.id = chipData->getChipID(); + errMsg.errType = ChipStat::RepeatingPixel; + errMsg.errInfo0 = chipData->getErrorInfo() & 0xffff; // row + errMsg.errInfo1 = (chipData->getErrorInfo() >> 16) & 0xffff; // row + } } if (action & ChipStat::ErrActDump) { linkHBFToDump[(uint64_t(cableLinkPtr[icab]->subSpec) << 32) + cableLinkPtr[icab]->hbfEntry] = cableLinkPtr[icab]->irHBF.orbit; diff --git a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx index 76bd1ec7454a0..7042cb7433ac5 100644 --- a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx @@ -247,7 +247,8 @@ void STFDecoder::run(ProcessingContext& pc) } auto& linkErrors = pc.outputs().make>(Output{orig, "LinkErrors", 0}); auto& decErrors = pc.outputs().make>(Output{orig, "ChipErrors", 0}); - mDecoder->collectDecodingErrors(linkErrors, decErrors); + auto& errMessages = pc.outputs().make>(Output{orig, "ErrorInfo", 0}); + mDecoder->collectDecodingErrors(linkErrors, decErrors, errMessages); pc.outputs().snapshot(Output{orig, "PHYSTRIG", 0}, mDecoder->getExternalTriggers()); @@ -398,6 +399,7 @@ DataProcessorSpec getSTFDecoderSpec(const STFDecoderInp& inp) outputs.emplace_back(inp.origin, "LinkErrors", 0, Lifetime::Timeframe); outputs.emplace_back(inp.origin, "ChipErrors", 0, Lifetime::Timeframe); + outputs.emplace_back(inp.origin, "ErrorInfo", 0, Lifetime::Timeframe); outputs.emplace_back(inp.origin, "CHIPSSTATUS", 0, Lifetime::Timeframe); if (inp.askSTFDist) { From b60b6c494715e940badf3bc2632c1909185278bd Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:05:56 +0100 Subject: [PATCH 3/3] DPL: use requires rather than enable_if / static_assert --- Framework/Core/include/Framework/ServiceRegistry.h | 9 ++++----- Framework/Core/include/Framework/ServiceRegistryRef.h | 3 ++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Framework/Core/include/Framework/ServiceRegistry.h b/Framework/Core/include/Framework/ServiceRegistry.h index e3fa23294ee78..2236562e6da75 100644 --- a/Framework/Core/include/Framework/ServiceRegistry.h +++ b/Framework/Core/include/Framework/ServiceRegistry.h @@ -267,33 +267,32 @@ struct ServiceRegistry { /// @deprecated old API to be substituted with the ServiceHandle one template + requires std::is_base_of_v void registerService(C* service, Salt salt = ServiceRegistry::globalDeviceSalt()) { // This only works for concrete implementations of the type T. // We need type elision as we do not want to know all the services in // advance - static_assert(std::is_base_of::value == true, - "Registered service is not derived from declared interface"); constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId()}; ServiceRegistry::registerService(typeHash, reinterpret_cast(service), K, salt, typeid(C).name()); } /// @deprecated old API to be substituted with the ServiceHandle one template + requires std::is_base_of_v void registerService(C const* service, Salt salt = ServiceRegistry::globalDeviceSalt()) { // This only works for concrete implementations of the type T. // We need type elision as we do not want to know all the services in // advance - static_assert(std::is_base_of::value == true, - "Registered service is not derived from declared interface"); constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId()}; this->registerService(typeHash, reinterpret_cast(const_cast(service)), K, salt, typeid(C).name()); } /// Check if service of type T is currently active. template - std::enable_if_t == false, bool> active(Salt salt) const + requires(std::is_const_v == false) + bool active(Salt salt) const { constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId()}; if (this->getPos(typeHash, GLOBAL_CONTEXT_SALT) != -1) { diff --git a/Framework/Core/include/Framework/ServiceRegistryRef.h b/Framework/Core/include/Framework/ServiceRegistryRef.h index fa791cc8c4643..910d4e726c080 100644 --- a/Framework/Core/include/Framework/ServiceRegistryRef.h +++ b/Framework/Core/include/Framework/ServiceRegistryRef.h @@ -72,7 +72,8 @@ class ServiceRegistryRef /// Check if service of type T is currently active. template - std::enable_if_t == false, bool> active() const + requires(std::is_const_v == false) + [[nodiscard]] bool active() const { return mRegistry.active(mSalt); }