The Gaudi Framework  v33r0 (d5ea422b)
Accumulators.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 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 // Forward declarations to avoid issues with relative include order of Gaudi/Accumulators.h and Gaudi/Chrono/Counters.h
15 namespace std::chrono {
16  template <typename, typename>
17  struct duration;
18 }
20  template <class Rep, class Period>
22  template <class Rep1, class Rep2, class Period>
24 } // namespace Gaudi::Accumulators
25 
153 #include "boost/algorithm/string/predicate.hpp"
154 #include "boost/format.hpp"
155 #include <atomic>
156 #include <cmath>
157 #include <iostream>
158 #include <limits>
159 #include <sstream>
160 #include <tuple>
161 #include <type_traits>
162 #include <utility>
163 
165 #include "GaudiKernel/MsgStream.h"
166 #include "GaudiKernel/detected.h"
167 
169 
171  enum class atomicity { none, full };
172 
174  template <class T>
175  auto sqrt( T d );
176 
180  template <typename T, T N>
181  struct Constant {
182  template <typename U>
183  constexpr T operator()( U&& ) const noexcept {
184  return N;
185  }
186  };
187 
191  struct Identity {
192  template <typename U>
193  constexpr decltype( auto ) operator()( U&& v ) const noexcept {
194  return std::forward<U>( v );
195  }
196  };
197 
201  struct Square {
202  template <typename U>
203  constexpr decltype( auto ) operator()( U&& v ) const noexcept {
204  return v * v;
205  }
206  };
207 
211  template <typename T, typename = int>
212  using has_fetch_add_ = decltype( std::atomic<T>{}.fetch_add( 0 ) );
213  template <typename T>
214  inline constexpr bool has_fetch_add_v = Gaudi::cpp17::is_detected_v<has_fetch_add_, T>;
215 
219  template <typename Arithmetic, typename Result = double>
220  using fp_result_type = std::conditional_t<std::is_integral_v<Arithmetic>, Result, Arithmetic>;
221 
225  template <typename Arithmetic, atomicity Atomicity>
227 
231  template <typename Arithmetic>
232  struct BaseValueHandler<Arithmetic, atomicity::none> {
233  using OutputType = Arithmetic;
234  using InternalType = Arithmetic;
235  static constexpr OutputType getValue( const InternalType& v ) noexcept { return v; };
236  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return std::exchange( v, newv ); }
237  };
238 
242  template <typename Arithmetic>
243  struct BaseValueHandler<Arithmetic, atomicity::full> {
244  using OutputType = Arithmetic;
246  static constexpr OutputType getValue( const InternalType& v ) noexcept {
247  return v.load( std::memory_order_relaxed );
248  };
249  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return v.exchange( newv ); }
250  };
251 
256  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
257  struct Adder;
258 
262  template <typename Arithmetic>
263  struct Adder<Arithmetic, atomicity::none> : BaseValueHandler<Arithmetic, atomicity::none> {
266  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
267  static void merge( InternalType& a, Arithmetic b ) noexcept { a += b; };
268  };
269 
273  template <typename Arithmetic>
274  struct Adder<Arithmetic, atomicity::full> : BaseValueHandler<Arithmetic, atomicity::full> {
277  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
278  static void merge( InternalType& a, Arithmetic b ) noexcept {
279  if ( DefaultValue() == b ) return; // avoid atomic operation if b is "0"
280  if constexpr ( has_fetch_add_v<InternalType> ) {
281  a.fetch_add( b, std::memory_order_relaxed );
282  } else {
284  while ( !a.compare_exchange_weak( current, current + b ) )
285  ;
286  }
287  };
288  };
289 
294  template <typename Arithmetic, atomicity Atomicity, typename Compare, Arithmetic ( *Initial )()>
295  struct Extremum;
296 
300  template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
301  struct Extremum<Arithmetic, atomicity::none, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::none> {
304  static constexpr OutputType DefaultValue() { return Initial(); }
305  static void merge( InternalType& a, Arithmetic b ) noexcept {
306  if ( Compare{}( b, a ) ) a = b;
307  };
308  };
309 
313  template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
314  struct Extremum<Arithmetic, atomicity::full, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::full> {
317  static constexpr OutputType DefaultValue() { return Initial(); }
318  static void merge( InternalType& a, Arithmetic b ) noexcept {
319  Arithmetic prev_value = BaseValueHandler<Arithmetic, atomicity::full>::getValue( a );
320  while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
321  ;
322  };
323  };
324 
329  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
331 
336  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
338 
356  template <typename InputType, typename InnerType, atomicity Atomicity = atomicity::full,
357  typename InputTransform = Identity, typename OutputTransform = Identity,
358  typename ValueHandler = Adder<InnerType, Atomicity>>
360  template <typename, typename, atomicity, typename, typename, typename>
361  friend class GenericAccumulator;
362 
363  public:
364  using OutputType = std::decay_t<std::result_of_t<OutputTransform( InnerType )>>;
365  GenericAccumulator operator+=( const InputType by ) {
366  ValueHandler::merge( m_value, InputTransform{}( by ) );
367  return *this;
368  }
369  GenericAccumulator() = default;
370  template <typename... Args>
371  GenericAccumulator( std::in_place_t, Args&&... args ) : m_value( std::forward<Args>( args )... ) {}
372  GenericAccumulator( const GenericAccumulator& other ) : m_value( ValueHandler::getValue( other.m_value ) ) {}
374  m_value = ValueHandler::getValue( other.m_value );
375  return *this;
376  }
377  OutputType value() const { return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
378  void reset() { reset( ValueHandler::DefaultValue() ); }
379  template <atomicity ato, typename VH>
381  ValueHandler::merge( m_value, VH::exchange( other.m_value, VH::DefaultValue() ) );
382  }
383 
384  protected:
385  void reset( InnerType in ) { m_value = std::move( in ); }
386 
387  private:
388  typename ValueHandler::InternalType m_value{ValueHandler::DefaultValue()};
389  };
390 
396  template <typename Arithmetic, atomicity Atomicity, template <typename, atomicity> class... Bases>
397  class AccumulatorSet : public Bases<Arithmetic, Atomicity>... {
398  public:
399  using InputType = Arithmetic;
401  constexpr AccumulatorSet() = default;
403  ( Bases<Arithmetic, Atomicity>::operator+=( by ), ... );
404  return *this;
405  }
406  OutputType value() const { return std::make_tuple( Bases<Arithmetic, Atomicity>::value()... ); }
407  void reset() { ( Bases<Arithmetic, Atomicity>::reset(), ... ); }
408  template <atomicity Ato>
410  ( Bases<Arithmetic, Atomicity>::mergeAndReset( static_cast<Bases<Arithmetic, Ato>&&>( other ) ), ... );
411  }
412 
413  protected:
414  void reset( const std::tuple<typename Bases<Arithmetic, Atomicity>::OutputType...>& t ) {
415  std::apply( [this]( const auto&... i ) { ( this->Bases<Arithmetic, Atomicity>::reset( i ), ... ); }, t );
416  }
417  };
418 
423  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
425  : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
426  Arithmetic max() const { return this->value(); }
427  };
428 
433  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
435  : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
436  Arithmetic min() const { return this->value(); }
437  };
438 
443  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
444  struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>> {
445  unsigned long nEntries() const { return this->value(); }
446  };
447 
452  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
453  struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
454  Arithmetic sum() const { return this->value(); }
455  };
456 
461  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
462  struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
463  Arithmetic sum2() const { return this->value(); };
464  };
465 
467  struct TrueTo1 {
468  unsigned int operator()( bool v ) const { return v; }
469  };
470 
476  template <typename Arithmetic, atomicity Atomicity>
477  struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
479  unsigned long nTrueEntries() const { return this->value(); };
480  };
481 
483  struct FalseTo1 {
484  unsigned int operator()( bool v ) const { return !v; }
485  };
486 
492  template <typename Arithmetic, atomicity Atomicity>
493  struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
495  unsigned long nFalseEntries() const { return this->value(); };
496  };
497 
503  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
504  struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, TrueAccumulator, FalseAccumulator> {
505  unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); };
506 
507  template <typename Result = fp_result_type<Arithmetic>>
508  auto efficiency() const {
509  auto nbEntries = nEntries();
510  if ( 1 > nbEntries ) return Result{-1};
511  return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
512  }
513  auto eff() const { return efficiency(); }
514 
515  template <typename Result = fp_result_type<Arithmetic>>
516  auto efficiencyErr() const {
517  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
518  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
520  using std::sqrt;
521  auto nbEntries = nEntries();
522  if ( 1 > nbEntries ) return Result{-1};
523  return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
524  }
525  auto effErr() const { return efficiencyErr(); }
527  struct binomial_t {
528  unsigned long nPass;
529  unsigned long nTotal;
530  };
532  assert( b.nPass <= b.nTotal );
535  FalseAccumulator<bool, atomicity::none>{std::in_place, b.nTotal - b.nPass} );
536  return *this;
537  }
538  };
539 
544  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
545  struct AveragingAccumulator : AccumulatorSet<Arithmetic, Atomicity, CountAccumulator, SumAccumulator> {
546 
547  template <typename Result = fp_result_type<Arithmetic>>
548  auto mean() const {
549  auto n = this->nEntries();
550  Result sum = this->sum();
551  return ( n > 0 ) ? static_cast<Result>( sum / n ) : Result{};
552  }
553  };
554 
559  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
560  struct SigmaAccumulator : AccumulatorSet<Arithmetic, Atomicity, AveragingAccumulator, SquareAccumulator> {
561 
562  template <typename Result = fp_result_type<Arithmetic>>
563  auto biased_sample_variance() const {
564  auto n = this->nEntries();
565  Result sum = this->sum();
566  return ( n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / n ) : Result{};
567  }
568 
569  template <typename Result = fp_result_type<Arithmetic>>
571  auto n = this->nEntries();
572  Result sum = this->sum();
573  return ( n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) ) : Result{};
574  }
575 
576  template <typename Result = fp_result_type<Arithmetic>>
577  auto standard_deviation() const {
578  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
579  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
581  using std::sqrt;
582  Result v = biased_sample_variance();
583  return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v ) );
584  }
585  [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const {
586  return standard_deviation();
587  }
588 
589  template <typename Result = fp_result_type<Arithmetic>>
590  auto meanErr() const {
591  auto n = this->nEntries();
592  if ( 0 == n ) return Result{};
593  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
594  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
596  using std::sqrt;
597  Result v = biased_sample_variance();
598  return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) );
599  }
600  };
601 
606  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
608 
615  template <typename Arithmetic, template <typename Int, atomicity Ato> class ContainedAccumulator>
616  class Buffer : public ContainedAccumulator<Arithmetic, atomicity::none> {
617  using prime_type = ContainedAccumulator<Arithmetic, atomicity::full>;
618  using base_type = ContainedAccumulator<Arithmetic, atomicity::none>;
619 
620  public:
621  Buffer() = delete;
622  Buffer( prime_type& p ) : base_type(), m_prime( p ) {}
623  Buffer( const Buffer& ) = delete;
624  void operator=( const Buffer& ) = delete;
625  Buffer( Buffer&& other ) : base_type( other ), m_prime( other.m_prime ) { other.reset(); }
626  void push() { m_prime.mergeAndReset( static_cast<base_type&&>( *this ) ); }
627  ~Buffer() { push(); }
628 
629  private:
631  };
632 
638  PrintableCounter() = default;
639  template <class OWNER>
640  PrintableCounter( OWNER* o, const std::string& tag ) {
641  o->declareCounter( tag, *this );
642  }
644  virtual ~PrintableCounter() = default;
645  // add tag to printout
646  template <typename stream>
647  stream& printImpl( stream& s, const std::string& tag ) const {
648  s << boost::format{" | %|-48.48s|%|50t|"} % ( "\"" + tag + "\"" );
649  return print( s, true );
650  }
652  virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
653  virtual MsgStream& print( MsgStream&, bool tableFormat = true ) const = 0;
655  virtual std::ostream& print( std::ostream& o, const std::string& tag ) const { return printImpl( o, tag ); }
656  virtual MsgStream& print( MsgStream& o, const std::string& tag ) const { return printImpl( o, tag ); }
659  virtual bool toBePrinted() const { return true; }
662  std::ostringstream ost;
663  print( ost );
664  return ost.str();
665  }
666  };
667 
671  inline std::ostream& operator<<( std::ostream& s, const PrintableCounter& counter ) { return counter.print( s ); }
672  inline MsgStream& operator<<( MsgStream& s, const PrintableCounter& counter ) { return counter.print( s ); }
678  template <typename Arithmetic, atomicity Atomicity, template <typename Int, atomicity Ato> class Accumulator>
680  using PrintableCounter::PrintableCounter;
681  Buffer<Arithmetic, Accumulator> buffer() { return {*static_cast<Accumulator<Arithmetic, Atomicity>*>( this )}; }
682  };
683 
688  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
689  struct Counter : BufferableCounter<Arithmetic, Atomicity, Counter>, CountAccumulator<Arithmetic, Atomicity> {
692  ( *this ) += Arithmetic{};
693  return *this;
694  }
696  auto copy = *this;
697  ++( *this );
698  return copy;
699  }
701 
702  template <typename stream>
703  stream& printImpl( stream& o, bool tableFormat ) const {
704  // Avoid printing empty counters in non DEBUG mode
705  auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" );
706  return o << boost::format{fmt} % this->nEntries();
707  }
708 
709  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
710  return printImpl( o, tableFormat );
711  }
712  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
713  bool toBePrinted() const override { return this->nEntries() > 0; }
714  };
715 
720  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
721  struct AveragingCounter : BufferableCounter<Arithmetic, Atomicity, AveragingCounter>,
722  AveragingAccumulator<Arithmetic, Atomicity> {
725 
726  template <typename stream>
727  stream& printImpl( stream& o, bool tableFormat ) const {
728  auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
729  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean();
730  }
731 
732  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
733  return printImpl( o, tableFormat );
734  }
735  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
736 
737  bool toBePrinted() const override { return this->nEntries() > 0; }
738  };
739  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
741 
746  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
747  struct SigmaCounter : BufferableCounter<Arithmetic, Atomicity, SigmaCounter>,
748  SigmaAccumulator<Arithmetic, Atomicity> {
751 
752  template <typename stream>
753  stream& printImpl( stream& o, bool tableFormat ) const {
754  auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |"
755  : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
756  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
757  }
758 
759  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
760  return printImpl( o, tableFormat );
761  }
762  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
763  bool toBePrinted() const override { return this->nEntries() > 0; }
764  };
765 
770  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
771  struct StatCounter : BufferableCounter<Arithmetic, Atomicity, StatCounter>, StatAccumulator<Arithmetic, Atomicity> {
774 
775  template <typename stream>
776  stream& printImpl( stream& o, bool tableFormat ) const {
777  auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |"
778  : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
779  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
780  this->min() % this->max();
781  }
782 
783  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
784  return printImpl( o, tableFormat );
785  }
786  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
787  bool toBePrinted() const override { return this->nEntries() > 0; }
788  };
789 
794  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
795  struct BinomialCounter : BufferableCounter<Arithmetic, Atomicity, BinomialCounter>,
796  BinomialAccumulator<Arithmetic, Atomicity> {
798 
799  template <typename stream>
800  stream& printImpl( stream& o, bool tableFormat ) const {
801  auto fmt = ( tableFormat ? "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |"
802  : "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
803  return o << boost::format{fmt} % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
804  ( this->efficiencyErr() * 100 );
805  }
806 
807  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
808  return printImpl( o, tableFormat );
809  }
810  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
811 
812  template <typename stream>
813  stream& printImpl( stream& o, const std::string& tag ) const {
814  // override default print to add a '*' in from of the name
815  o << boost::format{" |*%|-48.48s|%|50t|"} % ( "\"" + tag + "\"" );
816  return print( o, true );
817  }
819  std::ostream& print( std::ostream& o, const std::string& tag ) const override { return printImpl( o, tag ); }
820  MsgStream& print( MsgStream& o, const std::string& tag ) const override { return printImpl( o, tag ); }
821  bool toBePrinted() const override { return this->nEntries() > 0; }
822  };
823 
825  struct Logger {
826  CommonMessagingBase const* parent = nullptr;
829 
830  void operator()( bool suppress = false ) const {
831  if ( suppress ) {
832  parent->msgStream( lvl ) << "Suppressing message: " << std::quoted( msg, '\'' ) << endmsg;
833  } else {
834  parent->msgStream( lvl ) << msg << endmsg;
835  }
836  }
837  };
838 
839  template <atomicity Atomicity>
840  struct Data {
841  std::conditional_t<Atomicity == atomicity::none, unsigned long, std::atomic<unsigned long>> count = {0};
842  unsigned long max = 0;
843  Logger const* logger = nullptr;
844 
845  constexpr Data( Logger const* p, unsigned long mx ) : max{mx}, logger{p} {}
846 
847  template <atomicity OtherAtomicity>
848  Data( Data<OtherAtomicity> const& other ) {
849  count = other.count;
850  max = other.max;
851  logger = other.logger;
852  }
853  };
854 
855  template <atomicity Atomicity>
856  struct Handler {
859 
860  static constexpr OutputType getValue( InternalType const& v ) noexcept { return v; }
861 
862  static void merge( InternalType& orig, bool b ) {
863  if ( b ) {
864  auto count = ++orig.count;
865  if ( UNLIKELY( count <= orig.max ) ) ( *orig.logger )( count == orig.max );
866  }
867  }
868  };
870  template <atomicity Atomicity>
871  constexpr unsigned long operator()( Data<Atomicity> const& v ) const noexcept {
872  return v.count;
873  }
874  };
875  } // namespace details::MsgCounter
876 
877  template <MSG::Level level, atomicity Atomicity = atomicity::full>
878  struct MsgCounter
880  details::MsgCounter::Logger,
881  GenericAccumulator<bool, details::MsgCounter::Data<Atomicity>, Atomicity, Identity,
882  details::MsgCounter::OutputTransform, details::MsgCounter::Handler<Atomicity>> {
883  template <typename OWNER>
884  MsgCounter( OWNER* o, std::string const& msg, int nMax = 10 )
885  : PrintableCounter( o, msg )
886  , details::MsgCounter::Logger{o, msg, level}
888  details::MsgCounter::OutputTransform, details::MsgCounter::Handler<Atomicity>>{
889  std::in_place, this, nMax} {}
891  ( *this ) += true;
892  return *this;
893  }
894  template <typename stream>
895  stream& printImpl( stream& o, bool tableFormat ) const {
896  return o << boost::format{tableFormat ? "|%|10d| |" : "#=%|-7lu|"} % this->value();
897  }
898  using PrintableCounter::print;
899  std::ostream& print( std::ostream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
900  MsgStream& print( MsgStream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
901  bool toBePrinted() const override { return this->value() > 0; }
902  };
903 
909  template <typename Counter, typename Container, typename Fun>
910  void accumulate( Counter& counter, const Container& container, Fun f = Identity{} ) {
911  auto b = counter.buffer();
912  for ( const auto& elem : container ) b += f( elem );
913  }
914 
915 } // namespace Gaudi::Accumulators
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
Definition: Accumulators.h:380
#define UNLIKELY(x)
Definition: Kernel.h:106
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:34
An Adder ValueHandler operator(a, b) means a += b.
Definition: Accumulators.h:257
T copy(T... args)
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
Definition: Accumulators.h:616
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:713
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:737
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
std::string toString() const
get a string representation
Definition: Accumulators.h:661
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Accumulators.h:747
stream & printImpl(stream &o, const std::string &tag) const
Definition: Accumulators.h:813
BinomialAccumulator & operator+=(binomial_t b)
Definition: Accumulators.h:531
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:821
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
Definition: Accumulators.h:220
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:727
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
Definition: Accumulators.h:397
A counter dealing with binomial data.
Definition: Accumulators.h:795
helper functor for the FalseAccumulator
Definition: Accumulators.h:483
GenericAccumulator(const GenericAccumulator &other)
Definition: Accumulators.h:372
EventIDBase min(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:212
int merge(const char *target, const char *source, bool fixup=false, bool dbg=true)
Definition: merge.C:430
STL namespace.
MsgStream & print(MsgStream &os, bool tableFormat) const override
Definition: Accumulators.h:900
constexpr Data(Logger const *p, unsigned long mx)
Definition: Accumulators.h:845
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:703
T make_tuple(T... args)
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:763
std::ostream & print(std::ostream &os, bool tableFormat) const override
prints the counter to a stream
Definition: Accumulators.h:899
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:807
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:225
helper functor for the TrueAccumulator
Definition: Accumulators.h:467
Generic Accumulator, templated by.
Definition: Accumulators.h:359
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:786
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
STL class.
Buffer< Arithmetic, Accumulator > buffer()
Definition: Accumulators.h:681
A functor always returning the value N.
Definition: Accumulators.h:181
An empty ancester of all counters that provides a buffer method that returns a buffer on itself.
Definition: Accumulators.h:679
int N
Definition: IOTest.py:110
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...
Definition: Accumulators.h:910
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:783
void reset(const std::tuple< typename Bases< Arithmetic, Atomicity >::OutputType... > &t)
Definition: Accumulators.h:414
A counter aiming at computing sum and average.
Definition: Accumulators.h:721
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Accumulators.h:235
GAUDIPS_API Logger & logger()
Return the current logger instance.
stream & printImpl(stream &s, const std::string &tag) const
Definition: Accumulators.h:647
constexpr unsigned long operator()(Data< Atomicity > const &v) const noexcept
Definition: Accumulators.h:871
std::conditional_t< Atomicity==atomicity::none, unsigned long, std::atomic< unsigned long > > count
Definition: Accumulators.h:841
GenericAccumulator operator+=(const InputType by)
Definition: Accumulators.h:365
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:712
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, Bases... > &&other)
Definition: Accumulators.h:409
static constexpr OutputType getValue(InternalType const &v) noexcept
Definition: Accumulators.h:860
T str(T... args)
Base type for all functors used as ValuesHandler.
Definition: Accumulators.h:226
GenericAccumulator & operator=(const GenericAccumulator &other)
Definition: Accumulators.h:373
ContainedAccumulator< Arithmetic, atomicity::full > prime_type
Definition: Accumulators.h:617
GenericAccumulator(std::in_place_t, Args &&... args)
Definition: Accumulators.h:371
MsgStream & msgStream() const
Return an uninitialized MsgStream.
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:732
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Accumulators.h:278
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:759
T move(T... args)
unsigned int operator()(bool v) const
Definition: Accumulators.h:484
T count(T... args)
virtual MsgStream & print(MsgStream &o, const std::string &tag) const
Definition: Accumulators.h:656
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
Definition: Counters.h:34
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Accumulators.h:267
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:753
unsigned int operator()(bool v) const
Definition: Accumulators.h:468
T fetch_add(T... args)
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Accumulators.h:249
atomicity
Defines atomicity of the accumulators.
Definition: Accumulators.h:171
virtual std::ostream & print(std::ostream &o, const std::string &tag) const
prints the counter to a stream in table format, with the given tag
Definition: Accumulators.h:655
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:762
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Accumulators.h:771
constexpr T operator()(U &&) const noexcept
Definition: Accumulators.h:183
A basic counter counting input values.
Definition: Accumulators.h:689
string s
Definition: gaudirun.py:328
MsgCounter(OWNER *o, std::string const &msg, int nMax=10)
Definition: Accumulators.h:884
AccumulatorSet & operator+=(const InputType by)
Definition: Accumulators.h:402
virtual bool toBePrinted() const
hint whether we should print that counter or not.
Definition: Accumulators.h:659
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:800
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:735
T sqrt(T... args)
An empty ancester of all counters that knows how to print themselves.
Definition: Accumulators.h:637
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:776
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:895
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b,...
Definition: Accumulators.h:295
ContainedAccumulator< Arithmetic, atomicity::none > base_type
Definition: Accumulators.h:618
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Accumulators.h:236
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:901
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:709
STL class.
MsgStream & print(MsgStream &o, const std::string &tag) const override
Definition: Accumulators.h:820
Efficient counter implementations for Gaudi.
Definition: Histogram.h:19
T forward(T... args)
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:787
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
decltype(std::atomic< T >{}.fetch_add(0)) has_fetch_add_
type_traits for checking the presence of fetch_add in std::atomic<T>
Definition: Accumulators.h:212
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Accumulators.h:246
std::ostream & operator<<(std::ostream &o, const Gaudi::StringKey &key)
printout of the object reply on the native printout for the string
Definition: StringKey.h:245
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:810
std::ostream & print(std::ostream &o, const std::string &tag) const override
prints the counter to a stream in table format, with the given tag
Definition: Accumulators.h:819