File indexing completed on 2024-12-12 03:12:33
0001 #ifndef RecoParticleFlow_PFClusterProducer_plugins_alpaka_PFClusterECLCC_h
0002 #define RecoParticleFlow_PFClusterProducer_plugins_alpaka_PFClusterECLCC_h
0003
0004 #include "DataFormats/ParticleFlowReco/interface/alpaka/PFRecHitDeviceCollection.h"
0005 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0006 #include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h"
0007 #include "RecoParticleFlow/PFClusterProducer/interface/alpaka/PFClusteringEdgeVarsDeviceCollection.h"
0008 #include "RecoParticleFlow/PFClusterProducer/interface/alpaka/PFClusteringVarsDeviceCollection.h"
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 namespace ALPAKA_ACCELERATOR_NAMESPACE {
0063
0064
0065
0066 ALPAKA_FN_ACC inline int representative(const int idx,
0067 reco::PFClusteringVarsDeviceCollection::View pfClusteringVars) {
0068 int curr = pfClusteringVars[idx].pfrh_topoId();
0069 if (curr != idx) {
0070 int next, prev = idx;
0071 while (curr > (next = pfClusteringVars[curr].pfrh_topoId())) {
0072 pfClusteringVars[prev].pfrh_topoId() = next;
0073 prev = curr;
0074 curr = next;
0075 }
0076 }
0077 return curr;
0078 }
0079
0080
0081 class ECLCCInit {
0082 public:
0083 ALPAKA_FN_ACC void operator()(Acc1D const& acc,
0084 reco::PFRecHitDeviceCollection::ConstView pfRecHits,
0085 reco::PFClusteringVarsDeviceCollection::View pfClusteringVars,
0086 reco::PFClusteringEdgeVarsDeviceCollection::View pfClusteringEdgeVars) const {
0087 const int nRH = pfRecHits.size();
0088 for (int v : cms::alpakatools::uniform_elements(acc, nRH)) {
0089 const int beg = pfClusteringEdgeVars[v].pfrh_edgeIdx();
0090 const int end = pfClusteringEdgeVars[v + 1].pfrh_edgeIdx();
0091 int m = v;
0092 int i = beg;
0093 while ((m == v) && (i < end)) {
0094 m = std::min(m, pfClusteringEdgeVars[i].pfrh_edgeList());
0095 i++;
0096 }
0097 pfClusteringVars[v].pfrh_topoId() = m;
0098 }
0099 }
0100 };
0101
0102
0103
0104 class ECLCCCompute1 {
0105 public:
0106 ALPAKA_FN_ACC void operator()(Acc1D const& acc,
0107 reco::PFRecHitDeviceCollection::ConstView pfRecHits,
0108 reco::PFClusteringVarsDeviceCollection::View pfClusteringVars,
0109 reco::PFClusteringEdgeVarsDeviceCollection::View pfClusteringEdgeVars) const {
0110 const int nRH = pfRecHits.size();
0111
0112 for (int v : cms::alpakatools::uniform_elements(acc, nRH)) {
0113 const int vstat = pfClusteringVars[v].pfrh_topoId();
0114 if (v != vstat) {
0115 const int beg = pfClusteringEdgeVars[v].pfrh_edgeIdx();
0116 const int end = pfClusteringEdgeVars[v + 1].pfrh_edgeIdx();
0117 int vstat = representative(v, pfClusteringVars);
0118 for (int i = beg; i < end; i++) {
0119 const int nli = pfClusteringEdgeVars[i].pfrh_edgeList();
0120 if (v > nli) {
0121 int ostat = representative(nli, pfClusteringVars);
0122 bool repeat;
0123 do {
0124 repeat = false;
0125 if (vstat != ostat) {
0126 int ret;
0127 if (vstat < ostat) {
0128 if ((ret = alpaka::atomicCas(acc, &pfClusteringVars[ostat].pfrh_topoId(), ostat, vstat)) != ostat) {
0129 ostat = ret;
0130 repeat = true;
0131 }
0132 } else {
0133 if ((ret = alpaka::atomicCas(acc, &pfClusteringVars[vstat].pfrh_topoId(), vstat, ostat)) != vstat) {
0134 vstat = ret;
0135 repeat = true;
0136 }
0137 }
0138 }
0139 } while (repeat);
0140 }
0141 }
0142 }
0143 }
0144 }
0145 };
0146
0147
0148 class ECLCCFlatten {
0149 public:
0150 ALPAKA_FN_ACC void operator()(Acc1D const& acc,
0151 reco::PFRecHitDeviceCollection::ConstView pfRecHits,
0152 reco::PFClusteringVarsDeviceCollection::View pfClusteringVars,
0153 reco::PFClusteringEdgeVarsDeviceCollection::View pfClusteringEdgeVars) const {
0154 const int nRH = pfRecHits.size();
0155
0156 for (int v : cms::alpakatools::uniform_elements(acc, nRH)) {
0157 int next, vstat = pfClusteringVars[v].pfrh_topoId();
0158 const int old = vstat;
0159 while (vstat > (next = pfClusteringVars[vstat].pfrh_topoId())) {
0160 vstat = next;
0161 }
0162 if (old != vstat)
0163 pfClusteringVars[v].pfrh_topoId() = vstat;
0164 }
0165 }
0166 };
0167
0168
0169
0170 }
0171
0172 #endif