The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
Accumulators.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11
12#pragma once
13
14#include <Gaudi/MonitoringHub.h>
15
16#include <chrono>
17
19 template <class Rep, class Period>
20 auto sqrt( std::chrono::duration<Rep, Period> d );
21 template <class Rep1, class Rep2, class Period>
22 auto operator*( const std::chrono::duration<Rep1, Period>& lhs, const std::chrono::duration<Rep2, Period>& rhs );
23} // namespace Gaudi::Accumulators
24
25// Fix builds with GCC 11 and C++20
26#if defined( __GNUC__ ) && ( __GNUC__ == 11 ) && !defined( __clang__ )
27namespace std::chrono {
28 template <typename Ratio>
29 static constexpr const char* suffix( const Ratio& ) {
30 if constexpr ( std::ratio_equal_v<Ratio, std::ratio<1>> ) {
31 return "s";
32 } else if constexpr ( std::ratio_equal_v<Ratio, std::milli> ) {
33 return "ms";
34 } else if constexpr ( std::ratio_equal_v<Ratio, std::micro> ) {
35 return "us";
36 } else if constexpr ( std::ratio_equal_v<Ratio, std::nano> ) {
37 return "ns";
38 } else if constexpr ( std::ratio_equal_v<Ratio, std::ratio<60>> ) {
39 return "m";
40 } else if constexpr ( std::ratio_equal_v<Ratio, std::ratio<3600>> ) {
41 return "h";
42 }
43 return "";
44 }
45 template <class Rep, class Period>
46 std::ostream& operator<<( std::ostream& os, const std::chrono::duration<Rep, Period>& d ) {
47 return os << d.count() << suffix( Period{} );
48 }
49} // namespace std::chrono
50#endif
51
233
234#include <atomic>
235#include <boost/format.hpp>
236#include <cmath>
237#include <iostream>
238#include <limits>
239#include <nlohmann/json.hpp>
240#include <sstream>
241#include <tuple>
242#include <type_traits>
243#include <utility>
244
247
248// Json serialization for std::chrono::duration
249namespace nlohmann {
250 template <class Rep, class Period>
251 struct adl_serializer<std::chrono::duration<Rep, Period>> {
252 static void to_json( json& j, const std::chrono::duration<Rep, Period>& d ) { j = d.count(); }
253 static void from_json( const json& j, std::chrono::duration<Rep, Period>& d ) {
254 d = std::chrono::duration<Rep, Period>{ j.get<Rep>() };
255 }
256 };
257} // namespace nlohmann
258
259namespace Gaudi::Accumulators {
260
262 enum class atomicity { none, full };
263
265 template <class T>
266 auto sqrt( T d );
267
271 template <typename T, T N>
272 struct Constant {
273 template <typename U>
274 constexpr T operator()( U&& ) const noexcept {
275 return N;
276 }
277 };
278
282 struct Identity {
283 template <typename U>
284 constexpr decltype( auto ) operator()( U&& v ) const noexcept {
285 return std::forward<U>( v );
286 }
287 };
288
292 struct Square {
293 template <typename U>
294 constexpr decltype( auto ) operator()( U&& v ) const noexcept {
295 return v * v;
296 }
297 };
298
302 template <typename Arithmetic, typename Result = double>
303 using fp_result_type = std::conditional_t<std::is_integral_v<Arithmetic>, Result, Arithmetic>;
304
308 template <typename Arithmetic, atomicity Atomicity>
310
314 template <typename Arithmetic>
315 struct BaseValueHandler<Arithmetic, atomicity::none> {
316 using OutputType = Arithmetic;
317 using InternalType = Arithmetic;
318 static constexpr OutputType getValue( const InternalType& v ) noexcept { return v; }
319 static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return std::exchange( v, newv ); }
320 };
321
325 template <typename Arithmetic>
326 struct BaseValueHandler<Arithmetic, atomicity::full> {
327 using OutputType = Arithmetic;
328 using InternalType = std::atomic<Arithmetic>;
329 static constexpr OutputType getValue( const InternalType& v ) noexcept {
330 return v.load( std::memory_order_relaxed );
331 }
332 static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return v.exchange( newv ); }
333 };
334
339 template <typename Arithmetic, atomicity Atomicity>
340 struct Adder;
341
345 template <typename Arithmetic>
346 struct Adder<Arithmetic, atomicity::none> : BaseValueHandler<Arithmetic, atomicity::none> {
349 static constexpr OutputType DefaultValue() { return Arithmetic{}; }
350 static void merge( InternalType& a, Arithmetic b ) noexcept { a += b; }
351 };
352
356 template <typename AtomicType, typename Arithmetic>
357 void fetch_add( AtomicType& atVar, Arithmetic value ) {
358 if constexpr ( requires { atVar.fetch_add( value, std::memory_order_relaxed ); } ) {
359 atVar.fetch_add( value, std::memory_order_relaxed );
360 } else {
362 while ( !atVar.compare_exchange_weak( current, current + value ) )
363 ;
364 }
365 }
366
370 template <typename Arithmetic>
371 struct Adder<Arithmetic, atomicity::full> : BaseValueHandler<Arithmetic, atomicity::full> {
374 static constexpr OutputType DefaultValue() { return Arithmetic{}; }
375 static void merge( InternalType& a, Arithmetic b ) noexcept {
376 if constexpr ( !std::is_floating_point_v<Arithmetic> ) { // avoid comparisons for floating points
377 if ( DefaultValue() == b ) return; // avoid atomic operation if b is "0"
378 }
379 fetch_add( a, b );
380 }
381 };
382
387 template <typename Arithmetic, atomicity Atomicity, typename Compare, Arithmetic ( *Initial )()>
388 struct Extremum;
389
393 template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
394 struct Extremum<Arithmetic, atomicity::none, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::none> {
397 static constexpr OutputType DefaultValue() { return Initial(); }
398 static void merge( InternalType& a, Arithmetic b ) noexcept {
399 if ( Compare{}( b, a ) ) a = b;
400 }
401 };
402
406 template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
407 struct Extremum<Arithmetic, atomicity::full, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::full> {
410 static constexpr OutputType DefaultValue() { return Initial(); }
411 static void merge( InternalType& a, Arithmetic b ) noexcept {
413 while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
414 ;
415 }
416 };
417
422 template <typename Arithmetic, atomicity Atomicity = atomicity::full>
423 using Minimum = Extremum<Arithmetic, Atomicity, std::less<Arithmetic>, std::numeric_limits<Arithmetic>::max>;
424
429 template <typename Arithmetic, atomicity Atomicity = atomicity::full>
430 using Maximum = Extremum<Arithmetic, Atomicity, std::greater<Arithmetic>, std::numeric_limits<Arithmetic>::lowest>;
431
438 explicit construct_empty_t() = default;
439 };
441
459 template <typename InputTypeT, typename InnerType, atomicity Atomicity = atomicity::full,
460 typename InputTransform = Identity, typename OutputTransform = Identity,
461 typename ValueHandler = Adder<InnerType, Atomicity>>
463 template <typename, typename, atomicity, typename, typename, typename>
464 friend class GenericAccumulator;
465
466 public:
467 using InputType = InputTypeT;
468 using OutputType = std::decay_t<std::invoke_result_t<OutputTransform, InnerType>>;
469 using InternalType = InnerType;
470 using JSONStringEntriesType = std::string;
472 ValueHandler::merge( m_value, InputTransform{}( by ) );
473 return *this;
474 }
477 template <atomicity ato, typename VH>
481 template <typename... Args>
482 GenericAccumulator( std::in_place_t, Args&&... args ) : m_value( std::forward<Args>( args )... ) {}
483 GenericAccumulator( const GenericAccumulator& other ) : m_value( ValueHandler::getValue( other.m_value ) ) {}
485 m_value = ValueHandler::getValue( other.m_value );
486 return *this;
487 }
488 OutputType value() const { return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
489 void reset() { reset( ValueHandler::DefaultValue() ); }
490 template <atomicity ato, typename VH>
492 ValueHandler::merge( m_value, VH::exchange( other.m_value, VH::DefaultValue() ) );
493 }
494 template <atomicity ato, typename VH>
496 ValueHandler::merge( m_value, other.m_value );
497 }
498
499 protected:
500 GenericAccumulator( InnerType in ) : m_value( std::move( in ) ) {}
501 auto rawValue() const { return ValueHandler::getValue( m_value ); }
502 void reset( InnerType in ) { m_value = std::move( in ); }
503 static InnerType extractJSONData( const nlohmann::json& j, const JSONStringEntriesType& entries ) {
504 return j.at( entries ).get<InnerType>();
505 }
506
507 private:
508 typename ValueHandler::InternalType m_value{ ValueHandler::DefaultValue() };
509 };
510
516 template <typename Arithmetic, atomicity Atomicity, typename InputTypeT = Arithmetic,
517 template <atomicity, typename> class... Bases>
518 class AccumulatorSet : public Bases<Atomicity, Arithmetic>... {
519 public:
520 using InputType = InputTypeT;
521 using OutputType = std::tuple<typename Bases<Atomicity, Arithmetic>::OutputType...>;
522 using InternalType = std::tuple<typename Bases<Atomicity, Arithmetic>::InternalType...>;
523 using JSONStringEntriesType = std::tuple<typename Bases<Atomicity, Arithmetic>::JSONStringEntriesType...>;
524 constexpr AccumulatorSet() = default;
526 template <atomicity ato>
530 ( Bases<Atomicity, Arithmetic>::operator+=( by ), ... );
531 return *this;
532 }
533 OutputType value() const { return std::make_tuple( Bases<Atomicity, Arithmetic>::value()... ); }
534 void reset() { ( Bases<Atomicity, Arithmetic>::reset(), ... ); }
535 template <atomicity Ato>
537 ( Bases<Atomicity, Arithmetic>::mergeAndReset( static_cast<Bases<Ato, Arithmetic>&>( other ) ), ... );
538 }
539 template <atomicity Ato>
541 ( Bases<Atomicity, Arithmetic>::operator+( static_cast<Bases<Ato, Arithmetic>&&>( other ) ), ... );
542 }
543
544 protected:
546 void reset( const InternalType& t ) {
547 std::apply( [this]( const auto&... i ) { ( this->Bases<Atomicity, Arithmetic>::reset( i ), ... ); }, t );
548 }
549 static InternalType extractJSONData( const nlohmann::json& j, const JSONStringEntriesType& entries ) {
550 return extractJSONDataHelper( j, entries, std::index_sequence_for<Bases<Atomicity, Arithmetic>...>{} );
551 }
552
553 private:
554 template <size_t... Is>
555 static InternalType extractJSONDataHelper( const nlohmann::json& j, const JSONStringEntriesType& entries,
556 std::index_sequence<Is...> ) {
557 return extractJSONDataHelper( j, std::get<Is>( entries )... );
558 }
559 static InternalType
560 extractJSONDataHelper( const nlohmann::json& j,
561 typename Bases<Atomicity, Arithmetic>::JSONStringEntriesType... entries ) {
562 return { Bases<Atomicity, Arithmetic>::extractJSONData( j, entries )... };
563 }
564 };
565
570 template <atomicity Atomicity, typename Arithmetic = double>
572 : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
573 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity,
575 Arithmetic max() const { return this->value(); }
576 };
577
582 template <atomicity Atomicity, typename Arithmetic = double>
584 : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
585 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity,
587 Arithmetic min() const { return this->value(); }
588 };
589
596 template <atomicity Atomicity, typename Arithmetic = double>
597 struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>> {
598 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>>::GenericAccumulator;
600 ( *this ) += Arithmetic{};
601 return *this;
602 }
604 auto copy = *this;
605 ++( *this );
606 return copy;
607 }
608 unsigned long nEntries() const { return this->value(); }
609 };
610
615 template <atomicity Atomicity, typename Arithmetic = double>
616 struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
617 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity>::GenericAccumulator;
618 Arithmetic sum() const { return this->value(); }
619 };
620
626 template <atomicity Atomicity, typename Arithmetic = unsigned long>
627 struct IntegralAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
628 static_assert( std::is_integral_v<Arithmetic>,
629 "Invalid Arithmetic type for IntegralAccumulator. It must be an integral type" );
630
631 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity>::GenericAccumulator;
633 ( *this ) += 1;
634 return *this;
635 }
637 auto copy = *this;
638 ++( *this );
639 return copy;
640 }
641 Arithmetic nEntries() const { return this->value(); }
642 Arithmetic sum() const { return this->value(); }
643 };
644
649 template <atomicity Atomicity, typename Arithmetic = double>
650 struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
651 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square>::GenericAccumulator;
652 Arithmetic sum2() const { return this->value(); }
653 };
654
656 struct TrueTo1 {
657 unsigned int operator()( bool v ) const { return v; }
658 };
659
665 template <atomicity Atomicity, typename Arithmetic>
666 struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
667 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1>::GenericAccumulator;
668 unsigned long nTrueEntries() const { return this->value(); }
669 };
670
672 struct FalseTo1 {
673 unsigned int operator()( bool v ) const { return !v; }
674 };
675
681 template <atomicity Atomicity, typename Arithmetic>
682 struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
683 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1>::GenericAccumulator;
684 unsigned long nFalseEntries() const { return this->value(); }
685 };
686
692 template <atomicity Atomicity, typename Arithmetic>
693 struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, bool, TrueAccumulator, FalseAccumulator> {
695 unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); }
696
697 template <typename Result = fp_result_type<Arithmetic>>
698 auto efficiency() const {
699 auto nbEntries = nEntries();
700 if ( 1 > nbEntries ) return Result{ -1 };
701 return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
702 }
703 auto eff() const { return efficiency(); }
704
705 template <typename Result = fp_result_type<Arithmetic>>
706 auto efficiencyErr() const {
707 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
708 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
710 using std::sqrt;
711 auto nbEntries = nEntries();
712 if ( 1 > nbEntries ) return Result{ -1 };
713 return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
714 }
715 auto effErr() const { return efficiencyErr(); }
716 using AccumulatorSet<bool, Atomicity, bool, TrueAccumulator, FalseAccumulator>::operator+=;
717 struct binomial_t {
718 unsigned long nPass;
719 unsigned long nTotal;
720 };
722 assert( b.nPass <= b.nTotal );
723 TrueAccumulator<atomicity::none, bool> t{ std::in_place, b.nPass };
725 FalseAccumulator<atomicity::none, bool> f{ std::in_place, b.nTotal - b.nPass };
727 return *this;
728 }
729 };
730
736 template <atomicity Atomicity, typename Arithmetic, template <atomicity, typename> typename CountAcc,
737 template <atomicity, typename> typename SumAcc>
739 : AccumulatorSet<Arithmetic, Atomicity, typename CountAcc<Atomicity, Arithmetic>::InputType, CountAcc, SumAcc> {
740 static_assert( std::is_same_v<typename CountAcc<Atomicity, Arithmetic>::InputType,
741 typename SumAcc<Atomicity, Arithmetic>::InputType>,
742 "Incompatible Counters in definition of AveragingAccumulator. Both should have identical Input" );
743 using AccumulatorSet<Arithmetic, Atomicity, typename CountAcc<Atomicity, Arithmetic>::InputType, CountAcc,
744 SumAcc>::AccumulatorSet;
745 template <typename Result = fp_result_type<Arithmetic>>
746 auto mean() const {
747 auto n = this->nEntries();
748 Result sum = this->sum();
749 return ( n > 0 ) ? static_cast<Result>( sum / n ) : Result{};
750 }
751 };
752
757 template <atomicity Atomicity, typename Arithmetic>
759
765 template <atomicity Atomicity, typename Arithmetic, template <atomicity, typename> typename AvgAcc,
766 template <atomicity, typename> typename SquareAcc>
768 : AccumulatorSet<Arithmetic, Atomicity, typename AvgAcc<Atomicity, Arithmetic>::InputType, AvgAcc, SquareAcc> {
769 static_assert( std::is_same_v<typename AvgAcc<Atomicity, Arithmetic>::InputType,
770 typename SquareAcc<Atomicity, Arithmetic>::InputType>,
771 "Incompatible Counters in definition of SigmaAccumulator. Both should have identical Input" );
772 using AccumulatorSet<Arithmetic, Atomicity, typename SquareAcc<Atomicity, Arithmetic>::InputType, AvgAcc,
773 SquareAcc>::AccumulatorSet;
774 template <typename Result = fp_result_type<Arithmetic>>
776 auto n = this->nEntries();
777 Result sum = this->sum();
778 return ( n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / n ) : Result{};
779 }
780
781 template <typename Result = fp_result_type<Arithmetic>>
783 auto n = this->nEntries();
784 Result sum = this->sum();
785 return ( n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) ) : Result{};
786 }
787
788 template <typename Result = fp_result_type<Arithmetic>>
789 auto standard_deviation() const {
790 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
791 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
793 using std::sqrt;
794 Result v = biased_sample_variance();
795 return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v ) );
796 }
797 [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const {
798 return standard_deviation();
799 }
800
801 template <typename Result = fp_result_type<Arithmetic>>
802 auto meanErr() const {
803 auto n = this->nEntries();
804 if ( 0 == n ) return Result{};
805 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
806 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
808 using std::sqrt;
809 Result v = biased_sample_variance();
810 return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) );
811 }
812 };
813
818 template <atomicity Atomicity, typename Arithmetic>
820
825 template <atomicity Atomicity, typename Arithmetic>
828
835 template <template <atomicity Ato, typename... Int> class ContainedAccumulator, atomicity Atomicity, typename... Args>
836 class Buffer : public ContainedAccumulator<atomicity::none, Args...> {
837 using prime_type = ContainedAccumulator<Atomicity, Args...>;
838 using base_type = ContainedAccumulator<atomicity::none, Args...>;
839
840 public:
841 Buffer() = delete;
843 Buffer( const Buffer& ) = delete;
844 void operator=( const Buffer& ) = delete;
845 Buffer( Buffer&& other ) : base_type( std::move( other ) ), m_prime( other.m_prime ) { other.m_prime = nullptr; }
846 void push() {
847 if ( m_prime ) { m_prime->mergeAndReset( static_cast<base_type&>( *this ) ); }
848 }
849 ~Buffer() { push(); }
850
851 private:
852 prime_type* m_prime = nullptr;
853 };
854
860 PrintableCounter() = default;
862 virtual ~PrintableCounter() = default;
863 // add tag to printout
864 template <typename stream>
865 stream& printImpl( stream& s, std::string_view tag ) const {
866 s << boost::format{ " | %|-48.48s|%|50t|" } % ( std::string{ '\"' }.append( tag ).append( "\"" ) );
867 return print( s, true );
868 }
869
870 virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
871 virtual MsgStream& print( MsgStream&, bool tableFormat = true ) const = 0;
873 virtual std::ostream& print( std::ostream& o, std::string_view tag ) const { return printImpl( o, tag ); }
874 virtual MsgStream& print( MsgStream& o, std::string_view tag ) const { return printImpl( o, tag ); }
877 virtual bool toBePrinted() const { return true; }
879 std::string toString() const {
880 std::ostringstream ost;
881 print( ost );
882 return ost.str();
883 }
884 };
885
889 inline std::ostream& operator<<( std::ostream& s, const PrintableCounter& counter ) { return counter.print( s ); }
890 inline MsgStream& operator<<( MsgStream& s, const PrintableCounter& counter ) { return counter.print( s ); }
897 template <atomicity Atomicity, template <atomicity Ato, typename... Int> class Accumulator, typename... Args>
898 class BufferableCounter : public PrintableCounter, public Accumulator<Atomicity, Args...> {
899 public:
900 using Accumulator<Atomicity, Args...>::Accumulator;
901 using BufferType = Buffer<Accumulator, Atomicity, Args...>;
902 BufferableCounter() = default;
903 template <typename OWNER>
904 BufferableCounter( OWNER* o, std::string const& name ) : BufferableCounter( o, name, *this ) {}
905 BufferType buffer() { return { *this }; }
909 if ( m_monitoringHub ) { m_monitoringHub->removeEntity( *this ); }
910 }
911
912 inline static const std::string typeString{ "counter" };
913
914 protected:
915 template <typename OWNER, typename SELF, typename... CARGS>
916 BufferableCounter( OWNER* o, std::string const& name, SELF& self, CARGS... args )
917 : Accumulator<Atomicity, Args...>( args... ), m_monitoringHub( &o->serviceLocator()->monitoringHub() ) {
918 m_monitoringHub->registerEntity( o->name(), name, self.typeString, self );
919 }
920
921 private:
923 };
924
929 template <atomicity Atomicity = atomicity::full, typename Arithmetic = unsigned long>
930 struct Counter : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic> {
931 inline static const std::string typeString{ std::string{ "counter:Counter:" } + typeid( Arithmetic ).name() };
932 using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::BufferableCounter;
933 template <typename OWNER>
934 Counter( OWNER* o, std::string const& name )
935 : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>( o, name, *this ) {}
936 Counter& operator++() { return ( *this ) += 1; }
937 Counter& operator+=( const Arithmetic v ) {
939 return *this;
940 }
941 using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::print;
942
943 template <typename stream>
944 stream& printImpl( stream& o, bool tableFormat ) const {
945 // Avoid printing empty counters in non DEBUG mode
946 auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" );
947 return o << boost::format{ fmt } % this->nEntries();
948 }
949
950 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
951 return printImpl( o, tableFormat );
952 }
953 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
954 bool toBePrinted() const override { return this->nEntries() > 0; }
955 friend void reset( Counter& c ) { c.reset(); }
956 friend void mergeAndReset( Counter& c, Counter& o ) { c.mergeAndReset( o ); }
957 friend void to_json( nlohmann::json& j, Counter const& c ) {
958 j = { { "type", c.typeString }, { "empty", c.nEntries() == 0 }, { "nEntries", c.nEntries() } };
959 }
960 static Counter fromJSON( const nlohmann::json& j ) {
962 }
963 };
964
969 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
970 struct AveragingCounter : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic> {
971 inline static const std::string typeString{ std::string{ "counter:AveragingCounter:" } +
972 typeid( Arithmetic ).name() };
974 template <typename OWNER>
975 AveragingCounter( OWNER* o, std::string const& name )
976 : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>( o, name, *this ) {}
977 using BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>::print;
978
979 template <typename stream>
980 stream& printImpl( stream& o, bool tableFormat ) const {
981 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
982 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean();
983 }
984
985 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
986 return printImpl( o, tableFormat );
987 }
988 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
989
990 bool toBePrinted() const override { return this->nEntries() > 0; }
991 friend void reset( AveragingCounter& c ) { return c.reset(); }
992 friend void mergeAndReset( AveragingCounter& c, AveragingCounter& o ) { c.mergeAndReset( o ); }
993 friend void to_json( nlohmann::json& j, AveragingCounter const& c ) {
994 j = { { "type", c.typeString },
995 { "empty", c.nEntries() == 0 },
996 { "nEntries", c.nEntries() },
997 { "sum", c.sum() },
998 { "mean", c.mean() } };
999 }
1000 static AveragingCounter fromJSON( const nlohmann::json& j ) {
1001 return AveragingAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nEntries", "sum" } );
1002 }
1003 };
1004 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1006
1011 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1012 struct SigmaCounter : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic> {
1013 inline static const std::string typeString{ std::string{ "counter:SigmaCounter:" } + typeid( Arithmetic ).name() };
1014 using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::BufferableCounter;
1015 template <typename OWNER>
1016 SigmaCounter( OWNER* o, std::string const& name )
1017 : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>( o, name, *this ) {}
1018 using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::print;
1019
1020 template <typename stream>
1021 stream& printImpl( stream& o, bool tableFormat ) const {
1022 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |"
1023 : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
1024 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
1025 }
1026
1027 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1028 return printImpl( o, tableFormat );
1029 }
1030 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1031 bool toBePrinted() const override { return this->nEntries() > 0; }
1032 friend void reset( SigmaCounter& c ) { c.reset(); }
1033 friend void mergeAndReset( SigmaCounter& c, SigmaCounter& o ) { c.mergeAndReset( o ); }
1034 friend void to_json( nlohmann::json& j, SigmaCounter const& c ) {
1035 j = { { "type", c.typeString },
1036 { "empty", c.nEntries() == 0 },
1037 { "nEntries", c.nEntries() },
1038 { "sum", c.sum() },
1039 { "mean", c.mean() },
1040 { "sum2", c.sum2() },
1041 { "standard_deviation", c.standard_deviation() } };
1042 }
1043 static SigmaCounter fromJSON( const nlohmann::json& j ) {
1044 return SigmaAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { { "nEntries", "sum" }, "sum2" } );
1045 }
1046 };
1047
1052 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1053 struct StatCounter : BufferableCounter<Atomicity, StatAccumulator, Arithmetic> {
1054 inline static const std::string typeString{ std::string{ "counter:StatCounter:" } + typeid( Arithmetic ).name() };
1055 using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::BufferableCounter;
1056 template <typename OWNER>
1057 StatCounter( OWNER* o, std::string const& name )
1058 : BufferableCounter<Atomicity, StatAccumulator, Arithmetic>( o, name, *this ) {}
1059 using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::print;
1060
1061 template <typename stream>
1062 stream& printImpl( stream& o, bool tableFormat ) const {
1063 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |"
1064 : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
1065 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
1066 this->min() % this->max();
1067 }
1068
1069 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1070 return printImpl( o, tableFormat );
1071 }
1072 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1073 bool toBePrinted() const override { return this->nEntries() > 0; }
1074 friend void reset( StatCounter& c ) { c.reset(); }
1075 friend void mergeAndReset( StatCounter& c, StatCounter& o ) { c.mergeAndReset( o ); }
1076 friend void to_json( nlohmann::json& j, StatCounter const& c ) {
1077 j = { { "type", c.typeString },
1078 { "empty", c.nEntries() == 0 },
1079 { "nEntries", c.nEntries() },
1080 { "sum", c.sum() },
1081 { "mean", c.mean() },
1082 { "sum2", c.sum2() },
1083 { "standard_deviation", c.standard_deviation() },
1084 { "min", c.min() },
1085 { "max", c.max() } };
1086 }
1087 static StatCounter fromJSON( const nlohmann::json& j ) {
1089 j, { { { "nEntries", "sum" }, "sum2" }, "min", "max" } );
1090 }
1091 };
1092
1097 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1098 struct BinomialCounter : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic> {
1099 inline static const std::string typeString{ std::string{ "counter:BinomialCounter:" } +
1100 typeid( Arithmetic ).name() };
1101 using BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>::BufferableCounter;
1102 template <typename OWNER>
1103 BinomialCounter( OWNER* o, std::string const& name )
1104 : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>( o, name, *this ) {}
1105
1106 template <typename stream>
1107 stream& printImpl( stream& o, bool tableFormat ) const {
1108 auto fmt = ( tableFormat ? "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |"
1109 : "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
1110 return o << boost::format{ fmt } % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
1111 ( this->efficiencyErr() * 100 );
1112 }
1113
1114 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1115 return printImpl( o, tableFormat );
1116 }
1117 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1118
1119 template <typename stream>
1120 stream& printImpl( stream& o, std::string_view tag ) const {
1121 // override default print to add a '*' in from of the name
1122 o << boost::format{ " |*%|-48.48s|%|50t|" } % ( std::string{ "\"" }.append( tag ).append( "\"" ) );
1123 return print( o, true );
1124 }
1125
1126 std::ostream& print( std::ostream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
1127 MsgStream& print( MsgStream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
1128 bool toBePrinted() const override { return this->nEntries() > 0; }
1129 friend void reset( BinomialCounter& c ) { c.reset(); }
1130 friend void mergeAndReset( BinomialCounter& c, BinomialCounter& o ) { c.mergeAndReset( o ); }
1131 friend void to_json( nlohmann::json& j, BinomialCounter const& c ) {
1132 j = { { "type", c.typeString },
1133 { "empty", c.nEntries() == 0 },
1134 { "nEntries", c.nTrueEntries() + c.nFalseEntries() },
1135 { "nTrueEntries", c.nTrueEntries() },
1136 { "nFalseEntries", c.nFalseEntries() },
1137 { "efficiency", c.efficiency() },
1138 { "efficiencyErr", c.efficiencyErr() } };
1139 }
1140 static BinomialCounter fromJSON( const nlohmann::json& j ) {
1141 return BinomialAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nTrueEntries", "nFalseEntries" } );
1142 }
1143 };
1144
1146 template <atomicity Atomicity>
1147 struct Handler : Adder<unsigned long, Atomicity> {
1149 static void merge( typename Base::InternalType& orig, bool b ) {
1150 if ( b ) Base::merge( orig, 1 );
1151 }
1152 };
1153 // note that Arithmetic type is unused in this case but needs to be there in case
1154 // we want to create AccumulatorSets with this Accumulator
1155 template <atomicity Atomicity, typename Arithmetic = double>
1157 } // namespace details::MsgCounter
1158
1159 template <MSG::Level level, atomicity Atomicity = atomicity::full>
1161 public:
1162 inline static const std::string typeString{ "counter:MsgCounter" };
1163 template <typename OWNER>
1164 MsgCounter( OWNER* o, std::string const& ms, unsigned long nMax = 10 )
1165 : m_monitoringHub{ &o->serviceLocator()->monitoringHub() }, logger( o ), msg( ms ), max( nMax ) {
1166 m_monitoringHub->registerEntity( o->name(), ms, typeString, *this );
1167 }
1169 ( *this ) += true;
1170 return *this;
1171 }
1172 MsgCounter& operator+=( const bool by ) {
1174 if ( by ) log();
1175 return *this;
1176 }
1177 MsgCounter( MsgCounter const& ) = delete;
1178 MsgCounter& operator=( MsgCounter const& ) = delete;
1180 if ( m_monitoringHub ) m_monitoringHub->removeEntity( *this );
1181 }
1182 template <typename stream>
1183 stream& printImpl( stream& o, bool tableFormat ) const {
1184 return o << boost::format{ tableFormat ? "|%|10d| |" : "#=%|-7lu|" } % this->value();
1185 }
1187 std::ostream& print( std::ostream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
1188 MsgStream& print( MsgStream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
1189 bool toBePrinted() const override { return this->value() > 0; }
1190 friend void reset( MsgCounter& c ) { c.reset(); }
1191 friend void mergeAndReset( MsgCounter& c, MsgCounter& o ) { c.mergeAndReset( o ); }
1192 friend void to_json( nlohmann::json& j, MsgCounter const& c ) {
1193 j = { { "type", c.typeString }, { "empty", c.value() == 0 },
1194 { "nEntries", c.value() }, { "level", level },
1195 { "max", c.max }, { "msg", c.msg } };
1196 }
1197 static MsgCounter fromJSON( const nlohmann::json& j ) {
1198 return { j.at( "msg" ).get<std::string>(), j.at( "max" ).get<unsigned long>(),
1199 j.at( "nEntries" ).get<unsigned long>() };
1200 }
1201
1202 private:
1203 MsgCounter( std::string const& ms, unsigned long nMax, unsigned long count )
1204 : details::MsgCounter::MsgAccumulator<Atomicity>{ count }, msg( ms ), max( nMax ) {}
1205
1207 const CommonMessagingBase* logger{ nullptr };
1208 std::string msg;
1209 unsigned long max;
1210 void log() {
1211 if ( this->value() <= max && logger ) {
1212 if ( this->value() == max ) {
1213 logger->msgStream( level ) << "Suppressing message: " << std::quoted( msg, '\'' ) << endmsg;
1214 } else {
1215 logger->msgStream( level ) << msg << endmsg;
1216 }
1217 }
1218 }
1219 };
1220
1226 template <typename Counter, typename Container, typename Fun>
1227 void accumulate( Counter& counter, const Container& container, Fun f = Identity{} ) {
1228 auto b = counter.buffer();
1229 for ( const auto& elem : container ) b += f( elem );
1230 }
1231
1232} // namespace Gaudi::Accumulators
std::ostream & operator<<(std::ostream &s, AlgsExecutionStates::State x)
Streaming of State values.
#define class
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
static InternalType extractJSONData(const nlohmann::json &j, const JSONStringEntriesType &entries)
static InternalType extractJSONDataHelper(const nlohmann::json &j, const JSONStringEntriesType &entries, std::index_sequence< Is... >)
void operator+(AccumulatorSet< Arithmetic, Ato, InputType, Bases... > &&other)
std::tuple< typename Bases< Atomicity, Arithmetic >::InternalType... > InternalType
std::tuple< typename Bases< Atomicity, Arithmetic >::OutputType... > OutputType
AccumulatorSet(const InternalType &t)
static InternalType extractJSONDataHelper(const nlohmann::json &j, typename Bases< Atomicity, Arithmetic >::JSONStringEntriesType... entries)
constexpr AccumulatorSet()=default
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, InputType, Bases... > &other)
void reset(const InternalType &t)
AccumulatorSet & operator+=(const InputType by)
AccumulatorSet(construct_empty_t, const AccumulatorSet< Arithmetic, ato, InputType, Bases... > &)
constructor of an empty AccumulatorSet, copying the (non existent) config from another GenericAccumul...
std::tuple< typename Bases< Atomicity, Arithmetic >::JSONStringEntriesType... > JSONStringEntriesType
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
ContainedAccumulator< Atomicity, Args... > prime_type
ContainedAccumulator< atomicity::none, Args... > base_type
void operator=(const Buffer &)=delete
Buffer(const Buffer &)=delete
An empty ancester of all counters that provides a buffer method that returns a buffer on itself Also ...
BufferableCounter(OWNER *o, std::string const &name, SELF &self, CARGS... args)
Buffer< Accumulator, Atomicity, Args... > BufferType
BufferableCounter & operator=(BufferableCounter const &)=delete
BufferableCounter(BufferableCounter const &)=delete
BufferableCounter(OWNER *o, std::string const &name)
Generic Accumulator, templated by.
GenericAccumulator & operator=(const GenericAccumulator &other)
GenericAccumulator(const GenericAccumulator &other)
GenericAccumulator(std::in_place_t, Args &&... args)
std::decay_t< std::invoke_result_t< OutputTransform, InnerType > > OutputType
static InnerType extractJSONData(const nlohmann::json &j, const JSONStringEntriesType &entries)
GenericAccumulator(construct_empty_t, const GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &)
constructor of an empty GenericAccumulator, copying the (non existent) config from another GenericAcc...
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &other)
void operator+(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
GenericAccumulator operator+=(const InputType by)
std::ostream & print(std::ostream &os, bool tableFormat) const override
prints the counter to a stream
friend void to_json(nlohmann::json &j, MsgCounter const &c)
friend void reset(MsgCounter &c)
MsgCounter(OWNER *o, std::string const &ms, unsigned long nMax=10)
bool toBePrinted() const override
hint whether we should print that counter or not.
stream & printImpl(stream &o, bool tableFormat) const
friend void mergeAndReset(MsgCounter &c, MsgCounter &o)
static MsgCounter fromJSON(const nlohmann::json &j)
static const std::string typeString
const CommonMessagingBase * logger
MsgCounter & operator+=(const bool by)
MsgStream & print(MsgStream &os, bool tableFormat) const override
MsgCounter(MsgCounter const &)=delete
MsgCounter & operator=(MsgCounter const &)=delete
MsgCounter(std::string const &ms, unsigned long nMax, unsigned long count)
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
GenericAccumulator< bool, unsigned long, Atomicity, Identity, Identity, Handler< Atomicity > > MsgAccumulator
Efficient counter implementations for Gaudi.
auto operator*(const std::chrono::duration< Rep1, Period > &lhs, const std::chrono::duration< Rep2, Period > &rhs)
Multiplication of two std::chrono::duration objects with same Period.
Definition Counters.h:40
std::ostream & operator<<(std::ostream &s, const PrintableCounter &counter)
external printout operator to a stream type
AccumulatorSet< Arithmetic, Atomicity, Arithmetic, SigmaAccumulator, MinAccumulator, MaxAccumulator > StatAccumulator
StatAccumulator.
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
Definition Counters.h:34
Extremum< Arithmetic, Atomicity, std::less< Arithmetic >, std::numeric_limits< Arithmetic >::max > Minimum
A Minimun ValueHandler operator(a, b) means a = min(a, b) In case of full atomicity,...
Extremum< Arithmetic, Atomicity, std::greater< Arithmetic >, std::numeric_limits< Arithmetic >::lowest > Maximum
An Maximum ValueHandler operator(a, b) means a = max(a, b) In case of full atomicity,...
void accumulate(Counter &counter, const Container &container, Fun f=Identity{})
A helper function for accumulating data from a container into a counter This is internally using buff...
AveragingCounter< Arithmetic, Atomicity > SummingCounter
atomicity
Defines atomicity of the accumulators.
std::conditional_t< std::is_integral_v< Arithmetic >, Result, Arithmetic > fp_result_type
type_trait for the result type of a floating point operation on the type Arithmetic
constexpr construct_empty_t construct_empty
AveragingAccumulatorBase< Atomicity, Arithmetic, CountAccumulator, SumAccumulator > AveragingAccumulator
AveragingAccumulator.
void fetch_add(AtomicType &atVar, Arithmetic value)
generic fetch_add, also dealing with atomic types with no fetch_add member method
SigmaAccumulatorBase< Atomicity, Arithmetic, AveragingAccumulator, SquareAccumulator > SigmaAccumulator
SigmaAccumulator.
STL namespace.
An Adder ValueHandler operator(a, b) means a += b.
static void merge(InternalType &a, Arithmetic b) noexcept
static void merge(InternalType &a, Arithmetic b) noexcept
A counter aiming at computing sum and average.
stream & printImpl(stream &o, bool tableFormat) const
friend void mergeAndReset(AveragingCounter &c, AveragingCounter &o)
bool toBePrinted() const override
hint whether we should print that counter or not.
AveragingCounter(OWNER *o, std::string const &name)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
friend void to_json(nlohmann::json &j, AveragingCounter const &c)
static AveragingCounter fromJSON(const nlohmann::json &j)
friend void reset(AveragingCounter &c)
Base type for all functors used as ValuesHandler.
static constexpr OutputType getValue(const InternalType &v) noexcept
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
static constexpr OutputType getValue(const InternalType &v) noexcept
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
BinomialAccumulator & operator+=(binomial_t b)
friend void to_json(nlohmann::json &j, BinomialCounter const &c)
BinomialCounter(OWNER *o, std::string const &name)
stream & printImpl(stream &o, bool tableFormat) const
friend void mergeAndReset(BinomialCounter &c, BinomialCounter &o)
std::ostream & print(std::ostream &o, std::string_view tag) const override
prints the counter to a stream in table format, with the given tag
MsgStream & print(MsgStream &o, std::string_view tag) const override
static BinomialCounter fromJSON(const nlohmann::json &j)
static const std::string typeString
friend void reset(BinomialCounter &c)
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
bool toBePrinted() const override
hint whether we should print that counter or not.
stream & printImpl(stream &o, std::string_view tag) const
A functor always returning the value N.
constexpr T operator()(U &&) const noexcept
A basic integral counter;.
friend void mergeAndReset(Counter &c, Counter &o)
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Counter(OWNER *o, std::string const &name)
static Counter fromJSON(const nlohmann::json &j)
Counter & operator+=(const Arithmetic v)
friend void reset(Counter &c)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
bool toBePrinted() const override
hint whether we should print that counter or not.
stream & printImpl(stream &o, bool tableFormat) const
friend void to_json(nlohmann::json &j, Counter const &c)
static const std::string typeString
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b,...
helper functor for the FalseAccumulator
unsigned int operator()(bool v) const
An empty ancester of all counters that knows how to print themselves.
virtual ~PrintableCounter()=default
destructor
std::string toString() const
get a string representation
virtual std::ostream & print(std::ostream &, bool tableFormat=false) const =0
prints the counter to a stream
stream & printImpl(stream &s, std::string_view tag) const
virtual MsgStream & print(MsgStream &, bool tableFormat=true) const =0
virtual std::ostream & print(std::ostream &o, std::string_view tag) const
prints the counter to a stream in table format, with the given tag
virtual bool toBePrinted() const
hint whether we should print that counter or not.
virtual MsgStream & print(MsgStream &o, std::string_view tag) const
stream & printImpl(stream &o, bool tableFormat) const
bool toBePrinted() const override
hint whether we should print that counter or not.
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
friend void to_json(nlohmann::json &j, SigmaCounter const &c)
SigmaCounter(OWNER *o, std::string const &name)
friend void reset(SigmaCounter &c)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
friend void mergeAndReset(SigmaCounter &c, SigmaCounter &o)
static const std::string typeString
static SigmaCounter fromJSON(const nlohmann::json &j)
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
friend void mergeAndReset(StatCounter &c, StatCounter &o)
stream & printImpl(stream &o, bool tableFormat) const
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
friend void reset(StatCounter &c)
friend void to_json(nlohmann::json &j, StatCounter const &c)
static StatCounter fromJSON(const nlohmann::json &j)
bool toBePrinted() const override
hint whether we should print that counter or not.
StatCounter(OWNER *o, std::string const &name)
helper functor for the TrueAccumulator
unsigned int operator()(bool v) const
constant used to disambiguate construction of an empty Accumulator versus the copy constructor.
static void merge(typename Base::InternalType &orig, bool b)
Central entity in a Gaudi application that manages monitoring objects (i.e.
static void from_json(const json &j, std::chrono::duration< Rep, Period > &d)
static void to_json(json &j, const std::chrono::duration< Rep, Period > &d)