forked from cms-sw/cmssw
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Heterogeneous Cellular Automaton for pixel tracks
Port the Cellular Automaton (back) to GPUs and CUDA, using the `HeterogeneousEDProducer` approach: - do memory allocations in the framework begin stream - run the memory copies and kernels asynchronously, in a dedicated CUDA stream per framework stream Use the new GPU::VecArray for holding repeated data structures. By default, run on the GPU in all gpu-enable workflows (e.g. 10824.8).
- Loading branch information
1 parent
4f8add0
commit 96559f3
Showing
12 changed files
with
1,945 additions
and
296 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,55 @@ | ||
#ifndef RECOPIXELVERTEXING_PIXELTRIPLETS_CAGRAPH_H_ | ||
#define RECOPIXELVERTEXING_PIXELTRIPLETS_CAGRAPH_H_ | ||
|
||
#include <vector> | ||
#include <array> | ||
#include <string> | ||
#include <vector> | ||
|
||
struct CALayer | ||
{ | ||
CALayer(const std::string& layerName, std::size_t numberOfHits ) | ||
: theName(layerName) | ||
{ | ||
isOuterHitOfCell.resize(numberOfHits); | ||
} | ||
|
||
bool operator==(const std::string& otherString) | ||
{ | ||
return otherString == theName; | ||
} | ||
struct CALayer { | ||
CALayer(const std::string &layerName, std::size_t numberOfHits) | ||
: theName(layerName) { | ||
isOuterHitOfCell.resize(numberOfHits); | ||
} | ||
|
||
std::string name() const | ||
{ | ||
return theName; | ||
} | ||
bool operator==(const std::string &otherString) { | ||
return otherString == theName; | ||
} | ||
|
||
std::vector<int> theOuterLayerPairs; | ||
std::vector<int> theInnerLayerPairs; | ||
const std::string& name() const { return theName; } | ||
|
||
std::vector<int> theOuterLayers; | ||
std::vector<int> theInnerLayers; | ||
std::vector< std::vector<unsigned int> > isOuterHitOfCell; | ||
std::vector<int> theOuterLayerPairs; | ||
std::vector<int> theInnerLayerPairs; | ||
|
||
std::vector<int> theOuterLayers; | ||
std::vector<int> theInnerLayers; | ||
std::vector<std::vector<unsigned int>> isOuterHitOfCell; | ||
|
||
private: | ||
|
||
std::string theName; | ||
std::string theName; | ||
}; | ||
|
||
struct CALayerPair | ||
{ | ||
|
||
CALayerPair(int a, int b) | ||
|
||
{ | ||
theLayers[0] = a; | ||
theLayers[1] = b; | ||
} | ||
struct CALayerPair { | ||
|
||
CALayerPair(int a, int b) | ||
|
||
{ | ||
theLayers[0] = a; | ||
theLayers[1] = b; | ||
} | ||
|
||
bool operator==(const CALayerPair& otherLayerPair) | ||
{ | ||
return (theLayers[0] == otherLayerPair.theLayers[0]) | ||
&& (theLayers[1] == otherLayerPair.theLayers[1]); | ||
} | ||
bool operator==(const CALayerPair &otherLayerPair) { | ||
return (theLayers[0] == otherLayerPair.theLayers[0]) && | ||
(theLayers[1] == otherLayerPair.theLayers[1]); | ||
} | ||
|
||
std::array<int, 2> theLayers; | ||
std::array<unsigned int, 2> theFoundCells= {{0,0}}; | ||
std::array<int, 2> theLayers; | ||
std::array<unsigned int, 2> theFoundCells = {{0, 0}}; | ||
}; | ||
|
||
struct CAGraph | ||
{ | ||
std::vector<CALayer> theLayers; | ||
std::vector<CALayerPair> theLayerPairs; | ||
std::vector<int> theRootLayers; | ||
struct CAGraph { | ||
std::vector<CALayer> theLayers; | ||
std::vector<CALayerPair> theLayerPairs; | ||
std::vector<int> theRootLayers; | ||
}; | ||
|
||
#endif /* CAGRAPH_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
205 changes: 205 additions & 0 deletions
205
RecoPixelVertexing/PixelTriplets/plugins/CAHitNtupletHeterogeneousEDProducer.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
#include "DataFormats/Common/interface/Handle.h" | ||
#include "FWCore/Framework/interface/ConsumesCollector.h" | ||
#include "FWCore/Framework/interface/Event.h" | ||
#include "FWCore/Framework/interface/MakerMacros.h" | ||
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" | ||
#include "FWCore/ParameterSet/interface/ParameterSet.h" | ||
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" | ||
#include "FWCore/PluginManager/interface/ModuleDef.h" | ||
#include "FWCore/Utilities/interface/EDGetToken.h" | ||
#include "FWCore/Utilities/interface/RunningAverage.h" | ||
#include "HeterogeneousCore/CUDACore/interface/GPUCuda.h" | ||
#include "HeterogeneousCore/CUDAServices/interface/CUDAService.h" | ||
#include "HeterogeneousCore/Producer/interface/HeterogeneousEDProducer.h" | ||
|
||
#include "CAHitQuadrupletGenerator.h" | ||
#include "CAHitQuadrupletGeneratorGPU.h" | ||
#include "RecoPixelVertexing/PixelTriplets/interface/OrderedHitSeeds.h" | ||
#include "RecoTracker/TkHitPairs/interface/IntermediateHitDoublets.h" | ||
#include "RecoTracker/TkHitPairs/interface/RegionsSeedingHitSets.h" | ||
|
||
namespace { | ||
void fillNtuplets(RegionsSeedingHitSets::RegionFiller &seedingHitSetsFiller, | ||
const OrderedHitSeeds &quadruplets) { | ||
for (const auto &quad : quadruplets) { | ||
seedingHitSetsFiller.emplace_back(quad[0], quad[1], quad[2], quad[3]); | ||
} | ||
} | ||
} // namespace | ||
|
||
class CAHitNtupletHeterogeneousEDProducer | ||
: public HeterogeneousEDProducer<heterogeneous::HeterogeneousDevices< | ||
heterogeneous::GPUCuda, heterogeneous::CPU>> { | ||
public: | ||
CAHitNtupletHeterogeneousEDProducer(const edm::ParameterSet &iConfig); | ||
~CAHitNtupletHeterogeneousEDProducer() = default; | ||
|
||
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); | ||
void beginStreamGPUCuda(edm::StreamID streamId, | ||
cuda::stream_t<> &cudaStream) override; | ||
|
||
void acquireGPUCuda(const edm::HeterogeneousEvent &iEvent, | ||
const edm::EventSetup &iSetup, | ||
cuda::stream_t<> &cudaStream) override; | ||
void produceGPUCuda(edm::HeterogeneousEvent &iEvent, | ||
const edm::EventSetup &iSetup, | ||
cuda::stream_t<> &cudaStream) override; | ||
void produceCPU(edm::HeterogeneousEvent &iEvent, | ||
const edm::EventSetup &iSetup) override; | ||
|
||
private: | ||
edm::EDGetTokenT<IntermediateHitDoublets> doubletToken_; | ||
|
||
edm::RunningAverage localRA_; | ||
CAHitQuadrupletGeneratorGPU GPUGenerator_; | ||
CAHitQuadrupletGenerator CPUGenerator_; | ||
|
||
bool emptyRegionDoublets = false; | ||
std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_; | ||
std::vector<OrderedHitSeeds> ntuplets_; | ||
}; | ||
|
||
CAHitNtupletHeterogeneousEDProducer::CAHitNtupletHeterogeneousEDProducer( | ||
const edm::ParameterSet &iConfig) | ||
: HeterogeneousEDProducer(iConfig), | ||
doubletToken_(consumes<IntermediateHitDoublets>( | ||
iConfig.getParameter<edm::InputTag>("doublets"))), | ||
GPUGenerator_(iConfig, consumesCollector()), | ||
CPUGenerator_(iConfig, consumesCollector()) { | ||
produces<RegionsSeedingHitSets>(); | ||
} | ||
|
||
void CAHitNtupletHeterogeneousEDProducer::fillDescriptions( | ||
edm::ConfigurationDescriptions &descriptions) { | ||
edm::ParameterSetDescription desc; | ||
|
||
desc.add<edm::InputTag>("doublets", edm::InputTag("hitPairEDProducer")); | ||
CAHitQuadrupletGeneratorGPU::fillDescriptions(desc); | ||
HeterogeneousEDProducer::fillPSetDescription(desc); | ||
auto label = "caHitQuadrupletHeterogeneousEDProducer"; | ||
descriptions.add(label, desc); | ||
} | ||
|
||
void CAHitNtupletHeterogeneousEDProducer::beginStreamGPUCuda( | ||
edm::StreamID streamId, cuda::stream_t<> &cudaStream) { | ||
GPUGenerator_.allocateOnGPU(); | ||
} | ||
|
||
void CAHitNtupletHeterogeneousEDProducer::acquireGPUCuda( | ||
const edm::HeterogeneousEvent &iEvent, const edm::EventSetup &iSetup, | ||
cuda::stream_t<> &cudaStream) { | ||
edm::Handle<IntermediateHitDoublets> hdoublets; | ||
iEvent.event().getByToken(doubletToken_, hdoublets); | ||
const auto ®ionDoublets = *hdoublets; | ||
|
||
const SeedingLayerSetsHits &seedingLayerHits = | ||
regionDoublets.seedingLayerHits(); | ||
if (seedingLayerHits.numberOfLayersInSet() < | ||
CAHitQuadrupletGeneratorGPU::minLayers) { | ||
throw cms::Exception("LogicError") | ||
<< "CAHitNtupletHeterogeneousEDProducer expects " | ||
"SeedingLayerSetsHits::numberOfLayersInSet() to be >= " | ||
<< CAHitQuadrupletGeneratorGPU::minLayers << ", got " | ||
<< seedingLayerHits.numberOfLayersInSet() | ||
<< ". This is likely caused by a configuration error of this module, " | ||
"HitPairEDProducer, or SeedingLayersEDProducer."; | ||
} | ||
|
||
seedingHitSets_ = std::make_unique<RegionsSeedingHitSets>(); | ||
|
||
if (regionDoublets.empty()) { | ||
emptyRegionDoublets = true; | ||
} else { | ||
seedingHitSets_->reserve(regionDoublets.regionSize(), localRA_.upper()); | ||
GPUGenerator_.initEvent(iEvent.event(), iSetup); | ||
|
||
LogDebug("CAHitNtupletHeterogeneousEDProducer") | ||
<< "Creating ntuplets_ for " << regionDoublets.regionSize() | ||
<< " regions, and " << regionDoublets.layerPairsSize() | ||
<< " layer pairs"; | ||
ntuplets_.clear(); | ||
ntuplets_.resize(regionDoublets.regionSize()); | ||
for (auto &ntuplet : ntuplets_) | ||
ntuplet.reserve(localRA_.upper()); | ||
|
||
GPUGenerator_.hitNtuplets(regionDoublets, ntuplets_, iSetup, | ||
seedingLayerHits, cudaStream.id()); | ||
} | ||
} | ||
|
||
void CAHitNtupletHeterogeneousEDProducer::produceGPUCuda( | ||
edm::HeterogeneousEvent &iEvent, const edm::EventSetup &iSetup, | ||
cuda::stream_t<> &cudaStream) { | ||
|
||
if (!emptyRegionDoublets) { | ||
edm::Handle<IntermediateHitDoublets> hdoublets; | ||
iEvent.getByToken(doubletToken_, hdoublets); | ||
const auto ®ionDoublets = *hdoublets; | ||
const SeedingLayerSetsHits &seedingLayerHits = | ||
regionDoublets.seedingLayerHits(); | ||
int index = 0; | ||
for (const auto ®ionLayerPairs : regionDoublets) { | ||
const TrackingRegion ®ion = regionLayerPairs.region(); | ||
auto seedingHitSetsFiller = seedingHitSets_->beginRegion(®ion); | ||
GPUGenerator_.fillResults(regionDoublets, ntuplets_, iSetup, | ||
seedingLayerHits, cudaStream.id()); | ||
fillNtuplets(seedingHitSetsFiller, ntuplets_[index]); | ||
ntuplets_[index].clear(); | ||
index++; | ||
} | ||
localRA_.update(seedingHitSets_->size()); | ||
} | ||
iEvent.put(std::move(seedingHitSets_)); | ||
} | ||
|
||
void CAHitNtupletHeterogeneousEDProducer::produceCPU( | ||
edm::HeterogeneousEvent &iEvent, const edm::EventSetup &iSetup) { | ||
edm::Handle<IntermediateHitDoublets> hdoublets; | ||
iEvent.getByToken(doubletToken_, hdoublets); | ||
const auto ®ionDoublets = *hdoublets; | ||
|
||
const SeedingLayerSetsHits &seedingLayerHits = | ||
regionDoublets.seedingLayerHits(); | ||
if (seedingLayerHits.numberOfLayersInSet() < | ||
CAHitQuadrupletGenerator::minLayers) { | ||
throw cms::Exception("LogicError") | ||
<< "CAHitNtupletEDProducer expects " | ||
"SeedingLayerSetsHits::numberOfLayersInSet() to be >= " | ||
<< CAHitQuadrupletGenerator::minLayers << ", got " | ||
<< seedingLayerHits.numberOfLayersInSet() | ||
<< ". This is likely caused by a configuration error of this module, " | ||
"HitPairEDProducer, or SeedingLayersEDProducer."; | ||
} | ||
|
||
auto seedingHitSets = std::make_unique<RegionsSeedingHitSets>(); | ||
if (regionDoublets.empty()) { | ||
iEvent.put(std::move(seedingHitSets)); | ||
return; | ||
} | ||
seedingHitSets->reserve(regionDoublets.regionSize(), localRA_.upper()); | ||
CPUGenerator_.initEvent(iEvent.event(), iSetup); | ||
|
||
LogDebug("CAHitNtupletEDProducer") | ||
<< "Creating ntuplets_ for " << regionDoublets.regionSize() | ||
<< " regions, and " << regionDoublets.layerPairsSize() << " layer pairs"; | ||
std::vector<OrderedHitSeeds> ntuplets_; | ||
ntuplets_.resize(regionDoublets.regionSize()); | ||
for (auto &ntuplet : ntuplets_) | ||
ntuplet.reserve(localRA_.upper()); | ||
|
||
CPUGenerator_.hitNtuplets(regionDoublets, ntuplets_, iSetup, seedingLayerHits); | ||
int index = 0; | ||
for (const auto ®ionLayerPairs : regionDoublets) { | ||
const TrackingRegion ®ion = regionLayerPairs.region(); | ||
auto seedingHitSetsFiller = seedingHitSets->beginRegion(®ion); | ||
|
||
fillNtuplets(seedingHitSetsFiller, ntuplets_[index]); | ||
ntuplets_[index].clear(); | ||
index++; | ||
} | ||
localRA_.update(seedingHitSets->size()); | ||
|
||
iEvent.put(std::move(seedingHitSets)); | ||
} | ||
|
||
DEFINE_FWK_MODULE(CAHitNtupletHeterogeneousEDProducer); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.