The Gaudi Framework  master (57817a18)
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>
547
548// This pragma is only required when Arithmetic is a floating point while `Bases::poerator+=`
549// expects a boolean as the conversion implies calling `== 0` on the floating-point
550// This should never happen, but does in StatEntity.h
551// `StatEntity` is only present for backward compatibility and should be ultimately removed
552// At that moment, the pragma can be dropped
553#pragma GCC diagnostic push
554#pragma GCC diagnostic ignored "-Wfloat-equal"
556 ( Bases<Atomicity, Arithmetic>::operator+=( by ), ... );
557 return *this;
558 }
559#pragma GCC diagnostic pop
560
561 OutputType value() const { return std::make_tuple( Bases<Atomicity, Arithmetic>::value()... ); }
562 void reset() { ( Bases<Atomicity, Arithmetic>::reset(), ... ); }
563 template <atomicity Ato>
565 ( Bases<Atomicity, Arithmetic>::mergeAndReset( static_cast<Bases<Ato, Arithmetic>&>( other ) ), ... );
566 }
567 template <atomicity Ato>
569 ( Bases<Atomicity, Arithmetic>::operator+( static_cast<Bases<Ato, Arithmetic>&&>( other ) ), ... );
570 }
571 // explicitely delete operator++ as it's not 100% clear what one would expect from them in more
572 // complex cases, e.g. binomial counters, or counters based on enums, etc...
573 void operator++() = delete;
574 void operator++( int ) = delete;
575
576 protected:
578 void reset( const InternalType& t ) {
579 std::apply( [this]( const auto&... i ) { ( this->Bases<Atomicity, Arithmetic>::reset( i ), ... ); }, t );
580 }
581 static InternalType extractJSONData( const nlohmann::json& j, const JSONStringEntriesType& entries ) {
582 return extractJSONDataHelper( j, entries, std::index_sequence_for<Bases<Atomicity, Arithmetic>...>{} );
583 }
584
585 private:
586 template <size_t... Is>
587 static InternalType extractJSONDataHelper( const nlohmann::json& j, const JSONStringEntriesType& entries,
588 std::index_sequence<Is...> ) {
589 return extractJSONDataHelper( j, std::get<Is>( entries )... );
590 }
591 static InternalType
592 extractJSONDataHelper( const nlohmann::json& j,
593 typename Bases<Atomicity, Arithmetic>::JSONStringEntriesType... entries ) {
594 return { Bases<Atomicity, Arithmetic>::extractJSONData( j, entries )... };
595 }
596 };
597
602 template <atomicity Atomicity, typename Arithmetic = double>
604 : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
605 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity,
607 Arithmetic max() const { return this->value(); }
608 };
609
614 template <atomicity Atomicity, typename Arithmetic = double>
616 : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
617 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity,
619 Arithmetic min() const { return this->value(); }
620 };
621
628 template <atomicity Atomicity, typename Arithmetic = double>
629 struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>> {
630 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>>::GenericAccumulator;
632 ( *this ) += Arithmetic{};
633 return *this;
634 }
636 auto copy = *this;
637 ++( *this );
638 return copy;
639 }
640 unsigned long nEntries() const { return this->value(); }
641 };
642
647 template <atomicity Atomicity, typename Arithmetic = double>
648 struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
649 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity>::GenericAccumulator;
650 Arithmetic sum() const { return this->value(); }
651 };
652
658 template <atomicity Atomicity, typename Arithmetic = unsigned long>
659 struct IntegralAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
660 static_assert( std::is_integral_v<Arithmetic>,
661 "Invalid Arithmetic type for IntegralAccumulator. It must be an integral type" );
662
663 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity>::GenericAccumulator;
665 ( *this ) += 1;
666 return *this;
667 }
669 auto copy = *this;
670 ++( *this );
671 return copy;
672 }
673 Arithmetic nEntries() const { return this->value(); }
674 Arithmetic sum() const { return this->value(); }
675 };
676
681 template <atomicity Atomicity, typename Arithmetic = double>
682 struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
683 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square>::GenericAccumulator;
684 Arithmetic sum2() const { return this->value(); }
685 };
686
688 struct TrueTo1 {
689 unsigned int operator()( bool v ) const { return v; }
690 };
691
697 template <atomicity Atomicity, typename Arithmetic>
698 struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
699 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1>::GenericAccumulator;
700 unsigned long nTrueEntries() const { return this->value(); }
701 };
702
704 struct FalseTo1 {
705 unsigned int operator()( bool v ) const { return !v; }
706 };
707
713 template <atomicity Atomicity, typename Arithmetic>
714 struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
715 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1>::GenericAccumulator;
716 unsigned long nFalseEntries() const { return this->value(); }
717 };
718
724 template <atomicity Atomicity, typename Arithmetic>
725 struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, bool, TrueAccumulator, FalseAccumulator> {
727 unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); }
728
729 template <typename Result = fp_result_type<Arithmetic>>
730 auto efficiency() const {
731 auto nbEntries = nEntries();
732 if ( 1 > nbEntries ) return Result{ -1 };
733 return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
734 }
735 auto eff() const { return efficiency(); }
736
737 template <typename Result = fp_result_type<Arithmetic>>
738 auto efficiencyErr() const {
739 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
740 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
742 using std::sqrt;
743 auto nbEntries = nEntries();
744 if ( 1 > nbEntries ) return Result{ -1 };
745 return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
746 }
747 auto effErr() const { return efficiencyErr(); }
748 using AccumulatorSet<bool, Atomicity, bool, TrueAccumulator, FalseAccumulator>::operator+=;
749 struct binomial_t {
750 unsigned long nPass;
751 unsigned long nTotal;
752 };
754 assert( b.nPass <= b.nTotal );
755 TrueAccumulator<atomicity::none, bool> t{ std::in_place, b.nPass };
757 FalseAccumulator<atomicity::none, bool> f{ std::in_place, b.nTotal - b.nPass };
759 return *this;
760 }
761 };
762
768 template <atomicity Atomicity, typename Arithmetic, template <atomicity, typename> typename CountAcc,
769 template <atomicity, typename> typename SumAcc>
771 : AccumulatorSet<Arithmetic, Atomicity, typename CountAcc<Atomicity, Arithmetic>::InputType, CountAcc, SumAcc> {
772 static_assert( std::is_same_v<typename CountAcc<Atomicity, Arithmetic>::InputType,
773 typename SumAcc<Atomicity, Arithmetic>::InputType>,
774 "Incompatible Counters in definition of AveragingAccumulator. Both should have identical Input" );
775 using AccumulatorSet<Arithmetic, Atomicity, typename CountAcc<Atomicity, Arithmetic>::InputType, CountAcc,
776 SumAcc>::AccumulatorSet;
777 template <typename Result = fp_result_type<Arithmetic>>
778 auto mean() const {
779 auto n = this->nEntries();
780 Result sum = this->sum();
781 return ( n > 0 ) ? static_cast<Result>( sum / n ) : Result{};
782 }
783 };
784
789 template <atomicity Atomicity, typename Arithmetic>
791
797 template <atomicity Atomicity, typename Arithmetic, template <atomicity, typename> typename AvgAcc,
798 template <atomicity, typename> typename SquareAcc>
800 : AccumulatorSet<Arithmetic, Atomicity, typename AvgAcc<Atomicity, Arithmetic>::InputType, AvgAcc, SquareAcc> {
801 static_assert( std::is_same_v<typename AvgAcc<Atomicity, Arithmetic>::InputType,
802 typename SquareAcc<Atomicity, Arithmetic>::InputType>,
803 "Incompatible Counters in definition of SigmaAccumulator. Both should have identical Input" );
804 using AccumulatorSet<Arithmetic, Atomicity, typename SquareAcc<Atomicity, Arithmetic>::InputType, AvgAcc,
805 SquareAcc>::AccumulatorSet;
806 template <typename Result = fp_result_type<Arithmetic>>
808 auto n = this->nEntries();
809 Result sum = this->sum();
810 return ( n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / n ) : Result{};
811 }
812
813 template <typename Result = fp_result_type<Arithmetic>>
815 auto n = this->nEntries();
816 Result sum = this->sum();
817 return ( n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) ) : Result{};
818 }
819
820 template <typename Result = fp_result_type<Arithmetic>>
821 auto standard_deviation() const {
822 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
823 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
825 using std::sqrt;
826 Result v = biased_sample_variance();
827 return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v ) );
828 }
829 [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const {
830 return standard_deviation();
831 }
832
833 template <typename Result = fp_result_type<Arithmetic>>
834 auto meanErr() const {
835 auto n = this->nEntries();
836 if ( 0 == n ) return Result{};
837 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
838 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
840 using std::sqrt;
841 Result v = biased_sample_variance();
842 return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) );
843 }
844 };
845
850 template <atomicity Atomicity, typename Arithmetic>
852
857 template <atomicity Atomicity, typename Arithmetic>
860
867 template <template <atomicity Ato, typename... Int> class ContainedAccumulator, atomicity Atomicity, typename... Args>
868 class Buffer : public ContainedAccumulator<atomicity::none, Args...> {
869 using prime_type = ContainedAccumulator<Atomicity, Args...>;
870 using base_type = ContainedAccumulator<atomicity::none, Args...>;
871
872 public:
873 Buffer() = delete;
875 Buffer( const Buffer& ) = delete;
876 void operator=( const Buffer& ) = delete;
877 Buffer( Buffer&& other ) : base_type( std::move( other ) ), m_prime( other.m_prime ) { other.m_prime = nullptr; }
878 void push() {
879 if ( m_prime ) { m_prime->mergeAndReset( static_cast<base_type&>( *this ) ); }
880 }
881 ~Buffer() { push(); }
882
883 private:
884 prime_type* m_prime = nullptr;
885 };
886
892 PrintableCounter() = default;
894 virtual ~PrintableCounter() = default;
895 // add tag to printout
896 template <typename stream>
897 stream& printImpl( stream& s, std::string_view tag ) const {
898 s << boost::format{ " | %|-48.48s|%|50t|" } % ( std::string{ '\"' }.append( tag ).append( "\"" ) );
899 return print( s, true );
900 }
901
902 virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
903 virtual MsgStream& print( MsgStream&, bool tableFormat = true ) const = 0;
905 virtual std::ostream& print( std::ostream& o, std::string_view tag ) const { return printImpl( o, tag ); }
906 virtual MsgStream& print( MsgStream& o, std::string_view tag ) const { return printImpl( o, tag ); }
909 virtual bool toBePrinted() const { return true; }
911 std::string toString() const {
912 std::ostringstream ost;
913 print( ost );
914 return ost.str();
915 }
916 };
917
921 inline std::ostream& operator<<( std::ostream& s, const PrintableCounter& counter ) { return counter.print( s ); }
922 inline MsgStream& operator<<( MsgStream& s, const PrintableCounter& counter ) { return counter.print( s ); }
929 template <atomicity Atomicity, template <atomicity Ato, typename... Int> class Accumulator, typename... Args>
930 class BufferableCounter : public PrintableCounter, public Accumulator<Atomicity, Args...> {
931 public:
932 using Accumulator<Atomicity, Args...>::Accumulator;
933 using BufferType = Buffer<Accumulator, Atomicity, Args...>;
934 BufferableCounter() = default;
935 template <typename OWNER>
936 BufferableCounter( OWNER* o, std::string const& name ) : BufferableCounter( o, name, *this ) {}
937 BufferType buffer() { return { *this }; }
941 if ( m_monitoringHub ) { m_monitoringHub->removeEntity( *this ); }
942 }
943
944 inline static const std::string typeString{ "counter" };
945
946 protected:
947 template <typename OWNER, typename SELF, typename... CARGS>
948 BufferableCounter( OWNER* o, std::string const& name, SELF& self, CARGS... args )
949 : Accumulator<Atomicity, Args...>( args... ), m_monitoringHub( &o->serviceLocator()->monitoringHub() ) {
950 m_monitoringHub->registerEntity( o->name(), name, self.typeString, self );
951 }
952
953 private:
955 };
956
961 template <atomicity Atomicity = atomicity::full, typename Arithmetic = unsigned long>
962 struct Counter : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic> {
963 inline static const std::string typeString{ std::string{ "counter:Counter:" } + typeid( Arithmetic ).name() };
964 using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::BufferableCounter;
965 template <typename OWNER>
966 Counter( OWNER* o, std::string const& name )
967 : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>( o, name, *this ) {}
968 Counter& operator++() { return ( *this ) += 1; }
969 Counter& operator+=( const Arithmetic v ) {
971 return *this;
972 }
973 using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::print;
974
975 template <typename stream>
976 stream& printImpl( stream& o, bool tableFormat ) const {
977 // Avoid printing empty counters in non DEBUG mode
978 auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" );
979 return o << boost::format{ fmt } % this->nEntries();
980 }
981
982 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
983 return printImpl( o, tableFormat );
984 }
985 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
986 bool toBePrinted() const override { return this->nEntries() > 0; }
987 friend void reset( Counter& c ) { c.reset(); }
988 friend void mergeAndReset( Counter& c, Counter& o ) { c.mergeAndReset( o ); }
989 friend void to_json( nlohmann::json& j, Counter const& c ) {
990 j = { { "type", c.typeString }, { "empty", c.nEntries() == 0 }, { "nEntries", c.nEntries() } };
991 }
992 static Counter fromJSON( const nlohmann::json& j ) {
994 }
995 };
996
1001 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1002 struct AveragingCounter : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic> {
1003 inline static const std::string typeString{ std::string{ "counter:AveragingCounter:" } +
1004 typeid( Arithmetic ).name() };
1005 using BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>::BufferableCounter;
1006 template <typename OWNER>
1007 AveragingCounter( OWNER* o, std::string const& name )
1008 : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>( o, name, *this ) {}
1009 using BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>::print;
1010
1011 template <typename stream>
1012 stream& printImpl( stream& o, bool tableFormat ) const {
1013 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
1014 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean();
1015 }
1016
1017 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1018 return printImpl( o, tableFormat );
1019 }
1020 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1021
1022 bool toBePrinted() const override { return this->nEntries() > 0; }
1023 friend void reset( AveragingCounter& c ) { return c.reset(); }
1024 friend void mergeAndReset( AveragingCounter& c, AveragingCounter& o ) { c.mergeAndReset( o ); }
1025 friend void to_json( nlohmann::json& j, AveragingCounter const& c ) {
1026 j = { { "type", c.typeString },
1027 { "empty", c.nEntries() == 0 },
1028 { "nEntries", c.nEntries() },
1029 { "sum", c.sum() },
1030 { "mean", c.mean() } };
1031 }
1032 static AveragingCounter fromJSON( const nlohmann::json& j ) {
1033 return AveragingAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nEntries", "sum" } );
1034 }
1035 };
1036 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1038
1043 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1044 struct SigmaCounter : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic> {
1045 inline static const std::string typeString{ std::string{ "counter:SigmaCounter:" } + typeid( Arithmetic ).name() };
1046 using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::BufferableCounter;
1047 template <typename OWNER>
1048 SigmaCounter( OWNER* o, std::string const& name )
1049 : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>( o, name, *this ) {}
1050 using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::print;
1051
1052 template <typename stream>
1053 stream& printImpl( stream& o, bool tableFormat ) const {
1054 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |"
1055 : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
1056 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
1057 }
1058
1059 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1060 return printImpl( o, tableFormat );
1061 }
1062 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1063 bool toBePrinted() const override { return this->nEntries() > 0; }
1064 friend void reset( SigmaCounter& c ) { c.reset(); }
1065 friend void mergeAndReset( SigmaCounter& c, SigmaCounter& o ) { c.mergeAndReset( o ); }
1066 friend void to_json( nlohmann::json& j, SigmaCounter const& c ) {
1067 j = { { "type", c.typeString },
1068 { "empty", c.nEntries() == 0 },
1069 { "nEntries", c.nEntries() },
1070 { "sum", c.sum() },
1071 { "mean", c.mean() },
1072 { "sum2", c.sum2() },
1073 { "standard_deviation", c.standard_deviation() } };
1074 }
1075 static SigmaCounter fromJSON( const nlohmann::json& j ) {
1076 return SigmaAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { { "nEntries", "sum" }, "sum2" } );
1077 }
1078 };
1079
1084 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1085 struct StatCounter : BufferableCounter<Atomicity, StatAccumulator, Arithmetic> {
1086 inline static const std::string typeString{ std::string{ "counter:StatCounter:" } + typeid( Arithmetic ).name() };
1087 using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::BufferableCounter;
1088 template <typename OWNER>
1089 StatCounter( OWNER* o, std::string const& name )
1090 : BufferableCounter<Atomicity, StatAccumulator, Arithmetic>( o, name, *this ) {}
1091 using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::print;
1092
1093 template <typename stream>
1094 stream& printImpl( stream& o, bool tableFormat ) const {
1095 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |"
1096 : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
1097 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
1098 this->min() % this->max();
1099 }
1100
1101 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1102 return printImpl( o, tableFormat );
1103 }
1104 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1105 bool toBePrinted() const override { return this->nEntries() > 0; }
1106 friend void reset( StatCounter& c ) { c.reset(); }
1107 friend void mergeAndReset( StatCounter& c, StatCounter& o ) { c.mergeAndReset( o ); }
1108 friend void to_json( nlohmann::json& j, StatCounter const& c ) {
1109 j = { { "type", c.typeString },
1110 { "empty", c.nEntries() == 0 },
1111 { "nEntries", c.nEntries() },
1112 { "sum", c.sum() },
1113 { "mean", c.mean() },
1114 { "sum2", c.sum2() },
1115 { "standard_deviation", c.standard_deviation() },
1116 { "min", c.min() },
1117 { "max", c.max() } };
1118 }
1119 static StatCounter fromJSON( const nlohmann::json& j ) {
1121 j, { { { "nEntries", "sum" }, "sum2" }, "min", "max" } );
1122 }
1123 };
1124
1129 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1130 struct BinomialCounter : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic> {
1131 inline static const std::string typeString{ std::string{ "counter:BinomialCounter:" } +
1132 typeid( Arithmetic ).name() };
1133 using BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>::BufferableCounter;
1134 template <typename OWNER>
1135 BinomialCounter( OWNER* o, std::string const& name )
1136 : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>( o, name, *this ) {}
1137
1138 template <typename stream>
1139 stream& printImpl( stream& o, bool tableFormat ) const {
1140 auto fmt = ( tableFormat ? "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |"
1141 : "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
1142 return o << boost::format{ fmt } % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
1143 ( this->efficiencyErr() * 100 );
1144 }
1145
1146 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1147 return printImpl( o, tableFormat );
1148 }
1149 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1150
1151 template <typename stream>
1152 stream& printImpl( stream& o, std::string_view tag ) const {
1153 // override default print to add a '*' in from of the name
1154 o << boost::format{ " |*%|-48.48s|%|50t|" } % ( std::string{ "\"" }.append( tag ).append( "\"" ) );
1155 return print( o, true );
1156 }
1157
1158 std::ostream& print( std::ostream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
1159 MsgStream& print( MsgStream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
1160 bool toBePrinted() const override { return this->nEntries() > 0; }
1161 friend void reset( BinomialCounter& c ) { c.reset(); }
1162 friend void mergeAndReset( BinomialCounter& c, BinomialCounter& o ) { c.mergeAndReset( o ); }
1163 friend void to_json( nlohmann::json& j, BinomialCounter const& c ) {
1164 j = { { "type", c.typeString },
1165 { "empty", c.nEntries() == 0 },
1166 { "nEntries", c.nTrueEntries() + c.nFalseEntries() },
1167 { "nTrueEntries", c.nTrueEntries() },
1168 { "nFalseEntries", c.nFalseEntries() },
1169 { "efficiency", c.efficiency() },
1170 { "efficiencyErr", c.efficiencyErr() } };
1171 }
1172 static BinomialCounter fromJSON( const nlohmann::json& j ) {
1173 return BinomialAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nTrueEntries", "nFalseEntries" } );
1174 }
1175 };
1176
1178 template <atomicity Atomicity>
1179 struct Handler : Adder<unsigned long, Atomicity> {
1181 static void merge( typename Base::InternalType& orig, bool b ) {
1182 if ( b ) Base::merge( orig, 1 );
1183 }
1184 };
1185 // note that Arithmetic type is unused in this case but needs to be there in case
1186 // we want to create AccumulatorSets with this Accumulator
1187 template <atomicity Atomicity, typename Arithmetic = double>
1189 } // namespace details::MsgCounter
1190
1191 template <MSG::Level level, atomicity Atomicity = atomicity::full>
1193 public:
1194 inline static const std::string typeString{ "counter:MsgCounter" };
1195 template <typename OWNER>
1196 MsgCounter( OWNER* o, std::string const& ms, unsigned long nMax = 10 )
1197 : m_monitoringHub{ &o->serviceLocator()->monitoringHub() }, logger( o ), msg( ms ), max( nMax ) {
1198 m_monitoringHub->registerEntity( o->name(), ms, typeString, *this );
1199 }
1201 ( *this ) += true;
1202 return *this;
1203 }
1204 MsgCounter& operator+=( const bool by ) {
1206 if ( by ) log();
1207 return *this;
1208 }
1209 MsgCounter( MsgCounter const& ) = delete;
1210 MsgCounter& operator=( MsgCounter const& ) = delete;
1212 if ( m_monitoringHub ) m_monitoringHub->removeEntity( *this );
1213 }
1214 template <typename stream>
1215 stream& printImpl( stream& o, bool tableFormat ) const {
1216 return o << boost::format{ tableFormat ? "|%|10d| |" : "#=%|-7lu|" } % this->value();
1217 }
1219 std::ostream& print( std::ostream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
1220 MsgStream& print( MsgStream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
1221 bool toBePrinted() const override { return this->value() > 0; }
1222 friend void reset( MsgCounter& c ) { c.reset(); }
1223 friend void mergeAndReset( MsgCounter& c, MsgCounter& o ) { c.mergeAndReset( o ); }
1224 friend void to_json( nlohmann::json& j, MsgCounter const& c ) {
1225 j = { { "type", c.typeString }, { "empty", c.value() == 0 },
1226 { "nEntries", c.value() }, { "level", level },
1227 { "max", c.max }, { "msg", c.msg } };
1228 }
1229 static MsgCounter fromJSON( const nlohmann::json& j ) {
1230 return { j.at( "msg" ).get<std::string>(), j.at( "max" ).get<unsigned long>(),
1231 j.at( "nEntries" ).get<unsigned long>() };
1232 }
1233
1234 private:
1235 MsgCounter( std::string const& ms, unsigned long nMax, unsigned long count )
1236 : details::MsgCounter::MsgAccumulator<Atomicity>{ count }, msg( ms ), max( nMax ) {}
1237
1239 const CommonMessagingBase* logger{ nullptr };
1240 std::string msg;
1241 unsigned long max;
1242 void log() {
1243 if ( this->value() <= max && logger ) {
1244 if ( this->value() == max ) {
1245 logger->msgStream( level ) << "Suppressing message: " << std::quoted( msg, '\'' ) << endmsg;
1246 } else {
1247 logger->msgStream( level ) << msg << endmsg;
1248 }
1249 }
1250 }
1251 };
1252
1258 template <typename Counter, typename Container, typename Fun>
1259 void accumulate( Counter& counter, const Container& container, Fun f = Identity{} ) {
1260 auto b = counter.buffer();
1261 for ( const auto& elem : container ) b += f( elem );
1262 }
1263
1264} // 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
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
AccumulatorSet< Arithmetic, Atomicity, Arithmetic, SigmaAccumulator, MinAccumulator, MaxAccumulator > StatAccumulator
StatAccumulator.
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.
static void merge(InternalType &a, Arithmetic b) noexcept
static void merge(InternalType &a, Arithmetic b) noexcept
An Adder ValueHandler operator(a, b) means a += b.
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)
static constexpr OutputType getValue(const InternalType &v) noexcept
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
static constexpr OutputType getValue(const InternalType &v) noexcept
Base type for all functors used as ValuesHandler.
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)