Skip to content

Commit b038921

Browse files
authored
Merge pull request #49325 from pallabidas/EMTF_setup_hls
[L1T] replacing tensorflow with hls4ml model for EMTF at setup
2 parents e50d079 + a21c51f commit b038921

File tree

12 files changed

+44
-60
lines changed

12 files changed

+44
-60
lines changed

L1Trigger/L1TMuonEndCap/BuildFile.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
<use name="DataFormats/L1TMuon"/>
99
<use name="L1Trigger/L1TMuon"/>
1010
<use name="PhysicsTools/TensorFlow"/>
11+
<use name="hls"/>
12+
<use name="hls4mlEmulatorExtras"/>

L1Trigger/L1TMuonEndCap/interface/EMTFSetup.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "L1Trigger/L1TMuonEndCap/interface/SectorProcessorLUT.h"
1717
#include "L1Trigger/L1TMuonEndCap/interface/PtAssignmentEngine.h"
1818
#include "L1Trigger/L1TMuonEndCap/interface/PtAssignmentEngineDxy.h"
19+
#include "hls4ml/emulator.h"
1920

2021
class EMTFSetup {
2122
public:
@@ -72,6 +73,9 @@ class EMTFSetup {
7273
unsigned fw_ver_;
7374
unsigned pt_lut_ver_;
7475
unsigned pc_lut_ver_;
76+
77+
hls4mlEmulator::ModelLoader loader;
78+
std::shared_ptr<hls4mlEmulator::Model> model;
7579
};
7680

7781
#endif

L1Trigger/L1TMuonEndCap/interface/PtAssignment.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ class PtAssignment {
2323
bool bugGMTPhi,
2424
bool promoteMode7,
2525
int modeQualVer,
26-
std::vector<int> promoteMode7Sectors,
27-
std::string pbFileName);
26+
std::vector<int> promoteMode7Sectors);
2827

2928
void process(EMTFTrackCollection& best_tracks);
3029

L1Trigger/L1TMuonEndCap/interface/PtAssignmentEngineDxy.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,28 @@
1010

1111
#include "L1Trigger/L1TMuonEndCap/interface/Common.h"
1212
#include "L1Trigger/L1TMuonEndCap/interface/PtAssignmentEngineAux2017.h"
13-
#include "PhysicsTools/TensorFlow/interface/TensorFlow.h"
1413
#include "FWCore/ParameterSet/interface/FileInPath.h"
14+
#include "ap_fixed.h"
15+
#include "hls4ml/emulator.h"
1516

1617
class PtAssignmentEngineDxy {
1718
public:
18-
explicit PtAssignmentEngineDxy();
19+
explicit PtAssignmentEngineDxy(std::shared_ptr<hls4mlEmulator::Model> model);
1920
virtual ~PtAssignmentEngineDxy();
2021

21-
void configure(int verbose, const std::string pbFileNameDxy);
22+
void configure(int verbose);
2223

2324
const PtAssignmentEngineAux2017& aux() const;
2425

2526
virtual void calculate_pt_dxy(const EMTFTrack& track, emtf::Feature& feature, emtf::Prediction& prediction) const;
2627

2728
virtual void preprocessing_dxy(const EMTFTrack& track, emtf::Feature& feature) const;
2829

29-
virtual void call_tensorflow_dxy(const emtf::Feature& feature, emtf::Prediction& prediction) const;
30+
virtual void call_hls_dxy(const emtf::Feature& feature, emtf::Prediction& prediction) const;
3031

3132
protected:
3233
int verbose_;
33-
34-
tensorflow::GraphDef* graphDefDxy_;
35-
tensorflow::Session* sessionDxy_;
36-
std::string pbFileNameDxy_;
37-
std::string pbFilePathDxy_;
38-
std::string inputNameDxy_;
39-
std::vector<std::string> outputNamesDxy_;
34+
std::shared_ptr<hls4mlEmulator::Model> model_;
4035
};
4136

4237
#endif

