New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix for NOT
operator in triggerExpression::Parser
#39108
Conversation
NOT
operator in triggerExpression::parse
NOT
operator in triggerExpression::Parser
@@ -2,7 +2,7 @@ | |||
#define HLTrigger_HLTfilters_TriggerExpressionParser_h | |||
|
|||
// Note: this requires Boost 1.41 or higher, for Spirit 2.1 or higher | |||
#include <boost/spirit/include/phoenix.hpp> | |||
#include <boost/phoenix.hpp> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change quiets the following compile-time warning:
In file included from /cvmfs/cms.cern.ch/slc7_amd64_gcc10/external/boost/1.78.0-12075919175e8d078539685f9234134a/include/boost/config/header_deprecated.hpp:18,
from /cvmfs/cms.cern.ch/slc7_amd64_gcc10/external/boost/1.78.0-12075919175e8d078539685f9234134a/include/boost/spirit/include/phoenix.hpp:11,
from CMSSW_12_5_0_pre4/src/HLTrigger/HLTcore/interface/TriggerExpressionParser.h:5,
from CMSSW_12_5_0_pre4/src/HLTrigger/HLTcore/test/test_catch2_TriggerExpressionParser.cc:7:
/cvmfs/cms.cern.ch/slc7_amd64_gcc10/external/boost/1.78.0-12075919175e8d078539685f9234134a/include/boost/spirit/include/phoenix.hpp:12:1: note: '#pragma message: This header is deprecated. Use <boost/phoenix.hpp> instead.'
12 | BOOST_HEADER_DEPRECATED("<boost/phoenix.hpp>")
| ^~~~~~~~~~~~~~~~~~~~~~~
It seemed safe to do, but I'm not 100% sure. @fwyzard , what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it works and silences the warnings, go for it
@@ -37,7 +37,7 @@ namespace triggerExpression { | |||
|
|||
operand %= (prescale | element); | |||
|
|||
unary = (operand[qi::_val = qi::_1] | (qi::lit("NOT") >> operand)[qi::_val = new_<OperatorNot>(qi::_1)]); | |||
unary = ((qi::lit("NOT") >> operand)[qi::_val = new_<OperatorNot>(qi::_1)] | operand[qi::_val = qi::_1]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 1-line change is the fix.
SECTION("CorrectExpressions") { | ||
REQUIRE(testExpression("TRUE")); | ||
REQUIRE(testExpression("FALSE")); | ||
REQUIRE(testExpression("NOT (FALSE)")); | ||
REQUIRE(testExpression("(NOT FALSE) OR TRUE")); | ||
REQUIRE(testExpression("NOTThisHLTPath AND TRUE AND NOT L1_A?_*")); | ||
REQUIRE(testExpression("NOT NOTThisHLTPath")); | ||
REQUIRE(testExpression("ThisHLTANDNOTThatORTheOther")); | ||
REQUIRE(testExpression("NOT L1_SEED1 AND L1_SEED2*")); | ||
REQUIRE(testExpression("NOT L1_SEED2 AND (HLT_PATH_? AND NOT HLT_PATH2_??_*)")); | ||
REQUIRE(testExpression("NOT (HLT_Path1 AND HLT_Path2)")); | ||
REQUIRE(testExpression("NOT (NOTHLT_Path OR HLT_Path2)")); | ||
REQUIRE(testExpression("((L1_A AND HLT_B) OR Dataset_C) AND NOT (Status_D OR Name_E OR HLT_F*) AND L1_??_?_?")); | ||
REQUIRE(testExpression("NOT (NOT (HLT_Path1 AND HLT_Path_*))")); | ||
} | ||
|
||
// examples of expressions not supported by the triggerExpression parser | ||
SECTION("IncorrectExpressions") { | ||
REQUIRE(not testExpression("A | B")); | ||
REQUIRE(not testExpression("A && B")); | ||
REQUIRE(not testExpression("NOT L1_SEED1 ANDD L1_SEED2*")); | ||
REQUIRE(not testExpression("NOT (NOTHLT_Path OR HLT_Path2))")); | ||
REQUIRE(not testExpression("NOT NOT (HLT_Path1 AND L1_Seed_?? OR HLT_Path_*)")); | ||
REQUIRE(not testExpression("HLT_Path* NOT TRUE")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list of good and bad expressions is pretty much random. Suggestions are welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this one invalid ?
testExpression("NOT NOT (HLT_Path1 AND L1_Seed_?? OR HLT_Path_*)"));
I mean, it is silly to use NOT NOT
, but is it an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, the parser should understand it, but it doesn't.. NOT NOT [expr]
isn't working, while NOT (NOT [expr])
will work (last valid expression in the unit test). In the first case, it again gets into a state where it parses one of the NOT
s (I assume the 2nd one) as an HLT-path name, then fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood.
OK, I think NOT NOT ...
is pretty low on the wish list, we can definitely live without.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I would agree. On the other hand, more checking led me to realise that the parser now reads NOTHLT1
as equivalent to NOT HLT1
(or NOT(HLT1)
, or NOT (HLT1)
), and that seems wrong.. so I'll have to take a deeper look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe HLT1 ANDHLT2
etc share the same problem ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, they do.. the best I could come up with right now is the following:
- unary = ((qi::lit("NOT") >> operand)[qi::_val = new_<OperatorNot>(qi::_1)] | operand[qi::_val = qi::_1]);
+ unary = ((qi::lit("NOT ") >> operand)[qi::_val = new_<OperatorNot>(qi::_1)] | operand[qi::_val = qi::_1]);
expression =
- unary[qi::_val = qi::_1] >> *((qi::lit("AND") >> unary)[qi::_val = new_<OperatorAnd>(qi::_val, qi::_1)] |
+ unary[qi::_val = qi::_1] >> *((qi::lit("AND ") >> unary)[qi::_val = new_<OperatorAnd>(qi::_val, qi::_1)] |
- (qi::lit("OR") >> unary)[qi::_val = new_<OperatorOr>(qi::_val, qi::_1)]);
+ (qi::lit("OR ") >> unary)[qi::_val = new_<OperatorOr>(qi::_val, qi::_1)]);
That seems to work (more checks tomorrow), but it would make the following invalid b/c of no spaces
(ABC)AND((THIS)OR(THAT))
type bugfix |
+code-checks Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-39108/31646
|
A new Pull Request was created by @missirol (Marino Missiroli) for master. It involves the following packages:
@cmsbuild, @missirol, @Martin-Grunewald can you please review it and eventually sign? Thanks. cms-bot commands are listed here |
please test |
+1 Summary: https://cmssdt.cern.ch/SDT/jenkins-artifacts/pull-request-integration/PR-ff9ea4/26929/summary.html Comparison SummarySummary:
|
- Improve the representation of trigger expression - Improved the dumped representation of trigger expressions: - AND, OR, and NOT operators add parentheses around their subexpression; - uninitialised Path and L1uGT readers use an explicit name instead of FALSE. - Print how the expressions are interpreted - Delimit tokens and operands - Require a delimiter after each token and operamd, to avoid en expression like: "NOTSomePath ANDOtherPath" to be parsed as: "NOT SomePath AND OtherPath" - Add more tests - Compare the parsed and expected representations
+code-checks Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-39108/31675
|
Pull request #39108 was updated. @cmsbuild, @missirol, @Martin-Grunewald can you please check and sign again. |
+code-checks Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-39108/31695
|
Pull request #39108 was updated. @cmsbuild, @missirol, @Martin-Grunewald can you please check and sign again. |
please test As I grow skeptical of finding a better implementation myself, I start the tests. |
+1 Summary: https://cmssdt.cern.ch/SDT/jenkins-artifacts/pull-request-integration/PR-ff9ea4/26984/summary.html Comparison SummarySummary:
|
+hlt
|
This pull request is fully signed and it will be integrated in one of the next master IBs (tests are also fine). This pull request will now be reviewed by the release team before it's merged. @perrotta, @dpiparo, @qliphy, @rappoccio (and backports should be raised in the release meeting by the corresponding L2) |
+1 |
PR description:
The
NOT
operator of the parser in thetriggerExpression
namespace does not work correctly in recent CMSSW releases.This PR fixes that. All credit to @fwyzard for finding the solution.
The issue was that the parser was mistakenly interpreting "NOT" as the name of an HLT path (parsing it into a
TriggerExpressionPathReader
object).Unit tests are improved in order to catch issues with the parser, should they come up in the future:
HLTcore
;TriggerResultsFilters
inHLTfilters
are updated, including a numerical check on the trigger results of thecmsRun
jobs.(The above tests can be used to verify that without this PR the
NOT
operator would not work correctly in recent CMSSW releases.)Context:
triggerExpression
parser is used in theTriggerResultsFilter
plugin, many instances of which exist in the HLT menus;NOT
operator, so this fix will have no impact on any current production use case;12_4_X
.This PR has a small overlap with #39044, and takes precedence over it.
PR validation:
Relies on the updated unit tests.
If this PR is a backport, please specify the original PR and why you need to backport that PR. If this PR will be backported, please specify to which release cycle the backport is meant for:
CMSSW_12_4_X