diff --git a/DQM/Integration/python/clients/pfgpu_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/pfgpu_dqm_sourceclient-live_cfg.py
new file mode 100644
index 0000000000000..7e61cf2ed9ddc
--- /dev/null
+++ b/DQM/Integration/python/clients/pfgpu_dqm_sourceclient-live_cfg.py
@@ -0,0 +1,142 @@
+#-------------------------------------
+# PF DQM Application using New DQM Sources/Clients
+# Taken from HCAL DQM Client
+#-------------------------------------
+
+#-------------------------------------
+# Standard Python Imports
+#-------------------------------------
+import os, sys, socket, string
+
+#-------------------------------------
+# Standard CMSSW Imports/Definitions
+#-------------------------------------
+import FWCore.ParameterSet.Config as cms
+from Configuration.Eras.Era_Run3_cff import Run3
+process = cms.Process('PFDQM', Run3)
+subsystem = 'ParticleFlow'
+cmssw = os.getenv("CMSSW_VERSION").split("_")
+debugstr = "### PFDQM::cfg::DEBUG: "
+warnstr = "### PFDQM::cfg::WARN: "
+errorstr = "### PFDQM::cfg::ERROR:"
+useOfflineGT = False
+useFileInput = False
+useMap = False
+unitTest = 'unitTest=True' in sys.argv
+
+#-------------------------------------
+# Central DQM Stuff imports
+#-------------------------------------
+from DQM.Integration.config.online_customizations_cfi import *
+
+if useOfflineGT:
+ process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
+ process.GlobalTag.globaltag = autoCond['run3_data_prompt']
+else:
+ process.load('DQM.Integration.config.FrontierCondition_GT_cfi')
+
+if unitTest:
+ process.load("DQM.Integration.config.unitteststreamerinputsource_cfi")
+ from DQM.Integration.config.unitteststreamerinputsource_cfi import options
+elif useFileInput:
+ process.load("DQM.Integration.config.fileinputsource_cfi")
+ from DQM.Integration.config.fileinputsource_cfi import options
+else:
+ process.load('DQM.Integration.config.inputsource_cfi')
+ from DQM.Integration.config.inputsource_cfi import options
+
+process.load('DQM.Integration.config.environment_cfi')
+
+#-------------------------------------
+# Central DQM Customization
+#-------------------------------------
+
+if not useFileInput:
+ # stream label
+ if process.runType.getRunType() == process.runType.hi_run:
+ process.source.streamLabel = "streamHIDQMGPUvsCPU"
+ else:
+ process.source.streamLabel = "streamDQMGPUvsCPU"
+
+process.dqmEnv.subSystemFolder = subsystem
+process.dqmSaver.tag = 'PFGPU'
+process.dqmSaver.runNumber = options.runNumber
+process.dqmSaverPB.tag = 'PFGPU'
+process.dqmSaverPB.runNumber = options.runNumber
+process = customise(process)
+process.DQMStore.verbose = 0
+if not unitTest and not useFileInput :
+ if not options.BeamSplashRun :
+ process.source.minEventsPerLumi = 100
+
+#-------------------------------------
+# CMSSW/Hcal non-DQM Related Module import
+#-------------------------------------
+process.load("Configuration.StandardSequences.GeometryRecoDB_cff")
+process.load('FWCore.MessageLogger.MessageLogger_cfi')
+
+#-------------------------------------
+# CMSSW/Hcal non-DQM Related Module Settings
+# -> runType
+# -> Generic Input tag for the Raw Collection
+# -> cmssw version
+#----------------------------------------------
+
+runType = process.runType.getRunType()
+runTypeName = process.runType.getRunTypeName()
+isCosmicRun = runTypeName=="cosmic_run" or runTypeName=="cosmic_run_stage1"
+isHeavyIon = runTypeName=="hi_run"
+cmssw = os.getenv("CMSSW_VERSION").split("_")
+
+
+#-------------------------------------
+# PF DQM Tasks and Harvesters import
+# New Style
+#-------------------------------------
+process.load('DQM.PFTasks.pfHcalGPUComparisonTask_cfi')
+
+#-------------------------------------
+# Some Settings before Finishing up
+# New Style Modules
+#-------------------------------------
+oldsubsystem = subsystem
+#-------------------------------------
+# Hcal DQM Tasks/Clients Sequences Definition
+#-------------------------------------
+process.tasksPath = cms.Path(
+ process.pfHcalGPUComparisonTask
+)
+
+#-------------------------------------
+# Paths/Sequences Definitions
+#-------------------------------------
+
+process.dqmPath = cms.EndPath(
+ process.dqmEnv)
+process.dqmPath1 = cms.EndPath(
+ process.dqmSaver
+ *process.dqmSaverPB
+)
+
+process.schedule = cms.Schedule(
+ process.tasksPath,
+ process.dqmPath,
+ process.dqmPath1
+)
+
+#-------------------------------------
+# Scheduling and Process Customizations
+#-------------------------------------
+process.options = cms.untracked.PSet(
+ Rethrow = cms.untracked.vstring(
+ "TooManyProducts",
+ "TooFewProducts"
+ ),
+ TryToContinue = cms.untracked.vstring('ProductNotFound')
+)
+process.options.wantSummary = True
+
+# tracer
+#process.Tracer = cms.Service("Tracer")
+print("Final Source settings:", process.source)
+process = customise(process)
diff --git a/DQM/PFTasks/BuildFile.xml b/DQM/PFTasks/BuildFile.xml
new file mode 100644
index 0000000000000..743e726d67229
--- /dev/null
+++ b/DQM/PFTasks/BuildFile.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/DQM/PFTasks/plugins/BuildFile.xml b/DQM/PFTasks/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..e176b35acc3ae
--- /dev/null
+++ b/DQM/PFTasks/plugins/BuildFile.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/DQM/PFTasks/plugins/PFHcalGPUComparisonTask.cc b/DQM/PFTasks/plugins/PFHcalGPUComparisonTask.cc
new file mode 100644
index 0000000000000..cf53e07b2cbff
--- /dev/null
+++ b/DQM/PFTasks/plugins/PFHcalGPUComparisonTask.cc
@@ -0,0 +1,223 @@
+// -*- C++ -*-
+//
+
+#include "DQM/HcalCommon/interface/DQTask.h"
+#include "DQM/HcalCommon/interface/Utilities.h"
+#include "DQM/HcalCommon/interface/HashFilter.h"
+#include "DQM/HcalCommon/interface/Container1D.h"
+#include "DQM/HcalCommon/interface/Container2D.h"
+#include "DQM/HcalCommon/interface/ContainerProf1D.h"
+#include "DQM/HcalCommon/interface/ContainerProf2D.h"
+#include "DQM/HcalCommon/interface/ContainerSingle1D.h"
+#include "DQM/HcalCommon/interface/ContainerSingle2D.h"
+#include "DQM/HcalCommon/interface/ContainerSingleProf2D.h"
+#include "DQM/HcalCommon/interface/ElectronicsMap.h"
+#include "DQMServices/Core/interface/DQMEDAnalyzer.h"
+#include "DQMServices/Core/interface/DQMStore.h"
+#include "DataFormats/CaloRecHit/interface/CaloCluster.h"
+#include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h"
+#include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
+#include "DataFormats/CaloTowers/interface/CaloTowerDetId.h"
+#include "DataFormats/Common/interface/Handle.h"
+#include "DataFormats/DetId/interface/DetId.h"
+#include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
+#include "DataFormats/HcalDetId/interface/HcalDetId.h"
+#include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
+#include "DataFormats/Math/interface/Vector3D.h"
+#include "DataFormats/Math/interface/deltaR.h"
+#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
+#include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
+#include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
+#include "DataFormats/ParticleFlowReco/interface/PFBlockElementTrack.h"
+#include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
+#include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h"
+#include "DataFormats/ParticleFlowReco/interface/PFLayer.h"
+#include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
+#include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h"
+#include "FWCore/Framework/interface/Event.h"
+#include "FWCore/Framework/interface/EventSetup.h"
+#include "FWCore/Framework/interface/Frameworkfwd.h"
+#include "FWCore/MessageLogger/interface/MessageLogger.h"
+#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include "FWCore/PluginManager/interface/ModuleDef.h"
+#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
+
+#include
+#ifdef PFLOW_DEBUG
+#define LOGVERB(x) edm::LogVerbatim(x)
+#else
+#define LOGVERB(x) LogTrace(x)
+#endif
+
+using namespace hcaldqm;
+using namespace hcaldqm::constants;
+using namespace hcaldqm::filter;
+
+class PFHcalGPUComparisonTask : public hcaldqm::DQTask {
+public:
+ PFHcalGPUComparisonTask(edm::ParameterSet const&);
+ ~PFHcalGPUComparisonTask() override = default;
+
+ void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
+ std::shared_ptr globalBeginLuminosityBlock(edm::LuminosityBlock const&,
+ edm::EventSetup const&) const override;
+ void globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
+ static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
+
+private:
+ void _process(edm::Event const&, edm::EventSetup const&) override;
+ void _resetMonitors(hcaldqm::UpdateFreq) override;
+
+ edm::EDGetTokenT pfClusterTok_ref_;
+ edm::EDGetTokenT pfClusterTok_target_;
+
+ MonitorElement* pfCluster_Multiplicity_HostvsDevice_;
+ MonitorElement* pfCluster_Energy_HostvsDevice_;
+ MonitorElement* pfCluster_RecHitMultiplicity_HostvsDevice_;
+ MonitorElement* pfCluster_Layer_HostvsDevice_;
+ MonitorElement* pfCluster_Depth_HostvsDevice_;
+ MonitorElement* pfCluster_Eta_HostvsDevice_;
+ MonitorElement* pfCluster_Phi_HostvsDevice_;
+ MonitorElement* pfCluster_DuplicateMatches_HostvsDevice_;
+
+ std::string pfCaloGPUCompDir_;
+};
+
+PFHcalGPUComparisonTask::PFHcalGPUComparisonTask(edm::ParameterSet const& conf)
+ : DQTask(conf),
+ pfClusterTok_ref_{
+ consumes(conf.getUntrackedParameter("pfClusterToken_ref"))},
+ pfClusterTok_target_{
+ consumes(conf.getUntrackedParameter("pfClusterToken_target"))},
+ pfCaloGPUCompDir_{conf.getUntrackedParameter("name")} {}
+
+void PFHcalGPUComparisonTask::bookHistograms(DQMStore::IBooker& ibooker, edm::Run const& r, edm::EventSetup const& es) {
+ _subsystem = "ParticleFlow";
+ ibooker.setCurrentFolder("ParticleFlow/" + pfCaloGPUCompDir_);
+ DQTask::bookHistograms(ibooker, r, es);
+ // Book monitoring elements
+ const char* histo;
+
+ histo = "pfCluster_Multiplicity_HostvsDevice";
+ const char* histoAxis = "pfCluster_Multiplicity_HostvsDevice;Multiplicity Device;Multiplicity Device";
+ pfCluster_Multiplicity_HostvsDevice_ = ibooker.book2I(histo, histoAxis, 1000, 0, 1000, 1000, 0, 1000);
+
+ histo = "pfCluster_Energy_HostvsDevice";
+ histoAxis = "pfCluster_Energy_HostvsDevice;Energy Host [GeV];Energy Device [GeV]";
+ pfCluster_Energy_HostvsDevice_ = ibooker.book2D(histo, histoAxis, 500, 0, 500, 500, 0, 500);
+
+ histo = "pfCluster_RecHitMultiplicity_HostvsDevice";
+ histoAxis = "pfCluster_RecHitMultiplicity_HostvsDevice;RecHit Multiplicity Host;RecHit Multiplicity Device";
+ pfCluster_RecHitMultiplicity_HostvsDevice_ = ibooker.book2I(histo, histoAxis, 100, 0, 100, 100, 0, 100);
+
+ histo = "pfCluster_Layer_HostvsDevice";
+ histoAxis = "pfCluster_Layer_HostvsDevice;Cluster Layer Host;Cluster Layer Device";
+ pfCluster_Layer_HostvsDevice_ = ibooker.book2I(histo, histoAxis, 4, 0, 3, 4, 0, 3);
+
+ histo = "pfCluster_Depth_HostvsDevice";
+ histoAxis = "pfCluster_Depth_HostvsDevice;Cluster Depth Host;Cluster Depth Device";
+ pfCluster_Depth_HostvsDevice_ = ibooker.book2I(histo, histoAxis, 8, 0, 7, 8, 0, 7);
+
+ histo = "pfCluster_Eta_HostvsDevice";
+ histoAxis = "pfCluster_Eta_HostvsDevice;Cluster #eta Host;Cluster #eta Device";
+ pfCluster_Eta_HostvsDevice_ = ibooker.book2D(histo, histoAxis, 100, -5.f, 5.f, 100, -5.f, 5.f);
+
+ histo = "pfCluster_Phi_HostvsDevice";
+ histoAxis = "pfCluster_Phi_HostvsDevice;Cluster #phi Host;Cluster #phi Device";
+ pfCluster_Phi_HostvsDevice_ = ibooker.book2D(histo, histoAxis, 100, -M_PI, M_PI, 100, -M_PI, M_PI);
+
+ histo = "pfCluster_DuplicateMatches_HostvsDevice";
+ histoAxis = "pfCluster_Duplicates_HostvsDevice;Cluster Duplicates Host;Cluster Duplicates Device";
+ pfCluster_DuplicateMatches_HostvsDevice_ = ibooker.book1I(histo, histoAxis, 100, 0., 1000);
+}
+
+void PFHcalGPUComparisonTask::_resetMonitors(hcaldqm::UpdateFreq uf) { DQTask::_resetMonitors(uf); }
+
+void PFHcalGPUComparisonTask::_process(edm::Event const& event, edm::EventSetup const&) {
+ edm::Handle pfClusters_ref;
+ event.getByToken(pfClusterTok_ref_, pfClusters_ref);
+
+ edm::Handle pfClusters_target;
+ event.getByToken(pfClusterTok_target_, pfClusters_target);
+
+ auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
+ _currentLS = lumiCache->currentLS;
+ // Compare per-event PF cluster multiplicity
+
+ if (pfClusters_ref->size() != pfClusters_target->size())
+ LOGVERB("PFCaloGPUComparisonTask") << " PFCluster multiplicity " << pfClusters_ref->size() << " "
+ << pfClusters_target->size();
+ pfCluster_Multiplicity_HostvsDevice_->Fill((float)pfClusters_ref->size(), (float)pfClusters_target->size());
+
+ //
+ // Find matching PF cluster pairs
+ std::vector matched_idx;
+ matched_idx.reserve(pfClusters_ref->size());
+ for (unsigned i = 0; i < pfClusters_ref->size(); ++i) {
+ bool matched = false;
+ for (unsigned j = 0; j < pfClusters_target->size(); ++j) {
+ if (pfClusters_ref->at(i).seed() == pfClusters_target->at(j).seed()) {
+ if (!matched) {
+ matched = true;
+ matched_idx.push_back((int)j);
+ } else {
+ edm::LogWarning("PFCaloGPUComparisonTask") << "Found duplicate match";
+ pfCluster_DuplicateMatches_HostvsDevice_->Fill((int)j);
+ }
+ }
+ }
+ if (!matched)
+ matched_idx.push_back(-1); // if you don't find a match, put a dummy number
+ }
+
+ //
+ // Plot matching PF cluster variables
+ for (unsigned i = 0; i < pfClusters_ref->size(); ++i) {
+ if (matched_idx[i] >= 0) {
+ unsigned int j = matched_idx[i];
+ int ref_energy_bin =
+ pfCluster_Energy_HostvsDevice_->getTH2F()->GetXaxis()->FindBin(pfClusters_ref->at(i).energy());
+ int target_energy_bin =
+ pfCluster_Energy_HostvsDevice_->getTH2F()->GetXaxis()->FindBin(pfClusters_target->at(j).energy());
+ if (ref_energy_bin != target_energy_bin)
+ edm::LogPrint("PFCaloGPUComparisonTask")
+ << "Off-diagonal energy bin entries: " << pfClusters_ref->at(i).energy() << " "
+ << pfClusters_ref->at(i).eta() << " " << pfClusters_ref->at(i).phi() << " "
+ << pfClusters_target->at(j).energy() << " " << pfClusters_target->at(j).eta() << " "
+ << pfClusters_target->at(j).phi() << std::endl;
+ pfCluster_Energy_HostvsDevice_->Fill(pfClusters_ref->at(i).energy(), pfClusters_target->at(j).energy());
+ pfCluster_Layer_HostvsDevice_->Fill(pfClusters_ref->at(i).layer(), pfClusters_target->at(j).layer());
+ pfCluster_Eta_HostvsDevice_->Fill(pfClusters_ref->at(i).eta(), pfClusters_target->at(j).eta());
+ pfCluster_Phi_HostvsDevice_->Fill(pfClusters_ref->at(i).phi(), pfClusters_target->at(j).phi());
+ pfCluster_Depth_HostvsDevice_->Fill(pfClusters_ref->at(i).depth(), pfClusters_target->at(j).depth());
+ pfCluster_RecHitMultiplicity_HostvsDevice_->Fill((float)pfClusters_ref->at(i).recHitFractions().size(),
+ (float)pfClusters_target->at(j).recHitFractions().size());
+ }
+ }
+}
+
+std::shared_ptr PFHcalGPUComparisonTask::globalBeginLuminosityBlock(edm::LuminosityBlock const& lb,
+ edm::EventSetup const& es) const {
+ return DQTask::globalBeginLuminosityBlock(lb, es);
+}
+
+void PFHcalGPUComparisonTask::globalEndLuminosityBlock(edm::LuminosityBlock const& lb, edm::EventSetup const& es) {
+ if (_ptype != fOnline)
+ return;
+
+ auto lumiCache = luminosityBlockCache(lb.index());
+ _currentLS = lumiCache->currentLS;
+
+ // in the end always do the DQTask::endLumi
+ DQTask::globalEndLuminosityBlock(lb, es);
+}
+
+void PFHcalGPUComparisonTask::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
+ edm::ParameterSetDescription desc;
+ desc.addUntracked("name", "pfCaloGPUCompDir");
+ desc.addUntracked("pfClusterToken_ref", edm::InputTag("hltParticleFlowClusterHCALSerialSync"));
+ desc.addUntracked("pfClusterToken_target", edm::InputTag("hltParticleFlowClusterHCAL"));
+ descriptions.addWithDefaultLabel(desc);
+}
+
+DEFINE_FWK_MODULE(PFHcalGPUComparisonTask);