The Gaudi Framework  v33r1 (b1225454)
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 #include <chrono>
15 
16 namespace Gaudi::Accumulators {
17  template <class Rep, class Period>
19  template <class Rep1, class Rep2, class Period>
21 } // namespace Gaudi::Accumulators
22 
150 #include "boost/algorithm/string/predicate.hpp"
151 #include "boost/format.hpp"
152 #include <atomic>
153 #include <cmath>
154 #include <iostream>
155 #include <limits>
156 #include <sstream>
157 #include <tuple>
158 #include <type_traits>
159 #include <utility>
160 
162 #include "GaudiKernel/MsgStream.h"
163 #include "GaudiKernel/detected.h"
164 
166 
168  enum class atomicity { none, full };
169 
171  template <class T>
172  auto sqrt( T d );
173 
177  template <typename T, T N>
178  struct Constant {
179  template <typename U>
180  constexpr T operator()( U&& ) const noexcept {
181  return N;
182  }
183  };
184 
188  struct Identity {
189  template <typename U>
190  constexpr decltype( auto ) operator()( U&& v ) const noexcept {
191  return std::forward<U>( v );
192  }
193  };
194 
198  struct Square {
199  template <typename U>
200  constexpr decltype( auto ) operator()( U&& v ) const noexcept {
201  return v * v;
202  }
203  };
204 
208  template <typename T, typename = int>
209  using has_fetch_add_ = decltype( std::atomic<T>{}.fetch_add( 0 ) );
210  template <typename T>
211  inline constexpr bool has_fetch_add_v = Gaudi::cpp17::is_detected_v<has_fetch_add_, T>;
212 
216  template <typename Arithmetic, typename Result = double>
217  using fp_result_type = std::conditional_t<std::is_integral_v<Arithmetic>, Result, Arithmetic>;
218 
222  template <typename Arithmetic, atomicity Atomicity>
224 
228  template <typename Arithmetic>
229  struct BaseValueHandler<Arithmetic, atomicity::none> {
230  using OutputType = Arithmetic;
231  using InternalType = Arithmetic;
232  static constexpr OutputType getValue( const InternalType& v ) noexcept { return v; };
233  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return std::exchange( v, newv ); }
234  };
235 
239  template <typename Arithmetic>
240  struct BaseValueHandler<Arithmetic, atomicity::full> {
241  using OutputType = Arithmetic;
243  static constexpr OutputType getValue( const InternalType& v ) noexcept {
244  return v.load( std::memory_order_relaxed );
245  };
246  static Arithmetic exchange( InternalType& v, Arithmetic newv ) noexcept { return v.exchange( newv ); }
247  };
248 
253  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
254  struct Adder;
255 
259  template <typename Arithmetic>
260  struct Adder<Arithmetic, atomicity::none> : BaseValueHandler<Arithmetic, atomicity::none> {
263  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
264  static void merge( InternalType& a, Arithmetic b ) noexcept { a += b; };
265  };
266 
270  template <typename Arithmetic>
271  struct Adder<Arithmetic, atomicity::full> : BaseValueHandler<Arithmetic, atomicity::full> {
274  static constexpr OutputType DefaultValue() { return Arithmetic{}; }
275  static void merge( InternalType& a, Arithmetic b ) noexcept {
276  if ( DefaultValue() == b ) return; // avoid atomic operation if b is "0"
277  if constexpr ( has_fetch_add_v<InternalType> ) {
278  a.fetch_add( b, std::memory_order_relaxed );
279  } else {
281  while ( !a.compare_exchange_weak( current, current + b ) )
282  ;
283  }
284  };
285  };
286 
291  template <typename Arithmetic, atomicity Atomicity, typename Compare, Arithmetic ( *Initial )()>
292  struct Extremum;
293 
297  template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
298  struct Extremum<Arithmetic, atomicity::none, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::none> {
301  static constexpr OutputType DefaultValue() { return Initial(); }
302  static void merge( InternalType& a, Arithmetic b ) noexcept {
303  if ( Compare{}( b, a ) ) a = b;
304  };
305  };
306 
310  template <typename Arithmetic, typename Compare, Arithmetic ( *Initial )()>
311  struct Extremum<Arithmetic, atomicity::full, Compare, Initial> : BaseValueHandler<Arithmetic, atomicity::full> {
314  static constexpr OutputType DefaultValue() { return Initial(); }
315  static void merge( InternalType& a, Arithmetic b ) noexcept {
316  Arithmetic prev_value = BaseValueHandler<Arithmetic, atomicity::full>::getValue( a );
317  while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
318  ;
319  };
320  };
321 
326  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
328 
333  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
335 
353  template <typename InputType, typename InnerType, atomicity Atomicity = atomicity::full,
354  typename InputTransform = Identity, typename OutputTransform = Identity,
355  typename ValueHandler = Adder<InnerType, Atomicity>>
357  template <typename, typename, atomicity, typename, typename, typename>
358  friend class GenericAccumulator;
359 
360  public:
361  using OutputType = std::decay_t<std::result_of_t<OutputTransform( InnerType )>>;
362  GenericAccumulator operator+=( const InputType by ) {
363  ValueHandler::merge( m_value, InputTransform{}( by ) );
364  return *this;
365  }
366  GenericAccumulator() = default;
367  template <typename... Args>
368  GenericAccumulator( std::in_place_t, Args&&... args ) : m_value( std::forward<Args>( args )... ) {}
369  GenericAccumulator( const GenericAccumulator& other ) : m_value( ValueHandler::getValue( other.m_value ) ) {}
371  m_value = ValueHandler::getValue( other.m_value );
372  return *this;
373  }
374  OutputType value() const { return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
375  void reset() { reset( ValueHandler::DefaultValue() ); }
376  template <atomicity ato, typename VH>
378  ValueHandler::merge( m_value, VH::exchange( other.m_value, VH::DefaultValue() ) );
379  }
380 
381  protected:
382  void reset( InnerType in ) { m_value = std::move( in ); }
383 
384  private:
385  typename ValueHandler::InternalType m_value{ValueHandler::DefaultValue()};
386  };
387 
393  template <typename Arithmetic, atomicity Atomicity, template <typename, atomicity> class... Bases>
394  class AccumulatorSet : public Bases<Arithmetic, Atomicity>... {
395  public:
396  using InputType = Arithmetic;
398  constexpr AccumulatorSet() = default;
400  ( Bases<Arithmetic, Atomicity>::operator+=( by ), ... );
401  return *this;
402  }
403  OutputType value() const { return std::make_tuple( Bases<Arithmetic, Atomicity>::value()... ); }
404  void reset() { ( Bases<Arithmetic, Atomicity>::reset(), ... ); }
405  template <atomicity Ato>
407  ( Bases<Arithmetic, Atomicity>::mergeAndReset( static_cast<Bases<Arithmetic, Ato>&&>( other ) ), ... );
408  }
409 
410  protected:
411  void reset( const std::tuple<typename Bases<Arithmetic, Atomicity>::OutputType...>& t ) {
412  std::apply( [this]( const auto&... i ) { ( this->Bases<Arithmetic, Atomicity>::reset( i ), ... ); }, t );
413  }
414  };
415 
420  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
422  : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
423  Arithmetic max() const { return this->value(); }
424  };
425 
430  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
432  : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
433  Arithmetic min() const { return this->value(); }
434  };
435 
440  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
441  struct CountAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, Constant<unsigned long, 1UL>> {
442  unsigned long nEntries() const { return this->value(); }
443  };
444 
449  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
450  struct SumAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity> {
451  Arithmetic sum() const { return this->value(); }
452  };
453 
458  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
459  struct SquareAccumulator : GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Square> {
460  Arithmetic sum2() const { return this->value(); };
461  };
462 
464  struct TrueTo1 {
465  unsigned int operator()( bool v ) const { return v; }
466  };
467 
473  template <typename Arithmetic, atomicity Atomicity>
474  struct TrueAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, TrueTo1> {
476  unsigned long nTrueEntries() const { return this->value(); };
477  };
478 
480  struct FalseTo1 {
481  unsigned int operator()( bool v ) const { return !v; }
482  };
483 
489  template <typename Arithmetic, atomicity Atomicity>
490  struct FalseAccumulator : GenericAccumulator<Arithmetic, unsigned long, Atomicity, FalseTo1> {
492  unsigned long nFalseEntries() const { return this->value(); };
493  };
494 
500  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
501  struct BinomialAccumulator : AccumulatorSet<bool, Atomicity, TrueAccumulator, FalseAccumulator> {
502  unsigned long nEntries() const { return this->nTrueEntries() + this->nFalseEntries(); };
503 
504  template <typename Result = fp_result_type<Arithmetic>>
505  auto efficiency() const {
506  auto nbEntries = nEntries();
507  if ( 1 > nbEntries ) return Result{-1};
508  return static_cast<Result>( this->nTrueEntries() ) / nbEntries;
509  }
510  auto eff() const { return efficiency(); }
511 
512  template <typename Result = fp_result_type<Arithmetic>>
513  auto efficiencyErr() const {
514  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
515  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
517  using std::sqrt;
518  auto nbEntries = nEntries();
519  if ( 1 > nbEntries ) return Result{-1};
520  return sqrt( static_cast<Result>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
521  }
522  auto effErr() const { return efficiencyErr(); }
524  struct binomial_t {
525  unsigned long nPass;
526  unsigned long nTotal;
527  };
529  assert( b.nPass <= b.nTotal );
532  FalseAccumulator<bool, atomicity::none>{std::in_place, b.nTotal - b.nPass} );
533  return *this;
534  }
535  };
536 
541  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
542  struct AveragingAccumulator : AccumulatorSet<Arithmetic, Atomicity, CountAccumulator, SumAccumulator> {
543 
544  template <typename Result = fp_result_type<Arithmetic>>
545  auto mean() const {
546  auto n = this->nEntries();
547  Result sum = this->sum();
548  return ( n > 0 ) ? static_cast<Result>( sum / n ) : Result{};
549  }
550  };
551 
556  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
557  struct SigmaAccumulator : AccumulatorSet<Arithmetic, Atomicity, AveragingAccumulator, SquareAccumulator> {
558 
559  template <typename Result = fp_result_type<Arithmetic>>
560  auto biased_sample_variance() const {
561  auto n = this->nEntries();
562  Result sum = this->sum();
563  return ( n > 0 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / n ) : Result{};
564  }
565 
566  template <typename Result = fp_result_type<Arithmetic>>
568  auto n = this->nEntries();
569  Result sum = this->sum();
570  return ( n > 1 ) ? static_cast<Result>( ( this->sum2() - sum * ( sum / n ) ) / ( n - 1 ) ) : Result{};
571  }
572 
573  template <typename Result = fp_result_type<Arithmetic>>
574  auto standard_deviation() const {
575  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
576  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
578  using std::sqrt;
579  Result v = biased_sample_variance();
580  return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v ) );
581  }
582  [[deprecated( "The name 'rms' has changed to standard_deviation" )]] Arithmetic rms() const {
583  return standard_deviation();
584  }
585 
586  template <typename Result = fp_result_type<Arithmetic>>
587  auto meanErr() const {
588  auto n = this->nEntries();
589  if ( 0 == n ) return Result{};
590  // Note the usage of using, aiming at using the std version of sqrt by default, without preventing
591  // more specialized versions to be used via ADL (see http://en.cppreference.com/w/cpp/language/adl)
593  using std::sqrt;
594  Result v = biased_sample_variance();
595  return ( Result{0} > v ) ? Result{} : static_cast<Result>( sqrt( v / n ) );
596  }
597  };
598 
603  template <typename Arithmetic, atomicity Atomicity = atomicity::full>
605 
612  template <typename Arithmetic, template <typename Int, atomicity Ato> class ContainedAccumulator>
613  class Buffer : public ContainedAccumulator<Arithmetic, atomicity::none> {
614  using prime_type = ContainedAccumulator<Arithmetic, atomicity::full>;
615  using base_type = ContainedAccumulator<Arithmetic, atomicity::none>;
616 
617  public:
618  Buffer() = delete;
619  Buffer( prime_type& p ) : base_type(), m_prime( p ) {}
620  Buffer( const Buffer& ) = delete;
621  void operator=( const Buffer& ) = delete;
622  Buffer( Buffer&& other ) : base_type( other ), m_prime( other.m_prime ) { other.reset(); }
623  void push() { m_prime.mergeAndReset( static_cast<base_type&&>( *this ) ); }
624  ~Buffer() { push(); }
625 
626  private:
628  };
629 
635  PrintableCounter() = default;
636  template <class OWNER>
637  PrintableCounter( OWNER* o, std::string tag ) {
638  o->declareCounter( std::move( tag ), *this );
639  }
641  virtual ~PrintableCounter() = default;
642  // add tag to printout
643  template <typename stream>
644  stream& printImpl( stream& s, std::string_view tag ) const {
645  s << boost::format{" | %|-48.48s|%|50t|"} % ( std::string{'\"'}.append( tag ).append( "\"" ) );
646  return print( s, true );
647  }
649  virtual std::ostream& print( std::ostream&, bool tableFormat = false ) const = 0;
650  virtual MsgStream& print( MsgStream&, bool tableFormat = true ) const = 0;
652  virtual std::ostream& print( std::ostream& o, std::string_view tag ) const { return printImpl( o, tag ); }
653  virtual MsgStream& print( MsgStream& o, std::string_view tag ) const { return printImpl( o, tag ); }
656  virtual bool toBePrinted() const { return true; }
659  std::ostringstream ost;
660  print( ost );
661  return ost.str();
662  }
663  };
664 
668  inline std::ostream& operator<<( std::ostream& s, const PrintableCounter& counter ) { return counter.print( s ); }
669  inline MsgStream& operator<<( MsgStream& s, const PrintableCounter& counter ) { return counter.print( s ); }
675  template <typename Arithmetic, atomicity Atomicity, template <typename Int, atomicity Ato> class Accumulator>
677  using PrintableCounter::PrintableCounter;
678  Buffer<Arithmetic, Accumulator> buffer() { return {*static_cast<Accumulator<Arithmetic, Atomicity>*>( this )}; }
679  };
680 
685  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
686  struct Counter : BufferableCounter<Arithmetic, Atomicity, Counter>, CountAccumulator<Arithmetic, Atomicity> {
689  ( *this ) += Arithmetic{};
690  return *this;
691  }
693  auto copy = *this;
694  ++( *this );
695  return copy;
696  }
698 
699  template <typename stream>
700  stream& printImpl( stream& o, bool tableFormat ) const {
701  // Avoid printing empty counters in non DEBUG mode
702  auto fmt = ( tableFormat ? "|%|10d| |" : "#=%|-7lu|" );
703  return o << boost::format{fmt} % this->nEntries();
704  }
705 
706  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
707  return printImpl( o, tableFormat );
708  }
709  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
710  bool toBePrinted() const override { return this->nEntries() > 0; }
711  };
712 
717  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
718  struct AveragingCounter : BufferableCounter<Arithmetic, Atomicity, AveragingCounter>,
719  AveragingAccumulator<Arithmetic, Atomicity> {
722 
723  template <typename stream>
724  stream& printImpl( stream& o, bool tableFormat ) const {
725  auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |" : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|" );
726  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean();
727  }
728 
729  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
730  return printImpl( o, tableFormat );
731  }
732  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
733 
734  bool toBePrinted() const override { return this->nEntries() > 0; }
735  };
736  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
738 
743  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
744  struct SigmaCounter : BufferableCounter<Arithmetic, Atomicity, SigmaCounter>,
745  SigmaAccumulator<Arithmetic, Atomicity> {
748 
749  template <typename stream>
750  stream& printImpl( stream& o, bool tableFormat ) const {
751  auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |"
752  : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|" );
753  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation();
754  }
755 
756  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
757  return printImpl( o, tableFormat );
758  }
759  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
760  bool toBePrinted() const override { return this->nEntries() > 0; }
761  };
762 
767  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
768  struct StatCounter : BufferableCounter<Arithmetic, Atomicity, StatCounter>, StatAccumulator<Arithmetic, Atomicity> {
771 
772  template <typename stream>
773  stream& printImpl( stream& o, bool tableFormat ) const {
774  auto fmt = ( tableFormat ? "|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |"
775  : "#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|" );
776  return o << boost::format{fmt} % this->nEntries() % this->sum() % this->mean() % this->standard_deviation() %
777  this->min() % this->max();
778  }
779 
780  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
781  return printImpl( o, tableFormat );
782  }
783  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
784  bool toBePrinted() const override { return this->nEntries() > 0; }
785  };
786 
791  template <typename Arithmetic = double, atomicity Atomicity = atomicity::full>
792  struct BinomialCounter : BufferableCounter<Arithmetic, Atomicity, BinomialCounter>,
793  BinomialAccumulator<Arithmetic, Atomicity> {
795 
796  template <typename stream>
797  stream& printImpl( stream& o, bool tableFormat ) const {
798  auto fmt = ( tableFormat ? "|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%% |"
799  : "#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|" );
800  return o << boost::format{fmt} % this->nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
801  ( this->efficiencyErr() * 100 );
802  }
803 
804  std::ostream& print( std::ostream& o, bool tableFormat = false ) const override {
805  return printImpl( o, tableFormat );
806  }
807  MsgStream& print( MsgStream& o, bool tableFormat = false ) const override { return printImpl( o, tableFormat ); }
808 
809  template <typename stream>
810  stream& printImpl( stream& o, std::string_view tag ) const {
811  // override default print to add a '*' in from of the name
812  o << boost::format{" |*%|-48.48s|%|50t|"} % ( std::string{"\""}.append( tag ).append( "\"" ) );
813  return print( o, true );
814  }
816  std::ostream& print( std::ostream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
817  MsgStream& print( MsgStream& o, std::string_view tag ) const override { return printImpl( o, tag ); }
818  bool toBePrinted() const override { return this->nEntries() > 0; }
819  };
820 
822  struct Logger {
823  CommonMessagingBase const* parent = nullptr;
826 
827  void operator()( bool suppress = false ) const {
828  if ( suppress ) {
829  parent->msgStream( lvl ) << "Suppressing message: " << std::quoted( msg, '\'' ) << endmsg;
830  } else {
831  parent->msgStream( lvl ) << msg << endmsg;
832  }
833  }
834  };
835 
836  template <atomicity Atomicity>
837  struct Data {
838  std::conditional_t<Atomicity == atomicity::none, unsigned long, std::atomic<unsigned long>> count = {0};
839  unsigned long max = 0;
840  Logger const* logger = nullptr;
841 
842  constexpr Data( Logger const* p, unsigned long mx ) : max{mx}, logger{p} {}
843 
844  template <atomicity OtherAtomicity>
845  Data( Data<OtherAtomicity> const& other ) {
846  count = other.count;
847  max = other.max;
848  logger = other.logger;
849  }
850  };
851 
852  template <atomicity Atomicity>
853  struct Handler {
856 
857  static constexpr OutputType getValue( InternalType const& v ) noexcept { return v; }
858 
859  static void merge( InternalType& orig, bool b ) {
860  if ( b ) {
861  auto count = ++orig.count;
862  if ( UNLIKELY( count <= orig.max ) ) ( *orig.logger )( count == orig.max );
863  }
864  }
865  };
867  template <atomicity Atomicity>
868  constexpr unsigned long operator()( Data<Atomicity> const& v ) const noexcept {
869  return v.count;
870  }
871  };
872  } // namespace details::MsgCounter
873 
874  template <MSG::Level level, atomicity Atomicity = atomicity::full>
875  struct MsgCounter
877  details::MsgCounter::Logger,
878  GenericAccumulator<bool, details::MsgCounter::Data<Atomicity>, Atomicity, Identity,
879  details::MsgCounter::OutputTransform, details::MsgCounter::Handler<Atomicity>> {
880  template <typename OWNER>
881  MsgCounter( OWNER* o, std::string const& msg, int nMax = 10 )
882  : PrintableCounter( o, msg )
883  , details::MsgCounter::Logger{o, msg, level}
885  details::MsgCounter::OutputTransform, details::MsgCounter::Handler<Atomicity>>{
886  std::in_place, this, nMax} {}
888  ( *this ) += true;
889  return *this;
890  }
891  template <typename stream>
892  stream& printImpl( stream& o, bool tableFormat ) const {
893  return o << boost::format{tableFormat ? "|%|10d| |" : "#=%|-7lu|"} % this->value();
894  }
895  using PrintableCounter::print;
896  std::ostream& print( std::ostream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
897  MsgStream& print( MsgStream& os, bool tableFormat ) const override { return printImpl( os, tableFormat ); }
898  bool toBePrinted() const override { return this->value() > 0; }
899  };
900 
906  template <typename Counter, typename Container, typename Fun>
907  void accumulate( Counter& counter, const Container& container, Fun f = Identity{} ) {
908  auto b = counter.buffer();
909  for ( const auto& elem : container ) b += f( elem );
910  }
911 
912 } // namespace Gaudi::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
Definition: Accumulators.h:217
ContainedAccumulator< Arithmetic, atomicity::none > base_type
Definition: Accumulators.h:615
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
Definition: Accumulators.h:652
An empty ancester of all counters that knows how to print themselves.
Definition: Accumulators.h:634
#define UNLIKELY(x)
Definition: Kernel.h:106
A counter aiming at computing sum and average.
Definition: Accumulators.h:718
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:34
GenericAccumulator(std::in_place_t, Args &&... args)
Definition: Accumulators.h:368
Generic Accumulator, templated by.
Definition: Accumulators.h:356
virtual MsgStream & print(MsgStream &o, std::string_view tag) const
Definition: Accumulators.h:653
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:898
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
Definition: Accumulators.h:613
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:706
A functor always returning the value N.
Definition: Accumulators.h:178
EventIDBase min(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:212
A basic counter counting input values.
Definition: Accumulators.h:686
atomicity
Defines atomicity of the accumulators.
Definition: Accumulators.h:168
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Accumulators.h:233
Buffer< Arithmetic, Accumulator > buffer()
Definition: Accumulators.h:678
int merge(const char *target, const char *source, bool fixup=false, bool dbg=true)
Definition: merge.C:430
STL namespace.
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:209
T make_tuple(T... args)
constexpr unsigned long operator()(Data< Atomicity > const &v) const noexcept
Definition: Accumulators.h:868
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:732
Base type for all functors used as ValuesHandler.
Definition: Accumulators.h:223
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:892
MsgStream & print(MsgStream &o, std::string_view tag) const override
Definition: Accumulators.h:817
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:225
MsgCounter(OWNER *o, std::string const &msg, int nMax=10)
Definition: Accumulators.h:881
std::conditional_t< Atomicity==atomicity::none, unsigned long, std::atomic< unsigned long > > count
Definition: Accumulators.h:838
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:700
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:729
constexpr bool has_fetch_add_v
Definition: Accumulators.h:211
unsigned int operator()(bool v) const
Definition: Accumulators.h:481
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
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:709
STL class.
BinomialAccumulator & operator+=(binomial_t b)
Definition: Accumulators.h:528
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
Definition: Accumulators.h:246
int N
Definition: IOTest.py:110
GAUDIPS_API Logger & logger()
Return the current logger instance.
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:760
unsigned int operator()(bool v) const
Definition: Accumulators.h:465
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:797
T append(T... args)
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Accumulators.h:275
ContainedAccumulator< Arithmetic, atomicity::full > prime_type
Definition: Accumulators.h:614
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, Bases... > &&other)
Definition: Accumulators.h:406
stream & printImpl(stream &o, std::string_view tag) const
Definition: Accumulators.h:810
T str(T... args)
std::string toString() const
get a string representation
Definition: Accumulators.h:658
GenericAccumulator & operator=(const GenericAccumulator &other)
Definition: Accumulators.h:370
helper functor for the TrueAccumulator
Definition: Accumulators.h:464
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:783
MsgStream & msgStream() const
Return an uninitialized MsgStream.
T move(T... args)
A counter dealing with binomial data.
Definition: Accumulators.h:792
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
Definition: Accumulators.h:394
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:807
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:710
An Adder ValueHandler operator(a, b) means a += b.
Definition: Accumulators.h:254
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Accumulators.h:243
auto sqrt(std::chrono::duration< Rep, Period > d)
sqrt for std::chrono::duration
Definition: Counters.h:34
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:818
void reset(const std::tuple< typename Bases< Arithmetic, Atomicity >::OutputType... > &t)
Definition: Accumulators.h:411
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:773
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Accumulators.h:768
Data(Data< OtherAtomicity > const &other)
Definition: Accumulators.h:845
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:804
virtual bool toBePrinted() const
hint whether we should print that counter or not.
Definition: Accumulators.h:656
constexpr Data(Logger const *p, unsigned long mx)
Definition: Accumulators.h:842
T fetch_add(T... args)
GenericAccumulator(const GenericAccumulator &other)
Definition: Accumulators.h:369
static constexpr OutputType getValue(const InternalType &v) noexcept
Definition: Accumulators.h:232
static void merge(InternalType &a, Arithmetic b) noexcept
Definition: Accumulators.h:264
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:734
GenericAccumulator operator+=(const InputType by)
Definition: Accumulators.h:362
static void merge(InternalType &orig, bool b)
Definition: Accumulators.h:859
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
Definition: Accumulators.h:816
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
Definition: Accumulators.h:377
constexpr T operator()(U &&) const noexcept
Definition: Accumulators.h:180
bool toBePrinted() const override
hint whether we should print that counter or not.
Definition: Accumulators.h:784
stream & printImpl(stream &s, std::string_view tag) const
Definition: Accumulators.h:644
auto sqrt(T d)
forward declaration of sqrt for custom types
string s
Definition: gaudirun.py:328
const Gaudi::Algorithm & parent
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:724
std::decay_t< std::result_of_t< Identity(unsigned long)> > OutputType
Definition: Accumulators.h:361
T sqrt(T... args)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:756
MsgStream & print(MsgStream &o, bool tableFormat=false) const override
Definition: Accumulators.h:759
An empty ancester of all counters that provides a buffer method that returns a buffer on itself.
Definition: Accumulators.h:676
MsgStream & print(MsgStream &os, bool tableFormat) const override
Definition: Accumulators.h:897
A counter aiming at computing average and sum2 / variance / standard deviation.
Definition: Accumulators.h:744
stream & printImpl(stream &o, bool tableFormat) const
Definition: Accumulators.h:750
STL class.
Efficient counter implementations for Gaudi.
Definition: Histogram.h:19
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b,...
Definition: Accumulators.h:292
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
Definition: Accumulators.h:780
static constexpr OutputType getValue(InternalType const &v) noexcept
Definition: Accumulators.h:857
AccumulatorSet & operator+=(const InputType by)
Definition: Accumulators.h:399
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:907
helper functor for the FalseAccumulator
Definition: Accumulators.h:480
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:208
std::ostream & print(std::ostream &os, bool tableFormat) const override
prints the counter to a stream
Definition: Accumulators.h:896