From c37dab3c19e57259f2c0306bb334395ce7f4ae6b Mon Sep 17 00:00:00 2001 From: Sebastien Ponce <sebastien.ponce@cern.ch> Date: Fri, 8 Oct 2021 11:44:26 +0200 Subject: [PATCH 1/2] Made counters non movable and non copyable This sorts out problems of registration in the Hub that could lead to invalid pointers the main consequences are the dropping of the postfix ++ operator (prefix should be used) and the impossibility to create vectors of Counters. But deque can safely be used instead. --- GaudiExamples/src/CounterEx/CounterAlg.cpp | 24 ++++++++++- .../tests/qmtest/refs/CounterAlg.ref | 33 ++++++++++----- .../qmtest/refs/JSONSink-counters-ref.json | 40 +++++++++++++++++++ GaudiExamples/tests/qmtest/refs/JSONSink.ref | 12 +++++- GaudiKernel/include/Gaudi/Accumulators.h | 12 +++--- GaudiKernel/tests/src/CountersUnitTest.cpp | 2 +- 6 files changed, 102 insertions(+), 21 deletions(-) diff --git a/GaudiExamples/src/CounterEx/CounterAlg.cpp b/GaudiExamples/src/CounterEx/CounterAlg.cpp index 6d2b8ed178..374f73ca18 100644 --- a/GaudiExamples/src/CounterEx/CounterAlg.cpp +++ b/GaudiExamples/src/CounterEx/CounterAlg.cpp @@ -13,6 +13,10 @@ #include "GaudiAlg/Consumer.h" +#include <deque> +#include <fmt/format.h> +#include <mutex> + /// Simple algorithm illustrating the usage of different "counters" struct CounterAlg : Gaudi::Functional::Consumer<void()> { @@ -20,7 +24,7 @@ struct CounterAlg : Gaudi::Functional::Consumer<void()> { void operator()() const override { // update all counters by some fixed values - basic++; + ++basic; avg += 1.5; sig += 2.5; stat += 3.5; @@ -28,6 +32,19 @@ struct CounterAlg : Gaudi::Functional::Consumer<void()> { ++msg; avg_int += 1; avg_noAto += 1.5; + // update counters in the deque, creating new ones for the first 20 events + // and dropping first 10 in the next 10 events + { + // needs to be protected by a mutex in case of multithreaded usage as the + // deque is not thread safe + std::scoped_lock lock( counterDequeMutex ); + if ( counterCount < 20 ) { + counterDeque.emplace_back( this, fmt::format( "DQCounter{}", counterDeque.size() ) ); + ++counterCount; + } + if ( counterCount == 20 && counterDeque.size() > 10 ) { counterDeque.pop_front(); } + for ( auto& c : counterDeque ) ++c; + } } // declare all sorts of counters with default options (double values, atomicity full) @@ -42,6 +59,11 @@ struct CounterAlg : Gaudi::Functional::Consumer<void()> { mutable Gaudi::Accumulators::AveragingCounter<unsigned int> avg_int{this, "AverageInteger"}; mutable Gaudi::Accumulators::AveragingCounter<double, Gaudi::Accumulators::atomicity::none> avg_noAto{ this, "AverageNonAtomic"}; + + // test set of counters stored in a deque + mutable int counterCount{0}; + mutable std::deque<Gaudi::Accumulators::Counter<>> counterDeque; + mutable std::mutex counterDequeMutex; }; DECLARE_COMPONENT( CounterAlg ) diff --git a/GaudiExamples/tests/qmtest/refs/CounterAlg.ref b/GaudiExamples/tests/qmtest/refs/CounterAlg.ref index d20e65b734..1097955129 100644 --- a/GaudiExamples/tests/qmtest/refs/CounterAlg.ref +++ b/GaudiExamples/tests/qmtest/refs/CounterAlg.ref @@ -3,8 +3,8 @@ # <-- End of file '/home/sponce/dev4/Gaudi/GaudiExamples/options/CounterAlg.py' ApplicationMgr SUCCESS ==================================================================================================================================== - Welcome to ApplicationMgr (GaudiCoreSvc v34r0) - running on lblhcbpr11.cern.ch on Mon Aug 10 10:50:10 2020 + Welcome to ApplicationMgr (GaudiCoreSvc v36r1) + running on lblhcbpr11.cern.ch on Tue Oct 5 08:42:36 2021 ==================================================================================================================================== ApplicationMgr INFO Application Manager Configured successfully EventLoopMgr WARNING Unable to locate service "EventSelector" @@ -16,15 +16,26 @@ CounterAlg INFO Super nice message, max 5 times CounterAlg INFO Super nice message, max 5 times CounterAlg INFO Super nice message, max 5 times CounterAlg INFO Suppressing message: 'Super nice message, max 5 times' -CounterAlg INFO Number of counters : 8 - | "CounterAlg/Super nice message, max 5 times" | 500 | - | "CounterAlg/Stat" | 500 | 1750 | 3.5000 | 0.0000 | 3.5000 | 3.5000 | - | "CounterAlg/Sigma" | 500 | 1250 | 2.5000 | 0.0000 | - | "CounterAlg/Binomial" | 500 | 500 |( 100.0000 +- 0.000000)% | - | "CounterAlg/Basic" | 500 | - | "CounterAlg/AverageNonAtomic" | 500 | 750 | 1.5000 | - | "CounterAlg/AverageInteger" | 500 | 500 | 1.0000 | - | "CounterAlg/Average" | 500 | 750 | 1.5000 | +CounterAlg INFO Number of counters : 18 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "Average" | 500 | 750 | 1.5000 | + | "AverageInteger" | 500 | 500 | 1.0000 | + | "AverageNonAtomic" | 500 | 750 | 1.5000 | + | "Basic" | 500 | + |*"Binomial" | 500 | 500 |( 100.0000 +- 0.000000)% | + | "DQCounter10" | 490 | + | "DQCounter11" | 489 | + | "DQCounter12" | 488 | + | "DQCounter13" | 487 | + | "DQCounter14" | 486 | + | "DQCounter15" | 485 | + | "DQCounter16" | 484 | + | "DQCounter17" | 483 | + | "DQCounter18" | 482 | + | "DQCounter19" | 481 | + | "Sigma" | 500 | 1250 | 2.5000 | 0.0000 | + | "Stat" | 500 | 1750 | 3.5000 | 0.0000 | 3.5000 | 3.5000 | + | "Super nice message, max 5 times" | 500 | ApplicationMgr INFO Application Manager Stopped successfully EventLoopMgr INFO Histograms converted successfully according to request. ApplicationMgr INFO Application Manager Finalized successfully diff --git a/GaudiExamples/tests/qmtest/refs/JSONSink-counters-ref.json b/GaudiExamples/tests/qmtest/refs/JSONSink-counters-ref.json index fe292a40e9..71307c59dd 100644 --- a/GaudiExamples/tests/qmtest/refs/JSONSink-counters-ref.json +++ b/GaudiExamples/tests/qmtest/refs/JSONSink-counters-ref.json @@ -30,6 +30,46 @@ "nTrueEntries": 500, "type": "counter:BinomialCounter:d" }, + "DQCounter10": { + "nEntries": 490, + "type": "counter:Counter:m" + }, + "DQCounter11": { + "nEntries": 489, + "type": "counter:Counter:m" + }, + "DQCounter12": { + "nEntries": 488, + "type": "counter:Counter:m" + }, + "DQCounter13": { + "nEntries": 487, + "type": "counter:Counter:m" + }, + "DQCounter14": { + "nEntries": 486, + "type": "counter:Counter:m" + }, + "DQCounter15": { + "nEntries": 485, + "type": "counter:Counter:m" + }, + "DQCounter16": { + "nEntries": 484, + "type": "counter:Counter:m" + }, + "DQCounter17": { + "nEntries": 483, + "type": "counter:Counter:m" + }, + "DQCounter18": { + "nEntries": 482, + "type": "counter:Counter:m" + }, + "DQCounter19": { + "nEntries": 481, + "type": "counter:Counter:m" + }, "Sigma": { "mean": 2.5, "nEntries": 500, diff --git a/GaudiExamples/tests/qmtest/refs/JSONSink.ref b/GaudiExamples/tests/qmtest/refs/JSONSink.ref index dfd1048891..2e5ceae1f5 100644 --- a/GaudiExamples/tests/qmtest/refs/JSONSink.ref +++ b/GaudiExamples/tests/qmtest/refs/JSONSink.ref @@ -19,13 +19,23 @@ CounterAlg INFO Super nice message, max 5 times CounterAlg INFO Super nice message, max 5 times CounterAlg INFO Suppressing message: 'Super nice message, max 5 times' Gaudi::Monitori... INFO Writing counters to JSON file counters.json -CounterAlg INFO Number of counters : 8 +CounterAlg INFO Number of counters : 18 | Counter | # | sum | mean/eff^* | rms/err^* | min | max | | "Average" | 500 | 750 | 1.5000 | | "AverageInteger" | 500 | 500 | 1.0000 | | "AverageNonAtomic" | 500 | 750 | 1.5000 | | "Basic" | 500 | |*"Binomial" | 500 | 500 |( 100.0000 +- 0.000000)% | + | "DQCounter10" | 490 | + | "DQCounter11" | 489 | + | "DQCounter12" | 488 | + | "DQCounter13" | 487 | + | "DQCounter14" | 486 | + | "DQCounter15" | 485 | + | "DQCounter16" | 484 | + | "DQCounter17" | 483 | + | "DQCounter18" | 482 | + | "DQCounter19" | 481 | | "Sigma" | 500 | 1250 | 2.5000 | 0.0000 | | "Stat" | 500 | 1750 | 3.5000 | 0.0000 | 3.5000 | 3.5000 | | "Super nice message, max 5 times" | 500 | diff --git a/GaudiKernel/include/Gaudi/Accumulators.h b/GaudiKernel/include/Gaudi/Accumulators.h index e133916f84..ef6aaf7f08 100644 --- a/GaudiKernel/include/Gaudi/Accumulators.h +++ b/GaudiKernel/include/Gaudi/Accumulators.h @@ -861,6 +861,7 @@ namespace Gaudi::Accumulators { /** * An empty ancester of all counters that provides a buffer method that returns a buffer on itself * Also registers the counter to its owner, with default type "counter" + * Due to this registration, move semantic is disabled. But copy semantic remains. * @see Gaudi::Accumulators for detailed documentation */ template <atomicity Atomicity, template <atomicity Ato, typename... Int> class Accumulator, typename... Args> @@ -875,8 +876,8 @@ namespace Gaudi::Accumulators { template <typename OWNER> BufferableCounter( OWNER* o, std::string const& name ) : BufferableCounter( o, name, "counter" ) {} Buffer<Accumulator, Atomicity, Args...> buffer() { return {*this}; } - BufferableCounter( BufferableCounter const& ) = default; - BufferableCounter& operator=( BufferableCounter const& ) = default; + BufferableCounter( BufferableCounter const& ) = delete; + BufferableCounter& operator=( BufferableCounter const& ) = delete; ~BufferableCounter() { if ( m_monitoringHub ) { m_monitoringHub->removeEntity( *this ); } } @@ -897,11 +898,6 @@ namespace Gaudi::Accumulators { Counter( OWNER* o, std::string const& name ) : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>( o, name, typeString ) {} Counter& operator++() { return ( *this ) += 1; } - Counter operator++( int ) { - auto copy = *this; - ++( *this ); - return copy; - } Counter& operator+=( const Arithmetic v ) { BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::operator+=( v ); return *this; @@ -1130,6 +1126,8 @@ namespace Gaudi::Accumulators { if ( by ) log(); return *this; } + MsgCounter( MsgCounter const& ) = delete; + MsgCounter& operator=( MsgCounter const& ) = delete; ~MsgCounter() { m_monitoringHub.removeEntity( *this ); } template <typename stream> stream& printImpl( stream& o, bool tableFormat ) const { diff --git a/GaudiKernel/tests/src/CountersUnitTest.cpp b/GaudiKernel/tests/src/CountersUnitTest.cpp index 07d3dd8c15..515eaf7ec8 100644 --- a/GaudiKernel/tests/src/CountersUnitTest.cpp +++ b/GaudiKernel/tests/src/CountersUnitTest.cpp @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE( test_basic_counter, *utf::tolerance( 1e-14 ) ) { Counter<atomicity::full> c; BOOST_TEST( c.nEntries() == 0 ); BOOST_TEST( ( ++c ).nEntries() == 1 ); - BOOST_TEST( ( c++ ).nEntries() == 1 ); + ++c; BOOST_TEST( c.nEntries() == 2 ); c += 10; -- GitLab From e865538f47cdd28ee8309045510a0b675f6fb3b0 Mon Sep 17 00:00:00 2001 From: Marco Clemencic <marco.clemencic@cern.ch> Date: Tue, 16 Nov 2021 15:53:37 +0100 Subject: [PATCH 2/2] fix formatting --- GaudiExamples/src/CounterEx/CounterAlg.cpp | 18 +-- GaudiKernel/include/Gaudi/Accumulators.h | 141 +++++++++++---------- GaudiKernel/tests/src/CountersUnitTest.cpp | 8 +- 3 files changed, 85 insertions(+), 82 deletions(-) diff --git a/GaudiExamples/src/CounterEx/CounterAlg.cpp b/GaudiExamples/src/CounterEx/CounterAlg.cpp index 374f73ca18..613ab63f8d 100644 --- a/GaudiExamples/src/CounterEx/CounterAlg.cpp +++ b/GaudiExamples/src/CounterEx/CounterAlg.cpp @@ -48,20 +48,20 @@ struct CounterAlg : Gaudi::Functional::Consumer<void()> { } // declare all sorts of counters with default options (double values, atomicity full) - mutable Gaudi::Accumulators::Counter<> basic{this, "Basic"}; - mutable Gaudi::Accumulators::AveragingCounter<> avg{this, "Average"}; - mutable Gaudi::Accumulators::SigmaCounter<> sig{this, "Sigma"}; - mutable Gaudi::Accumulators::StatCounter<> stat{this, "Stat"}; - mutable Gaudi::Accumulators::BinomialCounter<> binomial{this, "Binomial"}; - mutable Gaudi::Accumulators::MsgCounter<MSG::INFO> msg{this, "Super nice message, max 5 times", 5}; + mutable Gaudi::Accumulators::Counter<> basic{ this, "Basic" }; + mutable Gaudi::Accumulators::AveragingCounter<> avg{ this, "Average" }; + mutable Gaudi::Accumulators::SigmaCounter<> sig{ this, "Sigma" }; + mutable Gaudi::Accumulators::StatCounter<> stat{ this, "Stat" }; + mutable Gaudi::Accumulators::BinomialCounter<> binomial{ this, "Binomial" }; + mutable Gaudi::Accumulators::MsgCounter<MSG::INFO> msg{ this, "Super nice message, max 5 times", 5 }; // test change of some template parameters - mutable Gaudi::Accumulators::AveragingCounter<unsigned int> avg_int{this, "AverageInteger"}; + mutable Gaudi::Accumulators::AveragingCounter<unsigned int> avg_int{ this, "AverageInteger" }; mutable Gaudi::Accumulators::AveragingCounter<double, Gaudi::Accumulators::atomicity::none> avg_noAto{ - this, "AverageNonAtomic"}; + this, "AverageNonAtomic" }; // test set of counters stored in a deque - mutable int counterCount{0}; + mutable int counterCount{ 0 }; mutable std::deque<Gaudi::Accumulators::Counter<>> counterDeque; mutable std::mutex counterDequeMutex; }; diff --git a/GaudiKernel/include/Gaudi/Accumulators.h b/GaudiKernel/include/Gaudi/Accumulators.h index ef6aaf7f08..595a99cadc 100644 --- a/GaudiKernel/include/Gaudi/Accumulators.h +++ b/GaudiKernel/include/Gaudi/Accumulators.h @@ -226,7 +226,7 @@ namespace nlohmann { struct adl_serializer<std::chrono::duration<Rep, Period>> { static void to_json( json& j, const std::chrono::duration<Rep, Period>& d ) { j = d.count(); } static void from_json( const json& j, std::chrono::duration<Rep, Period>& d ) { - d = std::chrono::duration<Rep, Period>{j.get<Rep>()}; + d = std::chrono::duration<Rep, Period>{ j.get<Rep>() }; } }; } // namespace nlohmann @@ -477,7 +477,7 @@ namespace Gaudi::Accumulators { } private: - typename ValueHandler::InternalType m_value{ValueHandler::DefaultValue()}; + typename ValueHandler::InternalType m_value{ ValueHandler::DefaultValue() }; }; /** @@ -530,7 +530,7 @@ namespace Gaudi::Accumulators { static InternalType extractJSONDataHelper( const nlohmann::json& j, typename Bases<Atomicity, Arithmetic>::JSONStringEntriesType... entries ) { - return {Bases<Atomicity, Arithmetic>::extractJSONData( j, entries )...}; + return { Bases<Atomicity, Arithmetic>::extractJSONData( j, entries )... }; } }; @@ -668,7 +668,7 @@ namespace Gaudi::Accumulators { template <typename Result = fp_result_type<Arithmetic>> auto efficiency() const { auto nbEntries = nEntries(); - if ( 1 > nbEntries ) return Result{-1}; + if ( 1 > nbEntries ) return Result{ -1 }; return static_cast<Result>( this->nTrueEntries() ) / nbEntries; } auto eff() const { return efficiency(); } @@ -680,7 +680,7 @@ namespace Gaudi::Accumulators { using Gaudi::Accumulators::sqrt; using std::sqrt; auto nbEntries = nEntries(); - if ( 1 > nbEntries ) return Result{-1}; + if ( 1 > nbEntries ) return Result{ -1 }; return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries; } auto effErr() const { return efficiencyErr(); } @@ -691,9 +691,10 @@ namespace Gaudi::Accumulators { }; BinomialAccumulator& operator+=( binomial_t b ) { assert( b.nPass <= b.nTotal ); - TrueAccumulator<Atomicity, bool>::mergeAndReset( TrueAccumulator<atomicity::none, bool>{std::in_place, b.nPass} ); + TrueAccumulator<Atomicity, bool>::mergeAndReset( + TrueAccumulator<atomicity::none, bool>{ std::in_place, b.nPass } ); FalseAccumulator<Atomicity, bool>::mergeAndReset( - FalseAccumulator<atomicity::none, bool>{std::in_place, b.nTotal - b.nPass} ); + FalseAccumulator<atomicity::none, bool>{ std::in_place, b.nTotal - b.nPass } ); return *this; } }; @@ -762,7 +763,7 @@ namespace Gaudi::Accumulators { using Gaudi::Accumulators::sqrt; using std::sqrt; Result v = biased_sample_variance(); - return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v ) ); + return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v ) ); } [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const { return standard_deviation(); @@ -777,7 +778,7 @@ namespace Gaudi::Accumulators { using Gaudi::Accumulators::sqrt; using std::sqrt; Result v = biased_sample_variance(); - return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) ); + return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) ); } }; @@ -831,7 +832,7 @@ namespace Gaudi::Accumulators { // add tag to printout template <typename stream> stream& printImpl( stream& s, std::string_view tag ) const { - s << boost::format{" | %|-48.48s|%|50t|"} % ( std::string{'\"'}.append( tag ).append( "\"" ) ); + s << boost::format{ " | %|-48.48s|%|50t|" } % ( std::string{ '\"' }.append( tag ).append( "\"" ) ); return print( s, true ); } /// prints the counter to a stream @@ -875,7 +876,7 @@ namespace Gaudi::Accumulators { } template <typename OWNER> BufferableCounter( OWNER* o, std::string const& name ) : BufferableCounter( o, name, "counter" ) {} - Buffer<Accumulator, Atomicity, Args...> buffer() { return {*this}; } + Buffer<Accumulator, Atomicity, Args...> buffer() { return { *this }; } BufferableCounter( BufferableCounter const& ) = delete; BufferableCounter& operator=( BufferableCounter const& ) = delete; ~BufferableCounter() { @@ -883,7 +884,7 @@ namespace Gaudi::Accumulators { } private: - Monitoring::Hub* m_monitoringHub{nullptr}; + Monitoring::Hub* m_monitoringHub{ nullptr }; }; /** @@ -892,7 +893,7 @@ namespace Gaudi::Accumulators { */ template <atomicity Atomicity = atomicity::full, typename Arithmetic = unsigned long> struct Counter : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic> { - inline static const std::string typeString{std::string{"counter:Counter:"} + typeid( unsigned long ).name()}; + inline static const std::string typeString{ std::string{ "counter:Counter:" } + typeid( unsigned long ).name() }; using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::BufferableCounter; template <typename OWNER> Counter( OWNER* o, std::string const& name ) @@ -908,7 +909,7 @@ namespace Gaudi::Accumulators { stream& printImpl( stream& o, bool tableFormat ) const { // Avoid printing empty counters in non DEBUG mode auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" ); - return o << boost::format{fmt} % this->nEntries(); + return o << boost::format{ fmt } % this->nEntries(); } std::ostream& print( std::ostream& o, bool tableFormat = false ) const override { @@ -917,10 +918,10 @@ namespace Gaudi::Accumulators { MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); } bool toBePrinted() const override { return this->nEntries() > 0; } virtual nlohmann::json toJSON() const override { - return {{"type", typeString}, {"empty", this->nEntries() == 0}, {"nEntries", this->nEntries()}}; + return { { "type", typeString }, { "empty", this->nEntries() == 0 }, { "nEntries", this->nEntries() } }; } static Counter fromJSON( const nlohmann::json& j ) { - return CountAccumulator<Atomicity, int>::extractJSONData( j, {"nEntries"} ); + return CountAccumulator<Atomicity, int>::extractJSONData( j, { "nEntries" } ); } }; @@ -930,7 +931,8 @@ namespace Gaudi::Accumulators { */ template <typename Arithmetic = double, atomicity Atomicity = atomicity::full> struct AveragingCounter : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic> { - inline static const std::string typeString{std::string{"counter:AveragingCounter:"} + typeid( Arithmetic ).name()}; + inline static const std::string typeString{ std::string{ "counter:AveragingCounter:" } + + typeid( Arithmetic ).name() }; using BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>::BufferableCounter; template <typename OWNER> AveragingCounter( OWNER* o, std::string const& name ) @@ -940,7 +942,7 @@ namespace Gaudi::Accumulators { template <typename stream> stream& printImpl( stream& o, bool tableFormat ) const { auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" ); - return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean(); + return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean(); } std::ostream& print( std::ostream& o, bool tableFormat = false ) const override { @@ -950,14 +952,14 @@ namespace Gaudi::Accumulators { bool toBePrinted() const override { return this->nEntries() > 0; } virtual nlohmann::json toJSON() const override { - return {{"type", typeString}, - {"empty", this->nEntries() == 0}, - {"nEntries", this->nEntries()}, - {"sum", this->sum()}, - {"mean", this->mean()}}; + return { { "type", typeString }, + { "empty", this->nEntries() == 0 }, + { "nEntries", this->nEntries() }, + { "sum", this->sum() }, + { "mean", this->mean() } }; } static AveragingCounter fromJSON( const nlohmann::json& j ) { - return AveragingAccumulator<Atomicity, Arithmetic>::extractJSONData( j, {"nEntries", "sum"} ); + return AveragingAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nEntries", "sum" } ); } }; template <typename Arithmetic = double, atomicity Atomicity = atomicity::full> @@ -969,7 +971,7 @@ namespace Gaudi::Accumulators { */ template <typename Arithmetic = double, atomicity Atomicity = atomicity::full> struct SigmaCounter : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic> { - inline static const std::string typeString{std::string{"counter:SigmaCounter:"} + typeid( Arithmetic ).name()}; + inline static const std::string typeString{ std::string{ "counter:SigmaCounter:" } + typeid( Arithmetic ).name() }; using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::BufferableCounter; template <typename OWNER> SigmaCounter( OWNER* o, std::string const& name ) @@ -980,7 +982,7 @@ namespace Gaudi::Accumulators { stream& printImpl( stream& o, bool tableFormat ) const { auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" ); - return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation(); + return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation(); } std::ostream& print( std::ostream& o, bool tableFormat = false ) const override { @@ -989,16 +991,16 @@ namespace Gaudi::Accumulators { MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); } bool toBePrinted() const override { return this->nEntries() > 0; } virtual nlohmann::json toJSON() const override { - return {{"type", typeString}, - {"empty", this->nEntries() == 0}, - {"nEntries", this->nEntries()}, - {"sum", this->sum()}, - {"mean", this->mean()}, - {"sum2", this->sum2()}, - {"standard_deviation", this->standard_deviation()}}; + return { { "type", typeString }, + { "empty", this->nEntries() == 0 }, + { "nEntries", this->nEntries() }, + { "sum", this->sum() }, + { "mean", this->mean() }, + { "sum2", this->sum2() }, + { "standard_deviation", this->standard_deviation() } }; } static SigmaCounter fromJSON( const nlohmann::json& j ) { - return SigmaAccumulator<Atomicity, Arithmetic>::extractJSONData( j, {{"nEntries", "sum"}, "sum2"} ); + return SigmaAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { { "nEntries", "sum" }, "sum2" } ); } }; @@ -1008,7 +1010,7 @@ namespace Gaudi::Accumulators { */ template <typename Arithmetic = double, atomicity Atomicity = atomicity::full> struct StatCounter : BufferableCounter<Atomicity, StatAccumulator, Arithmetic> { - inline static const std::string typeString{std::string{"counter:StatCounter:"} + typeid( Arithmetic ).name()}; + inline static const std::string typeString{ std::string{ "counter:StatCounter:" } + typeid( Arithmetic ).name() }; using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::BufferableCounter; template <typename OWNER> StatCounter( OWNER* o, std::string const& name ) @@ -1019,7 +1021,7 @@ namespace Gaudi::Accumulators { stream& printImpl( stream& o, bool tableFormat ) const { auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" ); - return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() % + return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() % this->min() % this->max(); } @@ -1029,19 +1031,19 @@ namespace Gaudi::Accumulators { MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); } bool toBePrinted() const override { return this->nEntries() > 0; } virtual nlohmann::json toJSON() const override { - return {{"type", typeString}, - {"empty", this->nEntries() == 0}, - {"nEntries", this->nEntries()}, - {"sum", this->sum()}, - {"mean", this->mean()}, - {"sum2", this->sum2()}, - {"standard_deviation", this->standard_deviation()}, - {"min", this->min()}, - {"max", this->max()}}; + return { { "type", typeString }, + { "empty", this->nEntries() == 0 }, + { "nEntries", this->nEntries() }, + { "sum", this->sum() }, + { "mean", this->mean() }, + { "sum2", this->sum2() }, + { "standard_deviation", this->standard_deviation() }, + { "min", this->min() }, + { "max", this->max() } }; } static StatCounter fromJSON( const nlohmann::json& j ) { - return StatAccumulator<Atomicity, Arithmetic>::extractJSONData( j, - {{{"nEntries", "sum"}, "sum2"}, "min", "max"} ); + return StatAccumulator<Atomicity, Arithmetic>::extractJSONData( + j, { { { "nEntries", "sum" }, "sum2" }, "min", "max" } ); } }; @@ -1051,7 +1053,8 @@ namespace Gaudi::Accumulators { */ template <typename Arithmetic = double, atomicity Atomicity = atomicity::full> struct BinomialCounter : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic> { - inline static const std::string typeString{std::string{"counter:BinomialCounter:"} + typeid( Arithmetic ).name()}; + inline static const std::string typeString{ std::string{ "counter:BinomialCounter:" } + + typeid( Arithmetic ).name() }; using BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>::BufferableCounter; template <typename OWNER> BinomialCounter( OWNER* o, std::string const& name ) @@ -1061,7 +1064,7 @@ namespace Gaudi::Accumulators { stream& printImpl( stream& o, bool tableFormat ) const { auto fmt = ( tableFormat ? "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |" : "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" ); - return o << boost::format{fmt} % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) % + return o << boost::format{ fmt } % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) % ( this->efficiencyErr() * 100 ); } @@ -1073,7 +1076,7 @@ namespace Gaudi::Accumulators { template <typename stream> stream& printImpl( stream& o, std::string_view tag ) const { // override default print to add a '*' in from of the name - o << boost::format{" |*%|-48.48s|%|50t|"} % ( std::string{"\""}.append( tag ).append( "\"" ) ); + o << boost::format{ " |*%|-48.48s|%|50t|" } % ( std::string{ "\"" }.append( tag ).append( "\"" ) ); return print( o, true ); } /// prints the counter to a stream in table format, with the given tag @@ -1081,16 +1084,16 @@ namespace Gaudi::Accumulators { MsgStream& print( MsgStream& o, std::string_view tag ) const override { return printImpl( o, tag ); } bool toBePrinted() const override { return this->nEntries() > 0; } virtual nlohmann::json toJSON() const override { - return {{"type", typeString}, - {"empty", this->nEntries() == 0}, - {"nEntries", this->nTrueEntries() + this->nFalseEntries()}, - {"nTrueEntries", this->nTrueEntries()}, - {"nFalseEntries", this->nFalseEntries()}, - {"efficiency", this->efficiency()}, - {"efficiencyErr", this->efficiencyErr()}}; + return { { "type", typeString }, + { "empty", this->nEntries() == 0 }, + { "nEntries", this->nTrueEntries() + this->nFalseEntries() }, + { "nTrueEntries", this->nTrueEntries() }, + { "nFalseEntries", this->nFalseEntries() }, + { "efficiency", this->efficiency() }, + { "efficiencyErr", this->efficiencyErr() } }; } static BinomialCounter fromJSON( const nlohmann::json& j ) { - return BinomialAccumulator<Atomicity, Arithmetic>::extractJSONData( j, {"nTrueEntries", "nFalseEntries"} ); + return BinomialAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nTrueEntries", "nFalseEntries" } ); } }; @@ -1111,10 +1114,10 @@ namespace Gaudi::Accumulators { template <MSG::Level level, atomicity Atomicity = atomicity::full> class MsgCounter : public PrintableCounter, public details::MsgCounter::MsgAccumulator<Atomicity> { public: - inline static const std::string typeString{"counter:MsgCounter"}; + inline static const std::string typeString{ "counter:MsgCounter" }; template <typename OWNER> MsgCounter( OWNER* o, std::string const& ms, int nMax = 10 ) - : m_monitoringHub{o->serviceLocator()->monitoringHub()}, logger( o ), msg( ms ), max( nMax ) { + : m_monitoringHub{ o->serviceLocator()->monitoringHub() }, logger( o ), msg( ms ), max( nMax ) { m_monitoringHub.registerEntity( o->name(), std::move( ms ), typeString, *this ); } MsgCounter& operator++() { @@ -1131,29 +1134,29 @@ namespace Gaudi::Accumulators { ~MsgCounter() { m_monitoringHub.removeEntity( *this ); } template <typename stream> stream& printImpl( stream& o, bool tableFormat ) const { - return o << boost::format{tableFormat ? "|%|10d| |" : "#=%|-7lu|"} % this->value(); + return o << boost::format{ tableFormat ? "|%|10d| |" : "#=%|-7lu|" } % this->value(); } using PrintableCounter::print; std::ostream& print( std::ostream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); } MsgStream& print( MsgStream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); } bool toBePrinted() const override { return this->value() > 0; } virtual nlohmann::json toJSON() const override { - return {{"type", typeString}, - {"empty", this->value() == 0}, - {"nEntries", this->value()}, - {"level", level}, - {"max", max}, - {"msg", msg}}; + return { { "type", typeString }, + { "empty", this->value() == 0 }, + { "nEntries", this->value() }, + { "level", level }, + { "max", max }, + { "msg", msg } }; } static MsgCounter fromJSON( const nlohmann::json& j ) { - MsgCounter c = MsgCounter::extractJSONData( j, {"nEntries"} ); + MsgCounter c = MsgCounter::extractJSONData( j, { "nEntries" } ); c.msg = j.at( "msg" ).get<std::string>(); c.max = j.at( "max" ).get<unsigned long>(); } private: Monitoring::Hub& m_monitoringHub; - const CommonMessagingBase* logger{nullptr}; + const CommonMessagingBase* logger{ nullptr }; std::string msg; unsigned long max; void log() { diff --git a/GaudiKernel/tests/src/CountersUnitTest.cpp b/GaudiKernel/tests/src/CountersUnitTest.cpp index 515eaf7ec8..89a0683cae 100644 --- a/GaudiKernel/tests/src/CountersUnitTest.cpp +++ b/GaudiKernel/tests/src/CountersUnitTest.cpp @@ -166,9 +166,9 @@ BOOST_AUTO_TEST_CASE( test_bulk_increment_with_Binomialcounter, *utf::tolerance( BinomialCounter<> bin; // bin += { .nPass = 4, .nTotal = 10 }; // C++20 only... - bin += {4, 10}; - bin += {1, 9}; - bin += {0, 1}; + bin += { 4, 10 }; + bin += { 1, 9 }; + bin += { 0, 1 }; BOOST_TEST( bin.nEntries() == 20 ); BOOST_TEST( bin.nTrueEntries() == 5 ); @@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE( test_StatEntity_binomial, } BOOST_AUTO_TEST_CASE( test_StatEntity_direct_set, *utf::tolerance( 1e-14 ) ) { - StatEntity sb{3, 14, 70, 3, 6}; + StatEntity sb{ 3, 14, 70, 3, 6 }; BOOST_TEST( sb.nEntries() == 3 ); BOOST_TEST( sb.sum() == 14 ); -- GitLab