diff --git a/CondFormats/DataRecord/interface/EcalRecHitConditionsRcd.h b/CondFormats/DataRecord/interface/EcalRecHitConditionsRcd.h new file mode 100644 index 0000000000000..267817addb905 --- /dev/null +++ b/CondFormats/DataRecord/interface/EcalRecHitConditionsRcd.h @@ -0,0 +1,27 @@ +#ifndef CondFormats_DataRecord_EcalRecHitConditionsRcd_h +#define CondFormats_DataRecord_EcalRecHitConditionsRcd_h + +#include "FWCore/Framework/interface/DependentRecordImplementation.h" + +#include "CondFormats/DataRecord/interface/EcalADCToGeVConstantRcd.h" +#include "CondFormats/DataRecord/interface/EcalChannelStatusRcd.h" +#include "CondFormats/DataRecord/interface/EcalIntercalibConstantsRcd.h" +#include "CondFormats/DataRecord/interface/EcalLaserAPDPNRatiosRcd.h" +#include "CondFormats/DataRecord/interface/EcalLaserAPDPNRatiosRefRcd.h" +#include "CondFormats/DataRecord/interface/EcalLaserAlphasRcd.h" +#include "CondFormats/DataRecord/interface/EcalLinearCorrectionsRcd.h" +#include "CondFormats/DataRecord/interface/EcalTimeCalibConstantsRcd.h" +#include "CondFormats/DataRecord/interface/EcalTimeOffsetConstantRcd.h" + +class EcalRecHitConditionsRcd + : public edm::eventsetup::DependentRecordImplementation> {}; +#endif diff --git a/CondFormats/DataRecord/interface/EcalRecHitParametersRcd.h b/CondFormats/DataRecord/interface/EcalRecHitParametersRcd.h new file mode 100644 index 0000000000000..978add26af250 --- /dev/null +++ b/CondFormats/DataRecord/interface/EcalRecHitParametersRcd.h @@ -0,0 +1,8 @@ +#ifndef CondFormats_DataRecord_EcalRecHitParametersRcd_h +#define CondFormats_DataRecord_EcalRecHitParametersRcd_h + +#include "FWCore/Framework/interface/EventSetupRecordImplementation.h" + +class EcalRecHitParametersRcd : public edm::eventsetup::EventSetupRecordImplementation {}; + +#endif diff --git a/CondFormats/DataRecord/src/EcalRecHitConditionsRcd.cc b/CondFormats/DataRecord/src/EcalRecHitConditionsRcd.cc new file mode 100644 index 0000000000000..792dfc0b5d65a --- /dev/null +++ b/CondFormats/DataRecord/src/EcalRecHitConditionsRcd.cc @@ -0,0 +1,4 @@ +#include "CondFormats/DataRecord/interface/EcalRecHitConditionsRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(EcalRecHitConditionsRcd); diff --git a/CondFormats/DataRecord/src/EcalRecHitParametersRcd.cc b/CondFormats/DataRecord/src/EcalRecHitParametersRcd.cc new file mode 100644 index 0000000000000..c61c3ee475d91 --- /dev/null +++ b/CondFormats/DataRecord/src/EcalRecHitParametersRcd.cc @@ -0,0 +1,4 @@ +#include "CondFormats/DataRecord/interface/EcalRecHitParametersRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(EcalRecHitParametersRcd); diff --git a/CondFormats/EcalObjects/interface/EcalRecHitConditionsHost.h b/CondFormats/EcalObjects/interface/EcalRecHitConditionsHost.h new file mode 100644 index 0000000000000..b8017cf0add38 --- /dev/null +++ b/CondFormats/EcalObjects/interface/EcalRecHitConditionsHost.h @@ -0,0 +1,11 @@ +#ifndef CondFormats_EcalObjects_interface_EcalRecHitConditionsHost_h +#define CondFormats_EcalObjects_interface_EcalRecHitConditionsHost_h + +#include "CondFormats/EcalObjects/interface/EcalRecHitConditionsSoA.h" +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" + +using EcalRecHitConditionsHost = PortableHostCollection; + +#endif diff --git a/CondFormats/EcalObjects/interface/EcalRecHitConditionsSoA.h b/CondFormats/EcalObjects/interface/EcalRecHitConditionsSoA.h new file mode 100644 index 0000000000000..3cc90e21a9ee3 --- /dev/null +++ b/CondFormats/EcalObjects/interface/EcalRecHitConditionsSoA.h @@ -0,0 +1,46 @@ +#ifndef CondFormats_EcalObjects_EcalRecHitConditionsSoA_h +#define CondFormats_EcalObjects_EcalRecHitConditionsSoA_h + +#include "DataFormats/SoATemplate/interface/SoACommon.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/SoATemplate/interface/SoAView.h" +#include "DataFormats/Provenance/interface/Timestamp.h" + +GENERATE_SOA_LAYOUT(EcalRecHitConditionsSoALayout, + SOA_COLUMN(uint32_t, rawid), + // energy intercalibrations + SOA_COLUMN(float, intercalibConstants), + // time intercalibrations + SOA_COLUMN(float, timeCalibConstants), + // channel status + SOA_COLUMN(uint16_t, channelStatus), + // laser APDPN ratios + SOA_COLUMN(float, laserAPDPNRatios_p1), + SOA_COLUMN(float, laserAPDPNRatios_p2), + SOA_COLUMN(float, laserAPDPNRatios_p3), + SOA_COLUMN(edm::TimeValue_t, laserAPDPNRatios_t1), + SOA_COLUMN(edm::TimeValue_t, laserAPDPNRatios_t2), + SOA_COLUMN(edm::TimeValue_t, laserAPDPNRatios_t3), + // laser APDPN reference + SOA_COLUMN(float, laserAPDPNref), + // laser alphas + SOA_COLUMN(float, laserAlpha), + // linear corrections + SOA_COLUMN(float, linearCorrections_p1), + SOA_COLUMN(float, linearCorrections_p2), + SOA_COLUMN(float, linearCorrections_p3), + SOA_COLUMN(edm::TimeValue_t, linearCorrections_t1), + SOA_COLUMN(edm::TimeValue_t, linearCorrections_t2), + SOA_COLUMN(edm::TimeValue_t, linearCorrections_t3), + // ADC to GeV constants + SOA_SCALAR(float, adcToGeVConstantEB), + SOA_SCALAR(float, adcToGeVConstantEE), + // time offsets constants + SOA_SCALAR(float, timeOffsetConstantEB), + SOA_SCALAR(float, timeOffsetConstantEE), + // offset for hashed ID access to EE items of columns + SOA_SCALAR(uint32_t, offsetEE)) + +using EcalRecHitConditionsSoA = EcalRecHitConditionsSoALayout<>; + +#endif diff --git a/CondFormats/EcalObjects/interface/EcalRecHitParametersHost.h b/CondFormats/EcalObjects/interface/EcalRecHitParametersHost.h new file mode 100644 index 0000000000000..33820185c6806 --- /dev/null +++ b/CondFormats/EcalObjects/interface/EcalRecHitParametersHost.h @@ -0,0 +1,11 @@ +#ifndef CondFormats_EcalObjects_interface_EcalRecHitParametersHost_h +#define CondFormats_EcalObjects_interface_EcalRecHitParametersHost_h + +#include "CondFormats/EcalObjects/interface/EcalRecHitParametersSoA.h" +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" + +using EcalRecHitParametersHost = PortableHostCollection; + +#endif diff --git a/CondFormats/EcalObjects/interface/EcalRecHitParametersSoA.h b/CondFormats/EcalObjects/interface/EcalRecHitParametersSoA.h new file mode 100644 index 0000000000000..d33028c37a041 --- /dev/null +++ b/CondFormats/EcalObjects/interface/EcalRecHitParametersSoA.h @@ -0,0 +1,21 @@ +#ifndef CondFormats_EcalObjects_EcalRecHitParametersSoA_h +#define CondFormats_EcalObjects_EcalRecHitParametersSoA_h + +#include +#include +#include "DataFormats/EcalRecHit/interface/EcalRecHit.h" +#include "DataFormats/SoATemplate/interface/SoACommon.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/SoATemplate/interface/SoAView.h" + +constexpr size_t kNEcalChannelStatusCodes = 16; // The HW supports 16 channel status codes +using RecoFlagBitsArray = + std::array; // associate recoFlagBits to all channel status codes + +GENERATE_SOA_LAYOUT(EcalRecHitParametersSoALayout, + SOA_SCALAR(RecoFlagBitsArray, recoFlagBits), + SOA_SCALAR(std::bitset, channelStatusCodesToBeExcluded)) + +using EcalRecHitParametersSoA = EcalRecHitParametersSoALayout<>; + +#endif diff --git a/CondFormats/EcalObjects/interface/alpaka/EcalRecHitConditionsDevice.h b/CondFormats/EcalObjects/interface/alpaka/EcalRecHitConditionsDevice.h new file mode 100644 index 0000000000000..a2904fae25e9f --- /dev/null +++ b/CondFormats/EcalObjects/interface/alpaka/EcalRecHitConditionsDevice.h @@ -0,0 +1,17 @@ +#ifndef CondFormats_EcalObjects_interface_alpaka_EcalRecHitConditionsDevice_h +#define CondFormats_EcalObjects_interface_alpaka_EcalRecHitConditionsDevice_h + +#include "CondFormats/EcalObjects/interface/EcalRecHitConditionsHost.h" +#include "CondFormats/EcalObjects/interface/EcalRecHitConditionsSoA.h" +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + using ::EcalRecHitConditionsHost; + using EcalRecHitConditionsDevice = PortableCollection; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif diff --git a/CondFormats/EcalObjects/interface/alpaka/EcalRecHitParametersDevice.h b/CondFormats/EcalObjects/interface/alpaka/EcalRecHitParametersDevice.h new file mode 100644 index 0000000000000..569a480ad91d6 --- /dev/null +++ b/CondFormats/EcalObjects/interface/alpaka/EcalRecHitParametersDevice.h @@ -0,0 +1,17 @@ +#ifndef CondFormats_EcalObjects_interface_alpaka_EcalRecHitParametersDevice_h +#define CondFormats_EcalObjects_interface_alpaka_EcalRecHitParametersDevice_h + +#include "CondFormats/EcalObjects/interface/EcalRecHitParametersHost.h" +#include "CondFormats/EcalObjects/interface/EcalRecHitParametersSoA.h" +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + using ::EcalRecHitParametersHost; + using EcalRecHitParametersDevice = PortableCollection; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif diff --git a/CondFormats/EcalObjects/src/ES_EcalRecHitConditionsHost.cc b/CondFormats/EcalObjects/src/ES_EcalRecHitConditionsHost.cc new file mode 100644 index 0000000000000..59c4ff8ef07d4 --- /dev/null +++ b/CondFormats/EcalObjects/src/ES_EcalRecHitConditionsHost.cc @@ -0,0 +1,4 @@ +#include "CondFormats/EcalObjects/interface/EcalRecHitConditionsHost.h" +#include "FWCore/Utilities/interface/typelookup.h" + +TYPELOOKUP_DATA_REG(EcalRecHitConditionsHost); diff --git a/CondFormats/EcalObjects/src/ES_EcalRecHitParametersHost.cc b/CondFormats/EcalObjects/src/ES_EcalRecHitParametersHost.cc new file mode 100644 index 0000000000000..aa6bfbe86371e --- /dev/null +++ b/CondFormats/EcalObjects/src/ES_EcalRecHitParametersHost.cc @@ -0,0 +1,4 @@ +#include "CondFormats/EcalObjects/interface/EcalRecHitParametersHost.h" +#include "FWCore/Utilities/interface/typelookup.h" + +TYPELOOKUP_DATA_REG(EcalRecHitParametersHost); diff --git a/CondFormats/EcalObjects/src/alpaka/ES_EcalRecHitConditionsDevice.cc b/CondFormats/EcalObjects/src/alpaka/ES_EcalRecHitConditionsDevice.cc new file mode 100644 index 0000000000000..a148ad126a87a --- /dev/null +++ b/CondFormats/EcalObjects/src/alpaka/ES_EcalRecHitConditionsDevice.cc @@ -0,0 +1,4 @@ +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/typelookup.h" + +#include "CondFormats/EcalObjects/interface/alpaka/EcalRecHitConditionsDevice.h" +TYPELOOKUP_ALPAKA_DATA_REG(EcalRecHitConditionsDevice); diff --git a/CondFormats/EcalObjects/src/alpaka/ES_EcalRecHitParametersDevice.cc b/CondFormats/EcalObjects/src/alpaka/ES_EcalRecHitParametersDevice.cc new file mode 100644 index 0000000000000..ab43d28e35dcf --- /dev/null +++ b/CondFormats/EcalObjects/src/alpaka/ES_EcalRecHitParametersDevice.cc @@ -0,0 +1,4 @@ +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/typelookup.h" + +#include "CondFormats/EcalObjects/interface/alpaka/EcalRecHitParametersDevice.h" +TYPELOOKUP_ALPAKA_DATA_REG(EcalRecHitParametersDevice); diff --git a/Configuration/ProcessModifiers/python/alpakaValidationEcal_cff.py b/Configuration/ProcessModifiers/python/alpakaValidationEcal_cff.py new file mode 100644 index 0000000000000..1b35527f48228 --- /dev/null +++ b/Configuration/ProcessModifiers/python/alpakaValidationEcal_cff.py @@ -0,0 +1,5 @@ +import FWCore.ParameterSet.Config as cms + +# This modifier is for turning on alpaka validation modules for ECAL DQM + +alpakaValidationEcal = cms.Modifier() diff --git a/Configuration/ProcessModifiers/python/alpakaValidation_cff.py b/Configuration/ProcessModifiers/python/alpakaValidation_cff.py index 3399bdda7c4df..a8e0ba3853ad8 100644 --- a/Configuration/ProcessModifiers/python/alpakaValidation_cff.py +++ b/Configuration/ProcessModifiers/python/alpakaValidation_cff.py @@ -1,11 +1,13 @@ import FWCore.ParameterSet.Config as cms from Configuration.ProcessModifiers.alpaka_cff import * +from Configuration.ProcessModifiers.alpakaValidationEcal_cff import * from Configuration.ProcessModifiers.alpakaValidationPixel_cff import * # This modifier chain is for turning on DQM modules used for alpaka device/host validation alpakaValidation = cms.ModifierChain( alpaka, + alpakaValidationEcal, alpakaValidationPixel ) diff --git a/Configuration/PyReleaseValidation/README.md b/Configuration/PyReleaseValidation/README.md index 54af3619935dc..ea9ffd9a01468 100644 --- a/Configuration/PyReleaseValidation/README.md +++ b/Configuration/PyReleaseValidation/README.md @@ -37,6 +37,7 @@ The offsets currently in use are: * 0.407: Alpaka, pixel only triplets, portable vs. CPU validation * 0.407: Alpaka, pixel only triplets, portable profiling * 0.412: Alpaka, ECAL only, portable +* 0.413: Alpaka, ECAL only, portable vs. CPU validation * 0.422: Alpaka, HCAL only, portable * 0.423: Alpaka, HCAL only, portable vs CPU validation * 0.424: Alpaka, HCAL only, portable profiling diff --git a/Configuration/PyReleaseValidation/python/relval_gpu.py b/Configuration/PyReleaseValidation/python/relval_gpu.py index b770900fc1332..90376d431b30e 100644 --- a/Configuration/PyReleaseValidation/python/relval_gpu.py +++ b/Configuration/PyReleaseValidation/python/relval_gpu.py @@ -48,7 +48,7 @@ # 2024, Alpaka-based noPU 12834.402, 12834.403, 12834.404, 12834.406, 12834.407, 12834.408, - 12834.412,#12834.413, 12834.414, + 12834.412, 12834.413,#12834.414, 12834.422, 12834.423, 12834.424, #12834.482, 12834.483, 12834.484 #12834.486, 12834.487, 12834.488 @@ -60,7 +60,7 @@ # 2024 with PU, Alpaka-based 13034.402, 13034.403, 13034.404, 13034.406, 13034.407, 13034.408, - 13034.412, #13034.413, 13034.414 + 13034.412, 13034.413, #13034.414 13034.422, 13034.423, 13034.424, #13034.482, 13034.483, 13034.484 #13034.486, 13034.487, 13034.488 diff --git a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py index dffde2a8f52c9..7852419b2f09f 100644 --- a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py +++ b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py @@ -1136,7 +1136,7 @@ def setup_(self, step, stepName, stepDict, k, properties): upgradeWFs['PatatrackECALOnlyAlpaka'] = PatatrackWorkflow( digi = { # customize the ECAL Local Reco part of the HLT menu for Alpaka - '--procModifiers': 'alpaka', + '--procModifiers': 'alpaka', '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling', }, reco = { @@ -1151,6 +1151,28 @@ def setup_(self, step, stepName, stepDict, k, properties): offset = 0.412, ) +# ECAL-only workflow running on CPU or GPU with Alpaka code +# - HLT with Alpaka +# - ECAL-only reconstruction with Alpaka on both CPU and GPU, with DQM and validation for GPU-vs-CPU comparisons +# - harvesting +upgradeWFs['PatatrackECALOnlyAlpakaValidation'] = PatatrackWorkflow( + digi = { + # customize the ECAL Local Reco part of the HLT menu for Alpaka + '--procModifiers': 'alpaka', + '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling', + }, + reco = { + '-s': 'RAW2DIGI:RawToDigi_ecalOnly,RECO:reconstruction_ecalOnly,VALIDATION:@ecalOnlyValidation,DQM:@ecalOnly', + '--procModifiers': 'alpakaValidation', + '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling', + }, + harvest = { + '-s': 'HARVESTING:@ecalOnlyValidation+@ecal' + }, + suffix = 'Patatrack_ECALOnlyAlpakaValidation', + offset = 0.413, +) + # ECAL-only workflow running on CPU # - HLT on CPU # - ECAL-only reconstruction on CPU, with DQM and validation diff --git a/DQM/EcalMonitorTasks/python/EcalMonitorTask_cff.py b/DQM/EcalMonitorTasks/python/EcalMonitorTask_cff.py index 35252ac0f438f..e6b8d05f9c331 100644 --- a/DQM/EcalMonitorTasks/python/EcalMonitorTask_cff.py +++ b/DQM/EcalMonitorTasks/python/EcalMonitorTask_cff.py @@ -4,13 +4,21 @@ # Customization to run the CPU vs GPU comparison task if the job runs on a GPU enabled machine from Configuration.ProcessModifiers.gpuValidationEcal_cff import gpuValidationEcal +from Configuration.ProcessModifiers.alpakaValidationEcal_cff import alpakaValidationEcal from DQM.EcalMonitorTasks.ecalGpuTask_cfi import ecalGpuTask gpuValidationEcal.toModify(ecalGpuTask.params, runGpuTask = True) gpuValidationEcal.toModify(ecalMonitorTask.workers, func = lambda workers: workers.append("GpuTask")) gpuValidationEcal.toModify(ecalMonitorTask, workerParameters = dict(GpuTask = ecalGpuTask)) +alpakaValidationEcal.toModify(ecalGpuTask.params, runGpuTask = True) +alpakaValidationEcal.toModify(ecalMonitorTask.workers, func = lambda workers: workers.append("GpuTask")) +alpakaValidationEcal.toModify(ecalMonitorTask, workerParameters = dict(GpuTask = ecalGpuTask)) + # Skip consuming and running over the EcalRawData collection for all GPU WFs # This is to be used as long as the GPU unpacker unpacks a dummy EcalRawData collection from Configuration.ProcessModifiers.gpu_cff import gpu gpu.toModify(ecalMonitorTask.skipCollections, func = lambda skipCollections: skipCollections.append("EcalRawData")) + +from Configuration.ProcessModifiers.alpaka_cff import alpaka +alpaka.toModify(ecalMonitorTask.skipCollections, func = lambda skipCollections: skipCollections.append("EcalRawData")) diff --git a/DQM/EcalMonitorTasks/python/ecalGpuTask_cfi.py b/DQM/EcalMonitorTasks/python/ecalGpuTask_cfi.py index 9cb6322cca3d2..ff2079b493bbd 100644 --- a/DQM/EcalMonitorTasks/python/ecalGpuTask_cfi.py +++ b/DQM/EcalMonitorTasks/python/ecalGpuTask_cfi.py @@ -748,6 +748,58 @@ ), description = cms.untracked.string('CPU Rec Hit Flags') ), + RecHitCpuChi2 = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit chi2 cpu'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(0), + high = cms.untracked.double(50.), + title = cms.untracked.string('Chi2') + ), + description = cms.untracked.string('CPU Rec Hit Chi2') + ), + RecHitCpuEnergyError = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit energyerror cpu'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(0), + high = cms.untracked.double(5.0), + title = cms.untracked.string('Energy error (Gev)') + ), + description = cms.untracked.string('CPU Rec Hit Energy Error (GeV)') + ), + RecHitCpuTimeError = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit timeerror cpu'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(0), + high = cms.untracked.double(5.0), + title = cms.untracked.string('Time error (ns)') + ), + description = cms.untracked.string('CPU Rec Hit Time Error (ns)') + ), + RecHitCpuNonCorrectedTime = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit non corrected time cpu'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(-25.), + high = cms.untracked.double(25.0), + title = cms.untracked.string('Non corrected time (ns)') + ), + description = cms.untracked.string('CPU Rec Hit non corrected time (ns)') + ), # GPU RecHit (optional) RecHitGpu = cms.untracked.PSet( path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit nHits gpu'), @@ -801,6 +853,58 @@ ), description = cms.untracked.string('GPU Rec Hit Flags') ), + RecHitGpuChi2 = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit chi2 gpu'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(0), + high = cms.untracked.double(50.), + title = cms.untracked.string('Chi2') + ), + description = cms.untracked.string('GPU Rec Hit Chi2') + ), + RecHitGpuEnergyError = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit energyerror gpu'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(0), + high = cms.untracked.double(5.0), + title = cms.untracked.string('Energy error (Gev)') + ), + description = cms.untracked.string('GPU Rec Hit Energy Error (GeV)') + ), + RecHitGpuTimeError = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit timeerror gpu'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(0), + high = cms.untracked.double(5.0), + title = cms.untracked.string('Time error (ns)') + ), + description = cms.untracked.string('GPU Rec Hit Time Error (ns)') + ), + RecHitGpuNonCorrectedTime = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit non corrected time gpu'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(-25.), + high = cms.untracked.double(25.0), + title = cms.untracked.string('Non corrected time (ns)') + ), + description = cms.untracked.string('GPU Rec Hit non corrected time (ns)') + ), # RecHit GPU-CPU Difference RecHitGpuCpu = cms.untracked.PSet( path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit nHits gpu-cpu diff'), @@ -854,6 +958,58 @@ ), description = cms.untracked.string('GPU-CPU differnece of Rec Hit Flags') ), + RecHitGpuCpuChi2 = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit chi2 gpu-cpu diff'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(-10.0), + high = cms.untracked.double(10.0), + title = cms.untracked.string('GPU-CPU Chi2') + ), + description = cms.untracked.string('GPU-CPU difference of Rec Hit Chi2') + ), + RecHitGpuCpuEnergyError = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit energyerror gpu-cpu diff'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(-1.0), + high = cms.untracked.double(1.0), + title = cms.untracked.string('GPU-CPU Energy Error (GeV)') + ), + description = cms.untracked.string('GPU-CPU difference of Rec Hit Energy Error (GeV)') + ), + RecHitGpuCpuTimeError = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit timeerror gpu-cpu diff'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(-1.0), + high = cms.untracked.double(1.0), + title = cms.untracked.string('GPU-CPU Time Error (ns)') + ), + description = cms.untracked.string('GPU-CPU difference of Rec Hit Time Error (ns)') + ), + RecHitGpuCpuNonCorrectedTime = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit non corrected time gpu-cpu diff'), + kind = cms.untracked.string('TH1F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(100), + low = cms.untracked.double(-2.5), + high = cms.untracked.double(2.5), + title = cms.untracked.string('GPU-CPU non corrected time (ns)') + ), + description = cms.untracked.string('GPU-CPU difference of Rec Hit non corrected time (ns)') + ), # RecHit 2D plots RecHit2D = cms.untracked.PSet( path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit nHits gpu-cpu map2D'), @@ -930,6 +1086,82 @@ title = cms.untracked.string('GPU Flags') ), description = cms.untracked.string('Rec Hit Flags. GPU vs CPU comparison') + ), + RecHit2DChi2 = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit chi2 gpu-cpu map2D'), + kind = cms.untracked.string('TH2F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(50), + low = cms.untracked.double(0), + high = cms.untracked.double(50.0), + title = cms.untracked.string('CPU Chi2') + ), + yaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(50), + low = cms.untracked.double(0), + high = cms.untracked.double(50.0), + title = cms.untracked.string('GPU Chi2') + ), + description = cms.untracked.string('Rec Hit Chi2. GPU vs CPU comparison') + ), + RecHit2DEnergyError = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit energyerror gpu-cpu map2D'), + kind = cms.untracked.string('TH2F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(50), + low = cms.untracked.double(0), + high = cms.untracked.double(5.0), + title = cms.untracked.string('CPU Energy Error (Gev)') + ), + yaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(50), + low = cms.untracked.double(0), + high = cms.untracked.double(5.0), + title = cms.untracked.string('GPU Energy Error (Gev)') + ), + description = cms.untracked.string('Rec Hit Energy Error (GeV). GPU vs CPU comparison') + ), + RecHit2DTimeError = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit timeerror gpu-cpu map2D'), + kind = cms.untracked.string('TH2F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(50), + low = cms.untracked.double(0), + high = cms.untracked.double(5.0), + title = cms.untracked.string('CPU Time Error (ns)') + ), + yaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(50), + low = cms.untracked.double(0), + high = cms.untracked.double(5.0), + title = cms.untracked.string('GPU Time Error (ns)') + ), + description = cms.untracked.string('Rec Hit Time Error (ns). GPU vs CPU comparison') + ), + RecHit2DNonCorrectedTime = cms.untracked.PSet( + path = cms.untracked.string('%(subdet)s/%(prefix)sGpuTask/RecHits/%(prefix)sGT rec hit non corrected time gpu-cpu map2D'), + kind = cms.untracked.string('TH2F'), + otype = cms.untracked.string('Ecal2P'), + btype = cms.untracked.string('User'), + xaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(50), + low = cms.untracked.double(-25.0), + high = cms.untracked.double(25.0), + title = cms.untracked.string('CPU Non Corrected Time (ns)') + ), + yaxis = cms.untracked.PSet( + nbins = cms.untracked.int32(50), + low = cms.untracked.double(-25.0), + high = cms.untracked.double(25.0), + title = cms.untracked.string('GPU Non Corrected Time (ns)') + ), + description = cms.untracked.string('Rec Hit non corrected time (ns). GPU vs CPU comparison') ) ) ) diff --git a/DQM/EcalMonitorTasks/src/GpuTask.cc b/DQM/EcalMonitorTasks/src/GpuTask.cc index 3af951c398e71..eace1a7a2bb0a 100644 --- a/DQM/EcalMonitorTasks/src/GpuTask.cc +++ b/DQM/EcalMonitorTasks/src/GpuTask.cc @@ -96,10 +96,18 @@ namespace ecaldqm { MEs_.erase(std::string("RecHitCpuEnergy")); MEs_.erase(std::string("RecHitCpuTime")); MEs_.erase(std::string("RecHitCpuFlags")); + MEs_.erase(std::string("RecHitCpuChi2")); + MEs_.erase(std::string("RecHitCpuEnergyError")); + MEs_.erase(std::string("RecHitCpuTimeError")); + MEs_.erase(std::string("RecHitCpuNonCorrectedTime")); MEs_.erase(std::string("RecHitGpuCpu")); MEs_.erase(std::string("RecHitGpuCpuEnergy")); MEs_.erase(std::string("RecHitGpuCpuTime")); MEs_.erase(std::string("RecHitGpuCpuFlags")); + MEs_.erase(std::string("RecHitGpuCpuChi2")); + MEs_.erase(std::string("RecHitGpuCpuEnergyError")); + MEs_.erase(std::string("RecHitGpuCpuTimeError")); + MEs_.erase(std::string("RecHitGpuCpuNonCorrectedTime")); } if (!digi1D_) { MEs_.erase(std::string("DigiGpu")); @@ -121,6 +129,10 @@ namespace ecaldqm { MEs_.erase(std::string("RecHitGpuEnergy")); MEs_.erase(std::string("RecHitGpuTime")); MEs_.erase(std::string("RecHitGpuFlags")); + MEs_.erase(std::string("RecHitGpuChi2")); + MEs_.erase(std::string("RecHitGpuEnergyError")); + MEs_.erase(std::string("RecHitGpuTimeError")); + MEs_.erase(std::string("RecHitGpuNonCorrectedTime")); } if (!digi2D_) { MEs_.erase(std::string("Digi2D")); @@ -142,6 +154,10 @@ namespace ecaldqm { MEs_.erase(std::string("RecHit2DEnergy")); MEs_.erase(std::string("RecHit2DTime")); MEs_.erase(std::string("RecHit2DFlags")); + MEs_.erase(std::string("RecHit2DChi2")); + MEs_.erase(std::string("RecHit2DEnergyError")); + MEs_.erase(std::string("RecHit2DTimeError")); + MEs_.erase(std::string("RecHit2DNonCorrectedTime")); } } @@ -469,6 +485,10 @@ namespace ecaldqm { MESet& meRecHitCpuEnergy(MEs_.at("RecHitCpuEnergy")); MESet& meRecHitCpuTime(MEs_.at("RecHitCpuTime")); MESet& meRecHitCpuFlags(MEs_.at("RecHitCpuFlags")); + MESet& meRecHitCpuChi2(MEs_.at("RecHitCpuChi2")); + MESet& meRecHitCpuEnergyError(MEs_.at("RecHitCpuEnergyError")); + MESet& meRecHitCpuTimeError(MEs_.at("RecHitCpuTimeError")); + MESet& meRecHitCpuNonCorrectedTime(MEs_.at("RecHitCpuNonCorrectedTime")); int iSubdet(collection == kEBCpuRecHit ? EcalBarrel : EcalEndcap); @@ -485,10 +505,18 @@ namespace ecaldqm { float cpuEnergy(cpuHit.energy()); float cpuTime(cpuHit.time()); uint32_t cpuFlags(cpuHit.flagsBits()); + float cpuChi2(cpuHit.chi2()); + float cpuEnergyError(cpuHit.energyError()); + float cpuTimeError(cpuHit.timeError()); + float cpuNonCorrectedTime(cpuHit.nonCorrectedTime()); meRecHitCpuEnergy.fill(getEcalDQMSetupObjects(), iSubdet, cpuEnergy); meRecHitCpuTime.fill(getEcalDQMSetupObjects(), iSubdet, cpuTime); meRecHitCpuFlags.fill(getEcalDQMSetupObjects(), iSubdet, cpuFlags); + meRecHitCpuChi2.fill(getEcalDQMSetupObjects(), iSubdet, cpuChi2); + meRecHitCpuEnergyError.fill(getEcalDQMSetupObjects(), iSubdet, cpuEnergyError); + meRecHitCpuTimeError.fill(getEcalDQMSetupObjects(), iSubdet, cpuTimeError); + meRecHitCpuNonCorrectedTime.fill(getEcalDQMSetupObjects(), iSubdet, cpuNonCorrectedTime); } } @@ -497,6 +525,10 @@ namespace ecaldqm { MESet& meRecHitGpuCpuEnergy(MEs_.at("RecHitGpuCpuEnergy")); MESet& meRecHitGpuCpuTime(MEs_.at("RecHitGpuCpuTime")); MESet& meRecHitGpuCpuFlags(MEs_.at("RecHitGpuCpuFlags")); + MESet& meRecHitGpuCpuChi2(MEs_.at("RecHitGpuCpuChi2")); + MESet& meRecHitGpuCpuEnergyError(MEs_.at("RecHitGpuCpuEnergyError")); + MESet& meRecHitGpuCpuTimeError(MEs_.at("RecHitGpuCpuTimeError")); + MESet& meRecHitGpuCpuNonCorrectedTime(MEs_.at("RecHitGpuCpuNonCorrectedTime")); int iSubdet(collection == kEBGpuRecHit ? EcalBarrel : EcalEndcap); @@ -536,33 +568,61 @@ namespace ecaldqm { float gpuEnergy(gpuHit.energy()); float gpuTime(gpuHit.time()); uint32_t gpuFlags(gpuHit.flagsBits()); + float gpuChi2(gpuHit.chi2()); + float gpuEnergyError(gpuHit.energyError()); + float gpuTimeError(gpuHit.timeError()); + float gpuNonCorrectedTime(gpuHit.nonCorrectedTime()); float cpuEnergy(cpuItr->energy()); float cpuTime(cpuItr->time()); uint32_t cpuFlags(cpuItr->flagsBits()); + float cpuChi2(cpuItr->chi2()); + float cpuEnergyError(cpuItr->energyError()); + float cpuTimeError(cpuItr->timeError()); + float cpuNonCorrectedTime(cpuItr->nonCorrectedTime()); meRecHitGpuCpuEnergy.fill(getEcalDQMSetupObjects(), iSubdet, gpuEnergy - cpuEnergy); meRecHitGpuCpuTime.fill(getEcalDQMSetupObjects(), iSubdet, gpuTime - cpuTime); meRecHitGpuCpuFlags.fill(getEcalDQMSetupObjects(), iSubdet, gpuFlags - cpuFlags); + meRecHitGpuCpuChi2.fill(getEcalDQMSetupObjects(), iSubdet, gpuChi2 - cpuChi2); + meRecHitGpuCpuEnergyError.fill(getEcalDQMSetupObjects(), iSubdet, gpuEnergyError - cpuEnergyError); + meRecHitGpuCpuTimeError.fill(getEcalDQMSetupObjects(), iSubdet, gpuTimeError - cpuTimeError); + meRecHitGpuCpuNonCorrectedTime.fill(getEcalDQMSetupObjects(), iSubdet, gpuNonCorrectedTime - cpuNonCorrectedTime); if (rechit1D_) { MESet& meRecHitGpuEnergy(MEs_.at("RecHitGpuEnergy")); MESet& meRecHitGpuTime(MEs_.at("RecHitGpuTime")); MESet& meRecHitGpuFlags(MEs_.at("RecHitGpuFlags")); + MESet& meRecHitGpuChi2(MEs_.at("RecHitGpuChi2")); + MESet& meRecHitGpuEnergyError(MEs_.at("RecHitGpuEnergyError")); + MESet& meRecHitGpuTimeError(MEs_.at("RecHitGpuTimeError")); + MESet& meRecHitGpuNonCorrectedTime(MEs_.at("RecHitGpuNonCorrectedTime")); meRecHitGpuEnergy.fill(getEcalDQMSetupObjects(), iSubdet, gpuEnergy); meRecHitGpuTime.fill(getEcalDQMSetupObjects(), iSubdet, gpuTime); meRecHitGpuFlags.fill(getEcalDQMSetupObjects(), iSubdet, gpuFlags); + meRecHitGpuChi2.fill(getEcalDQMSetupObjects(), iSubdet, gpuChi2); + meRecHitGpuEnergyError.fill(getEcalDQMSetupObjects(), iSubdet, gpuEnergyError); + meRecHitGpuTimeError.fill(getEcalDQMSetupObjects(), iSubdet, gpuTimeError); + meRecHitGpuNonCorrectedTime.fill(getEcalDQMSetupObjects(), iSubdet, gpuNonCorrectedTime); } if (rechit2D_) { MESet& meRecHit2DEnergy(MEs_.at("RecHit2DEnergy")); MESet& meRecHit2DTime(MEs_.at("RecHit2DTime")); MESet& meRecHit2DFlags(MEs_.at("RecHit2DFlags")); + MESet& meRecHit2DChi2(MEs_.at("RecHit2DChi2")); + MESet& meRecHit2DEnergyError(MEs_.at("RecHit2DEnergyError")); + MESet& meRecHit2DTimeError(MEs_.at("RecHit2DTimeError")); + MESet& meRecHit2DNonCorrectedTime(MEs_.at("RecHit2DNonCorrectedTime")); meRecHit2DEnergy.fill(getEcalDQMSetupObjects(), iSubdet, cpuEnergy, gpuEnergy); meRecHit2DTime.fill(getEcalDQMSetupObjects(), iSubdet, cpuTime, gpuTime); meRecHit2DFlags.fill(getEcalDQMSetupObjects(), iSubdet, cpuFlags, gpuFlags); + meRecHit2DChi2.fill(getEcalDQMSetupObjects(), iSubdet, cpuChi2, gpuChi2); + meRecHit2DEnergyError.fill(getEcalDQMSetupObjects(), iSubdet, cpuEnergyError, gpuEnergyError); + meRecHit2DTimeError.fill(getEcalDQMSetupObjects(), iSubdet, cpuTimeError, gpuTimeError); + meRecHit2DNonCorrectedTime.fill(getEcalDQMSetupObjects(), iSubdet, cpuNonCorrectedTime, gpuNonCorrectedTime); } } } diff --git a/DataFormats/EcalRecHit/interface/EcalRecHitHostCollection.h b/DataFormats/EcalRecHit/interface/EcalRecHitHostCollection.h new file mode 100644 index 0000000000000..c5f877988f8ce --- /dev/null +++ b/DataFormats/EcalRecHit/interface/EcalRecHitHostCollection.h @@ -0,0 +1,10 @@ +#ifndef DataFormats_EcalRecHit_EcalRecHitHostCollection_h +#define DataFormats_EcalRecHit_EcalRecHitHostCollection_h + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitSoA.h" + +// EcalRecHitSoA in host memory +using EcalRecHitHostCollection = PortableHostCollection; + +#endif diff --git a/DataFormats/EcalRecHit/interface/EcalRecHitSoA.h b/DataFormats/EcalRecHit/interface/EcalRecHitSoA.h new file mode 100644 index 0000000000000..b61da3ecd186b --- /dev/null +++ b/DataFormats/EcalRecHit/interface/EcalRecHitSoA.h @@ -0,0 +1,16 @@ +#ifndef DataFormats_EcalRecHit_EcalRecHitSoA_h +#define DataFormats_EcalRecHit_EcalRecHitSoA_h + +#include "DataFormats/SoATemplate/interface/SoALayout.h" + +GENERATE_SOA_LAYOUT(EcalRecHitSoALayout, + SOA_SCALAR(uint32_t, size), + SOA_COLUMN(uint32_t, id), + SOA_COLUMN(float, energy), + SOA_COLUMN(float, time), + SOA_COLUMN(uint32_t, flagBits), + SOA_COLUMN(uint32_t, extra)) + +using EcalRecHitSoA = EcalRecHitSoALayout<>; + +#endif diff --git a/DataFormats/EcalRecHit/interface/alpaka/EcalRecHitDeviceCollection.h b/DataFormats/EcalRecHit/interface/alpaka/EcalRecHitDeviceCollection.h new file mode 100644 index 0000000000000..5a7f7761afb89 --- /dev/null +++ b/DataFormats/EcalRecHit/interface/alpaka/EcalRecHitDeviceCollection.h @@ -0,0 +1,15 @@ +#ifndef DataFormats_EcalRecHit_alpaka_EcalRecHitDeviceCollection_h +#define DataFormats_EcalRecHit_alpaka_EcalRecHitDeviceCollection_h + +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitSoA.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + // EcalRecHitSoA in device global memory + using EcalRecHitDeviceCollection = PortableCollection; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#endif diff --git a/DataFormats/EcalRecHit/src/alpaka/classes_cuda.h b/DataFormats/EcalRecHit/src/alpaka/classes_cuda.h index e8f1c8d74e657..49a436ed51a59 100644 --- a/DataFormats/EcalRecHit/src/alpaka/classes_cuda.h +++ b/DataFormats/EcalRecHit/src/alpaka/classes_cuda.h @@ -2,3 +2,5 @@ #include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/EcalRecHit/interface/EcalUncalibratedRecHitSoA.h" #include "DataFormats/EcalRecHit/interface/alpaka/EcalUncalibratedRecHitDeviceCollection.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitSoA.h" +#include "DataFormats/EcalRecHit/interface/alpaka/EcalRecHitDeviceCollection.h" diff --git a/DataFormats/EcalRecHit/src/alpaka/classes_cuda_def.xml b/DataFormats/EcalRecHit/src/alpaka/classes_cuda_def.xml index 6bc692f6e1372..247b0da861868 100644 --- a/DataFormats/EcalRecHit/src/alpaka/classes_cuda_def.xml +++ b/DataFormats/EcalRecHit/src/alpaka/classes_cuda_def.xml @@ -2,4 +2,8 @@ + + + + diff --git a/DataFormats/EcalRecHit/src/alpaka/classes_rocm.h b/DataFormats/EcalRecHit/src/alpaka/classes_rocm.h index e8f1c8d74e657..49a436ed51a59 100644 --- a/DataFormats/EcalRecHit/src/alpaka/classes_rocm.h +++ b/DataFormats/EcalRecHit/src/alpaka/classes_rocm.h @@ -2,3 +2,5 @@ #include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/EcalRecHit/interface/EcalUncalibratedRecHitSoA.h" #include "DataFormats/EcalRecHit/interface/alpaka/EcalUncalibratedRecHitDeviceCollection.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitSoA.h" +#include "DataFormats/EcalRecHit/interface/alpaka/EcalRecHitDeviceCollection.h" diff --git a/DataFormats/EcalRecHit/src/alpaka/classes_rocm_def.xml b/DataFormats/EcalRecHit/src/alpaka/classes_rocm_def.xml index a9d31a4bb0de2..dd1aa58d33687 100644 --- a/DataFormats/EcalRecHit/src/alpaka/classes_rocm_def.xml +++ b/DataFormats/EcalRecHit/src/alpaka/classes_rocm_def.xml @@ -2,4 +2,8 @@ + + + + diff --git a/DataFormats/EcalRecHit/src/classes.cc b/DataFormats/EcalRecHit/src/classes.cc index c52911f9a852d..ffc7dc11935b3 100644 --- a/DataFormats/EcalRecHit/src/classes.cc +++ b/DataFormats/EcalRecHit/src/classes.cc @@ -1,4 +1,6 @@ #include "DataFormats/EcalRecHit/interface/EcalUncalibratedRecHitHostCollection.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitHostCollection.h" #include "DataFormats/Portable/interface/PortableHostCollectionReadRules.h" SET_PORTABLEHOSTCOLLECTION_READ_RULES(EcalUncalibratedRecHitHostCollection); +SET_PORTABLEHOSTCOLLECTION_READ_RULES(EcalRecHitHostCollection); diff --git a/DataFormats/EcalRecHit/src/classes.h b/DataFormats/EcalRecHit/src/classes.h index 98eaae1434ad5..52d605000c21f 100644 --- a/DataFormats/EcalRecHit/src/classes.h +++ b/DataFormats/EcalRecHit/src/classes.h @@ -16,3 +16,5 @@ #include "DataFormats/EcalRecHit/interface/EcalUncalibratedRecHitHostCollection.h" #include "DataFormats/EcalRecHit/interface/EcalUncalibratedRecHitSoA.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitHostCollection.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitSoA.h" diff --git a/DataFormats/EcalRecHit/src/classes_def.xml b/DataFormats/EcalRecHit/src/classes_def.xml index 8439f27a50f64..128d9bb01c7a4 100644 --- a/DataFormats/EcalRecHit/src/classes_def.xml +++ b/DataFormats/EcalRecHit/src/classes_def.xml @@ -47,4 +47,11 @@ + + + + + + + diff --git a/EventFilter/EcalRawToDigi/python/ecalDigis_cff.py b/EventFilter/EcalRawToDigi/python/ecalDigis_cff.py index 0710a87569343..51c5951230a0d 100644 --- a/EventFilter/EcalRawToDigi/python/ecalDigis_cff.py +++ b/EventFilter/EcalRawToDigi/python/ecalDigis_cff.py @@ -76,3 +76,9 @@ # copy the ECAL digis from GPU to CPU (if needed) and convert them from SoA to legacy format ecalDigis )) + +# for alpaka validation compare the legacy CPU module with the alpaka module +from Configuration.ProcessModifiers.alpakaValidationEcal_cff import alpakaValidationEcal +alpakaValidationEcal.toModify(ecalDigis, cpu = ecalDigisCPU) +alpakaValidationEcal.toModify(ecalDigis, cuda = _ecalDigisFromPortable.clone()) + diff --git a/RecoLocalCalo/EcalRecProducers/plugins/EcalRecHitSoAToLegacy.cc b/RecoLocalCalo/EcalRecProducers/plugins/EcalRecHitSoAToLegacy.cc new file mode 100644 index 0000000000000..d3a76e7da7ce1 --- /dev/null +++ b/RecoLocalCalo/EcalRecProducers/plugins/EcalRecHitSoAToLegacy.cc @@ -0,0 +1,96 @@ +#include "DataFormats/DetId/interface/DetId.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHit.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHitHostCollection.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/EmptyGroupDescription.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" + +class EcalRecHitSoAToLegacy : public edm::stream::EDProducer<> { +public: + explicit EcalRecHitSoAToLegacy(edm::ParameterSet const &ps); + ~EcalRecHitSoAToLegacy() override = default; + static void fillDescriptions(edm::ConfigurationDescriptions &); + +private: + using InputProduct = EcalRecHitHostCollection; + void produce(edm::Event &, edm::EventSetup const &) override; + +private: + const bool isPhase2_; + const edm::EDGetTokenT recHitsPortableEB_; + const edm::EDGetTokenT recHitsPortableEE_; + const edm::EDPutTokenT recHitsCPUEBToken_; + const edm::EDPutTokenT recHitsCPUEEToken_; +}; + +void EcalRecHitSoAToLegacy::fillDescriptions(edm::ConfigurationDescriptions &confDesc) { + edm::ParameterSetDescription desc; + + desc.add("recHitsPortableEB", edm::InputTag("ecalRecHitPortable", "EcalRecHitsEB")); + desc.add("recHitsLabelCPUEB", "EcalRecHitsEB"); + desc.ifValue(edm::ParameterDescription("isPhase2", false, true), + false >> (edm::ParameterDescription( + "recHitsPortableEE", edm::InputTag("ecalRecHitPortable", "EcalRecHitsEE"), true) and + edm::ParameterDescription("recHitsLabelCPUEE", "EcalRecHitsEE", true)) or + true >> edm::EmptyGroupDescription()); + confDesc.add("ecalRecHitSoAToLegacy", desc); +} + +EcalRecHitSoAToLegacy::EcalRecHitSoAToLegacy(edm::ParameterSet const &ps) + : isPhase2_{ps.getParameter("isPhase2")}, + recHitsPortableEB_{consumes(ps.getParameter("recHitsPortableEB"))}, + recHitsPortableEE_{isPhase2_ ? edm::EDGetTokenT{} + : consumes(ps.getParameter("recHitsPortableEE"))}, + recHitsCPUEBToken_{produces(ps.getParameter("recHitsLabelCPUEB"))}, + recHitsCPUEEToken_{isPhase2_ ? edm::EDPutTokenT{} + : produces(ps.getParameter("recHitsLabelCPUEE"))} {} + +void EcalRecHitSoAToLegacy::produce(edm::Event &event, edm::EventSetup const &setup) { + auto const &recHitsEBColl = event.get(recHitsPortableEB_); + auto const &recHitsEBCollView = recHitsEBColl.const_view(); + auto recHitsCPUEB = std::make_unique(); + recHitsCPUEB->reserve(recHitsEBCollView.size()); + + for (uint32_t i = 0; i < recHitsEBCollView.size(); ++i) { + // Save only if energy is >= 0 ! + // This is important because the channels that were supposed + // to be excluded get "-1" as energy + if (recHitsEBCollView.energy()[i] >= 0.) { + recHitsCPUEB->emplace_back(DetId{recHitsEBCollView.id()[i]}, + recHitsEBCollView.energy()[i], + recHitsEBCollView.time()[i], + recHitsEBCollView.extra()[i], + recHitsEBCollView.flagBits()[i]); + } + } + event.put(recHitsCPUEBToken_, std::move(recHitsCPUEB)); + + if (!isPhase2_) { + auto const &recHitsEEColl = event.get(recHitsPortableEE_); + auto const &recHitsEECollView = recHitsEEColl.const_view(); + auto recHitsCPUEE = std::make_unique(); + recHitsCPUEE->reserve(recHitsEECollView.size()); + + for (uint32_t i = 0; i < recHitsEECollView.size(); ++i) { + // Save only if energy is >= 0 ! + // This is important because the channels that were supposed + // to be excluded get "-1" as energy + if (recHitsEECollView.energy()[i] >= 0.) { + recHitsCPUEE->emplace_back(DetId{recHitsEECollView.id()[i]}, + recHitsEECollView.energy()[i], + recHitsEECollView.time()[i], + recHitsEECollView.extra()[i], + recHitsEECollView.flagBits()[i]); + } + } + event.put(recHitsCPUEEToken_, std::move(recHitsCPUEE)); + } +} + +DEFINE_FWK_MODULE(EcalRecHitSoAToLegacy); diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/DeclsForKernels.h b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/DeclsForKernels.h index 6f96b26d253d1..c7f96cb17ee7f 100644 --- a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/DeclsForKernels.h +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/DeclsForKernels.h @@ -127,4 +127,31 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::multifit { } // namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::multifit +// +// ECAL Rechit producer +// + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::rechit { + + // parameters that are read from the configuration file for rechit producer + struct ConfigurationParameters { + bool killDeadChannels; + + bool recoverEBIsolatedChannels; + bool recoverEEIsolatedChannels; + bool recoverEBVFE; + bool recoverEEVFE; + bool recoverEBFE; + bool recoverEEFE; + + float EBLaserMIN; + float EELaserMIN; + float EBLaserMAX; + float EELaserMAX; + + uint32_t flagmask; + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::rechit + #endif // RecoLocalCalo_EcalRecProducers_plugins_alpaka_DeclsForKernels_h diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitBuilder.dev.cc b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitBuilder.dev.cc new file mode 100644 index 0000000000000..5c9c85b280398 --- /dev/null +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitBuilder.dev.cc @@ -0,0 +1,82 @@ +#include + +#include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h" + +#include "EcalRecHitBuilder.h" +#include "EnergyComputationKernels.h" + +//#define DEBUG +//#define ECAL_RECO_ALPAKA_DEBUG + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::rechit { + + using namespace cms::alpakatools; + + // host version, to be called by the plugin + void create_ecal_rechit(Queue& queue, + InputProduct const* ebUncalibRecHits, + InputProduct const* eeUncalibRecHits, + OutputProduct& ebRecHits, + OutputProduct& eeRecHits, + EcalRecHitConditionsDevice const& conditionsDev, + EcalRecHitParametersDevice const& parametersDev, + edm::TimeValue_t const& eventTime, + ConfigurationParameters const& configParams, + bool const isPhase2) { + auto nchannels = static_cast(ebUncalibRecHits->const_view().metadata().size()); + if (!isPhase2 && eeUncalibRecHits != nullptr) { + nchannels += static_cast(eeUncalibRecHits->const_view().metadata().size()); + } + + // + // kernel create rechit + // + uint32_t constexpr nchannels_per_block = 16; + auto constexpr threads = nchannels_per_block; + auto const blocks = cms::alpakatools::divide_up_by(nchannels, threads); + auto workDiv = cms::alpakatools::make_workdiv(blocks, threads); + if (!isPhase2 && eeUncalibRecHits != nullptr) { + alpaka::exec(queue, + workDiv, + KernelCreateEcalRechit{}, + ebUncalibRecHits->const_view(), + eeUncalibRecHits->const_view(), + ebRecHits.view(), + eeRecHits.view(), + conditionsDev.const_view(), + parametersDev.const_view(), + eventTime, + // configuration + configParams.killDeadChannels, + configParams.recoverEBIsolatedChannels, + configParams.recoverEEIsolatedChannels, + configParams.recoverEBVFE, + configParams.recoverEEVFE, + configParams.recoverEBFE, + configParams.recoverEEFE, + configParams.EBLaserMIN, + configParams.EELaserMIN, + configParams.EBLaserMAX, + configParams.EELaserMAX, + configParams.flagmask); + } else { + alpaka::exec(queue, + workDiv, + KernelCreateEcalRechitPhase2{}, + ebUncalibRecHits->const_view(), + ebRecHits.view(), + conditionsDev.const_view(), + parametersDev.const_view(), + eventTime, + // configuration + configParams.killDeadChannels, + configParams.recoverEBIsolatedChannels, + configParams.recoverEBVFE, + configParams.recoverEBFE, + configParams.EBLaserMIN, + configParams.EBLaserMAX, + configParams.flagmask); + } + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::rechit diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitBuilder.h b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitBuilder.h new file mode 100644 index 0000000000000..42c2ae51c6e0e --- /dev/null +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitBuilder.h @@ -0,0 +1,36 @@ +#ifndef RecoLocalCalo_EcalRecProducers_plugins_alpaka_EcalRecHitBuilder_h +#define RecoLocalCalo_EcalRecProducers_plugins_alpaka_EcalRecHitBuilder_h + +// +// Builder of ECAL RecHits on GPU +// + +#include "CondFormats/EcalObjects/interface/alpaka/EcalRecHitConditionsDevice.h" +#include "CondFormats/EcalObjects/interface/alpaka/EcalRecHitParametersDevice.h" +#include "DataFormats/EcalRecHit/interface/alpaka/EcalRecHitDeviceCollection.h" +#include "DataFormats/EcalRecHit/interface/alpaka/EcalUncalibratedRecHitDeviceCollection.h" +#include "DataFormats/Provenance/interface/Timestamp.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" + +#include "DeclsForKernels.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::rechit { + + using InputProduct = EcalUncalibratedRecHitDeviceCollection; + using OutputProduct = EcalRecHitDeviceCollection; + + // host version, to be called by the plugin + void create_ecal_rechit(Queue& queue, + InputProduct const* ebUncalibRecHits, + InputProduct const* eeUncalibRecHits, + OutputProduct& ebRecHits, + OutputProduct& eeRecHits, + EcalRecHitConditionsDevice const& conditionsDev, + EcalRecHitParametersDevice const& parametersDev, + edm::TimeValue_t const& eventTime, + ConfigurationParameters const& configParams, + bool const isPhase2); + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::rechit + +#endif // RecoLocalCalo_EcalRecProducers_plugins_alpaka_EcalRecHitBuilder_h diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitConditionsHostESProducer.cc b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitConditionsHostESProducer.cc new file mode 100644 index 0000000000000..fab591d65b5fc --- /dev/null +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitConditionsHostESProducer.cc @@ -0,0 +1,198 @@ +#include "FWCore/Framework/interface/ESTransientHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "CondFormats/DataRecord/interface/EcalADCToGeVConstantRcd.h" +#include "CondFormats/DataRecord/interface/EcalChannelStatusRcd.h" +#include "CondFormats/DataRecord/interface/EcalIntercalibConstantsRcd.h" +#include "CondFormats/DataRecord/interface/EcalLaserAPDPNRatiosRcd.h" +#include "CondFormats/DataRecord/interface/EcalLaserAPDPNRatiosRefRcd.h" +#include "CondFormats/DataRecord/interface/EcalLaserAlphasRcd.h" +#include "CondFormats/DataRecord/interface/EcalLinearCorrectionsRcd.h" +#include "CondFormats/DataRecord/interface/EcalTimeCalibConstantsRcd.h" +#include "CondFormats/DataRecord/interface/EcalTimeOffsetConstantRcd.h" +#include "CondFormats/EcalObjects/interface/EcalADCToGeVConstant.h" +#include "CondFormats/EcalObjects/interface/EcalChannelStatus.h" +#include "CondFormats/EcalObjects/interface/EcalIntercalibConstants.h" +#include "CondFormats/EcalObjects/interface/EcalLaserAPDPNRatios.h" +#include "CondFormats/EcalObjects/interface/EcalLaserAPDPNRatiosRef.h" +#include "CondFormats/EcalObjects/interface/EcalLaserAlphas.h" +#include "CondFormats/EcalObjects/interface/EcalLinearCorrections.h" +#include "CondFormats/EcalObjects/interface/EcalTimeCalibConstants.h" +#include "CondFormats/EcalObjects/interface/EcalTimeOffsetConstant.h" + +#include "CondFormats/EcalObjects/interface/alpaka/EcalRecHitConditionsDevice.h" +#include "CondFormats/EcalObjects/interface/EcalRecHitConditionsSoA.h" +#include "CondFormats/DataRecord/interface/EcalRecHitConditionsRcd.h" + +#include "DataFormats/EcalDigi/interface/EcalConstants.h" + +#include "DataFormats/EcalDetId/interface/EcalElectronicsId.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESProducer.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ModuleFactory.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/host.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + class EcalRecHitConditionsHostESProducer : public ESProducer { + public: + EcalRecHitConditionsHostESProducer(edm::ParameterSet const& iConfig) + : ESProducer(iConfig), isPhase2_{iConfig.getParameter("isPhase2")} { + auto cc = setWhatProduced(this); + adcToGeVConstantToken_ = cc.consumes(); + intercalibConstantsToken_ = cc.consumes(); + channelStatusToken_ = cc.consumes(); + laserAPDPNRatiosToken_ = cc.consumes(); + laserAPDPNRatiosRefToken_ = cc.consumes(); + laserAlphasToken_ = cc.consumes(); + linearCorrectionsToken_ = cc.consumes(); + timeCalibConstantsToken_ = cc.consumes(iConfig.getParameter("timeCalibTag")); + timeOffsetConstantToken_ = cc.consumes(iConfig.getParameter("timeOffsetTag")); + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("timeCalibTag", edm::ESInputTag()); + desc.add("timeOffsetTag", edm::ESInputTag()); + desc.add("isPhase2", false); + descriptions.addWithDefaultLabel(desc); + } + + std::unique_ptr produce(EcalRecHitConditionsRcd const& iRecord) { + auto const& adcToGeVConstantData = iRecord.get(adcToGeVConstantToken_); + auto const& intercalibConstantsData = iRecord.get(intercalibConstantsToken_); + auto const& channelStatusData = iRecord.get(channelStatusToken_); + auto const& laserAPDPNRatiosData = iRecord.get(laserAPDPNRatiosToken_); + auto const& laserAPDPNRatiosRefData = iRecord.get(laserAPDPNRatiosRefToken_); + auto const& laserAlphasData = iRecord.get(laserAlphasToken_); + auto const& linearCorrectionsData = iRecord.get(linearCorrectionsToken_); + auto const& timeCalibConstantsData = iRecord.get(timeCalibConstantsToken_); + auto const& timeOffsetConstantData = iRecord.get(timeOffsetConstantToken_); + + const auto barrelSize = channelStatusData.barrelItems().size(); + auto numberOfXtals = barrelSize; + if (!isPhase2_) { + numberOfXtals += channelStatusData.endcapItems().size(); + } + + auto product = std::make_unique(numberOfXtals, cms::alpakatools::host()); + auto view = product->view(); + + // Filling crystal level conditions + auto const& intercalibConstantsEB = intercalibConstantsData.barrelItems(); + auto const& channelStatusEB = channelStatusData.barrelItems(); + auto const& laserAPDPNRatiosLaserEB = laserAPDPNRatiosData.getLaserMap().barrelItems(); + auto const& laserAPDPNRatiosTime = laserAPDPNRatiosData.getTimeMap(); + auto const& laserAPDPNRatiosRefEB = laserAPDPNRatiosRefData.barrelItems(); + auto const& laserAlphasEB = laserAlphasData.barrelItems(); + auto const& linearCorrectionsEB = linearCorrectionsData.getValueMap().barrelItems(); + auto const& linearCorrectionsTime = linearCorrectionsData.getTimeMap(); + auto const& timeCalibConstantsEB = timeCalibConstantsData.barrelItems(); + + // barrel conditions + for (unsigned int i = 0; i < barrelSize; ++i) { + auto vi = view[i]; + + vi.intercalibConstants() = intercalibConstantsEB[i]; + vi.channelStatus() = channelStatusEB[i].getEncodedStatusCode(); + + vi.laserAPDPNRatios_p1() = laserAPDPNRatiosLaserEB[i].p1; + vi.laserAPDPNRatios_p2() = laserAPDPNRatiosLaserEB[i].p2; + vi.laserAPDPNRatios_p3() = laserAPDPNRatiosLaserEB[i].p3; + + vi.laserAPDPNref() = laserAPDPNRatiosRefEB[i]; + vi.laserAlpha() = laserAlphasEB[i]; + + vi.linearCorrections_p1() = linearCorrectionsEB[i].p1; + vi.linearCorrections_p2() = linearCorrectionsEB[i].p2; + vi.linearCorrections_p3() = linearCorrectionsEB[i].p3; + + vi.timeCalibConstants() = timeCalibConstantsEB[i]; + } // end Barrel loop + + // time maps + for (unsigned int i = 0; i < laserAPDPNRatiosData.getTimeMap().size(); ++i) { + auto vi = view[i]; + vi.laserAPDPNRatios_t1() = laserAPDPNRatiosTime[i].t1.value(); + vi.laserAPDPNRatios_t2() = laserAPDPNRatiosTime[i].t2.value(); + vi.laserAPDPNRatios_t3() = laserAPDPNRatiosTime[i].t3.value(); + } + + for (unsigned int i = 0; i < linearCorrectionsData.getTimeMap().size(); ++i) { + auto vi = view[i]; + vi.linearCorrections_t1() = linearCorrectionsTime[i].t1.value(); + vi.linearCorrections_t2() = linearCorrectionsTime[i].t2.value(); + vi.linearCorrections_t3() = linearCorrectionsTime[i].t3.value(); + } + + // scalar data + // ADC to GeV constants + view.adcToGeVConstantEB() = adcToGeVConstantData.getEBValue(); + + // time offset constants + view.timeOffsetConstantEB() = timeOffsetConstantData.getEBValue(); + + // endcap conditions + if (!isPhase2_) { + auto const& intercalibConstantsEE = intercalibConstantsData.endcapItems(); + auto const& channelStatusEE = channelStatusData.endcapItems(); + auto const& laserAPDPNRatiosLaserEE = laserAPDPNRatiosData.getLaserMap().endcapItems(); + auto const& laserAPDPNRatiosRefEE = laserAPDPNRatiosRefData.endcapItems(); + auto const& laserAlphasEE = laserAlphasData.endcapItems(); + auto const& linearCorrectionsEE = linearCorrectionsData.getValueMap().endcapItems(); + auto const& timeCalibConstantsEE = timeCalibConstantsData.endcapItems(); + + const auto endcapSize = channelStatusData.endcapItems().size(); + for (unsigned int i = 0; i < endcapSize; ++i) { + auto vi = view[barrelSize + i]; + + vi.intercalibConstants() = intercalibConstantsEE[i]; + vi.channelStatus() = channelStatusEE[i].getEncodedStatusCode(); + + vi.laserAPDPNRatios_p1() = laserAPDPNRatiosLaserEE[i].p1; + vi.laserAPDPNRatios_p2() = laserAPDPNRatiosLaserEE[i].p2; + vi.laserAPDPNRatios_p3() = laserAPDPNRatiosLaserEE[i].p3; + + vi.laserAPDPNref() = laserAPDPNRatiosRefEE[i]; + vi.laserAlpha() = laserAlphasEE[i]; + + vi.linearCorrections_p1() = linearCorrectionsEE[i].p1; + vi.linearCorrections_p2() = linearCorrectionsEE[i].p2; + vi.linearCorrections_p3() = linearCorrectionsEE[i].p3; + + vi.timeCalibConstants() = timeCalibConstantsEE[i]; + } // end Endcap loop + + // scalar data + // ADC to GeV constants + view.adcToGeVConstantEE() = adcToGeVConstantData.getEEValue(); + + // time offset constants + view.timeOffsetConstantEE() = timeOffsetConstantData.getEEValue(); + } + + // number of barrel items as offset for hashed ID access to EE items of columns + view.offsetEE() = barrelSize; + + return product; + } + + private: + edm::ESGetToken adcToGeVConstantToken_; + edm::ESGetToken intercalibConstantsToken_; + edm::ESGetToken channelStatusToken_; + edm::ESGetToken laserAPDPNRatiosToken_; + edm::ESGetToken laserAPDPNRatiosRefToken_; + edm::ESGetToken laserAlphasToken_; + edm::ESGetToken linearCorrectionsToken_; + edm::ESGetToken timeCalibConstantsToken_; + edm::ESGetToken timeOffsetConstantToken_; + + bool const isPhase2_; + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +DEFINE_FWK_EVENTSETUP_ALPAKA_MODULE(EcalRecHitConditionsHostESProducer); diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitParametersHostESProducer.cc b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitParametersHostESProducer.cc new file mode 100644 index 0000000000000..e4374445a79a2 --- /dev/null +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitParametersHostESProducer.cc @@ -0,0 +1,97 @@ +#include "CommonTools/Utils/interface/StringToEnumValue.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "CondFormats/DataRecord/interface/EcalRecHitParametersRcd.h" +#include "CondFormats/EcalObjects/interface/EcalChannelStatusCode.h" +#include "CondFormats/EcalObjects/interface/EcalRecHitParametersSoA.h" +#include "CondFormats/EcalObjects/interface/alpaka/EcalRecHitParametersDevice.h" + +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESProducer.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ModuleFactory.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/host.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + class EcalRecHitParametersHostESProducer : public ESProducer { + public: + EcalRecHitParametersHostESProducer(edm::ParameterSet const&); + ~EcalRecHitParametersHostESProducer() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions&); + std::unique_ptr produce(EcalRecHitParametersRcd const&); + + private: + std::bitset channelStatusCodesToBeExcluded_; + RecoFlagBitsArray recoFlagBitsArray_; + }; + + EcalRecHitParametersHostESProducer::EcalRecHitParametersHostESProducer(edm::ParameterSet const& iConfig) + : ESProducer(iConfig), recoFlagBitsArray_() { + setWhatProduced(this); + + // Translate string representation of ChannelStatusToBeExcluded to enum values and pack into bitset + auto const& channelStatusToBeExcluded = StringToEnumValue( + iConfig.getParameter>("ChannelStatusToBeExcluded")); + for (auto const& st : channelStatusToBeExcluded) { + channelStatusCodesToBeExcluded_.set(st); + } + + // Generate map of channel status codes and corresponding recoFlag bits + auto const& fmdbRecoPset = iConfig.getParameter("flagsMapDBReco"); + auto const& recoFlagStrings = fmdbRecoPset.getParameterNames(); + for (auto const& recoFlagString : recoFlagStrings) { + auto const recoFlag = static_cast(StringToEnumValue(recoFlagString)); + auto const& channelStatusCodeStrings = fmdbRecoPset.getParameter>(recoFlagString); + for (auto const& channelStatusCodeString : channelStatusCodeStrings) { + auto const chStatCode = StringToEnumValue(channelStatusCodeString); + // set recoFlagBits for this channel status code + recoFlagBitsArray_.at(chStatCode) = static_cast(recoFlag); + } + } + } + + void EcalRecHitParametersHostESProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + // channel statuses to be exluded from reconstruction + desc.add>("ChannelStatusToBeExcluded", + {"kDAC", + "kNoisy", + "kNNoisy", + "kFixedG6", + "kFixedG1", + "kFixedG0", + "kNonRespondingIsolated", + "kDeadVFE", + "kDeadFE", + "kNoDataNoTP"}); + + // reco flags association to channel status flags + edm::ParameterSetDescription psd0; + psd0.add>("kGood", {"kOk", "kDAC", "kNoLaser", "kNoisy"}); + psd0.add>("kNeighboursRecovered", {"kFixedG0", "kNonRespondingIsolated", "kDeadVFE"}); + psd0.add>("kDead", {"kNoDataNoTP"}); + psd0.add>("kNoisy", {"kNNoisy", "kFixedG6", "kFixedG1"}); + psd0.add>("kTowerRecovered", {"kDeadFE"}); + desc.add("flagsMapDBReco", psd0); + + descriptions.addWithDefaultLabel(desc); + } + + std::unique_ptr EcalRecHitParametersHostESProducer::produce( + EcalRecHitParametersRcd const& iRecord) { + size_t const sizeone = 1; + auto product = std::make_unique(sizeone, cms::alpakatools::host()); + auto view = product->view(); + + std::memcpy(view.recoFlagBits().data(), recoFlagBitsArray_.data(), sizeof(uint32_t) * recoFlagBitsArray_.size()); + + view.channelStatusCodesToBeExcluded() = channelStatusCodesToBeExcluded_; + + return product; + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +DEFINE_FWK_EVENTSETUP_ALPAKA_MODULE(EcalRecHitParametersHostESProducer); diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitProducerPortable.cc b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitProducerPortable.cc new file mode 100644 index 0000000000000..6d98945fc700f --- /dev/null +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalRecHitProducerPortable.cc @@ -0,0 +1,179 @@ +#include "CondFormats/DataRecord/interface/EcalRecHitConditionsRcd.h" +#include "CondFormats/DataRecord/interface/EcalRecHitParametersRcd.h" +#include "CondFormats/EcalObjects/interface/alpaka/EcalRecHitConditionsDevice.h" +#include "CondFormats/EcalObjects/interface/alpaka/EcalRecHitParametersDevice.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHit.h" +#include "DataFormats/EcalRecHit/interface/RecoTypes.h" +#include "DataFormats/EcalRecHit/interface/alpaka/EcalUncalibratedRecHitDeviceCollection.h" +#include "DataFormats/EcalRecHit/interface/alpaka/EcalRecHitDeviceCollection.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/EmptyGroupDescription.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EDGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EDPutToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/Event.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EventSetup.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" + +#include "DeclsForKernels.h" +#include "EcalRecHitBuilder.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + class EcalRecHitProducerPortable : public stream::EDProducer<> { + public: + explicit EcalRecHitProducerPortable(edm::ParameterSet const& ps); + ~EcalRecHitProducerPortable() override = default; + static void fillDescriptions(edm::ConfigurationDescriptions&); + + void produce(device::Event&, device::EventSetup const&) override; + + private: + bool const isPhase2_; + // input + using InputProduct = EcalUncalibratedRecHitDeviceCollection; + const device::EDGetToken uncalibRecHitsTokenEB_; + const device::EDGetToken uncalibRecHitsTokenEE_; + // output + using OutputProduct = EcalRecHitDeviceCollection; + const device::EDPutToken recHitsTokenEB_; + device::EDPutToken recHitsTokenEE_; + + // configuration parameters + ecal::rechit::ConfigurationParameters configParameters_; + + // conditions tokens + const device::ESGetToken recHitConditionsToken_; + const device::ESGetToken recHitParametersToken_; + }; + + void EcalRecHitProducerPortable::fillDescriptions(edm::ConfigurationDescriptions& confDesc) { + edm::ParameterSetDescription desc; + + desc.add("uncalibrecHitsInLabelEB", + edm::InputTag("ecalMultiFitUncalibRecHitPortable", "EcalUncalibRecHitsEB")); + desc.add("recHitsLabelEB", "EcalRecHitsEB"); + desc.add("killDeadChannels", true); + desc.add("recoverEBIsolatedChannels", false); + desc.add("recoverEBVFE", false); + desc.add("recoverEBFE", true); + + desc.add("EBLaserMIN", 0.5); + desc.add("EBLaserMAX", 3.0); + + desc.ifValue(edm::ParameterDescription("isPhase2", false, true), + false >> (edm::ParameterDescription( + "uncalibrecHitsInLabelEE", + edm::InputTag("ecalMultiFitUncalibRecHitPortable", "EcalUncalibRecHitsEE"), + true) and + edm::ParameterDescription("recHitsLabelEE", "EcalRecHitsEE", true) and + edm::ParameterDescription("recoverEEIsolatedChannels", false, true) and + edm::ParameterDescription("recoverEEVFE", false, true) and + edm::ParameterDescription("recoverEEFE", true, true) and + edm::ParameterDescription("EELaserMIN", 0.5, true) and + edm::ParameterDescription("EELaserMAX", 8.0, true)) or + true >> edm::EmptyGroupDescription()); + + confDesc.addWithDefaultLabel(desc); + } + + EcalRecHitProducerPortable::EcalRecHitProducerPortable(const edm::ParameterSet& ps) + : isPhase2_{ps.getParameter("isPhase2")}, + uncalibRecHitsTokenEB_{consumes(ps.getParameter("uncalibrecHitsInLabelEB"))}, + uncalibRecHitsTokenEE_{isPhase2_ ? device::EDGetToken{} + : consumes(ps.getParameter("uncalibrecHitsInLabelEE"))}, + recHitsTokenEB_{produces(ps.getParameter("recHitsLabelEB"))}, + recHitConditionsToken_{esConsumes()}, + recHitParametersToken_{esConsumes()} { + if (!isPhase2_) { + recHitsTokenEE_ = produces(ps.getParameter("recHitsLabelEE")); + } + configParameters_.killDeadChannels = ps.getParameter("killDeadChannels"); + configParameters_.EBLaserMIN = ps.getParameter("EBLaserMIN"); + configParameters_.EELaserMIN = isPhase2_ ? 0. : ps.getParameter("EELaserMIN"); + configParameters_.EBLaserMAX = ps.getParameter("EBLaserMAX"); + configParameters_.EELaserMAX = isPhase2_ ? 0. : ps.getParameter("EELaserMAX"); + + // do not propagate channels with these flags on + uint32_t flagmask = 0; + flagmask |= 0x1 << EcalRecHit::kNeighboursRecovered; + flagmask |= 0x1 << EcalRecHit::kTowerRecovered; + flagmask |= 0x1 << EcalRecHit::kDead; + flagmask |= 0x1 << EcalRecHit::kKilled; + flagmask |= 0x1 << EcalRecHit::kTPSaturated; + flagmask |= 0x1 << EcalRecHit::kL1SpikeFlag; + configParameters_.flagmask = flagmask; + + // for recovery and killing + configParameters_.recoverEBIsolatedChannels = ps.getParameter("recoverEBIsolatedChannels"); + configParameters_.recoverEEIsolatedChannels = + isPhase2_ ? false : ps.getParameter("recoverEEIsolatedChannels"); + configParameters_.recoverEBVFE = ps.getParameter("recoverEBVFE"); + configParameters_.recoverEEVFE = isPhase2_ ? false : ps.getParameter("recoverEEVFE"); + configParameters_.recoverEBFE = ps.getParameter("recoverEBFE"); + configParameters_.recoverEEFE = isPhase2_ ? false : ps.getParameter("recoverEEFE"); + } + + void EcalRecHitProducerPortable::produce(device::Event& event, device::EventSetup const& setup) { + auto& queue = event.queue(); + + // get device collections from event + auto const* uncalibRecHitsDevEB = &event.get(uncalibRecHitsTokenEB_); + auto const* uncalibRecHitsDevEE = isPhase2_ ? nullptr : &event.get(uncalibRecHitsTokenEE_); + + // get the size of the input collections from the metadata + auto const uncalibRecHitsSizeEB = uncalibRecHitsDevEB->const_view().metadata().size(); + auto const uncalibRecHitsSizeEE = isPhase2_ ? 0 : uncalibRecHitsDevEE->const_view().metadata().size(); + + // output device collections with the same size than the input collections + auto recHitsDevEB = std::make_unique(uncalibRecHitsSizeEB, queue); + auto recHitsDevEE = + isPhase2_ ? std::unique_ptr() : std::make_unique(uncalibRecHitsSizeEE, queue); + // reset the size scalar of the SoA + // memset takes an alpaka view that is created from the scalar in a view to the portable device collection + auto recHitSizeViewEB = + cms::alpakatools::make_device_view(alpaka::getDev(queue), recHitsDevEB->view().size()); + alpaka::memset(queue, recHitSizeViewEB, 0); + + if (!isPhase2_) { + auto recHitSizeViewEE = + cms::alpakatools::make_device_view(alpaka::getDev(queue), recHitsDevEE->view().size()); + alpaka::memset(queue, recHitSizeViewEE, 0); + } + + // stop here if there are no uncalibrated rechits + if (uncalibRecHitsSizeEB + uncalibRecHitsSizeEE > 0) { + // to get the event time from device::Event one has to access the underlying edm::Event + auto const& eventTime = static_cast(event).time().value(); + + // conditions + auto const& recHitConditionsDev = setup.getData(recHitConditionsToken_); + auto const& recHitParametersDev = setup.getData(recHitParametersToken_); + + // + // schedule algorithms + // + ecal::rechit::create_ecal_rechit(queue, + uncalibRecHitsDevEB, + uncalibRecHitsDevEE, + *recHitsDevEB, + *recHitsDevEE, + recHitConditionsDev, + recHitParametersDev, + eventTime, + configParameters_, + isPhase2_); + } + + // put collections into the event + event.put(recHitsTokenEB_, std::move(recHitsDevEB)); + if (!isPhase2_) { + event.put(recHitsTokenEE_, std::move(recHitsDevEE)); + } + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/MakerMacros.h" +DEFINE_FWK_ALPAKA_MODULE(EcalRecHitProducerPortable); diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EnergyComputationKernels.h b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EnergyComputationKernels.h new file mode 100644 index 0000000000000..4fc7e07c706d9 --- /dev/null +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/EnergyComputationKernels.h @@ -0,0 +1,486 @@ +#ifndef RecoLocalCalo_EcalRecProducers_plugins_alpaka_EnergyComputationKernels_h +#define RecoLocalCalo_EcalRecProducers_plugins_alpaka_EnergyComputationKernels_h + +#include + +#include "CondFormats/EcalObjects/interface/EcalChannelStatusCode.h" +#include "DataFormats/EcalDetId/interface/EcalSubdetector.h" +#include "DataFormats/EcalDigi/interface/EcalConstants.h" +#include "DataFormats/EcalRecHit/interface/EcalRecHit.h" +#include "DataFormats/EcalRecHit/interface/EcalUncalibratedRecHit.h" + +#include "KernelHelpers.h" + +//#define DEBUG +//#define ECAL_RECO_ALPAKA_DEBUG + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::rechit { + + using namespace cms::alpakatools; + + ALPAKA_STATIC_ACC_MEM_CONSTANT constexpr float ip10[] = { + 1.e5f, 1.e4f, 1.e3f, 1.e2f, 1.e1f, 1.e0f, 1.e-1f, 1.e-2f, 1.e-3f, 1.e-4}; + + ALPAKA_FN_ACC ALPAKA_FN_INLINE bool checkUncalibRecHitFlag(uint32_t const& flags, + EcalUncalibratedRecHit::Flags flag) { + return flags & (0x1 << flag); + } + + ALPAKA_FN_ACC ALPAKA_FN_INLINE void setFlag(uint32_t& flags, EcalRecHit::Flags flag) { flags |= (0x1 << flag); } + + ALPAKA_FN_ACC void makeRecHit(int const inputCh, + uint32_t const* didCh, + float const* amplitude, + float const* amplitudeError, + float const* jitter, + uint32_t const* aux, + float const* chi2_in, + uint32_t const* flags_in, + uint32_t* did, + float* energy, + float* time, + uint32_t* flagBits, + uint32_t* extra, + EcalRecHitConditionsDevice::ConstView conditionsDev, + EcalRecHitParametersDevice::ConstView parametersDev, + // time, used for time dependent corrections + edm::TimeValue_t const& eventTime, + // configuration + bool const isPhase2, + bool const killDeadChannels, + bool const recoverIsolatedChannels, + bool const recoverVFE, + bool const recoverFE, + float const laserMIN, + float const laserMAX, + uint32_t flagmask) { + // simple copy of input det id to output + did[inputCh] = didCh[inputCh]; + + auto const did_to_use = DetId{didCh[inputCh]}; + + auto const isBarrel = did_to_use.subdetId() == EcalBarrel; + auto const hashedId = isBarrel ? ecal::reconstruction::hashedIndexEB(did_to_use.rawId()) + : conditionsDev.offsetEE() + ecal::reconstruction::hashedIndexEE(did_to_use.rawId()); + + auto const intercalib = conditionsDev.intercalibConstants()[hashedId]; + + // only two values for ADC to GeV, EB or EE + auto const adc2gev_to_use = isBarrel ? conditionsDev.adcToGeVConstantEB() : conditionsDev.adcToGeVConstantEE(); + + auto const timeCalib = conditionsDev.timeCalibConstants()[hashedId]; + auto const timeOffset = isBarrel ? conditionsDev.timeOffsetConstantEB() : conditionsDev.timeOffsetConstantEE(); + + int iLM = 1; + if (isBarrel) { + iLM = ecal::reconstruction::laserMonitoringRegionEB(did_to_use.rawId()); + } else { + iLM = ecal::reconstruction::laserMonitoringRegionEE(did_to_use.rawId()); + } + + long long t_i = 0, t_f = 0; + float p_i = 0, p_f = 0; + auto const t1 = conditionsDev.laserAPDPNRatios_t1()[iLM - 1]; + auto const t2 = conditionsDev.laserAPDPNRatios_t2()[iLM - 1]; + auto const t3 = conditionsDev.laserAPDPNRatios_t3()[iLM - 1]; + auto const p1 = conditionsDev.laserAPDPNRatios_p1()[hashedId]; + auto const p2 = conditionsDev.laserAPDPNRatios_p2()[hashedId]; + auto const p3 = conditionsDev.laserAPDPNRatios_p3()[hashedId]; + + // laser + if (eventTime >= t1 && eventTime < t2) { + t_i = t1; + t_f = t2; + p_i = p1; + p_f = p2; + } else if (eventTime >= t2 && eventTime <= t3) { + t_i = t2; + t_f = t3; + p_i = p2; + p_f = p3; + } else if (eventTime < t1) { + t_i = t1; + t_f = t2; + p_i = p1; + p_f = p2; + } else if (eventTime > t3) { + t_i = t2; + t_f = t3; + p_i = p2; + p_f = p3; + } + + long long lt_i = 0, lt_f = 0; + float lp_i = 0, lp_f = 0; + auto const lt1 = conditionsDev.linearCorrections_t1()[iLM - 1]; + auto const lt2 = conditionsDev.linearCorrections_t2()[iLM - 1]; + auto const lt3 = conditionsDev.linearCorrections_t3()[iLM - 1]; + auto const lp1 = conditionsDev.linearCorrections_p1()[hashedId]; + auto const lp2 = conditionsDev.linearCorrections_p2()[hashedId]; + auto const lp3 = conditionsDev.linearCorrections_p3()[hashedId]; + + // linear corrections + if (eventTime >= lt1 && eventTime < lt2) { + lt_i = lt1; + lt_f = lt2; + lp_i = lp1; + lp_f = lp2; + } else if (eventTime >= lt2 && eventTime <= lt3) { + lt_i = lt2; + lt_f = lt3; + lp_i = lp2; + lp_f = lp3; + } else if (eventTime < lt1) { + lt_i = lt1; + lt_f = lt2; + lp_i = lp1; + lp_f = lp2; + } else if (eventTime > lt3) { + lt_i = lt2; + lt_f = lt3; + lp_i = lp2; + lp_f = lp3; + } + + // apdpnref and alpha + auto const apdpnref = conditionsDev.laserAPDPNref()[hashedId]; + auto const alpha = conditionsDev.laserAlpha()[hashedId]; + + // now calculate transparency correction + float lasercalib = 1.; + if (apdpnref != 0 && (t_i - t_f) != 0 && (lt_i - lt_f) != 0) { + long long tt = eventTime; // never subtract two unsigned! + auto const interpolatedLaserResponse = + p_i / apdpnref + static_cast(tt - t_i) * (p_f - p_i) / (apdpnref * static_cast(t_f - t_i)); + + auto interpolatedLinearResponse = + lp_i / apdpnref + + static_cast(tt - lt_i) * (lp_f - lp_i) / (apdpnref * static_cast(lt_f - lt_i)); // FIXED BY FC + + if (interpolatedLinearResponse > 2.f || interpolatedLinearResponse < 0.1f) { + interpolatedLinearResponse = 1.f; + } + if (interpolatedLaserResponse <= 0.) { + lasercalib = 1.; + } else { + auto const interpolatedTransparencyResponse = interpolatedLaserResponse / interpolatedLinearResponse; + lasercalib = 1.f / (std::pow(interpolatedTransparencyResponse, alpha) * interpolatedLinearResponse); + } + } + + // + // Check for channels to be excluded from reconstruction + // + // Default energy not to be updated if "channelStatusToBeExcluded" + energy[inputCh] = -1.; //un-physical default + + // default values for the flags + flagBits[inputCh] = 0; + extra[inputCh] = 0; + + auto const dbChStatus = static_cast(conditionsDev.channelStatus()[hashedId] & + EcalChannelStatusCode::chStatusMask); + auto const& exclChStatCodes = parametersDev.channelStatusCodesToBeExcluded(); + if (exclChStatCodes[dbChStatus]) { + // skip the channel if the channel status bit is set and should be excluded + return; + } + + // Take our association map of dbChStatuses-> recHit flagbits and return the appropriate flagbit word + auto const& recoFlagBits = parametersDev.recoFlagBits()[dbChStatus]; + flagBits[inputCh] = recoFlagBits; + + if ((flagmask & recoFlagBits) && killDeadChannels) { + // skip this channel + return; + } + + // + // multiply the adc counts with factors to get the energy in GeV + // + energy[inputCh] = amplitude[inputCh] * adc2gev_to_use * intercalib * lasercalib; + + // time + auto const sampPeriod = isPhase2 ? ecalPh2::Samp_Period : ecalPh1::Samp_Period; + time[inputCh] = jitter[inputCh] * sampPeriod + timeCalib + timeOffset; + + // NB: calculate the "flagBits extra" --> not really "flags", but actually an encoded version of energy uncertainty, time unc., ... + + // + // extra packing ... + // + uint32_t extravar = 0; + + // chi2 + // truncate + auto const chi2 = chi2_in[inputCh] > 64 ? 64 : chi2_in[inputCh]; + // use 7 bits + uint32_t const rawChi2 = lround(chi2 / 64. * ((1 << 7) - 1)); + extravar = ecal::reconstruction::rechitSetMasked(extravar, rawChi2, 0, 7); + + // energy uncertainty (amplitudeError is currently not set in the portable uncalibrated rec hit producer) + auto const energyError = amplitudeError[inputCh] * adc2gev_to_use * intercalib * lasercalib; + uint32_t rawEnergy = 0; + if (energyError > 0.001) { + uint16_t const exponent = static_cast(ecal::reconstruction::rechitGetPower10(energyError)); + uint16_t significand = lround(energyError * ip10[exponent]); + // use 13 bits (3 exponent, 10 significand) + rawEnergy = exponent << 10 | significand; + } + extravar = ecal::reconstruction::rechitSetMasked(extravar, rawEnergy, 8, 13); + + // time uncertainty directly from uncalib rechit (the jitter error is currently not stored in aux in the portable uncalibrated rec hit producer) + uint8_t const timeErrBits = aux[inputCh] & 0xFF; + extravar = ecal::reconstruction::rechitSetMasked(extravar, timeErrBits, 24, 8); + + // + // set output extra variable + // + extra[inputCh] = extravar; + + // + // additional flags setting + // using correctly the flags as calculated at the UncalibRecHit stage + // + bool good = true; + if (checkUncalibRecHitFlag(flags_in[inputCh], EcalUncalibratedRecHit::Flags::kLeadingEdgeRecovered)) { + setFlag(flagBits[inputCh], EcalRecHit::Flags::kLeadingEdgeRecovered); + good = false; + } + if (checkUncalibRecHitFlag(flags_in[inputCh], EcalUncalibratedRecHit::Flags::kSaturated)) { + // leading edge recovery failed - still keep the information + // about the saturation and do not flag as dead + setFlag(flagBits[inputCh], EcalRecHit::Flags::kSaturated); + good = false; + } + if (checkUncalibRecHitFlag(flags_in[inputCh], EcalUncalibratedRecHit::Flags::kOutOfTime)) { + setFlag(flagBits[inputCh], EcalRecHit::Flags::kOutOfTime); + good = false; + } + if (checkUncalibRecHitFlag(flags_in[inputCh], EcalUncalibratedRecHit::Flags::kPoorReco)) { + setFlag(flagBits[inputCh], EcalRecHit::Flags::kPoorReco); + good = false; + } + if (checkUncalibRecHitFlag(flags_in[inputCh], EcalUncalibratedRecHit::Flags::kHasSwitchToGain6)) { + setFlag(flagBits[inputCh], EcalRecHit::Flags::kHasSwitchToGain6); + } + if (checkUncalibRecHitFlag(flags_in[inputCh], EcalUncalibratedRecHit::Flags::kHasSwitchToGain1)) { + setFlag(flagBits[inputCh], EcalRecHit::Flags::kHasSwitchToGain1); + } + + if (good) { + setFlag(flagBits[inputCh], EcalRecHit::Flags::kGood); + } + + if (lasercalib < laserMIN || lasercalib > laserMAX) { + setFlag(flagBits[inputCh], EcalRecHit::Flags::kPoorCalib); + } + + // recover, killing, and other stuff + // + // Structure: + // EB + // EE + // + // - single MVA + // - democratic sharing + // - kill all the other cases + + // recoverable channel status codes + if (dbChStatus == EcalChannelStatusCode::Code::kFixedG0 || + dbChStatus == EcalChannelStatusCode::Code::kNonRespondingIsolated || + dbChStatus == EcalChannelStatusCode::Code::kDeadVFE) { + bool is_Single = false; + bool is_FE = false; + bool is_VFE = false; + + if (dbChStatus == EcalChannelStatusCode::Code::kDeadVFE) { + is_VFE = true; + } else if (dbChStatus == EcalChannelStatusCode::Code::kDeadFE) { + is_FE = true; + } else { + is_Single = true; + } + + // EB + if (isBarrel) { + if (is_Single || is_FE || is_VFE) { + if (is_Single && (recoverIsolatedChannels || !killDeadChannels)) { + // single MVA + // TODO + } else if (is_FE && (recoverFE || !killDeadChannels)) { + // democratic sharing + // TODO + } else { + // kill all the other cases + energy[inputCh] = 0.; + // TODO: set flags + } + } + } else { // EE + if (is_Single || is_FE || is_VFE) { + if (is_Single && (recoverIsolatedChannels || !killDeadChannels)) { + // single MVA + // TODO + } else if (is_FE && (recoverFE || !killDeadChannels)) { + // democratic sharing + // TODO + } else { + // kill all the other cases + energy[inputCh] = 0.; + // TODO: set flags + } + } + } + } + } + + class KernelCreateEcalRechitPhase2 { + public: + template >> + ALPAKA_FN_ACC void operator()(TAcc const& acc, + EcalUncalibratedRecHitDeviceCollection::ConstView uncalibRecHits, + EcalRecHitDeviceCollection::View recHits, + EcalRecHitConditionsDevice::ConstView conditionsDev, + EcalRecHitParametersDevice::ConstView parametersDev, + // time, used for time dependent corrections + edm::TimeValue_t const& eventTime, + // configuration + bool const killDeadChannels, + bool const recoverIsolatedChannels, + bool const recoverVFE, + bool const recoverFE, + float const laserMIN, + float const laserMAX, + uint32_t flagmask) const { + auto const nchannels = uncalibRecHits.size(); + + for (auto ch : cms::alpakatools::uniform_elements(acc, nchannels)) { + // set the output collection size scalar + if (ch == 0) { + recHits.size() = nchannels; + } + + makeRecHit(ch, + uncalibRecHits.id(), + uncalibRecHits.amplitude(), + uncalibRecHits.amplitudeError(), + uncalibRecHits.jitter(), + uncalibRecHits.aux(), + uncalibRecHits.chi2(), + uncalibRecHits.flags(), + recHits.id(), + recHits.energy(), + recHits.time(), + recHits.flagBits(), + recHits.extra(), + conditionsDev, + parametersDev, + eventTime, + true, + killDeadChannels, + recoverIsolatedChannels, + recoverVFE, + recoverFE, + laserMIN, + laserMAX, + flagmask); + + } // end channel + } + }; + + class KernelCreateEcalRechit { + public: + template >> + ALPAKA_FN_ACC void operator()(TAcc const& acc, + EcalUncalibratedRecHitDeviceCollection::ConstView ebUncalibRecHits, + EcalUncalibratedRecHitDeviceCollection::ConstView eeUncalibRecHits, + EcalRecHitDeviceCollection::View ebRecHits, + EcalRecHitDeviceCollection::View eeRecHits, + EcalRecHitConditionsDevice::ConstView conditionsDev, + EcalRecHitParametersDevice::ConstView parametersDev, + // time, used for time dependent corrections + edm::TimeValue_t const& eventTime, + // configuration + bool const killDeadChannels, + bool const recoverEBIsolatedChannels, + bool const recoverEEIsolatedChannels, + bool const recoverEBVFE, + bool const recoverEEVFE, + bool const recoverEBFE, + bool const recoverEEFE, + float const EBLaserMIN, + float const EELaserMIN, + float const EBLaserMAX, + float const EELaserMAX, + uint32_t flagmask) const { + auto const nchannelsEB = ebUncalibRecHits.size(); + auto const nchannelsEE = eeUncalibRecHits.size(); + auto const nchannels = nchannelsEB + nchannelsEE; + + for (auto ch : cms::alpakatools::uniform_elements(acc, nchannels)) { + // set the output collection size scalars + if (ch == 0) { + ebRecHits.size() = nchannelsEB; + } else if (ch == nchannelsEB) { + eeRecHits.size() = nchannelsEE; + } + + bool const isEndcap = ch >= nchannelsEB; + int const inputCh = isEndcap ? ch - nchannelsEB : ch; + + // inputs + auto const* didCh = isEndcap ? eeUncalibRecHits.id() : ebUncalibRecHits.id(); + auto const* amplitude = isEndcap ? eeUncalibRecHits.amplitude() : ebUncalibRecHits.amplitude(); + auto const* amplitudeError = isEndcap ? eeUncalibRecHits.amplitudeError() : ebUncalibRecHits.amplitudeError(); + auto const* jitter = isEndcap ? eeUncalibRecHits.jitter() : ebUncalibRecHits.jitter(); + auto const* aux = isEndcap ? eeUncalibRecHits.aux() : ebUncalibRecHits.aux(); + auto const* chi2_in = isEndcap ? eeUncalibRecHits.chi2() : ebUncalibRecHits.chi2(); + auto const* flags_in = isEndcap ? eeUncalibRecHits.flags() : ebUncalibRecHits.flags(); + + // outputs + auto* did = isEndcap ? eeRecHits.id() : ebRecHits.id(); + auto* energy = isEndcap ? eeRecHits.energy() : ebRecHits.energy(); + auto* time = isEndcap ? eeRecHits.time() : ebRecHits.time(); + auto* flagBits = isEndcap ? eeRecHits.flagBits() : ebRecHits.flagBits(); + auto* extra = isEndcap ? eeRecHits.extra() : ebRecHits.extra(); + + bool const recoverIsolatedChannels = isEndcap ? recoverEEIsolatedChannels : recoverEBIsolatedChannels; + bool const recoverVFE = isEndcap ? recoverEEVFE : recoverEBVFE; + bool const recoverFE = isEndcap ? recoverEEFE : recoverEBFE; + float const laserMIN = isEndcap ? EELaserMIN : EBLaserMIN; + float const laserMAX = isEndcap ? EELaserMAX : EBLaserMAX; + + makeRecHit(inputCh, + didCh, + amplitude, + amplitudeError, + jitter, + aux, + chi2_in, + flags_in, + did, + energy, + time, + flagBits, + extra, + conditionsDev, + parametersDev, + eventTime, + false, + killDeadChannels, + recoverIsolatedChannels, + recoverVFE, + recoverFE, + laserMIN, + laserMAX, + flagmask); + + } // end channel + } + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::rechit + +#endif // RecoLocalCalo_EcalRecProducers_plugins_alpaka_EnergyComputationKernels_h diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/KernelHelpers.dev.cc b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/KernelHelpers.dev.cc index 906b96fa2b6b6..4b07b170c6f01 100644 --- a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/KernelHelpers.dev.cc +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/KernelHelpers.dev.cc @@ -272,4 +272,22 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::reconstruction { return ilmr; } + ALPAKA_FN_ACC int32_t rechitSetMasked(uint32_t value, uint32_t x, uint32_t offset, uint32_t width) { + const uint32_t mask = ((1 << width) - 1) << offset; + value &= ~mask; + value |= (x & ((1U << width) - 1)) << offset; + return value; + } + + ALPAKA_STATIC_ACC_MEM_CONSTANT constexpr float p10[] = { + 1.e-2f, 1.e-1f, 1.f, 1.e1f, 1.e2f, 1.e3f, 1.e4f, 1.e5f, 1.e6f}; + + ALPAKA_FN_ACC int32_t rechitGetPower10(float e) { + int b = e < p10[4] ? 0 : 5; + for (; b < 9; ++b) + if (e < p10[b]) + break; + return b; + } + } // namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::reconstruction diff --git a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/KernelHelpers.h b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/KernelHelpers.h index 3b1772ecf2981..ab40666add850 100644 --- a/RecoLocalCalo/EcalRecProducers/plugins/alpaka/KernelHelpers.h +++ b/RecoLocalCalo/EcalRecProducers/plugins/alpaka/KernelHelpers.h @@ -14,6 +14,10 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::reconstruction { ALPAKA_FN_ACC int32_t laserMonitoringRegionEE(uint32_t id); + ALPAKA_FN_ACC int32_t rechitSetMasked(uint32_t value, uint32_t x, uint32_t offset, uint32_t width); + + ALPAKA_FN_ACC int32_t rechitGetPower10(float e); + } // namespace ALPAKA_ACCELERATOR_NAMESPACE::ecal::reconstruction #endif // RecoLocalCalo_EcalRecProducers_plugins_alpaka_KernelHelpers_h diff --git a/RecoLocalCalo/EcalRecProducers/python/ecalMultiFitUncalibRecHit_cff.py b/RecoLocalCalo/EcalRecProducers/python/ecalMultiFitUncalibRecHit_cff.py index c6104c21b62db..051dd04a6be02 100644 --- a/RecoLocalCalo/EcalRecProducers/python/ecalMultiFitUncalibRecHit_cff.py +++ b/RecoLocalCalo/EcalRecProducers/python/ecalMultiFitUncalibRecHit_cff.py @@ -103,3 +103,9 @@ # ECAL multifit running on CPU, or convert the uncalibrated rechits from SoA to legacy format ecalMultiFitUncalibRecHit, )) + +# for alpaka validation compare the legacy CPU module with the alpaka module +from Configuration.ProcessModifiers.alpakaValidationEcal_cff import alpakaValidationEcal +alpakaValidationEcal.toModify(ecalMultiFitUncalibRecHit, cpu = ecalMultiFitUncalibRecHitCPU) +alpakaValidationEcal.toModify(ecalMultiFitUncalibRecHit, cuda = _ecalUncalibRecHitSoAToLegacy.clone()) + diff --git a/RecoLocalCalo/EcalRecProducers/python/ecalRecHit_cff.py b/RecoLocalCalo/EcalRecProducers/python/ecalRecHit_cff.py index 71247d33d6063..53b776ac96a13 100644 --- a/RecoLocalCalo/EcalRecProducers/python/ecalRecHit_cff.py +++ b/RecoLocalCalo/EcalRecProducers/python/ecalRecHit_cff.py @@ -4,14 +4,17 @@ # ECAL calibrated rechit reconstruction on CPU from RecoLocalCalo.EcalRecProducers.ecalRecHit_cfi import ecalRecHit as _ecalRecHit +ecalRecHitCPU = _ecalRecHit.clone() ecalRecHit = SwitchProducerCUDA( - cpu = _ecalRecHit.clone() + cpu = ecalRecHitCPU ) ecalCalibratedRecHitTask = cms.Task( ecalRecHit ) +from Configuration.StandardSequences.Accelerators_cff import * + # ECAL rechit calibrations on GPU from RecoLocalCalo.EcalRecProducers.ecalRechitADCToGeVConstantGPUESProducer_cfi import ecalRechitADCToGeVConstantGPUESProducer from RecoLocalCalo.EcalRecProducers.ecalRechitChannelStatusGPUESProducer_cfi import ecalRechitChannelStatusGPUESProducer @@ -65,3 +68,47 @@ # convert the rechits from SoA to legacy format ecalRecHit )) + +# modifications for alpaka +from Configuration.ProcessModifiers.alpaka_cff import alpaka + +# ECAL conditions used by the rechit producer running on the accelerator +from RecoLocalCalo.EcalRecProducers.ecalRecHitConditionsHostESProducer_cfi import ecalRecHitConditionsHostESProducer +from RecoLocalCalo.EcalRecProducers.ecalRecHitParametersHostESProducer_cfi import ecalRecHitParametersHostESProducer + +ecalRecHitParametersSource = cms.ESSource("EmptyESSource", + recordName = cms.string('EcalRecHitParametersRcd'), + iovIsRunNotTime = cms.bool(True), + firstValid = cms.vuint32(1) +) + +# ECAL rechit producer running on the accelerator +from RecoLocalCalo.EcalRecProducers.ecalRecHitProducerPortable_cfi import ecalRecHitProducerPortable as _ecalRecHitProducerPortable +ecalRecHitPortable = _ecalRecHitProducerPortable.clone( + uncalibrecHitsInLabelEB = 'ecalMultiFitUncalibRecHitPortable:EcalUncalibRecHitsEB', + uncalibrecHitsInLabelEE = 'ecalMultiFitUncalibRecHitPortable:EcalUncalibRecHitsEE' +) + +# replace the SwitchProducerCUDA branches with the module to convert the rechits from SoA to legacy format +from RecoLocalCalo.EcalRecProducers.ecalRecHitSoAToLegacy_cfi import ecalRecHitSoAToLegacy as _ecalRecHitSoAToLegacy +# TODO: the portably produced ECAL calibrated rechits correct yet. +# When they are working and validated, remove this comment and uncomment the next lines: +#alpaka.toModify(ecalRecHit, +# cpu = _ecalRecHitSoAToLegacy.clone() +#) + +alpaka.toReplaceWith(ecalCalibratedRecHitTask, cms.Task( + # ECAL conditions and parameters used by the rechit producer running on the accelerator + ecalRecHitConditionsHostESProducer, + ecalRecHitParametersHostESProducer, + # ECAL rechit producer running on device + ecalRecHitPortable, + # ECAL rechit producer running on CPU, or convert the rechits from SoA to legacy format + ecalRecHit, +)) + +# for alpaka validation compare the legacy CPU module with the alpaka module +from Configuration.ProcessModifiers.alpakaValidationEcal_cff import alpakaValidationEcal +alpakaValidationEcal.toModify(ecalRecHit, cpu = ecalRecHitCPU) +alpakaValidationEcal.toModify(ecalRecHit, cuda = _ecalRecHitSoAToLegacy.clone()) +