Skip to content

[Phase-2 L1T] Move TauNNIdHW to the externally-built NNPuppiTauModel package#51263

Merged
cmsbuild merged 5 commits into
cms-sw:masterfrom
artlbv:claude/nnpuppitau-externals-migration-u1xa0p
Jul 9, 2026
Merged

[Phase-2 L1T] Move TauNNIdHW to the externally-built NNPuppiTauModel package#51263
cmsbuild merged 5 commits into
cms-sw:masterfrom
artlbv:claude/nnpuppitau-externals-migration-u1xa0p

Conversation

@artlbv

@artlbv artlbv commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

L1Trigger/Phase2L1ParticleFlow's hardware-emulation tau ID/regression path (TauNNIdHW) previously compiled its hls4ml-generated weights in-tree as plain global C arrays (w2, b2, ..., w20, b20). These symbols had no namespace and external linkage, so when other in-tree or externally-loaded hls4ml models were linked into the same process, ELF symbol interposition could silently clobber NNPuppiTau's weights with another model's weights of the same name — the bug class behind #49632.

This PR fixes that by moving NNPuppiTau onto the same "externals" pattern already used by AXOL1TL, L1TSC4NGJetModel, and (within this same package) JetId/L1TSC4NGJetID: all hls4ml-generated code (weights, layer configs, the dense/activation call sequence) now lives in a new standalone, versioned, externally-built shared library, cms-hls4ml/NNPuppiTauModel, with every symbol except the fixed extern "C" create_model()/destroy_model() factory pair wrapped in a per-model+version C++ namespace (hls4ml_nnpuppitaumodel_v1). CMSSW now loads the model at runtime via hls4mlEmulator::ModelLoader/hls4mlEmulator::Model, never touching the raw weight symbols directly.

