Choose your own Gaudi::Functional adventure!
This is a quick attempt at a guide to the functional algorithm functionality that is currently being proposed for Gaudi. By following the following iterative reasoning, you should be able to determine which algorithm of Gaudi::Functional is right for you, if any.
How many inputs does your Algorithm have?
If you have no inputs...
...you may want to use a Producer. It takes no Gaudi input, and produces eve t data that is either constant, or generated through side effects such as file IO.
Are your inputs of the same type?
What do you want to do with your inputs?
To turn N inputs of one type into N outputs of another...
...you may want to use a
ScalarTransformer. Given instructions on how to transform an single object of type T1 into another object of type T2, it applies the transform to all inputs in a vector of T1, and stores the results in an equally sized vector of T2.
ScalarTransformer is, in this sense, similar to the STL "transform" algorithm, the functional "map" operation and the TBB "parallel_for" algorithm, if you are familiar with any of those.
To turn N inputs of one type into 1 output of another...
...you may want to use a
MergingTransformer. This pattern is similar to the STL "accumulate" algorithm and the functional "reduce" operation, and intended for operations such as concatenating containers or summing their contents.
What kind of output does your Algorithm produce?
- <<no-output, Nothing>>
- <<filter-decision, An event filtering decision>>
- <<event-data-output, Event data>>
==
no-outputIf you have no output...
...you may want to use a Consumer. It takes some input data, and does something with it that is not Gaudi's concern, such as writing it down to a log file. Another use case to be discussed is filling up a monitoring histogram.
image::Consumer.png[]
==
filter-decisionIf you want to filter events...
...you may want to use a
FilterPredicate. Given some input data, it decides whether the processing of a given event should be continued or not.
image::FilterPredicate.png[]
==
event-data-outputWhat kind of event data are you producing?
- <<one-event-output, One single object>>
- <<homogeneous-outputs, Several objects of the same type>>
- <<heterogeneous-outputs, Several objects of different types>>
==
one-event-outputTo produce one object out of multiple ones...
...you may want to use a Transformer. Given N inputs of different types, it produces a single output. Producing multiple outputs is also possible with
MultiTransformer, but C++ compilers offer stronger optimization guarantees when only one output is produced.
image::Transformer.png[]
==
homogeneous-outputsTo produce several objects of the same type...
...you may want to use a
SplittingTransformer. Given N inputs of different types, it produces a vector of outputs of the same type. A typical use case is to split a large container into multiple smaller containers.
image::SplittingTransformer.png[]
==
heterogeneous-outputsTo produce several objects of different types...
...you may want to use a
MultiTransformer. This is a generalized version of Transformer that can produce multiple outputs. The drawback of this pattern is that it is only efficient if all output objects are efficiently movable.
image::MultiTransformer.png[]
--
HadrienGrasland - 2016-09-22