Skip to content

SelReportsMaker configurations causes line algorithms to run unconditionally.

The configuration of the SelReportsMaker algorithm has the (converted) output of all lines as input. When the scheduler runs the maker, it resolves the data dependency tree by running the line algorithms, regardless of whether or not the line's control flow node passed. Some line algorithms should not be run if their prefilters fail, but the dependency resolution ignores this. This is wasteful and potentially meaningless.

In summary, we somehow need to handle optional data dependencies.

Detail

Imagine this control flow (which is similar to what Moore constructs) for two lines:

MooreNode
    HLTLinesNode
        PassthroughLineNode
            TrueFilterAlg
        PhysicsLineNode
            PVFilterAlg
            TwoTrackCombinerAlg
    PersistencyNode
        DecReportsAlg
        SelReportsAlg
  1. The algorithms in PersistencyNode will be run if any node under HLTLinesNode passes.
  2. The configuration of SelReportsAlg has the output of TwoTrackCombinerAlg as input.
  3. In an event, let's say that PVFilterAlg fails, so TwoTrackCombinerAlg will not be run, but TrueFilterAlg passes. Then HLTLinesNode passes and hence PersistencyNode is run. SelReportsAlg is run and the scheduler sees the data dependency on the output of TwoTrackCombinerAlg and so runs the combiner algorithm.

The combiner algorithm may have undefined behaviour if the prefilter in the control flow fails. For example, the functor may require a non-zero number of PVs in order for the functor evaluation to make sense. But now the scheduler is running this algorithm regardless of whether the PV container is empty or not. 💣

IRL

We observed this problem in the HLT1 performance comparison configuration. This runs a 'GEC passthrough' line which fires if the GEC passes. If every physics line fails but the passthrough line fires, the output algorithm of each line will be run by the scheduler in order to meet the data dependencies of the SelReports maker. !439 (merged) temporarily addresses this by removing the passthrough line from the configuration, but the underlying problem remains; any line that fires without requiring PVs will trigger the issue.

Solutions

A couple of ideas for dealing with optional data dependencies (for this particular case; maybe there's a better solution that's more general):

  1. getIfExists. The maker algorithm has list of inputs, one per line, and it could retrieve them with a getIfExists, skipping making a SelReport if the dependecy doesn't exists. This isn't nice because:
    1. It circumvents the explicit declarations made possible via Gaudi::Property and DataHandle objects.
    2. The actual input might not be the direct output of a line algorithm, but the output of a converter, so we might need the dependency resolution mechanism to walk up the tree for us to run the (chain of) converters.
  2. Tie the control flow node dependency explicitly to the data dependency. Each input is, somehow, a pair that expresses the intent of "only resolve this data dependency if that control flow node passed".

The second solution seems most elegant to me, and the implementation in the scheduler is probably fairly straight forward. The tricky part is how to express this in the algorithm implementation, i.e. the implementation of the OptionalDataHandle property (and associated lists/maps of optional deps.) and how these are passed to the operator(). (These problems may be of interest to @graven.)

/cc @olupton @ahennequ @nnolte