This is part of a 3-PR migration:

  1. New external repo: cms-hls4ml/NNPuppiTauModel — the externally-built package itself.
  2. cmsdist PR — spec + toolfile so SCRAM builds/installs the new external (Add NNPuppiTauModel external spec and toolfile cmsdist#10665)
  3. This PRcmssw changes to consume it.

Changes

  • TauNNIdHW constructor now takes a std::shared_ptr<hls4mlEmulator::Model> instead of reading in-tree weight headers; EvaluateNN() becomes a thin prepare_input/predict/read_result wrapper instead of inlining the dense/relu/sigmoid layer sequence.
  • L1NNTauProducer gains an hls4mlEmulator::ModelLoader member and a new configurable tauModelPath parameter (default "NNPuppiTauModel_v1"), mirroring L1TSC4NGJetProducer.
  • Deletes the now-dead in-tree interface/taus/{defines.h, tau_parameters.h, weights/, nnet_utils/} — fully superseded by the external package.
  • Adds a CppUnit test (testNNPuppiTauModel.cppunit.cc) that loads the external model — including two instances at once, the exact scenario that used to clash on un-namespaced symbols — and sanity-checks predict() output.

Dependencies

Requires the cmsdist external for NNPuppiTauModel to be available in the IB before this can build (see linked cmsdist PR).

PR validation

Code compiles against the NNPuppiTauModel_v1 external loaded via hls4mlEmulator::ModelLoader. New unit test exercises model load (including multi-instance) and a basic predict() range check. No numeric regression expected — the layer sequence and weights are an unmodified, mechanical extraction from the previous in-tree code; full RelVal numeric comparison against current master output recommended once cms-bot picks this up.

Follow-up:
I ran the L1Nano (+HLT) workflow from #51004 (runTheMatrix.py -l 34434.774 -w upgrade --ibeos -i all) for both the latest IB baseline and the PR build, then compared all L1nnPuppiTau_* branches (pt, chargedIso/NN score, fullIso, dXY, id, and all pass/fail flags) along with all 40 L1_* P2GT emulator decision bits for 100 events and did not find any mismatches anywhere.

Replaces the in-tree hls4ml weight arrays (w2/b2/.../w20/b20, global
linkage, no namespace) with a call through hls4mlEmulator::Model, loaded
at runtime via hls4mlEmulator::ModelLoader from the new cms-hls4ml/
NNPuppiTauModel external. This follows the same pattern already used for
JetId/L1TSC4NGJetID, and avoids ELF symbol clashes when multiple hls4ml
models are loaded into the same process (cms-sw#49632).

- TauNNIdHW takes a std::shared_ptr<hls4mlEmulator::Model> in its
  constructor; EvaluateNN() becomes a thin prepare_input/predict/
  read_result wrapper instead of inlining the dense/relu/sigmoid layer
  sequence.
- L1NNTauProducer gains a ModelLoader member and a configurable
  tauModelPath parameter (default "NNPuppiTauModel_v1"), mirroring
  L1TSC4NGJetProducer.
- Deletes the now-dead in-tree taus/{defines.h,tau_parameters.h,weights/,
  nnet_utils/} -- fully superseded by the external package.
- Adds a CppUnit test (testNNPuppiTauModel.cppunit.cc) that loads the
  external model (including two instances at once, the scenario that used
  to clash on un-namespaced symbols) and sanity-checks predict() output.

Co-authored-by: artlbv <arturlbv@gmail.com>
@cmsbuild

cmsbuild commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

cms-bot internal usage

@cmsbuild

Copy link
Copy Markdown
Contributor

-code-checks

Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-51263/49845

Code check has found code style and quality issues which could be resolved by applying following patch(s)

Co-authored-by: artlbv <arturlbv@gmail.com>
@cmsbuild

Copy link
Copy Markdown
Contributor

+code-checks

Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-51263/49846

@cmsbuild

Copy link
Copy Markdown
Contributor

Pull request #51263 was updated.

@artlbv artlbv marked this pull request as ready for review June 19, 2026 05:40
Rename the global input_t/result_t typedefs in TauNNIdHW.h to the
distinctive tauinput_t/tauresult_t (matching the inputtype-style naming
precedent in L1TSC4NGJetID.h) to avoid reintroducing the kind of
unnamespaced global-symbol collision risk this migration is meant to
eliminate, and make TauNNIdHW.cc's input-count magic number constexpr.

Co-authored-by: artlbv <arturlbv@gmail.com>
@cmsbuild

Copy link
Copy Markdown
Contributor

+code-checks

Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-51263/49850

@cmsbuild

Copy link
Copy Markdown
Contributor

A new Pull Request was created by @artlbv for master.

It involves the following packages:

  • L1Trigger/Phase2L1ParticleFlow (l1)

@BenjaminRS, @cmsbuild, @quinnanm can you please review it and eventually sign? Thanks.
@Martin-Grunewald, @missirol, @mmusich this is something you requested to watch as well.
@ftenchini, @mandrenguyen, @sextonkennedy you are the release manager for this.

cms-bot commands are listed here

@quinnanm

Copy link
Copy Markdown
Contributor

please test

@artlbv

artlbv commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review @quinnanm ! Could you or @BenjaminRS test again?

@cmsbuild

cmsbuild commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

+code-checks

Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-51263/50098

@cmsbuild

cmsbuild commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Pull request #51263 was updated. @BenjaminRS, @cmsbuild, @quinnanm can you please check and sign again.

artlbv added a commit to artlbv/cmssw that referenced this pull request Jul 7, 2026
Address review comments on cms-sw#51263 (backport to CMSSW_17_0_X)
@quinnanm

quinnanm commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

please test

@cmsbuild

cmsbuild commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

+1

Size: This PR adds an extra 16KB to repository
Summary: https://cmssdt.cern.ch/SDT/jenkins-artifacts/pull-request-integration/PR-b80173/54583/summary.html
COMMIT: 96b5f82
CMSSW: CMSSW_20_1_X_2026-07-07-2300/el9_amd64_gcc13
User test area: For local testing, you can use /cvmfs/cms-ci.cern.ch/week1/cms-sw/cmssw/51263/54583/install.sh to create a dev area with all the needed externals and cmssw changes.

Comparison Summary

Summary:

  • You potentially added 1 lines to the logs
  • Reco comparison results: 0 differences found in the comparisons
  • DQMHistoTests: Total files compared: 45
  • DQMHistoTests: Total histograms compared: 3547841
  • DQMHistoTests: Total failures: 0
  • DQMHistoTests: Total nulls: 0
  • DQMHistoTests: Total successes: 3547823
  • DQMHistoTests: Total skipped: 18
  • DQMHistoTests: Total Missing objects: 0
  • DQMHistoSizes: Histogram memory added: 0.0 KiB( 44 files compared)
  • Checked 195 log files, 163 edm output root files, 45 DQM output files
  • TriggerResults: no differences found

@quinnanm

quinnanm commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

+l1

@cmsbuild

cmsbuild commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

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. @mandrenguyen, @ftenchini, @sextonkennedy (and backports should be raised in the release meeting by the corresponding L2)

@mandrenguyen

Copy link
Copy Markdown
Contributor

+1

@cmsbuild cmsbuild merged commit f5e8375 into cms-sw:master Jul 9, 2026
10 checks passed
cmsbuild pushed a commit that referenced this pull request Jul 14, 2026
…ce tau typedefs, drop empty dtor, dedupe model name string

- Move tauinput_t/tauresult_t typedefs into the L1TauEmu namespace to avoid
  clashing with other hls4ml model headers, updating all call sites
- Replace the empty TauNNIdHW destructor with = default
- Store the "NNPuppiTauModel_v1" model name in a single constant in the
  cppunit test and in the python config instead of repeating the literal

Co-authored-by: artlbv <4972492+artlbv@users.noreply.github.com>
cmsbuild added a commit that referenced this pull request Jul 14, 2026
…CMSSW_17_0_X

[Backport of #51263] [Phase-2 L1T] Move TauNNIdHW to the externally-built NNPuppiTauModel package
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants