The Gaudi Framework  master (34daa81a)
Loading...
Searching...
No Matches
Accumulators.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 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
383 namespace detail {
387 template <typename Arithmetic>
388 struct Min {
389 static constexpr Arithmetic value() { return std::numeric_limits<Arithmetic>::lowest(); }
390 };
391
395 template <typename Arithmetic>
396 struct Max {
397 static constexpr Arithmetic value() { return std::numeric_limits<Arithmetic>::max(); }
398 };
399 } // namespace detail
400
405 template <typename Arithmetic, atomicity Atomicity, typename Compare, typename Initial>
406 struct Extremum;
407
411 template <typename Arithmetic, typename Compare, typename Initial>
412 struct Extremum<Arithmetic, atomicity::none, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::none> {
415 static constexpr OutputType DefaultValue() { return Initial::value(); }
416 static void merge( InternalType& a, Arithmetic b ) noexcept {
417 if ( Compare{}( b, a ) ) a = b;
418 }
419 };
420
424 template <typename Arithmetic, typename Compare, typename Initial>
425 struct Extremum<Arithmetic, atomicity::full, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::full> {
428 static constexpr OutputType DefaultValue() { return Initial::value(); }
429 static void merge( InternalType& a, Arithmetic b ) noexcept {
431 while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
432 ;
433 }
434 };
435
440 template <typename Arithmetic, atomicity Atomicity = atomicity::full>
442
447 template <typename Arithmetic, atomicity Atomicity = atomicity::full>
449
456 explicit construct_empty_t() = default;
457 };
459
477 template <typename InputTypeT, typename InnerType, atomicity Atomicity = atomicity::full,
478 typename InputTransform = Identity, typename OutputTransform = Identity,
479 typename ValueHandler = Adder<InnerType, Atomicity>>
481 template <typename, typename, atomicity, typename, typename, typename>
482 friend class GenericAccumulator;
483
484 public:
485 using InputType = InputTypeT;
486 using OutputType = std::decay_t<std::invoke_result_t<OutputTransform, InnerType>>;
487 using InternalType = InnerType;
488 using JSONStringEntriesType = std::string;
490 ValueHandler::merge( m_value, InputTransform{}( by ) );
491 return *this;
492 }
495 template <atomicity ato, typename VH>
499 template <typename... Args>
500 GenericAccumulator( std::in_place_t, Args&&... args ) : m_value( std::forward<Args>( args )... ) {}
501 GenericAccumulator( const GenericAccumulator& other ) : m_value( ValueHandler::getValue( other.m_value ) ) {}
503 m_value = ValueHandler::getValue( other.m_value );
504 return *this;
505 }
506 OutputType value() const { return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
507 void reset() { reset( ValueHandler::DefaultValue() ); }
508 template <atomicity ato, typename VH>
510 ValueHandler::merge( m_value, VH::exchange( other.m_value, VH::DefaultValue() ) );
511 }
512 template <atomicity ato, typename VH>
514 ValueHandler::merge( m_value, other.m_value );
515 }
516
517 protected:
518 GenericAccumulator( InnerType in ) : m_value( std::move( in ) ) {}
519 auto rawValue() const { return ValueHandler::getValue( m_value ); }
520 void reset( InnerType in ) { m_value = std::move( in ); }
521 static InnerType extractJSONData( const nlohmann::json& j, const JSONStringEntriesType& entries ) {
522 return j.at( entries ).get<InnerType>();
523 }
524
525 private:
526 typename ValueHandler::InternalType m_value{ ValueHandler::DefaultValue() };
527 };
528
534 template <typename Arithmetic, atomicity Atomicity, typename InputTypeT = Arithmetic,
535 template <atomicity, typename> class... Bases>
536 class AccumulatorSet : public Bases<Atomicity, Arithmetic>... {
537 public:
538 using InputType = InputTypeT;
539 using OutputType = std::tuple<typename Bases<Atomicity, Arithmetic>::OutputType...>;
540 using InternalType = std::tuple<typename Bases<Atomicity, Arithmetic>::InternalType...>;
541 using JSONStringEntriesType = std::tuple<typename Bases<Atomicity, Arithmetic>::JSONStringEntriesType...>;
542 constexpr AccumulatorSet() = default;
544 template <atomicity ato>
548 ( Bases<Atomicity, Arithmetic>::operator+=( by ), ... );
549 return *this;
550 }
551 OutputType value() const { return std::make_tuple( Bases<Atomicity, Arithmetic>::value()... ); }
552 void reset() { ( Bases<Atomicity, Arithmetic>::reset(), ... ); }
553 template <atomicity Ato>
555 ( Bases<Atomicity, Arithmetic>::mergeAndReset( static_cast<Bases<Ato, Arithmetic>&>( other ) ), ... );
556 }
557 template <atomicity Ato>
559 ( Bases<Atomicity, Arithmetic>::operator+( static_cast<Bases<Ato, Arithmetic>&&>( other ) ), ... );
560 }
561 // explicitely delete operator++ as it's not 100% clear what one would expect from them in more
562 // complex cases, e.g. binomial counters, or counters based on enums, etc...
563 void operator++() = delete;
564 void operator++( int ) = delete;
565
566 protected:
568 void reset( const InternalType& t ) {
569 std::apply( [this]( const auto&... i ) { ( this->Bases<Atomicity, Arithmetic>::reset( i ), ... ); }, t );
570 }
571 static InternalType extractJSONData( const nlohmann::json& j, const JSONStringEntriesType& entries ) {
572 return extractJSONDataHelper( j, entries, std::index_sequence_for<Bases<Atomicity, Arithmetic>...>{} );
573 }
574
575 private:
576 template <size_t... Is>
577 static InternalType extractJSONDataHelper( const nlohmann::json& j, const JSONStringEntriesType& entries,
578 std::index_sequence<Is...> ) {
579 return extractJSONDataHelper( j, std::get<Is>( entries )... );
580 }
581 static InternalType
582 extractJSONDataHelper( const nlohmann::json& j,
583 typename Bases<Atomicity, Arithmetic>::JSONStringEntriesType... entries ) {
584 return { Bases<Atomicity, Arithmetic>::extractJSONData( j, entries )... };
585 }
586 };
587
592 template <atomicity Atomicity, typename Arithmetic = double>
594 : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
595 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity,
597 Arithmetic max() const { return this->value(); }
598 };
599
604 template <atomicity Atomicity, typename Arithmetic = double>
606 : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
607 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity,
609 Arithmetic min() const { return this->value(); }
610 };
611
618 template <atomicity Atomicity, typename Arithmetic = double>
619 struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>> {
620 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>>::GenericAccumulator;
622 ( *this ) += Arithmetic{};
623 return *this;
624 }
626 auto copy = *this;
627 ++( *this );
628 return copy;
629 }
630 unsigned long nEntries() const { return this->value(); }
631 };
632
637 template <atomicity Atomicity, typename Arithmetic = double>
638 struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
639 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity>::GenericAccumulator;
640 Arithmetic sum() const { return this->value(); }
641 };
642
648 template <atomicity Atomicity, typename Arithmetic = unsigned long>
649 struct IntegralAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
650 static_assert( std::is_integral_v<Arithmetic>,
651 "Invalid Arithmetic type for IntegralAccumulator. It must be an integral type" );
652
653 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity>::GenericAccumulator;
655 ( *this ) += 1;
656 return *this;
657 }
659 auto copy = *this;
660 ++( *this );
661 return copy;
662 }
663 Arithmetic nEntries() const { return this->value(); }
664 Arithmetic sum() const { return this->value(); }
665 };
666
671 template <atomicity Atomicity, typename Arithmetic = double>
672 struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
673 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square>::GenericAccumulator;
674 Arithmetic sum2() const { return this->value(); }
675 };
676
678 struct TrueTo1 {
679 unsigned int operator()( bool v ) const { return v; }
680 };
681
687 template <atomicity Atomicity, typename Arithmetic>
688 struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
689 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1>::GenericAccumulator;
690 unsigned long nTrueEntries() const { return this->value(); }
691 };
692
694 struct FalseTo1 {
695 unsigned int operator()( bool v ) const { return !v; }
696 };
697
703 template <atomicity Atomicity, typename Arithmetic>
704 struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
705 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1>::GenericAccumulator;
706 unsigned long nFalseEntries() const { return this->value(); }
707 };
708
714 template <atomicity Atomicity, typename Arithmetic>
715 struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, bool, TrueAccumulator, FalseAccumulator> {
717 unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); }
718
719 template <typename Result = fp_result_type<Arithmetic>>
720 auto efficiency() const {
721 auto nbEntries = nEntries();
722 if ( 1 > nbEntries ) return Result{ -1 };
723 return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
724 }
725 auto eff() const { return efficiency(); }
726
727 template <typename Result = fp_result_type<Arithmetic>>
728 auto efficiencyErr() const {
729 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
730 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
732 using std::sqrt;
733 auto nbEntries = nEntries();
734 if ( 1 > nbEntries ) return Result{ -1 };
735 return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
736 }
737 auto effErr() const { return efficiencyErr(); }
738 using AccumulatorSet<bool, Atomicity, bool, TrueAccumulator, FalseAccumulator>::operator+=;
739 struct binomial_t {
740 unsigned long nPass;
741 unsigned long nTotal;
742 };
744 assert( b.nPass <= b.nTotal );
745 TrueAccumulator<atomicity::none, bool> t{ std::in_place, b.nPass };
747 FalseAccumulator<atomicity::none, bool> f{ std::in_place, b.nTotal - b.nPass };
749 return *this;
750 }
751 };
752
758 template <atomicity Atomicity, typename Arithmetic, template <atomicity, typename> typename CountAcc,
759 template <atomicity, typename> typename SumAcc>
761 : AccumulatorSet<Arithmetic, Atomicity, typename CountAcc<Atomicity, Arithmetic>::InputType, CountAcc, SumAcc> {
762 static_assert( std::is_same_v<typename CountAcc<Atomicity, Arithmetic>::InputType,
763 typename SumAcc<Atomicity, Arithmetic>::InputType>,
764 "Incompatible Counters in definition of AveragingAccumulator. Both should have identical Input" );
765 using AccumulatorSet<Arithmetic, Atomicity, typename CountAcc<Atomicity, Arithmetic>::InputType, CountAcc,
766 SumAcc>::AccumulatorSet;
767 template <typename Result = fp_result_type<Arithmetic>>
768 auto mean() const {
769 auto n = this->nEntries();
770 Result sum = this->sum();
771 return ( n > 0 ) ? static_cast<Result>( sum / n ) : Result{};
772 }
773 };
774
779 template <atomicity Atomicity, typename Arithmetic>
781
787 template <atomicity Atomicity, typename Arithmetic, template <atomicity, typename> typename AvgAcc,
788 template <atomicity, typename> typename SquareAcc>
790 : AccumulatorSet<Arithmetic, Atomicity, typename AvgAcc<Atomicity, Arithmetic>::InputType, AvgAcc, SquareAcc> {
791 static_assert( std::is_same_v<typename AvgAcc<Atomicity, Arithmetic>::InputType,
792 typename SquareAcc<Atomicity, Arithmetic>::InputType>,
793 "Incompatible Counters in definition of SigmaAccumulator. Both should have identical Input" );
794 using AccumulatorSet<Arithmetic, Atomicity, typename SquareAcc<Atomicity, Arithmetic>::InputType, AvgAcc,
795 SquareAcc>::AccumulatorSet;
796 template <typename Result = fp_result_type<Arithmetic>>
798 auto n = this->nEntries();
799 Result sum = this->sum();
800 return ( n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / n ) : Result{};
801 }
802
803 template <typename Result = fp_result_type<Arithmetic>>
805 auto n = this->nEntries();
806 Result sum = this->sum();
807 return ( n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) ) : Result{};
808 }
809
810 template <typename Result = fp_result_type<Arithmetic>>
811 auto standard_deviation() const {
812 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
813 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
815 using std::sqrt;
816 Result v = biased_sample_variance();
817 return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v ) );
818 }
819 [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const {
820 return standard_deviation();
821 }
822
823 template <typename Result = fp_result_type<Arithmetic>>
824 auto meanErr() const {
825 auto n = this->nEntries();
826 if ( 0 == n ) return Result{};
827 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
828 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
830 using std::sqrt;
831 Result v = biased_sample_variance();
832 return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) );
833 }
834 };
835
840 template <atomicity Atomicity, typename Arithmetic>
842
847 template <atomicity Atomicity, typename Arithmetic>
850
857 template <template <atomicity Ato, typename... Int> class ContainedAccumulator, atomicity Atomicity, typename... Args>
858 class Buffer : public ContainedAccumulator<atomicity::none, Args...> {
859 using prime_type = ContainedAccumulator<Atomicity, Args...>;
860 using base_type = ContainedAccumulator<atomicity::none, Args...>;
861
862 public:
863 Buffer() = delete;
865 Buffer( const Buffer& ) = delete;
866 void operator=( const Buffer& ) = delete;
867 Buffer( Buffer&& other ) : base_type( std::move( other ) ), m_prime( other.m_prime ) { other.m_prime = nullptr; }
868 void push() {
869 if ( m_prime ) { m_prime->mergeAndReset( static_cast<base_type&>( *this ) ); }
870 }
871 ~Buffer() { push(); }
872
873 private:
874 prime_type* m_prime = nullptr;
875 };
876
882 PrintableCounter() = default;
884 virtual ~PrintableCounter() = default;
885 // add tag to printout
886 template <typename stream>
887 stream& printImpl( stream& s, std::string_view tag ) const {
888 s << boost::format{ " | %|-48.48s|%|50t|" } % ( std::string{ '\"' }.append( tag ).append( "\"" ) );
889 return print( s, true );
890 }
891
892 virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
893 virtual MsgStream& print( MsgStream&, bool tableFormat = true ) const = 0;
895 virtual std::ostream& print( std::ostream& o, std::string_view tag ) const { return printImpl( o, tag ); }
896 virtual MsgStream& print( MsgStream& o, std::string_view tag ) const { return printImpl( o, tag ); }
899 virtual bool toBePrinted() const { return true; }
901 std::string toString() const {
902 std::ostringstream ost;
903 print( ost );
904 return ost.str();
905 }
906 };
907
911 inline std::ostream& operator<<( std::ostream& s, const PrintableCounter& counter ) { return counter.print( s ); }
912 inline MsgStream& operator<<( MsgStream& s, const PrintableCounter& counter ) { return counter.print( s ); }
919 template <atomicity Atomicity, template <atomicity Ato, typename... Int> class Accumulator, typename... Args>
920 class BufferableCounter : public PrintableCounter, public Accumulator<Atomicity, Args...> {
921 public:
922 using Accumulator<Atomicity, Args...>::Accumulator;
923 using BufferType = Buffer<Accumulator, Atomicity, Args...>;
924 BufferableCounter() = default;
925 template <typename OWNER>
926 BufferableCounter( OWNER* o, std::string const& name ) : BufferableCounter( o, name, *this ) {}
927 BufferType buffer() { return { *this }; }
931 if ( m_monitoringHub ) { m_monitoringHub->removeEntity( *this ); }
932 }
933
934 inline static const std::string typeString{ "counter" };
935
936 protected:
937 template <typename OWNER, typename SELF, typename... CARGS>
938 BufferableCounter( OWNER* o, std::string const& name, SELF& self, CARGS... args )
939 : Accumulator<Atomicity, Args...>( args... ), m_monitoringHub( &o->serviceLocator()->monitoringHub() ) {
940 m_monitoringHub->registerEntity( o->name(), name, self.typeString, self );
941 }
942
943 private:
945 };
946
951 template <atomicity Atomicity = atomicity::full, typename Arithmetic = unsigned long>
952 struct Counter : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic> {
953 inline static const std::string typeString{ std::string{ "counter:Counter:" } + typeid( Arithmetic ).name() };
954 using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::BufferableCounter;
955 template <typename OWNER>
956 Counter( OWNER* o, std::string const& name )
957 : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>( o, name, *this ) {}
958 Counter& operator++() { return ( *this ) += 1; }
959 Counter& operator+=( const Arithmetic v ) {
961 return *this;
962 }
963 using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::print;
964
965 template <typename stream>
966 stream& printImpl( stream& o, bool tableFormat ) const {
967 // Avoid printing empty counters in non DEBUG mode
968 auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" );
969 return o << boost::format{ fmt } % this->nEntries();
970 }
971
972 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
973 return printImpl( o, tableFormat );
974 }
975 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
976 bool toBePrinted() const override { return this->nEntries() > 0; }
977 friend void reset( Counter& c ) { c.reset(); }
978 friend void mergeAndReset( Counter& c, Counter& o ) { c.mergeAndReset( o ); }
979 friend void to_json( nlohmann::json& j, Counter const& c ) {
980 j = { { "type", c.typeString }, { "empty", c.nEntries() == 0 }, { "nEntries", c.nEntries() } };
981 }
982 static Counter fromJSON( const nlohmann::json& j ) {
984 }
985 };
986
991 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
992 struct AveragingCounter : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic> {
993 inline static const std::string typeString{ std::string{ "counter:AveragingCounter:" } +
994 typeid( Arithmetic ).name() };
996 template <typename OWNER>
997 AveragingCounter( OWNER* o, std::string const& name )
998 : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>( o, name, *this ) {}
999 using BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>::print;
1000
1001 template <typename stream>
1002 stream& printImpl( stream& o, bool tableFormat ) const {
1003 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
1004 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean();
1005 }
1006
1007 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1008 return printImpl( o, tableFormat );
1009 }
1010 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1011
1012 bool toBePrinted() const override { return this->nEntries() > 0; }
1013 friend void reset( AveragingCounter& c ) { return c.reset(); }
1014 friend void mergeAndReset( AveragingCounter& c, AveragingCounter& o ) { c.mergeAndReset( o ); }
1015 friend void to_json( nlohmann::json& j, AveragingCounter const& c ) {
1016 j = { { "type", c.typeString },
1017 { "empty", c.nEntries() == 0 },
1018 { "nEntries", c.nEntries() },
1019 { "sum", c.sum() },
1020 { "mean", c.mean() } };
1021 }
1022 static AveragingCounter fromJSON( const nlohmann::json& j ) {
1023 return AveragingAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nEntries", "sum" } );
1024 }
1025 };
1026 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1028
1033 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1034 struct SigmaCounter : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic> {
1035 inline static const std::string typeString{ std::string{ "counter:SigmaCounter:" } + typeid( Arithmetic ).name() };
1036 using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::BufferableCounter;
1037 template <typename OWNER>
1038 SigmaCounter( OWNER* o, std::string const& name )
1039 : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>( o, name, *this ) {}
1040 using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::print;
1041
1042 template <typename stream>
1043 stream& printImpl( stream& o, bool tableFormat ) const {
1044 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |"
1045 : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
1046 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
1047 }
1048
1049 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1050 return printImpl( o, tableFormat );
1051 }
1052 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1053 bool toBePrinted() const override { return this->nEntries() > 0; }
1054 friend void reset( SigmaCounter& c ) { c.reset(); }
1055 friend void mergeAndReset( SigmaCounter& c, SigmaCounter& o ) { c.mergeAndReset( o ); }
1056 friend void to_json( nlohmann::json& j, SigmaCounter const& c ) {
1057 j = { { "type", c.typeString },
1058 { "empty", c.nEntries() == 0 },
1059 { "nEntries", c.nEntries() },
1060 { "sum", c.sum() },
1061 { "mean", c.mean() },
1062 { "sum2", c.sum2() },
1063 { "standard_deviation", c.standard_deviation() } };
1064 }
1065 static SigmaCounter fromJSON( const nlohmann::json& j ) {
1066 return SigmaAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { { "nEntries", "sum" }, "sum2" } );
1067 }
1068 };
1069
1074 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1075 struct StatCounter : BufferableCounter<Atomicity, StatAccumulator, Arithmetic> {
1076 inline static const std::string typeString{ std::string{ "counter:StatCounter:" } + typeid( Arithmetic ).name() };
1077 using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::BufferableCounter;
1078 template <typename OWNER>
1079 StatCounter( OWNER* o, std::string const& name )
1080 : BufferableCounter<Atomicity, StatAccumulator, Arithmetic>( o, name, *this ) {}
1081 using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::print;
1082
1083 template <typename stream>
1084 stream& printImpl( stream& o, bool tableFormat ) const {
1085 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |"
1086 : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
1087 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
1088 this->min() % this->max();
1089 }
1090
1091 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1092 return printImpl( o, tableFormat );
1093 }
1094 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1095 bool toBePrinted() const override { return this->nEntries() > 0; }
1096 friend void reset( StatCounter& c ) { c.reset(); }
1097 friend void mergeAndReset( StatCounter& c, StatCounter& o ) { c.mergeAndReset( o ); }
1098 friend void to_json( nlohmann::json& j, StatCounter const& c ) {
1099 j = { { "type", c.typeString },
1100 { "empty", c.nEntries() == 0 },
1101 { "nEntries", c.nEntries() },
1102 { "sum", c.sum() },
1103 { "mean", c.mean() },
1104 { "sum2", c.sum2() },
1105 { "standard_deviation", c.standard_deviation() },
1106 { "min", c.min() },
1107 { "max", c.max() } };
1108 }
1109 static StatCounter fromJSON( const nlohmann::json& j ) {
1111 j, { { { "nEntries", "sum" }, "sum2" }, "min", "max" } );
1112 }
1113 };
1114
1119 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1120 struct BinomialCounter : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic> {
1121 inline static const std::string typeString{ std::string{ "counter:BinomialCounter:" } +
1122 typeid( Arithmetic ).name() };
1123 using BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>::BufferableCounter;
1124 template <typename OWNER>
1125 BinomialCounter( OWNER* o, std::string const& name )
1126 : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>( o, name, *this ) {}
1127
1128 template <typename stream>
1129 stream& printImpl( stream& o, bool tableFormat ) const {
1130 auto fmt = ( tableFormat ? "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |"
1131 : "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
1132 return o << boost::format{ fmt } % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
1133 ( this->efficiencyErr() * 100 );
1134 }
1135
1136 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1137 return printImpl( o, tableFormat );
1138 }
1139 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1140
1141 template <typename stream>
1142 stream& printImpl( stream& o, std::string_view tag ) const {
1143 // override default print to add a '*' in from of the name
1144 o << boost::format{ " |*%|-48.48s|%|50t|" } % ( std::string{ "\"" }.append( tag ).append( "\"" ) );
1145 return print( o, true );
1146 }
1147
1148 std::ostream& print( std::ostream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
1149 MsgStream& print( MsgStream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
1150 bool toBePrinted() const override { return this->nEntries() > 0; }
1151 friend void reset( BinomialCounter& c ) { c.reset(); }
1152 friend void mergeAndReset( BinomialCounter& c, BinomialCounter& o ) { c.mergeAndReset( o ); }
1153 friend void to_json( nlohmann::json& j, BinomialCounter const& c ) {
1154 j = { { "type", c.typeString },
1155 { "empty", c.nEntries() == 0 },
1156 { "nEntries", c.nTrueEntries() + c.nFalseEntries() },
1157 { "nTrueEntries", c.nTrueEntries() },
1158 { "nFalseEntries", c.nFalseEntries() },
1159 { "efficiency", c.efficiency() },
1160 { "efficiencyErr", c.efficiencyErr() } };
1161 }
1162 static BinomialCounter fromJSON( const nlohmann::json& j ) {
1163 return BinomialAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nTrueEntries", "nFalseEntries" } );
1164 }
1165 };
1166
1168 template <atomicity Atomicity>
1169 struct Handler : Adder<unsigned long, Atomicity> {
1171 static void merge( typename Base::InternalType& orig, bool b ) {
1172 if ( b ) Base::merge( orig, 1 );
1173 }
1174 };
1175 // note that Arithmetic type is unused in this case but needs to be there in case
1176 // we want to create AccumulatorSets with this Accumulator
1177 template <atomicity Atomicity, typename Arithmetic = double>
1179 } // namespace details::MsgCounter
1180
1181 template <MSG::Level level, atomicity Atomicity = atomicity::full>
1183 public:
1184 inline static const std::string typeString{ "counter:MsgCounter" };
1185 template <typename OWNER>
1186 MsgCounter( OWNER* o, std::string const& ms, unsigned long nMax = 10 )
1187 : m_monitoringHub{ &o->serviceLocator()->monitoringHub() }, logger( o ), msg( ms ), max( nMax ) {
1188 m_monitoringHub->registerEntity( o->name(), ms, typeString, *this );
1189 }
1191 ( *this ) += true;
1192 return *this;
1193 }
1194 MsgCounter& operator+=( const bool by ) {
1196 if ( by ) log();
1197 return *this;
1198 }
1199 MsgCounter( MsgCounter const& ) = delete;
1200 MsgCounter& operator=( MsgCounter const& ) = delete;
1202 if ( m_monitoringHub ) m_monitoringHub->removeEntity( *this );
1203 }
1204 template <typename stream>
1205 stream& printImpl( stream& o, bool tableFormat ) const {
1206 return o << boost::format{ tableFormat ? "|%|10d| |" : "#=%|-7lu|" } % this->value();
1207 }
1209 std::ostream& print( std::ostream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
1210 MsgStream& print( MsgStream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
1211 bool toBePrinted() const override { return this->value() > 0; }
1212 friend void reset( MsgCounter& c ) { c.reset(); }
1213 friend void mergeAndReset( MsgCounter& c, MsgCounter& o ) { c.mergeAndReset( o ); }
1214 friend void to_json( nlohmann::json& j, MsgCounter const& c ) {
1215 j = { { "type", c.typeString }, { "empty", c.value() == 0 },
1216 { "nEntries", c.value() }, { "level", level },
1217 { "max", c.max }, { "msg", c.msg } };
1218 }
1219 static MsgCounter fromJSON( const nlohmann::json& j ) {
1220 return { j.at( "msg" ).get<std::string>(), j.at( "max" ).get<unsigned long>(),
1221 j.at( "nEntries" ).get<unsigned long>() };
1222 }
1223
1224 private:
1225 MsgCounter( std::string const& ms, unsigned long nMax, unsigned long count )
1226 : details::MsgCounter::MsgAccumulator<Atomicity>{ count }, msg( ms ), max( nMax ) {}
1227
1229 const CommonMessagingBase* logger{ nullptr };
1230 std::string msg;
1231 unsigned long max;
1232 void log() {
1233 if ( this->value() <= max && logger ) {
1234 if ( this->value() == max ) {
1235 logger->msgStream( level ) << "Suppressing message: " << std::quoted( msg, '\'' ) << endmsg;
1236 } else {
1237 logger->msgStream( level ) << msg << endmsg;
1238 }
1239 }
1240 }
1241 };
1242
1248 template <typename Counter, typename Container, typename Fun>
1249 void accumulate( Counter& counter, const Container& container, Fun f = Identity{} ) {
1250 auto b = counter.buffer();
1251 for ( const auto& elem : container ) b += f( elem );
1252 }
1253
1254} // 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.
Extremum< Arithmetic, Atomicity, std::less< Arithmetic >, detail::Max< Arithmetic > > Minimum
A Minimun ValueHandler operator(a, b) means a = min(a, b) In case of full atomicity,...
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
Definition Counters.h:34
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...
Extremum< Arithmetic, Atomicity, std::greater< Arithmetic >, detail::Min< Arithmetic > > Maximum
An Maximum ValueHandler operator(a, b) means a = max(a, b) In case of full atomicity,...
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.
Type trait providing the highest possible value (to be used as initial value for Minimum)
static constexpr Arithmetic value()
Type trait providing the lowest possible value (to be used as initial value for Maximum)
static constexpr Arithmetic value()
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)