L1Trigger/L1TMuonEndCap/interface/VersionControl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class VersionControl {
1818
int verbose() const { return verbose_; }
1919
bool useO2O() const { return useO2O_; }
2020
std::string era() const { return era_; }
21+
std::string nnModelDxy() const { return nnModel_; }
2122

2223
friend class SectorProcessor; // allow access to private memebers
2324

@@ -58,7 +59,7 @@ class VersionControl {
5859
bool bug9BitDPhi_, bugMode7CLCT_, bugNegPt_, bugGMTPhi_, promoteMode7_;
5960
int modeQualVer_;
6061
std::vector<int> promoteMode7Sectors_; // Sectors to promote mode 7 tracks in Run 2 and Run 3, -1 for all sectors
61-
std::string pbFileName_;
62+
std::string nnModel_;
6263
};
6364

6465
#endif
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<library file="*.cc" name="L1TriggerL1TMuonEndCapPlugins">
22
<use name="L1Trigger/L1TMuonEndCap"/>
3+
<use name="hls"/>
4+
<use name="hls4mlEmulatorExtras"/>
35
<flags EDM_PLUGIN="1"/>
46
</library>

L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
PromoteMode7 = cms.bool(False), # Assign station 2-3-4 tracks with |eta| > 1.6 SingleMu quality
127127
ModeQualVer = cms.int32(2), # Version 2 contains modified mode-quality mapping for 2018
128128
PromoteMode7Sectors = cms.vint32(-1), # Sectors to promote mode 7 tracks in Run 2 and Run 3, -1 for all sectors
129-
ProtobufFileName = cms.string('model_graph.displ.16.pb'), # Protobuf file name to be used by NN based pT assignment NNv16 is online since 26.06.2023
129+
NNModel = cms.string('EMTFnn_v1'), # HLS model name to be used by NN based pT assignment NNv16 is online since 26.06.2023
130130
),
131131

132132
)

