Add vectorised track combiner
Brief summary: add a vectorised track combiner CombineTracksSIMD (which produces v2::Composites), and a whole bunch of other related changes to selection/functor code to enable this.
CombineTracksSIMD:
- Implements generic
N-body combinations from a single input container of tracks, producingv2::Composites - The combiner has to be explicitly instantiated for each input container type,
Nand target vector backend. The output typev2::Compositeserases all of these details. - If a relevant functor cache is available, the combination generation, combination cut(s), vertex fit and vertex/parent cut are all explicitly vectorised. If no cache is available, the cuts are JIT compiled and the algorithm falls back to scalar calculation.
- Vertex fit implementation is lifted from
ThOrParticleCombiner, thanks @nnolte :)
Converters:
- Add
LHCb::Converters::Composites::ToVectorOfRecVertex<T>algorithm for convertingv2::Compositesto a vector of vertices, for use in the SelReports code
Functor interface changes:
- Store whether a functor with JIT compiled or loaded from the functor cache.
- Add
getFunctors()method towith_functorsmixin to return multiple decoded functors at once. - Add
Functors::mask_arg_ttag type; this can be used to tag that the following (second) argument is a mask that gives the validity of the remaining arguments:Functor<Output( mask_arg_t, mask_v const&, Input const& )>. This is useful whenInputis some type representing a vector of values. - Drop
BPVIPCHI2STATEfunctor - Make the
CompositeMassfunctor returnp.momentum().M()instead ofp.measuredMass()when applied to av1::Particle - Make the
COMBfunctor [reconstructing a "combination" object from a "composite"] compatible with a runtime-variable number of heterogeneous child types & vectorised instantiation - Make the
MVAfunctor support vectorised instantiation; the calculation of inputs is vectorised, but evaluation of the classifier is [masked] scalar. (We should really get some faster MVA implementations here!) - Add
PODfunctor (meaning Plain Old Data, but perhaps someone would like to suggest a better name) that wraps the newSel::Utils::as_arithmetichelper. This converts objects representing scalar values into plain C++ types (e.g.SIMDWrapper::scalar::int_v->int). This is a step on the way to retiring the "unwrapping" functionality ofLHCb::Pr::Zip.PODcan be automatically added as a wrapper around a functor expression to make it yield a type that e.g.TTreecan understand.
Selection utilities changes:
- Add
Sel::Utils::hmin,Sel::Utils::hmax,Sel::Utils::as_arithmetichelpers for writing generic code that handles both plain C++ types and e.g.SIMDWrapperint/float types. - Add various helpers for writing generic code, e.g.
Sel::vector::dot{}( a, b )takes the dot product of vectorsaandb, abstracting away some API inconsistencies between different vector types in the codebase - Reorganise various type trait helpers, e.g.
Sel::type_traits::has_eta_v<T>queries whether an object of typeThas aneta()method - Add
Sel::Utils::stateDOCA( s1, s2 )helper for calculating the distance of closest approach between two states of distinct type. This is copied fromLHCb::TrackVertexUtils::docato avoid the unfortunate issue that callingLHCb::TrackVertexUtils::docawith two arguments of different types despatches to the calculation of DOCA between a state and a point (a state has x/y/z accessors, so this is not a compile error!)
Event model changes:
- Add
v2::Composites-compatible accessors toTrackCompactVertex - Prefer
static_assert( std::numeric_limits<T>::is_specialized )andstd::numeric_limits<T>nowSIMDWrappersupportsstd::numeric_limits
Internal functor changes:
- Pass
Functors::TopLevelInfo&to internal functor bind methods instead ofGaudi::Algorithm*, making it easier to expose more helper functionality; add a helper to avoid hitting https://its.cern.ch/jira/browse/GAUDI-1023 when multiple functors need to access the same service - Add some missing inheritance from
FunctionandPredicate - Use demangled
typeid( T ).name()in some error messages - Minor code improvements/cleanups.
- Support explicit masks in functors. If a functor defines
constexpr static bool requires_explicit_mask = truethen it will be invoked with a mask as its first argument, which gives the validity of the remaining arguments. Make this change in the various adapter functors. - Use explicit mask support in
MINIP[CHI2]CUTfunctors, where the mask can be used to short-circuit earlier.
To be tested with LHCb!2650 (merged) and Moore!562 (merged)
cc: @nnolte
Edited by Olli Lupton