-
Notifications
You must be signed in to change notification settings - Fork 4.4k
[L1T] L1TSC4NGJetModel (Phase 2) #47798
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
base: master
Are you sure you want to change the base?
[L1T] L1TSC4NGJetModel (Phase 2) #47798
Conversation
cms-bot internal usage |
+1 Size: This PR adds an extra 16KB to repository Comparison SummarySummary:
|
fMaxEta_(cfg.getParameter<double>("maxEta")), | ||
fMaxJets_(cfg.getParameter<int>("maxJets")), | ||
fNParticles_(cfg.getParameter<int>("nParticles")), | ||
loader(hls4mlEmulator::ModelLoader(cfg.getParameter<string>("l1tSC4NGJetModelPath"))) { |
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.
Just a note: in Run 3 we get the model names from the menu, but we should generally discuss how we want to do this in Phase 2
std::vector<l1ct::JetTagClass> classes_; | ||
|
||
hls4mlEmulator::ModelLoader loader; | ||
std::shared_ptr<hls4mlEmulator::Model> model; |
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.
could you add a logerror in case the model is not loaded properly?
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.
Added a error throw when the model is not found
fId_.get()[i0] = iParts[i0]->id(); | ||
} | ||
setNNVectorVar(); | ||
return EvaluateNNFixed(); |
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.
general comment: would it be useful to add some log error/debug lines in case the nn evaluation doesnt work as expected?
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.
Added debugging to model input and output so the NN evaluation can be properly debugged
@@ -363,11 +369,29 @@ void l1ct::TrackInputEmulator::configPhi(int bits) { | |||
|
|||
float l1ct::TrackInputEmulator::floatZ0(ap_int<12> z0) const { return z0Scale_ * toFloat_(z0); } | |||
|
|||
// float l1ct::TrackInputEmulator::floatDxy(ap_int<13> dxy) const { return dxyScale_ * toFloat_(dxy); } | |||
float l1ct::TrackInputEmulator::floatDxy(ap_int<13> dxy) const { | |||
// return dxyScale_ * toFloat_(dxy); |
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.
can this comment be removed? (L372, L374)
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.
Done
l1ct::z0_t l1ct::TrackInputEmulator::convZ0(ap_int<12> z0) const { | ||
int offs = z0 >= 0 ? z0OffsPos_ : z0OffsNeg_; | ||
return (z0.to_int() * z0Mult_ + offs) >> z0BitShift_; | ||
} | ||
|
||
l1ct::dxy_t l1ct::TrackInputEmulator::convDxy(ap_int<13> dxy) const { | ||
int offs = dxy >= 0 ? dxyOffsPos_ : dxyOffsNeg_; | ||
// return (dxy.to_int() * dxyMult_ + offs) >> dxyBitShift_; |
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.
can this comment be removed?
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.
Done
@@ -34,7 +34,7 @@ namespace l1ct { | |||
typedef ap_ufixed<10, 5, AP_TRN, AP_SAT> hoe_t; | |||
typedef ap_uint<4> redChi2Bin_t; | |||
typedef ap_fixed<10, 1, AP_RND_CONV, AP_SAT> id_score_t; // ID score to be between -1 (background) and 1 (signal) | |||
typedef ap_ufixed<10, 1, AP_RND, AP_SAT> b_tag_score_t; // result_t from the NN is still apx_fixed<16,6> | |||
typedef ap_ufixed<8, 1, AP_RND_CONV, AP_SAT> jet_tag_score_t; // 8 bit jet jet probability from 0 to 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.
Just something to keep in mind: we found with axol1tl that the score type is subject to change with different model versions, so we are thinking about adding a template function to the base cms-hls4ml emulator class to get the result/score type so that the score type does not need to be hardcoded into the emulator. just something to look out for and perhaps modify in the future
@@ -144,7 +144,9 @@ namespace l1ct { | |||
constexpr float INTPT_LSB = 0.25; | |||
constexpr float ETAPHI_LSB = M_PI / INTPHI_PI; | |||
constexpr float Z0_LSB = 0.05; | |||
constexpr float DXY_LSB = 0.05; | |||
//constexpr float DXY_LSB = 0.05; |
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.
could this comment be removed?
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.
Done
dxyMult_ = std::round(scale * (1 << bits)); | ||
switch (encoding_) { | ||
case Encoding::Stepping: | ||
dxyOffsPos_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); | ||
dxyOffsNeg_ = std::round(-scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); | ||
break; | ||
case Encoding::Biased: | ||
dxyOffsPos_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); | ||
dxyOffsNeg_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); | ||
break; | ||
case Encoding::Unbiased: |
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.
some comments explaining what is being done here might be useful
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.
Added comment explaining the function and the variables it sets
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.
Hi Chris, thanks for this PR. I have some comments on the code.
@@ -19,7 +19,7 @@ namespace l1ct { | |||
typedef ap_int<11> glbphi_t; | |||
typedef ap_int<5> vtx_t; | |||
typedef ap_int<10> z0_t; // 40cm / 0.1 | |||
typedef ap_int<8> dxy_t; // tbd | |||
typedef ap_uint<8> dxy_t; // tbd |
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.
In the comment: why is this tbd?
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.
Changed from tbd to an explanation of the variable
constexpr float DXY_LSB = 0.00390625; | ||
constexpr float DXYSQRT_LSB = 0.015625; |
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.
Is it possible to add comments explaining these values please?
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.
Added comments explaining where these values come from
inline float floatPuppiW(puppiWgt_t puppiw) { return puppiw.to_float(); } | ||
inline float floatIso(iso_t iso) { return iso.to_float(); } | ||
inline float floatSrrTot(srrtot_t srrtot) { return srrtot.to_float() / SRRTOT_SCALE; }; | ||
inline float floatMeanZ(meanz_t meanz) { return meanz + MEANZ_OFFSET; }; | ||
inline float floatHoe(hoe_t hoe) { return hoe.to_float(); }; | ||
inline float floatIDScore(id_score_t score) { return score.to_float(); }; | ||
inline float floatBtagScore(b_tag_score_t b_tag_score) { return b_tag_score.to_float(); } |
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.
Is it correct to remove the b-tag score completely?
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.
We now wrap everything up in the float ID score which supersedes the BtagScore
@@ -169,20 +171,20 @@ namespace l1ct { | |||
inline float floatEta(glbeta_t eta) { return eta.to_float() * ETAPHI_LSB; } | |||
inline float floatPhi(glbphi_t phi) { return phi.to_float() * ETAPHI_LSB; } | |||
inline float floatZ0(z0_t z0) { return z0.to_float() * Z0_LSB; } | |||
inline float floatDxy(dxy_t dxy) { return dxy.to_float() * DXY_LSB; } | |||
inline float floatDxy(dxy_t dxy) { return dxy.to_float() * DXYSQRT_LSB; } |
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.
Is it correct to have this using DXYSQRT_LSB
and in
inline dxy_t makeDxy(float dxy) { return dxy_t(std::round(dxy / DXY_LSB)); } |
DXY_LSB
?
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 has been changes at L187 to use DXYSQRT_LSB
inline bool operator==(const Jet &other) const { return valid == other.valid && z0 == other.z0 && v3 == other.v3; } | ||
inline bool operator==(const Jet &other) const { | ||
bool eq = valid == other.valid && z0 == other.z0 && v3 == other.v3; | ||
for (unsigned i = 0; i < NTagFields; i++) { |
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.
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.
Not changed as NTagFields is a single integer value so there wasn't a clean auto loop version
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.
As an FYI you can include the ranges
library and then use:
for (auto i : std::views::iota(0, static_cast<int>(NTagFields))){
But it is up to you if you want to change these or not
#include "L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h" | ||
|
||
//HLS4ML compiled emulator modeling | ||
#include <string> |
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.
Already included on
#include <string> |
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.
Removed
class L1TSC4NGJetID { | ||
public: | ||
L1TSC4NGJetID(const std::shared_ptr<hls4mlEmulator::Model> model, int iNParticles); | ||
~L1TSC4NGJetID() = default; |
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.
Needed?
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.
Not needed and removed
#include <string> | ||
#include "ap_fixed.h" | ||
#include "hls4ml/emulator.h" |
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.
No need for these as they are already included in
cmssw/L1Trigger/Phase2L1ParticleFlow/interface/L1TSC4NGJetID.h
Lines 12 to 14 in a6c8e7c
#include <string> | |
#include "ap_fixed.h" | |
#include "hls4ml/emulator.h" |
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.
Done
#include "ap_fixed.h" | ||
#include "hls4ml/emulator.h" | ||
|
||
using namespace l1t; |
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.
Can we avoid this please? I see l1t::PFJet
is used below anyway
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.
Done
} | ||
std::sort(taggedJets.begin(), taggedJets.end(), [](l1t::PFJet a, l1t::PFJet b) { return (a.pt() > b.pt()); }); | ||
|
||
std::unique_ptr<l1t::PFJetCollection> taggedJetsCollection(new l1t::PFJetCollection); |
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.
Should use std::make_unique
instead of the new
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.
Done
PR code review 1
+code-checks Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-47798/44599
|
Pull request #47798 was updated. @BenjaminRS, @Moanwar, @cmsbuild, @quinnanm, @srimanob, @subirsarkar can you please check and sign again. |
test parameters:
|
please test |
+1 Size: This PR adds an extra 16KB to repository Comparison SummarySummary:
|
+l1 |
PR description:
This PR adds the v0.0.0 Level-1 Trigger SeededCone 4 Next Gen Jet Model to CMSSW. This model tags seededcone 4 jets into 8 different classes uds, g, b, c, tau+, tau-, e, mu and regresses a pT correction for the jet.
This PR also includes changes to the jet data format to include the additional tag scores.
There are minor changes to the PF datatypes to add proper functionality for dxy
The model training is documented here
This model is specifically from this release of the code
This model's training artefacts; firmware, model file and performance plots are located here
The cms-hls4ml model file tagged v0.0.0 is found here
The in progress DPS note is found here
This PR relies on an addition to the cms-dist externals, with the open PR cms-sw/cmsdist#9778
PR validation:
Testing of the code happens automatically as part of the model training CI, artefacts of this are found here
Standard code style checks have been performed as has a phase-2 Level-1 trigger cmsDriver test as documented here