L1Trigger/L1TMuonEndCap/src/EMTFSetup.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ EMTFSetup::EMTFSetup(const edm::ParameterSet& iConfig, edm::ConsumesCollector iC
1717
pt_assign_engine_dxy_(nullptr),
1818
fw_ver_(0),
1919
pt_lut_ver_(0),
20-
pc_lut_ver_(0) {
20+
pc_lut_ver_(0),
21+
loader(version_control_.nnModelDxy()) {
2122
// Set pt assignment engine according to Era
2223
if (era() == "Run2_2016") {
2324
pt_assign_engine_ = std::make_unique<PtAssignmentEngine2016>();
@@ -29,7 +30,8 @@ EMTFSetup::EMTFSetup(const edm::ParameterSet& iConfig, edm::ConsumesCollector iC
2930
}
3031

3132
// No era setup for displaced pT assignment engine
32-
pt_assign_engine_dxy_ = std::make_unique<PtAssignmentEngineDxy>();
33+
model = loader.load_model();
34+
pt_assign_engine_dxy_ = std::make_unique<PtAssignmentEngineDxy>(model);
3335

3436
emtf_assert(pt_assign_engine_ != nullptr);
3537
emtf_assert(pt_assign_engine_dxy_ != nullptr);

L1Trigger/L1TMuonEndCap/src/PtAssignment.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ void PtAssignment::configure(PtAssignmentEngine* pt_assign_engine,
1717
bool bugGMTPhi,
1818
bool promoteMode7,
1919
int modeQualVer,
20-
std::vector<int> promoteMode7Sectors,
21-
std::string pbFileName) {
20+
std::vector<int> promoteMode7Sectors) {
2221
emtf_assert(pt_assign_engine != nullptr);
2322
emtf_assert(pt_assign_engine_dxy != nullptr);
2423

@@ -33,7 +32,7 @@ void PtAssignment::configure(PtAssignmentEngine* pt_assign_engine,
3332

3433
pt_assign_engine_->configure(verbose_, readPtLUTFile, fixMode15HighPt, bug9BitDPhi, bugMode7CLCT, bugNegPt);
3534

36-
pt_assign_engine_dxy_->configure(verbose_, pbFileName);
35+
pt_assign_engine_dxy_->configure(verbose_);
3736

3837
bugGMTPhi_ = bugGMTPhi;
3938
promoteMode7_ = promoteMode7;

L1Trigger/L1TMuonEndCap/src/PtAssignmentEngineDxy.cc

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,11 @@
66

77
#include "helper.h" // assert_no_abort
88

9-
PtAssignmentEngineDxy::PtAssignmentEngineDxy() : graphDefDxy_(nullptr), sessionDxy_(nullptr) {}
9+
PtAssignmentEngineDxy::PtAssignmentEngineDxy(std::shared_ptr<hls4mlEmulator::Model> model) { model_ = model; }
1010

11-
PtAssignmentEngineDxy::~PtAssignmentEngineDxy() {
12-
if (sessionDxy_ != nullptr) {
13-
tensorflow::closeSession(sessionDxy_);
14-
}
15-
delete graphDefDxy_;
16-
}
17-
18-
void PtAssignmentEngineDxy::configure(int verbose, const std::string pbFileNameDxy) {
19-
verbose_ = verbose;
20-
21-
pbFileNameDxy_ = pbFileNameDxy;
22-
std::string pbFilePathDxy_ = "L1Trigger/L1TMuon/data/emtf_luts/" + pbFileNameDxy_;
23-
24-
inputNameDxy_ = "input1";
25-
outputNamesDxy_ = {"Identity"};
26-
27-
if (graphDefDxy_ == nullptr) {
28-
graphDefDxy_ = tensorflow::loadGraphDef(edm::FileInPath(pbFilePathDxy_).fullPath());
29-
}
30-
emtf_assert(graphDefDxy_ != nullptr);
31-
32-
if (sessionDxy_ == nullptr) {
33-
sessionDxy_ = tensorflow::createSession(graphDefDxy_);
34-
}
11+
PtAssignmentEngineDxy::~PtAssignmentEngineDxy() {}
3512

36-
emtf_assert(sessionDxy_ != nullptr);
37-
}
13+
void PtAssignmentEngineDxy::configure(int verbose) { verbose_ = verbose; }
3814

3915
const PtAssignmentEngineAux2017& PtAssignmentEngineDxy::aux() const {
4016
static const PtAssignmentEngineAux2017 instance;
@@ -46,7 +22,7 @@ void PtAssignmentEngineDxy::calculate_pt_dxy(const EMTFTrack& track,
4622
emtf::Prediction& prediction) const {
4723
// This is called for each track instead of for entire track collection as was done in Phase-2 implementation
4824
preprocessing_dxy(track, feature);
49-
call_tensorflow_dxy(feature, prediction);
25+
call_hls_dxy(feature, prediction);
5026
return;
5127
}
5228

@@ -153,19 +129,24 @@ void PtAssignmentEngineDxy::preprocessing_dxy(const EMTFTrack& track, emtf::Feat
153129
return;
154130
}
155131

156-
void PtAssignmentEngineDxy::call_tensorflow_dxy(const emtf::Feature& feature, emtf::Prediction& prediction) const {
157-
tensorflow::Tensor input(tensorflow::DT_FLOAT, {1, emtf::NUM_FEATURES});
158-
std::vector<tensorflow::Tensor> outputs;
132+
void PtAssignmentEngineDxy::call_hls_dxy(const emtf::Feature& feature, emtf::Prediction& prediction) const {
159133
emtf_assert(feature.size() == emtf::NUM_FEATURES);
160134

161-
float* d = input.flat<float>().data();
162-
std::copy(feature.begin(), feature.end(), d);
163-
tensorflow::run(sessionDxy_, {{inputNameDxy_, input}}, outputNamesDxy_, &outputs);
164-
emtf_assert(outputs.size() == 1);
135+
ap_uint<13> nn_input[29];
136+
for (size_t i = 0; i < feature.size(); i++) {
137+
nn_input[i] = feature[i];
138+
}
139+
ap_uint<8> nn_output[2];
140+
model_->prepare_input(nn_input);
141+
model_->predict();
142+
model_->read_result(nn_output);
143+
ap_uint<8> pT = nn_output[0];
144+
ap_uint<7> dxy = (nn_output[1] > 127) ? ap_uint<7>(127) : ap_uint<7>(nn_output[1]);
145+
165146
emtf_assert(prediction.size() == emtf::NUM_PREDICTIONS);
166147

167-
prediction.at(0) = outputs[0].matrix<float>()(0, 0);
168-
prediction.at(1) = outputs[0].matrix<float>()(0, 1);
148+
prediction.at(0) = pT.to_float();
149+
prediction.at(1) = dxy.to_float();
169150

170151
return;
171152
}

0 commit comments

Comments
 (0)