1 #ifndef GAUDIKERNEL_COUNTERS_H 2 #define GAUDIKERNEL_COUNTERS_H 1 127 #include "boost/algorithm/string/predicate.hpp" 128 #include "boost/format.hpp" 131 #include <initializer_list> 136 #include <type_traits> 144 namespace Accumulators
153 template <
unsigned long N>
155 template <
typename U>
166 template <
typename U>
167 constexpr decltype(
auto )
operator()( U&& v )
const noexcept
169 return std::forward<U>( v );
177 template <
typename U>
178 constexpr decltype(
auto )
operator()( U&& v )
const noexcept
187 template <
typename T,
typename =
int>
189 template <
typename T>
190 using has_fetch_add =
typename Gaudi::cpp17::is_detected<has_fetch_add_, T>::value_t;
195 template <
typename Arithmetic, atomicity Atomicity>
201 template <
typename Arithmetic>
212 template <
typename Arithmetic>
218 return v.load( std::memory_order_relaxed );
227 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
233 template <
typename Arithmetic>
244 template <
typename Arithmetic>
249 #if __cplusplus > 201402L 250 static void merge(
InternalType& a, Arithmetic b ) noexcept
252 if ( DefaultValue() == b )
return;
265 template <
typename T>
268 auto current = a.
load( std::memory_order_relaxed );
272 template <
typename T>
275 a.
fetch_add( b, std::memory_order_relaxed );
281 if ( DefaultValue() == b )
return;
291 template <
typename Arithmetic, atomicity Atomicity,
typename Compare, Arithmetic ( *Initial )()>
297 template <
typename Arithmetic,
typename Compare, Arithmetic ( *Initial )()>
304 if ( Compare{}( b, a ) ) a = b;
311 template <
typename Arithmetic,
typename Compare, Arithmetic ( *Initial )()>
319 while ( Compare{}( b, prev_value ) && !a.compare_exchange_weak( prev_value, b ) )
328 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
335 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
360 template <
typename A,
typename B, atomicity C,
typename D,
typename E,
typename F>
364 using OutputType = std::decay_t<std::result_of_t<OutputTransform( InnerType )>>;
367 ValueHandler::merge( m_value, InputTransform{}( by ) );
374 m_value = ValueHandler::getValue( other.
m_value );
377 OutputType value()
const {
return OutputTransform{}( ValueHandler::getValue( m_value ) ); }
379 template <atomicity ato,
typename VH>
382 auto otherValue = VH::exchange( other.m_value, VH::DefaultValue() );
383 ValueHandler::merge( m_value, otherValue );
396 template <
typename Arithmetic, atomicity Atomicity,
template <
typename, atomicity>
class... Bases>
410 template <atomicity Ato>
414 ( Bases<Arithmetic, Atomicity>::mergeAndReset(
static_cast<Bases<Arithmetic, Ato>&&
>( other ) ), 0 )...};
418 void reset(
const std::tuple<
typename Bases<Arithmetic, Atomicity>::OutputType...>& t )
421 [
this](
const auto&... i ) {
431 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
433 :
GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Maximum<Arithmetic, Atomicity>> {
434 Arithmetic
max()
const {
return this->value(); }
440 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
442 :
GenericAccumulator<Arithmetic, Arithmetic, Atomicity, Identity, Identity, Minimum<Arithmetic, Atomicity>> {
443 Arithmetic
min()
const {
return this->value(); }
449 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
451 unsigned long nEntries()
const {
return this->value(); }
457 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
459 Arithmetic
sum()
const {
return this->value(); }
465 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
467 Arithmetic
sum2()
const {
return this->value(); };
479 template <
typename Arithmetic, atomicity Atomicity>
493 template <
typename Arithmetic, atomicity Atomicity>
502 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
504 unsigned long nEntries()
const {
return this->nTrueEntries() + this->nFalseEntries(); };
508 if ( 1 > nbEntries )
return -1;
509 return static_cast<Arithmetic
>( this->nTrueEntries() ) / static_cast<Arithmetic>( nbEntries );
511 Arithmetic
eff()
const {
return efficiency(); }
517 Arithmetic nbEntries =
static_cast<Arithmetic
>(
nEntries() );
518 if ( 1 > nbEntries )
return -1;
519 return sqrt( static_cast<Arithmetic>( this->nTrueEntries() * this->nFalseEntries() ) / nbEntries ) / nbEntries;
521 Arithmetic
effErr()
const {
return efficiencyErr(); }
527 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
532 return n ? this->
sum() /
n : Arithmetic{};
539 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
545 return count ? ( this->sum2() -
sum * (
sum / count ) ) / count : Arithmetic{};
551 return count ? ( this->sum2() -
sum * (
sum / count ) ) / ( count - 1 ) : Arithmetic{};
558 auto v = biased_sample_variance();
559 return ( 0 > v ) ? Arithmetic{} : sqrt( v );
561 [[deprecated(
"The name 'rms' has changed to standard_deviation" )]] Arithmetic
rms()
const 563 return standard_deviation();
568 if ( 0 ==
n )
return Arithmetic{};
572 auto v = biased_sample_variance();
573 if ( 0 > v )
return Arithmetic{};
574 return sqrt( v /
n );
581 template <
typename Arithmetic, atomicity Atomicity = atomicity::full>
589 template <
typename Arithmetic,
template <
typename Int, atomicity Ato>
class ContainedAccumulator>
590 class Buffer :
public ContainedAccumulator<Arithmetic, atomicity::none>
592 using prime_type = ContainedAccumulator<Arithmetic, atomicity::full>;
593 using base_type = ContainedAccumulator<Arithmetic, atomicity::none>;
601 void push() { m_prime.mergeAndReset( static_cast<base_type&&>( *
this ) ); }
612 template <
class OWNER>
615 o->registerCounter( tag, *
this );
624 o <<
boost::format{
" | %|-48.48s|%|50t|"} % (
"\"" + tag +
"\"" );
625 return print( o,
true );
641 return counter.
print( stream );
648 template <
typename Arithmetic, atomicity Atomicity,
template <
typename Int, atomicity Ato>
class Accumulator>
657 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
662 ( *this ) += Arithmetic{};
686 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
695 fmt =
"|%|7d| |%|11.7g| |%|#11.5g| |";
697 fmt =
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g|";
702 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
708 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
717 fmt =
"|%|7d| |%|11.7g| |%|#11.5g| |%|#10.5g| |";
719 fmt =
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g|";
728 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
736 fmt =
"|%|7d| |%|11.7g| |%|#11.5g| |%|#10.5g| |%|#10.5g| |%|#10.5g| |";
738 fmt =
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
741 this->min() % this->max();
745 template <
typename Arithmetic =
double, atomicity Atomicity = atomicity::full>
753 fmt =
"|%|7d| |%|11.5g| |(%|#9.7g| +- %|-#8.6g|)%%|";
755 fmt =
"#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
757 return o <<
boost::format{fmt} % this->
nEntries() % this->nTrueEntries() % ( this->efficiency() * 100 ) %
758 ( this->efficiencyErr() * 100 );
764 o <<
boost::format{
"*| %|-48.48s|%|50t|"} % (
"\"" + tag +
"\"" );
765 return print( o,
true );
779 Gaudi::Accumulators::StatAccumulator,
780 Gaudi::Accumulators::BinomialAccumulator>
788 using AccParent::reset;
791 template <
class OWNER>
794 o->registerCounter( tag, *
this );
796 StatEntity(
const unsigned long entries,
const double flag,
const double flag2,
const double minFlag,
797 const double maxFlag )
803 void reset() { AccParent::reset(); }
811 ( *this ) += ( -by );
839 std::make_tuple( se.nEntries(), se.sum(), se.min(), se.max(), se.sum2() );
852 unsigned long add(
const double v )
862 double rms()
const {
return standard_deviation(); }
863 double Rms()
const {
return standard_deviation(); }
864 double RMS()
const {
return standard_deviation(); }
865 double Eff()
const {
return eff(); }
866 double Min()
const {
return min(); }
867 double Max()
const {
return max(); }
870 double flag2()
const {
return sum2(); }
872 double flagRMS()
const {
return standard_deviation(); }
878 using boost::algorithm::icontains;
879 return icontains( name,
"eff" ) || icontains( name,
"acc" ) || icontains( name,
"filt" ) ||
880 icontains( name,
"fltr" ) || icontains( name,
"pass" );
885 fmt %
nEntries() %
sum() %
mean() % standard_deviation() % min() % max();
886 return o << fmt.str();
892 if ( flag && effCounter( name ) && 0 <= eff() && 0 <= effErr() &&
sum() <=
nEntries() &&
893 ( 0 == min() || 1 == min() ) && ( 0 == max() || 1 == max() ) ) {
897 if ( name.
empty() ) {
898 fmt =
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
900 ( efficiencyErr() * 100 );
902 fmt =
"*" + fmtHead +
"|%|10d| |%|11.5g| |(%|#9.7g| +- %|-#8.7g|)%%| ------- | ------- |";
904 ( efficiency() * 100 ) % ( efficiencyErr() * 100 );
907 fmt =
"#=%|-7lu| Sum=%|-11.5g| Eff=|(%|#9.7g| +- %|-#8.6g|)%%|";
909 ( efficiencyErr() * 100 );
915 if ( name.
empty() ) {
916 fmt =
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
920 fmt =
" " + fmtHead +
"|%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |";
925 fmt =
"#=%|-7lu| Sum=%|-11.5g| Mean=%|#10.4g| +- %|-#10.5g| Min/Max=%|#10.4g|/%|-#10.4g|";
932 return print( o,
true, tag,
true );
937 return print( o, tableFormat, emptyName,
true );
948 #endif // GAUDIKERNEL_COUNTERS_H constexpr unsigned long operator()(U &&) const noexcept
ContainedAccumulator< Arithmetic, atomicity::full > prime_type
virtual 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
std::string toString() const
static void merge(InternalType &a, Arithmetic b) noexcept
static void merge(InternalType &a, Arithmetic b) noexcept
void mergeAndReset(AccumulatorSet< Arithmetic, Ato, Bases... > &&other)
unsigned long nEntries() const
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
PrintableCounter()=default
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
decltype(std::atomic< T >{}.fetch_add(0)) has_fetch_add_
type_traits for checking the presence of fetch_add in std::atomic<T>
std::ostream & fillStream(std::ostream &o) const
unsigned long nEntries() const
unsigned long nFalseEntries() const
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
An empty ancester of all counters that provides a buffer method that returns a buffer on itself...
double sum(double x, double y, double z)
unsigned long nTrueEntries() const
atomicity
Defines atomicity of the accumulators.
A counter aiming at computing average and sum2 / variance / standard deviation.
typename Gaudi::cpp17::is_detected< has_fetch_add_, T >::value_t has_fetch_add
Gaudi::Accumulators::BinomialAccumulator< double, Gaudi::Accumulators::atomicity::full > BinomialAccParent
An Adder ValueHandler operator(a, b) means a += b.
Gaudi::Accumulators::AccumulatorSet< double, Gaudi::Accumulators::atomicity::full, Gaudi::Accumulators::StatAccumulator, Gaudi::Accumulators::BinomialAccumulator > AccParent
A counter aiming at computing sum and average.
Arithmetic unbiased_sample_variance() const
class MergingTransformer< Out(const vector_of_const_< In > void
decltype(auto) constexpr apply(F &&f, Tuple &&t) noexcept(noexcept( detail::apply_impl(std::forward< F >(f), std::forward< Tuple >(t), std::make_index_sequence< std::tuple_size< std::remove_reference_t< Tuple >>::value >{})))
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
An functor always returning the value N.
An empty ancester of all counters that knows how to print themselves.
double flagMeanErr() const
std::ostream & printFormatted(std::ostream &o, const std::string &format) const
bool operator<(const StatEntity &se) const
Arithmetic effErr() const
StatEntity operator++(int)
Arithmetic standard_deviation() const
static void add(InternalType &a, T b, std::true_type)
std::decay_t< std::result_of_t< Identity(unsigned long)>> OutputType
static constexpr OutputType getValue(const InternalType &v) noexcept
static constexpr OutputType DefaultValue()
PropertyMgr & operator=(const PropertyMgr &)=delete
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
StatEntity & operator++()
static constexpr OutputType DefaultValue()
PrintableCounter(OWNER *o, const std::string &tag)
GenericAccumulator operator+=(const InputType by)
static void add(InternalType &a, T b, std::false_type)
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
unsigned int operator()(bool v) const
AccumulatorSet & operator+=(const InputType by)
StatEntity & operator-=(double by)
StatEntity(OWNER *o, const std::string &tag)
Buffer is a non atomic Accumulator which, when it goes out-of-scope, updates the underlying thread-sa...
Buffer< Arithmetic, Accumulator > buffer()
virtual 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
Arithmetic biased_sample_variance() const
std::ostream & print(std::ostream &o, bool tableFormat, const std::string &name, bool flag=true, std::string fmtHead="%|-48.48s|%|27t|") const
virtual std::ostream & print(std::ostream &, bool tableFormat=false) const =0
prints the counter to a stream
GenericAccumulator & operator=(const GenericAccumulator &other)
std::string toString() const
get a string representation
A counter aiming at computing average and sum2 / variance / standard deviation.
void mergeAndReset(GenericAccumulator< InputType, InnerType, ato, InputTransform, OutputTransform, VH > &&other)
Arithmetic efficiency() const
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
AccumulatorSet is an Accumulator that holds a set of Accumulators templated by same Arithmetic and At...
StatEntity & operator+=(StatEntity by)
Arithmetic efficiencyErr() const
Arithmetic meanErr() const
AccumulatorSet< Arithmetic, Atomicity, SigmaAccumulator, MinAccumulator, MaxAccumulator > StatAccumulator
StatAccumulator.
StatEntity & operator--()
void reset(const std::tuple< typename Bases< Arithmetic, Atomicity >::OutputType... > &t)
static bool effCounter(const std::string &name)
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
ValueHandler::InternalType m_value
static constexpr OutputType DefaultValue()
std::ostream & operator<<(std::ostream &stream, const PrintableCounter &counter)
external printout operator to std::ostream
helper functor for the TrueAccumulator
helper functor for the FalseAccumulator
unsigned long addFlag(const double v)
Base type for all functors used as ValuesHandler.
GenericAccumulator(const GenericAccumulator &other)
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
A basic counter counting input values.
T compare_exchange_weak(T...args)
static constexpr OutputType DefaultValue()
static void merge(InternalType &a, Arithmetic b) noexcept
static void merge(InternalType &a, Arithmetic b) noexcept
static Arithmetic exchange(InternalType &v, Arithmetic newv) noexcept
StatEntity(const unsigned long entries, const double flag, const double flag2, const double minFlag, const double maxFlag)
static constexpr OutputType getValue(const InternalType &v) noexcept
backward compatible StatEntity class.
StatEntity operator--(int)
StatEntity & operator+=(double by)
ContainedAccumulator< Arithmetic, atomicity::none > base_type
An Extremum ValueHandler, to be reused for Minimum and Maximum operator(a, b) means if (Compare(b...
std::ostream & print(std::ostream &o, bool tableFormat=false) const override
prints the counter to a stream
unsigned int operator()(bool v) const
Generic Accumulator, templated by.
Helper functions to set/get the application return code.
void operator=(double by)
unsigned long add(const double v)