The Gaudi Framework  master (69a68366)
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
562 protected:
564 void reset( const InternalType& t ) {
565 std::apply( [this]( const auto&... i ) { ( this->Bases<Atomicity, Arithmetic>::reset( i ), ... ); }, t );
566 }
567 static InternalType extractJSONData( const nlohmann::json& j, const JSONStringEntriesType& entries ) {
568 return extractJSONDataHelper( j, entries, std::index_sequence_for<Bases<Atomicity, Arithmetic>...>{} );
569 }
570
571 private:
572 template <size_t... Is>
573 static InternalType extractJSONDataHelper( const nlohmann::json& j, const JSONStringEntriesType& entries,
574 std::index_sequence<Is...> ) {
575 return extractJSONDataHelper( j, std::get<Is>( entries )... );
576 }
577 static InternalType
578 extractJSONDataHelper( const nlohmann::json& j,
579 typename Bases<Atomicity, Arithmetic>::JSONStringEntriesType... entries ) {
580 return { Bases<Atomicity, Arithmetic>::extractJSONData( j, entries )... };
581 }
582 };
583
588 template <atomicity Atomicity, typename Arithmetic = double>
590 : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
591 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity,
593 Arithmetic max() const { return this->value(); }
594 };
595
600 template <atomicity Atomicity, typename Arithmetic = double>
602 : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
603 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity,
605 Arithmetic min() const { return this->value(); }
606 };
607
614 template <atomicity Atomicity, typename Arithmetic = double>
615 struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>> {
616 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>>::GenericAccumulator;
618 ( *this ) += Arithmetic{};
619 return *this;
620 }
622 auto copy = *this;
623 ++( *this );
624 return copy;
625 }
626 unsigned long nEntries() const { return this->value(); }
627 };
628
633 template <atomicity Atomicity, typename Arithmetic = double>
634 struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
635 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity>::GenericAccumulator;
636 Arithmetic sum() const { return this->value(); }
637 };
638
644 template <atomicity Atomicity, typename Arithmetic = unsigned long>
645 struct IntegralAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
646 static_assert( std::is_integral_v<Arithmetic>,
647 "Invalid Arithmetic type for IntegralAccumulator. It must be an integral type" );
648
649 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity>::GenericAccumulator;
651 ( *this ) += 1;
652 return *this;
653 }
655 auto copy = *this;
656 ++( *this );
657 return copy;
658 }
659 Arithmetic nEntries() const { return this->value(); }
660 Arithmetic sum() const { return this->value(); }
661 };
662
667 template <atomicity Atomicity, typename Arithmetic = double>
668 struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
669 using GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square>::GenericAccumulator;
670 Arithmetic sum2() const { return this->value(); }
671 };
672
674 struct TrueTo1 {
675 unsigned int operator()( bool v ) const { return v; }
676 };
677
683 template <atomicity Atomicity, typename Arithmetic>
684 struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
685 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1>::GenericAccumulator;
686 unsigned long nTrueEntries() const { return this->value(); }
687 };
688
690 struct FalseTo1 {
691 unsigned int operator()( bool v ) const { return !v; }
692 };
693
699 template <atomicity Atomicity, typename Arithmetic>
700 struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
701 using GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1>::GenericAccumulator;
702 unsigned long nFalseEntries() const { return this->value(); }
703 };
704
710 template <atomicity Atomicity, typename Arithmetic>
711 struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, bool, TrueAccumulator, FalseAccumulator> {
713 unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); }
714
715 template <typename Result = fp_result_type<Arithmetic>>
716 auto efficiency() const {
717 auto nbEntries = nEntries();
718 if ( 1 > nbEntries ) return Result{ -1 };
719 return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
720 }
721 auto eff() const { return efficiency(); }
722
723 template <typename Result = fp_result_type<Arithmetic>>
724 auto efficiencyErr() const {
725 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
726 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
728 using std::sqrt;
729 auto nbEntries = nEntries();
730 if ( 1 > nbEntries ) return Result{ -1 };
731 return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
732 }
733 auto effErr() const { return efficiencyErr(); }
734 using AccumulatorSet<bool, Atomicity, bool, TrueAccumulator, FalseAccumulator>::operator+=;
735 struct binomial_t {
736 unsigned long nPass;
737 unsigned long nTotal;
738 };
740 assert( b.nPass <= b.nTotal );
741 TrueAccumulator<atomicity::none, bool> t{ std::in_place, b.nPass };
743 FalseAccumulator<atomicity::none, bool> f{ std::in_place, b.nTotal - b.nPass };
745 return *this;
746 }
747 };
748
754 template <atomicity Atomicity, typename Arithmetic, template <atomicity, typename> typename CountAcc,
755 template <atomicity, typename> typename SumAcc>
757 : AccumulatorSet<Arithmetic, Atomicity, typename CountAcc<Atomicity, Arithmetic>::InputType, CountAcc, SumAcc> {
758 static_assert( std::is_same_v<typename CountAcc<Atomicity, Arithmetic>::InputType,
759 typename SumAcc<Atomicity, Arithmetic>::InputType>,
760 "Incompatible Counters in definition of AveragingAccumulator. Both should have identical Input" );
761 using AccumulatorSet<Arithmetic, Atomicity, typename CountAcc<Atomicity, Arithmetic>::InputType, CountAcc,
762 SumAcc>::AccumulatorSet;
763 template <typename Result = fp_result_type<Arithmetic>>
764 auto mean() const {
765 auto n = this->nEntries();
766 Result sum = this->sum();
767 return ( n > 0 ) ? static_cast<Result>( sum / n ) : Result{};
768 }
769 };
770
775 template <atomicity Atomicity, typename Arithmetic>
777
783 template <atomicity Atomicity, typename Arithmetic, template <atomicity, typename> typename AvgAcc,
784 template <atomicity, typename> typename SquareAcc>
786 : AccumulatorSet<Arithmetic, Atomicity, typename AvgAcc<Atomicity, Arithmetic>::InputType, AvgAcc, SquareAcc> {
787 static_assert( std::is_same_v<typename AvgAcc<Atomicity, Arithmetic>::InputType,
788 typename SquareAcc<Atomicity, Arithmetic>::InputType>,
789 "Incompatible Counters in definition of SigmaAccumulator. Both should have identical Input" );
790 using AccumulatorSet<Arithmetic, Atomicity, typename SquareAcc<Atomicity, Arithmetic>::InputType, AvgAcc,
791 SquareAcc>::AccumulatorSet;
792 template <typename Result = fp_result_type<Arithmetic>>
794 auto n = this->nEntries();
795 Result sum = this->sum();
796 return ( n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / n ) : Result{};
797 }
798
799 template <typename Result = fp_result_type<Arithmetic>>
801 auto n = this->nEntries();
802 Result sum = this->sum();
803 return ( n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) ) : Result{};
804 }
805
806 template <typename Result = fp_result_type<Arithmetic>>
807 auto standard_deviation() const {
808 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
809 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
811 using std::sqrt;
812 Result v = biased_sample_variance();
813 return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v ) );
814 }
815 [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const {
816 return standard_deviation();
817 }
818
819 template <typename Result = fp_result_type<Arithmetic>>
820 auto meanErr() const {
821 auto n = this->nEntries();
822 if ( 0 == n ) return Result{};
823 // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
824 // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
826 using std::sqrt;
827 Result v = biased_sample_variance();
828 return ( Result{ 0 } > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) );
829 }
830 };
831
836 template <atomicity Atomicity, typename Arithmetic>
838
843 template <atomicity Atomicity, typename Arithmetic>
846
853 template <template <atomicity Ato, typename... Int> class ContainedAccumulator, atomicity Atomicity, typename... Args>
854 class Buffer : public ContainedAccumulator<atomicity::none, Args...> {
855 using prime_type = ContainedAccumulator<Atomicity, Args...>;
856 using base_type = ContainedAccumulator<atomicity::none, Args...>;
857
858 public:
859 Buffer() = delete;
861 Buffer( const Buffer& ) = delete;
862 void operator=( const Buffer& ) = delete;
863 Buffer( Buffer&& other ) : base_type( std::move( other ) ), m_prime( other.m_prime ) { other.m_prime = nullptr; }
864 void push() {
865 if ( m_prime ) { m_prime->mergeAndReset( static_cast<base_type&>( *this ) ); }
866 }
867 ~Buffer() { push(); }
868
869 private:
870 prime_type* m_prime = nullptr;
871 };
872
878 PrintableCounter() = default;
880 virtual ~PrintableCounter() = default;
881 // add tag to printout
882 template <typename stream>
883 stream& printImpl( stream& s, std::string_view tag ) const {
884 s << boost::format{ " | %|-48.48s|%|50t|" } % ( std::string{ '\"' }.append( tag ).append( "\"" ) );
885 return print( s, true );
886 }
887
888 virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
889 virtual MsgStream& print( MsgStream&, bool tableFormat = true ) const = 0;
891 virtual std::ostream& print( std::ostream& o, std::string_view tag ) const { return printImpl( o, tag ); }
892 virtual MsgStream& print( MsgStream& o, std::string_view tag ) const { return printImpl( o, tag ); }
895 virtual bool toBePrinted() const { return true; }
897 std::string toString() const {
898 std::ostringstream ost;
899 print( ost );
900 return ost.str();
901 }
902 };
903
907 inline std::ostream& operator<<( std::ostream& s, const PrintableCounter& counter ) { return counter.print( s ); }
908 inline MsgStream& operator<<( MsgStream& s, const PrintableCounter& counter ) { return counter.print( s ); }
915 template <atomicity Atomicity, template <atomicity Ato, typename... Int> class Accumulator, typename... Args>
916 class BufferableCounter : public PrintableCounter, public Accumulator<Atomicity, Args...> {
917 public:
918 using Accumulator<Atomicity, Args...>::Accumulator;
919 using BufferType = Buffer<Accumulator, Atomicity, Args...>;
920 BufferableCounter() = default;
921 template <typename OWNER>
922 BufferableCounter( OWNER* o, std::string const& name ) : BufferableCounter( o, name, *this ) {}
923 BufferType buffer() { return { *this }; }
927 if ( m_monitoringHub ) { m_monitoringHub->removeEntity( *this ); }
928 }
929
930 inline static const std::string typeString{ "counter" };
931
932 protected:
933 template <typename OWNER, typename SELF, typename... CARGS>
934 BufferableCounter( OWNER* o, std::string const& name, SELF& self, CARGS... args )
935 : Accumulator<Atomicity, Args...>( args... ), m_monitoringHub( &o->serviceLocator()->monitoringHub() ) {
936 m_monitoringHub->registerEntity( o->name(), name, self.typeString, self );
937 }
938
939 private:
941 };
942
947 template <atomicity Atomicity = atomicity::full, typename Arithmetic = unsigned long>
948 struct Counter : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic> {
949 inline static const std::string typeString{ std::string{ "counter:Counter:" } + typeid( Arithmetic ).name() };
950 using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::BufferableCounter;
951 template <typename OWNER>
952 Counter( OWNER* o, std::string const& name )
953 : BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>( o, name, *this ) {}
954 Counter& operator++() { return ( *this ) += 1; }
955 Counter& operator+=( const Arithmetic v ) {
957 return *this;
958 }
959 using BufferableCounter<Atomicity, IntegralAccumulator, Arithmetic>::print;
960
961 template <typename stream>
962 stream& printImpl( stream& o, bool tableFormat ) const {
963 // Avoid printing empty counters in non DEBUG mode
964 auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" );
965 return o << boost::format{ fmt } % this->nEntries();
966 }
967
968 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
969 return printImpl( o, tableFormat );
970 }
971 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
972 bool toBePrinted() const override { return this->nEntries() > 0; }
973 friend void reset( Counter& c ) { c.reset(); }
974 friend void mergeAndReset( Counter& c, Counter& o ) { c.mergeAndReset( o ); }
975 friend void to_json( nlohmann::json& j, Counter const& c ) {
976 j = { { "type", c.typeString }, { "empty", c.nEntries() == 0 }, { "nEntries", c.nEntries() } };
977 }
978 static Counter fromJSON( const nlohmann::json& j ) {
980 }
981 };
982
987 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
988 struct AveragingCounter : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic> {
989 inline static const std::string typeString{ std::string{ "counter:AveragingCounter:" } +
990 typeid( Arithmetic ).name() };
992 template <typename OWNER>
993 AveragingCounter( OWNER* o, std::string const& name )
994 : BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>( o, name, *this ) {}
995 using BufferableCounter<Atomicity, AveragingAccumulator, Arithmetic>::print;
996
997 template <typename stream>
998 stream& printImpl( stream& o, bool tableFormat ) const {
999 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
1000 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean();
1001 }
1002
1003 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1004 return printImpl( o, tableFormat );
1005 }
1006 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1007
1008 bool toBePrinted() const override { return this->nEntries() > 0; }
1009 friend void reset( AveragingCounter& c ) { return c.reset(); }
1010 friend void mergeAndReset( AveragingCounter& c, AveragingCounter& o ) { c.mergeAndReset( o ); }
1011 friend void to_json( nlohmann::json& j, AveragingCounter const& c ) {
1012 j = { { "type", c.typeString },
1013 { "empty", c.nEntries() == 0 },
1014 { "nEntries", c.nEntries() },
1015 { "sum", c.sum() },
1016 { "mean", c.mean() } };
1017 }
1018 static AveragingCounter fromJSON( const nlohmann::json& j ) {
1019 return AveragingAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nEntries", "sum" } );
1020 }
1021 };
1022 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1024
1029 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1030 struct SigmaCounter : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic> {
1031 inline static const std::string typeString{ std::string{ "counter:SigmaCounter:" } + typeid( Arithmetic ).name() };
1032 using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::BufferableCounter;
1033 template <typename OWNER>
1034 SigmaCounter( OWNER* o, std::string const& name )
1035 : BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>( o, name, *this ) {}
1036 using BufferableCounter<Atomicity, SigmaAccumulator, Arithmetic>::print;
1037
1038 template <typename stream>
1039 stream& printImpl( stream& o, bool tableFormat ) const {
1040 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |"
1041 : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
1042 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
1043 }
1044
1045 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1046 return printImpl( o, tableFormat );
1047 }
1048 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1049 bool toBePrinted() const override { return this->nEntries() > 0; }
1050 friend void reset( SigmaCounter& c ) { c.reset(); }
1051 friend void mergeAndReset( SigmaCounter& c, SigmaCounter& o ) { c.mergeAndReset( o ); }
1052 friend void to_json( nlohmann::json& j, SigmaCounter const& c ) {
1053 j = { { "type", c.typeString },
1054 { "empty", c.nEntries() == 0 },
1055 { "nEntries", c.nEntries() },
1056 { "sum", c.sum() },
1057 { "mean", c.mean() },
1058 { "sum2", c.sum2() },
1059 { "standard_deviation", c.standard_deviation() } };
1060 }
1061 static SigmaCounter fromJSON( const nlohmann::json& j ) {
1062 return SigmaAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { { "nEntries", "sum" }, "sum2" } );
1063 }
1064 };
1065
1070 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1071 struct StatCounter : BufferableCounter<Atomicity, StatAccumulator, Arithmetic> {
1072 inline static const std::string typeString{ std::string{ "counter:StatCounter:" } + typeid( Arithmetic ).name() };
1073 using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::BufferableCounter;
1074 template <typename OWNER>
1075 StatCounter( OWNER* o, std::string const& name )
1076 : BufferableCounter<Atomicity, StatAccumulator, Arithmetic>( o, name, *this ) {}
1077 using BufferableCounter<Atomicity, StatAccumulator, Arithmetic>::print;
1078
1079 template <typename stream>
1080 stream& printImpl( stream& o, bool tableFormat ) const {
1081 auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |"
1082 : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
1083 return o << boost::format{ fmt } % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
1084 this->min() % this->max();
1085 }
1086
1087 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1088 return printImpl( o, tableFormat );
1089 }
1090 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1091 bool toBePrinted() const override { return this->nEntries() > 0; }
1092 friend void reset( StatCounter& c ) { c.reset(); }
1093 friend void mergeAndReset( StatCounter& c, StatCounter& o ) { c.mergeAndReset( o ); }
1094 friend void to_json( nlohmann::json& j, StatCounter const& c ) {
1095 j = { { "type", c.typeString },
1096 { "empty", c.nEntries() == 0 },
1097 { "nEntries", c.nEntries() },
1098 { "sum", c.sum() },
1099 { "mean", c.mean() },
1100 { "sum2", c.sum2() },
1101 { "standard_deviation", c.standard_deviation() },
1102 { "min", c.min() },
1103 { "max", c.max() } };
1104 }
1105 static StatCounter fromJSON( const nlohmann::json& j ) {
1107 j, { { { "nEntries", "sum" }, "sum2" }, "min", "max" } );
1108 }
1109 };
1110
1115 template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
1116 struct BinomialCounter : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic> {
1117 inline static const std::string typeString{ std::string{ "counter:BinomialCounter:" } +
1118 typeid( Arithmetic ).name() };
1119 using BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>::BufferableCounter;
1120 template <typename OWNER>
1121 BinomialCounter( OWNER* o, std::string const& name )
1122 : BufferableCounter<Atomicity, BinomialAccumulator, Arithmetic>( o, name, *this ) {}
1123
1124 template <typename stream>
1125 stream& printImpl( stream& o, bool tableFormat ) const {
1126 auto fmt = ( tableFormat ? "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |"
1127 : "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
1128 return o << boost::format{ fmt } % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
1129 ( this->efficiencyErr() * 100 );
1130 }
1131
1132 std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
1133 return printImpl( o, tableFormat );
1134 }
1135 MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
1136
1137 template <typename stream>
1138 stream& printImpl( stream& o, std::string_view tag ) const {
1139 // override default print to add a '*' in from of the name
1140 o << boost::format{ " |*%|-48.48s|%|50t|" } % ( std::string{ "\"" }.append( tag ).append( "\"" ) );
1141 return print( o, true );
1142 }
1143
1144 std::ostream& print( std::ostream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
1145 MsgStream& print( MsgStream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
1146 bool toBePrinted() const override { return this->nEntries() > 0; }
1147 friend void reset( BinomialCounter& c ) { c.reset(); }
1148 friend void mergeAndReset( BinomialCounter& c, BinomialCounter& o ) { c.mergeAndReset( o ); }
1149 friend void to_json( nlohmann::json& j, BinomialCounter const& c ) {
1150 j = { { "type", c.typeString },
1151 { "empty", c.nEntries() == 0 },
1152 { "nEntries", c.nTrueEntries() + c.nFalseEntries() },
1153 { "nTrueEntries", c.nTrueEntries() },
1154 { "nFalseEntries", c.nFalseEntries() },
1155 { "efficiency", c.efficiency() },
1156 { "efficiencyErr", c.efficiencyErr() } };
1157 }
1158 static BinomialCounter fromJSON( const nlohmann::json& j ) {
1159 return BinomialAccumulator<Atomicity, Arithmetic>::extractJSONData( j, { "nTrueEntries", "nFalseEntries" } );
1160 }
1161 };
1162
1164 template <atomicity Atomicity>
1165 struct Handler : Adder<unsigned long, Atomicity> {
1167 static void merge( typename Base::InternalType& orig, bool b ) {
1168 if ( b ) Base::merge( orig, 1 );
1169 }
1170 };
1171 // note that Arithmetic type is unused in this case but needs to be there in case
1172 // we want to create AccumulatorSets with this Accumulator
1173 template <atomicity Atomicity, typename Arithmetic = double>
1175 } // namespace details::MsgCounter
1176
1177 template <MSG::Level level, atomicity Atomicity = atomicity::full>
1179 public:
1180 inline static const std::string typeString{ "counter:MsgCounter" };
1181 template <typename OWNER>
1182 MsgCounter( OWNER* o, std::string const& ms, unsigned long nMax = 10 )
1183 : m_monitoringHub{ &o->serviceLocator()->monitoringHub() }, logger( o ), msg( ms ), max( nMax ) {
1184 m_monitoringHub->registerEntity( o->name(), ms, typeString, *this );
1185 }
1187 ( *this ) += true;
1188 return *this;
1189 }
1190 MsgCounter& operator+=( const bool by ) {
1192 if ( by ) log();
1193 return *this;
1194 }
1195 MsgCounter( MsgCounter const& ) = delete;
1196 MsgCounter& operator=( MsgCounter const& ) = delete;
1198 if ( m_monitoringHub ) m_monitoringHub->removeEntity( *this );
1199 }
1200 template <typename stream>
1201 stream& printImpl( stream& o, bool tableFormat ) const {
1202 return o << boost::format{ tableFormat ? "|%|10d| |" : "#=%|-7lu|" } % this->value();
1203 }
1205 std::ostream& print( std::ostream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
1206 MsgStream& print( MsgStream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
1207 bool toBePrinted() const override { return this->value() > 0; }
1208 friend void reset( MsgCounter& c ) { c.reset(); }
1209 friend void mergeAndReset( MsgCounter& c, MsgCounter& o ) { c.mergeAndReset( o ); }
1210 friend void to_json( nlohmann::json& j, MsgCounter const& c ) {
1211 j = { { "type", c.typeString }, { "empty", c.value() == 0 },
1212 { "nEntries", c.value() }, { "level", level },
1213 { "max", c.max }, { "msg", c.msg } };
1214 }
1215 static MsgCounter fromJSON( const nlohmann::json& j ) {
1216 return { j.at( "msg" ).get<std::string>(), j.at( "max" ).get<unsigned long>(),
1217 j.at( "nEntries" ).get<unsigned long>() };
1218 }
1219
1220 private:
1221 MsgCounter( std::string const& ms, unsigned long nMax, unsigned long count )
1222 : details::MsgCounter::MsgAccumulator<Atomicity>{ count }, msg( ms ), max( nMax ) {}
1223
1225 const CommonMessagingBase* logger{ nullptr };
1226 std::string msg;
1227 unsigned long max;
1228 void log() {
1229 if ( this->value() <= max && logger ) {
1230 if ( this->value() == max ) {
1231 logger->msgStream( level ) << "Suppressing message: " << std::quoted( msg, '\'' ) << endmsg;
1232 } else {
1233 logger->msgStream( level ) << msg << endmsg;
1234 }
1235 }
1236 }
1237 };
1238
1244 template <typename Counter, typename Container, typename Fun>
1245 void accumulate( Counter& counter, const Container& container, Fun f = Identity{} ) {
1246 auto b = counter.buffer();
1247 for ( const auto& elem : container ) b += f( elem );
1248 }
1249
1250} // 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)