Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-09-12 10:18:19

0001 #include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
0002 #include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h"
0003 #include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h"
0004 
0005 #include "LSTEvent.h"
0006 
0007 #include "Hit.h"
0008 #include "Kernels.h"
0009 #include "MiniDoublet.h"
0010 #include "PixelQuintuplet.h"
0011 #include "PixelTriplet.h"
0012 #include "Quintuplet.h"
0013 #include "Segment.h"
0014 #include "TrackCandidate.h"
0015 #include "Triplet.h"
0016 
0017 using Device = ALPAKA_ACCELERATOR_NAMESPACE::Device;
0018 using Queue = ALPAKA_ACCELERATOR_NAMESPACE::Queue;
0019 using Acc1D = ALPAKA_ACCELERATOR_NAMESPACE::Acc1D;
0020 using Acc3D = ALPAKA_ACCELERATOR_NAMESPACE::Acc3D;
0021 
0022 using namespace ALPAKA_ACCELERATOR_NAMESPACE::lst;
0023 
0024 void LSTEvent::initSync() {
0025   alpaka::wait(queue_);  // other calls can be asynchronous
0026 
0027   //reset the arrays
0028   for (int i = 0; i < 6; i++) {
0029     n_minidoublets_by_layer_barrel_[i] = 0;
0030     n_segments_by_layer_barrel_[i] = 0;
0031     n_triplets_by_layer_barrel_[i] = 0;
0032     n_quintuplets_by_layer_barrel_[i] = 0;
0033     if (i < 5) {
0034       n_minidoublets_by_layer_endcap_[i] = 0;
0035       n_segments_by_layer_endcap_[i] = 0;
0036       n_triplets_by_layer_endcap_[i] = 0;
0037       n_quintuplets_by_layer_endcap_[i] = 0;
0038     }
0039   }
0040 }
0041 
0042 void LSTEvent::resetEventSync() {
0043   alpaka::wait(queue_);  // synchronize to reset consistently
0044   //reset the arrays
0045   for (int i = 0; i < 6; i++) {
0046     n_minidoublets_by_layer_barrel_[i] = 0;
0047     n_segments_by_layer_barrel_[i] = 0;
0048     n_triplets_by_layer_barrel_[i] = 0;
0049     n_quintuplets_by_layer_barrel_[i] = 0;
0050     if (i < 5) {
0051       n_minidoublets_by_layer_endcap_[i] = 0;
0052       n_segments_by_layer_endcap_[i] = 0;
0053       n_triplets_by_layer_endcap_[i] = 0;
0054       n_quintuplets_by_layer_endcap_[i] = 0;
0055     }
0056   }
0057   lstInputDC_ = nullptr;
0058   hitsDC_.reset();
0059   rangesDC_.reset();
0060   miniDoubletsDC_.reset();
0061   segmentsDC_.reset();
0062   pixelSegmentsDC_.reset();
0063   tripletsDC_.reset();
0064   quintupletsDC_.reset();
0065   trackCandidatesBaseDC_.reset();
0066   trackCandidatesExtendedDC_.reset();
0067   pixelTripletsDC_.reset();
0068   pixelQuintupletsDC_.reset();
0069 
0070   lstInputHC_.reset();
0071   hitsHC_.reset();
0072   rangesHC_.reset();
0073   miniDoubletsHC_.reset();
0074   segmentsHC_.reset();
0075   pixelSegmentsHC_.reset();
0076   tripletsHC_.reset();
0077   quintupletsHC_.reset();
0078   pixelTripletsHC_.reset();
0079   pixelQuintupletsHC_.reset();
0080   trackCandidatesBaseHC_.reset();
0081   trackCandidatesExtendedHC_.reset();
0082   modulesHC_.reset();
0083 }
0084 
0085 void LSTEvent::addInputToEvent(LSTInputDeviceCollection const* lstInputDC) {
0086   lstInputDC_ = lstInputDC;
0087 
0088   pixelSize_ = lstInputDC_->sizes()[1];
0089   pixelModuleIndex_ = pixelMapping_.pixelModuleIndex;
0090 }
0091 
0092 void LSTEvent::addHitToEvent() {
0093   if (!hitsDC_) {
0094     int nHits = lstInputDC_->sizes()[0];
0095     std::array<int, 2> const hits_sizes{{nHits, static_cast<int>(nModules_)}};
0096     hitsDC_.emplace(hits_sizes, queue_);
0097     auto buf = hitsDC_->buffer();
0098     alpaka::memset(queue_, buf, 0xff);
0099   }
0100 
0101   if (!rangesDC_) {
0102     rangesDC_.emplace(nLowerModules_ + 1, queue_);
0103     auto buf = rangesDC_->buffer();
0104     alpaka::memset(queue_, buf, 0xff);
0105   }
0106 
0107   auto const hit_loop_workdiv = cms::alpakatools::make_workdiv<Acc1D>(max_blocks, 256);
0108 
0109   alpaka::exec<Acc1D>(queue_,
0110                       hit_loop_workdiv,
0111                       HitLoopKernel{},
0112                       Endcap,
0113                       TwoS,
0114                       nModules_,
0115                       nEndCapMap_,
0116                       endcapGeometry_.const_view(),
0117                       modules_.const_view<ModulesSoA>(),
0118                       lstInputDC_->const_view<HitsBaseSoA>(),
0119                       hitsDC_->view<HitsExtendedSoA>(),
0120                       hitsDC_->view<HitsRangesSoA>());
0121 
0122   auto const module_ranges_workdiv = cms::alpakatools::make_workdiv<Acc1D>(max_blocks, 256);
0123 
0124   alpaka::exec<Acc1D>(queue_,
0125                       module_ranges_workdiv,
0126                       ModuleRangesKernel{},
0127                       modules_.const_view<ModulesSoA>(),
0128                       hitsDC_->view<HitsRangesSoA>(),
0129                       nLowerModules_);
0130 }
0131 
0132 void LSTEvent::addPixelSegmentToEventStart() {
0133   if (pixelSize_ == n_max_pixel_segments_per_module) {
0134     lstWarning(
0135         "\
0136           *********************************************************\n\
0137           * Warning: Pixel line segments may be truncated.        *\n\
0138           * You need to increase n_max_pixel_segments_per_module. *\n\
0139           *********************************************************");
0140   }
0141 
0142   if (!pixelSegmentsDC_) {
0143     pixelSegmentsDC_.emplace(pixelSize_, queue_);
0144   }
0145 }
0146 
0147 void LSTEvent::addPixelSegmentToEventFinalize() {
0148   auto const addPixelSegmentToEvent_workdiv = cms::alpakatools::make_workdiv<Acc1D>(max_blocks, 256);
0149 
0150   alpaka::exec<Acc1D>(queue_,
0151                       addPixelSegmentToEvent_workdiv,
0152                       AddPixelSegmentToEventKernel{},
0153                       modules_.const_view<ModulesSoA>(),
0154                       rangesDC_->const_view(),
0155                       lstInputDC_->const_view<HitsBaseSoA>(),
0156                       hitsDC_->view<HitsExtendedSoA>(),
0157                       lstInputDC_->const_view<PixelSeedsSoA>(),
0158                       miniDoubletsDC_->view<MiniDoubletsSoA>(),
0159                       segmentsDC_->view<SegmentsSoA>(),
0160                       pixelSegmentsDC_->view(),
0161                       pixelModuleIndex_,
0162                       pixelSize_);
0163 }
0164 
0165 void LSTEvent::createMiniDoublets() {
0166   if (!miniDoubletsDC_) {
0167     // Create a view for the element nLowerModules_ inside rangesOccupancy->miniDoubletModuleOccupancy
0168     auto rangesOccupancy = rangesDC_->view();
0169     auto dst_view_miniDoubletModuleOccupancy =
0170         cms::alpakatools::make_device_view(queue_, rangesOccupancy.miniDoubletModuleOccupancy()[nLowerModules_]);
0171 
0172     // Create a host buffer for a value to be passed to the device
0173     auto pixelMaxMDs_buf_h = cms::alpakatools::make_host_buffer<int>(queue_);
0174     *pixelMaxMDs_buf_h.data() = n_max_pixel_md_per_modules;
0175 
0176     alpaka::memcpy(queue_, dst_view_miniDoubletModuleOccupancy, pixelMaxMDs_buf_h);
0177 
0178     auto dst_view_miniDoubletModuleOccupancyPix =
0179         cms::alpakatools::make_device_view(queue_, rangesOccupancy.miniDoubletModuleOccupancy()[pixelModuleIndex_]);
0180 
0181     alpaka::memcpy(queue_, dst_view_miniDoubletModuleOccupancyPix, pixelMaxMDs_buf_h);
0182 
0183     auto const createMDArrayRangesGPU_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 1024);
0184 
0185     alpaka::exec<Acc1D>(queue_,
0186                         createMDArrayRangesGPU_workDiv,
0187                         CreateMDArrayRangesGPU{},
0188                         modules_.const_view<ModulesSoA>(),
0189                         hitsDC_->const_view<HitsRangesSoA>(),
0190                         rangesDC_->view(),
0191                         ptCut_);
0192 
0193     auto nTotalMDs_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0194     auto nTotalMDs_buf_d = cms::alpakatools::make_device_view(queue_, rangesOccupancy.nTotalMDs());
0195     alpaka::memcpy(queue_, nTotalMDs_buf_h, nTotalMDs_buf_d);
0196     alpaka::wait(queue_);  // wait to get the data before manipulation
0197 
0198     *nTotalMDs_buf_h.data() += n_max_pixel_md_per_modules;
0199     unsigned int nTotalMDs = *nTotalMDs_buf_h.data();
0200 
0201     std::array<int, 2> const mds_sizes{{static_cast<int>(nTotalMDs), static_cast<int>(nLowerModules_ + 1)}};
0202     miniDoubletsDC_.emplace(mds_sizes, queue_);
0203 
0204     auto mdsOccupancy = miniDoubletsDC_->view<MiniDoubletsOccupancySoA>();
0205     auto nMDs_view = cms::alpakatools::make_device_view(queue_, mdsOccupancy.nMDs(), mdsOccupancy.metadata().size());
0206     auto totOccupancyMDs_view =
0207         cms::alpakatools::make_device_view(queue_, mdsOccupancy.totOccupancyMDs(), mdsOccupancy.metadata().size());
0208     alpaka::memset(queue_, nMDs_view, 0u);
0209     alpaka::memset(queue_, totOccupancyMDs_view, 0u);
0210   }
0211 
0212   auto mdView = miniDoubletsDC_->view<MiniDoubletsSoA>();
0213   auto connView = cms::alpakatools::make_device_view(queue_, mdView.connectedMax(), mdView.metadata().size());
0214   alpaka::memset(queue_, connView, 0u);
0215 
0216   unsigned int mdSize = pixelSize_ * 2;
0217   auto src_view_mdSize = cms::alpakatools::make_host_view(mdSize);
0218 
0219   auto mdsOccupancy = miniDoubletsDC_->view<MiniDoubletsOccupancySoA>();
0220   auto dst_view_nMDs = cms::alpakatools::make_device_view(queue_, mdsOccupancy.nMDs()[pixelModuleIndex_]);
0221   alpaka::memcpy(queue_, dst_view_nMDs, src_view_mdSize);
0222 
0223   auto dst_view_totOccupancyMDs =
0224       cms::alpakatools::make_device_view(queue_, mdsOccupancy.totOccupancyMDs()[pixelModuleIndex_]);
0225   alpaka::memcpy(queue_, dst_view_totOccupancyMDs, src_view_mdSize);
0226 
0227   alpaka::wait(queue_);  // FIXME: remove synch after inputs refactored to be in pinned memory
0228 
0229   constexpr int threadsPerBlockY = 16;
0230   auto const createMiniDoublets_workDiv =
0231       cms::alpakatools::make_workdiv<Acc2D>({nLowerModules_ / threadsPerBlockY, 1}, {threadsPerBlockY, 32});
0232 
0233   alpaka::exec<Acc2D>(queue_,
0234                       createMiniDoublets_workDiv,
0235                       CreateMiniDoublets{},
0236                       modules_.const_view<ModulesSoA>(),
0237                       lstInputDC_->const_view<HitsBaseSoA>(),
0238                       hitsDC_->const_view<HitsExtendedSoA>(),
0239                       hitsDC_->const_view<HitsRangesSoA>(),
0240                       miniDoubletsDC_->view<MiniDoubletsSoA>(),
0241                       miniDoubletsDC_->view<MiniDoubletsOccupancySoA>(),
0242                       rangesDC_->const_view(),
0243                       ptCut_);
0244 
0245   auto const addMiniDoubletRangesToEventExplicit_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 1024);
0246 
0247   alpaka::exec<Acc1D>(queue_,
0248                       addMiniDoubletRangesToEventExplicit_workDiv,
0249                       AddMiniDoubletRangesToEventExplicit{},
0250                       modules_.const_view<ModulesSoA>(),
0251                       miniDoubletsDC_->view<MiniDoubletsOccupancySoA>(),
0252                       rangesDC_->view(),
0253                       hitsDC_->const_view<HitsRangesSoA>());
0254 
0255   if (addObjects_) {
0256     addMiniDoubletsToEventExplicit();
0257   }
0258 }
0259 
0260 void LSTEvent::createSegmentsWithModuleMap() {
0261   if (!segmentsDC_) {
0262     auto const countMDConn_wd = cms::alpakatools::make_workdiv<Acc3D>({nLowerModules_, 1, 1}, {1, 8, 32});
0263 
0264     alpaka::exec<Acc3D>(queue_,
0265                         countMDConn_wd,
0266                         CountMiniDoubletConnections{},
0267                         modules_.const_view<ModulesSoA>(),
0268                         miniDoubletsDC_->view<MiniDoubletsSoA>(),
0269                         miniDoubletsDC_->const_view<MiniDoubletsOccupancySoA>(),
0270                         rangesDC_->const_view(),
0271                         ptCut_);
0272 
0273     auto const createSegmentArrayRanges_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 1024);
0274 
0275     alpaka::exec<Acc1D>(queue_,
0276                         createSegmentArrayRanges_workDiv,
0277                         CreateSegmentArrayRanges{},
0278                         modules_.const_view<ModulesSoA>(),
0279                         rangesDC_->view(),
0280                         miniDoubletsDC_->const_view<MiniDoubletsSoA>(),
0281                         miniDoubletsDC_->const_view<MiniDoubletsOccupancySoA>());
0282 
0283     auto rangesOccupancy = rangesDC_->view();
0284     auto nTotalSegments_view_h = cms::alpakatools::make_host_view(nTotalSegments_);
0285     auto nTotalSegments_view_d = cms::alpakatools::make_device_view(queue_, rangesOccupancy.nTotalSegs());
0286     alpaka::memcpy(queue_, nTotalSegments_view_h, nTotalSegments_view_d);
0287     alpaka::wait(queue_);  // wait to get the value before manipulation
0288 
0289     nTotalSegments_ += n_max_pixel_segments_per_module;
0290 
0291     std::array<int, 2> const segments_sizes{{static_cast<int>(nTotalSegments_), static_cast<int>(nLowerModules_ + 1)}};
0292     segmentsDC_.emplace(segments_sizes, queue_);
0293 
0294     auto segmentsOccupancy = segmentsDC_->view<SegmentsOccupancySoA>();
0295     auto segments = segmentsDC_->view<SegmentsSoA>();
0296     auto nSegments_view =
0297         cms::alpakatools::make_device_view(queue_, segmentsOccupancy.nSegments(), segmentsOccupancy.metadata().size());
0298     auto totOccupancySegments_view = cms::alpakatools::make_device_view(
0299         queue_, segmentsOccupancy.totOccupancySegments(), segmentsOccupancy.metadata().size());
0300     alpaka::memset(queue_, nSegments_view, 0u);
0301     alpaka::memset(queue_, totOccupancySegments_view, 0u);
0302     auto conn_view = cms::alpakatools::make_device_view(queue_, segments.connectedMax(), segments.metadata().size());
0303     alpaka::memset(queue_, conn_view, 0u);
0304 
0305     auto src_view_size = cms::alpakatools::make_host_view(pixelSize_);
0306 
0307     auto dst_view_segments =
0308         cms::alpakatools::make_device_view(queue_, segmentsOccupancy.nSegments()[pixelModuleIndex_]);
0309     alpaka::memcpy(queue_, dst_view_segments, src_view_size);
0310 
0311     auto dst_view_totOccupancySegments =
0312         cms::alpakatools::make_device_view(queue_, segmentsOccupancy.totOccupancySegments()[pixelModuleIndex_]);
0313     alpaka::memcpy(queue_, dst_view_totOccupancySegments, src_view_size);
0314     alpaka::wait(queue_);
0315   }
0316 
0317   auto const createSegments_workDiv = cms::alpakatools::make_workdiv<Acc3D>({nLowerModules_, 1, 1}, {1, 8, 32});
0318 
0319   alpaka::exec<Acc3D>(queue_,
0320                       createSegments_workDiv,
0321                       CreateSegments{},
0322                       modules_.const_view<ModulesSoA>(),
0323                       miniDoubletsDC_->const_view<MiniDoubletsSoA>(),
0324                       miniDoubletsDC_->const_view<MiniDoubletsOccupancySoA>(),
0325                       segmentsDC_->view<SegmentsSoA>(),
0326                       segmentsDC_->view<SegmentsOccupancySoA>(),
0327                       rangesDC_->const_view(),
0328                       ptCut_);
0329 
0330   auto const addSegmentRangesToEventExplicit_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 1024);
0331 
0332   alpaka::exec<Acc1D>(queue_,
0333                       addSegmentRangesToEventExplicit_workDiv,
0334                       AddSegmentRangesToEventExplicit{},
0335                       modules_.const_view<ModulesSoA>(),
0336                       segmentsDC_->view<SegmentsOccupancySoA>(),
0337                       rangesDC_->view());
0338 
0339   if (addObjects_) {
0340     addSegmentsToEventExplicit();
0341   }
0342 }
0343 
0344 void LSTEvent::createTriplets() {
0345   if (!tripletsDC_) {
0346     auto const countSegConn_wd = cms::alpakatools::make_workdiv<Acc3D>({nLowerModules_, 1, 1}, {1, 16, 16});
0347 
0348     alpaka::exec<Acc3D>(queue_,
0349                         countSegConn_wd,
0350                         CountSegmentConnections{},
0351                         modules_.const_view<ModulesSoA>(),
0352                         segmentsDC_->view<SegmentsSoA>(),
0353                         segmentsDC_->const_view<SegmentsOccupancySoA>(),
0354                         rangesDC_->const_view());
0355 
0356     auto const createTripletArrayRanges_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 1024);
0357 
0358     alpaka::exec<Acc1D>(queue_,
0359                         createTripletArrayRanges_workDiv,
0360                         CreateTripletArrayRanges{},
0361                         modules_.const_view<ModulesSoA>(),
0362                         rangesDC_->view(),
0363                         segmentsDC_->const_view<SegmentsSoA>(),
0364                         segmentsDC_->const_view<SegmentsOccupancySoA>());
0365 
0366     // TODO: Why are we pulling this back down only to put it back on the device in a new struct?
0367     auto rangesOccupancy = rangesDC_->view();
0368     auto maxTriplets_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0369     auto maxTriplets_buf_d = cms::alpakatools::make_device_view(queue_, rangesOccupancy.nTotalTrips());
0370     alpaka::memcpy(queue_, maxTriplets_buf_h, maxTriplets_buf_d);
0371     alpaka::wait(queue_);  // wait to get the value before using it
0372 
0373     std::array<int, 2> const triplets_sizes{
0374         {static_cast<int>(*maxTriplets_buf_h.data()), static_cast<int>(nLowerModules_)}};
0375     tripletsDC_.emplace(triplets_sizes, queue_);
0376 
0377     auto tripletsOccupancy = tripletsDC_->view<TripletsOccupancySoA>();
0378     auto nTriplets_view =
0379         cms::alpakatools::make_device_view(queue_, tripletsOccupancy.nTriplets(), tripletsOccupancy.metadata().size());
0380     alpaka::memset(queue_, nTriplets_view, 0u);
0381     auto totOccupancyTriplets_view = cms::alpakatools::make_device_view(
0382         queue_, tripletsOccupancy.totOccupancyTriplets(), tripletsOccupancy.metadata().size());
0383     alpaka::memset(queue_, totOccupancyTriplets_view, 0u);
0384     auto triplets = tripletsDC_->view<TripletsSoA>();
0385     auto partOfPT5_view = cms::alpakatools::make_device_view(queue_, triplets.partOfPT5(), triplets.metadata().size());
0386     alpaka::memset(queue_, partOfPT5_view, 0u);
0387     auto partOfT5_view = cms::alpakatools::make_device_view(queue_, triplets.partOfT5(), triplets.metadata().size());
0388     alpaka::memset(queue_, partOfT5_view, 0u);
0389     auto partOfPT3_view = cms::alpakatools::make_device_view(queue_, triplets.partOfPT3(), triplets.metadata().size());
0390     alpaka::memset(queue_, partOfPT3_view, 0u);
0391     auto connectedMax_view =
0392         cms::alpakatools::make_device_view(queue_, triplets.connectedMax(), triplets.metadata().size());
0393     alpaka::memset(queue_, connectedMax_view, 0u);
0394   }
0395 
0396   uint16_t nonZeroModules = 0;
0397   unsigned int max_InnerSeg = 0;
0398 
0399   // Allocate and copy nSegments from device to host (only nLowerModules in OT, not the +1 with pLSs)
0400   auto nSegments_buf_h = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nLowerModules_);
0401   auto nSegments_buf_d = cms::alpakatools::make_device_view(
0402       queue_, segmentsDC_->const_view<SegmentsOccupancySoA>().nSegments(), nLowerModules_);
0403   alpaka::memcpy(queue_, nSegments_buf_h, nSegments_buf_d, nLowerModules_);
0404 
0405   // ... same for module_nConnectedModules
0406   // FIXME: replace by ES host data
0407   auto modules = modules_.const_view<ModulesSoA>();
0408   auto module_nConnectedModules_buf_h = cms::alpakatools::make_host_buffer<uint16_t[]>(queue_, nLowerModules_);
0409   auto module_nConnectedModules_buf_d =
0410       cms::alpakatools::make_device_view(queue_, modules.nConnectedModules(), nLowerModules_);  // only lower modules
0411   alpaka::memcpy(queue_, module_nConnectedModules_buf_h, module_nConnectedModules_buf_d, nLowerModules_);
0412 
0413   alpaka::wait(queue_);  // wait for nSegments and module_nConnectedModules before using
0414 
0415   auto const* nSegments = nSegments_buf_h.data();
0416   auto const* module_nConnectedModules = module_nConnectedModules_buf_h.data();
0417 
0418   // Allocate host index and fill it directly
0419   auto index_buf_h = cms::alpakatools::make_host_buffer<uint16_t[]>(queue_, nLowerModules_);
0420   auto* index = index_buf_h.data();
0421 
0422   for (uint16_t innerLowerModuleIndex = 0; innerLowerModuleIndex < nLowerModules_; innerLowerModuleIndex++) {
0423     uint16_t nConnectedModules = module_nConnectedModules[innerLowerModuleIndex];
0424     unsigned int nInnerSegments = nSegments[innerLowerModuleIndex];
0425     if (nConnectedModules != 0 and nInnerSegments != 0) {
0426       index[nonZeroModules] = innerLowerModuleIndex;
0427       nonZeroModules++;
0428     }
0429     max_InnerSeg = std::max(max_InnerSeg, nInnerSegments);
0430   }
0431 
0432   // Allocate and copy to device index
0433   auto index_gpu_buf = cms::alpakatools::make_device_buffer<uint16_t[]>(queue_, nLowerModules_);
0434   alpaka::memcpy(queue_, index_gpu_buf, index_buf_h, nonZeroModules);
0435 
0436   auto const createTriplets_workDiv = cms::alpakatools::make_workdiv<Acc3D>({nonZeroModules, 1, 1}, {1, 16, 16});
0437 
0438   alpaka::exec<Acc3D>(queue_,
0439                       createTriplets_workDiv,
0440                       CreateTriplets{},
0441                       modules_.const_view<ModulesSoA>(),
0442                       miniDoubletsDC_->const_view<MiniDoubletsSoA>(),
0443                       segmentsDC_->const_view<SegmentsSoA>(),
0444                       segmentsDC_->const_view<SegmentsOccupancySoA>(),
0445                       tripletsDC_->view<TripletsSoA>(),
0446                       tripletsDC_->view<TripletsOccupancySoA>(),
0447                       rangesDC_->const_view(),
0448                       index_gpu_buf.data(),
0449                       nonZeroModules,
0450                       ptCut_);
0451 
0452   auto const addTripletRangesToEventExplicit_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 1024);
0453 
0454   alpaka::exec<Acc1D>(queue_,
0455                       addTripletRangesToEventExplicit_workDiv,
0456                       AddTripletRangesToEventExplicit{},
0457                       modules_.const_view<ModulesSoA>(),
0458                       tripletsDC_->const_view<TripletsOccupancySoA>(),
0459                       rangesDC_->view());
0460 
0461   if (addObjects_) {
0462     addTripletsToEventExplicit();
0463   }
0464 }
0465 
0466 void LSTEvent::createTrackCandidates(bool no_pls_dupclean, bool tc_pls_triplets) {
0467   if (!trackCandidatesBaseDC_) {
0468     trackCandidatesBaseDC_.emplace(n_max_nonpixel_track_candidates + n_max_pixel_track_candidates, queue_);
0469     trackCandidatesBaseDC_->zeroInitialise(queue_);
0470 
0471     trackCandidatesExtendedDC_.emplace(n_max_nonpixel_track_candidates + n_max_pixel_track_candidates, queue_);
0472     trackCandidatesExtendedDC_->zeroInitialise(queue_);
0473   }
0474 
0475   auto const crossCleanpT3_workDiv = cms::alpakatools::make_workdiv<Acc2D>({20, 4}, {64, 16});
0476 
0477   alpaka::exec<Acc2D>(queue_,
0478                       crossCleanpT3_workDiv,
0479                       CrossCleanpT3{},
0480                       modules_.const_view<ModulesSoA>(),
0481                       rangesDC_->const_view(),
0482                       pixelTripletsDC_->view(),
0483                       lstInputDC_->const_view<PixelSeedsSoA>(),
0484                       pixelQuintupletsDC_->const_view());
0485 
0486   auto const addpT3asTrackCandidates_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 512);
0487 
0488   alpaka::exec<Acc1D>(queue_,
0489                       addpT3asTrackCandidates_workDiv,
0490                       AddpT3asTrackCandidates{},
0491                       nLowerModules_,
0492                       pixelTripletsDC_->const_view(),
0493                       trackCandidatesBaseDC_->view(),
0494                       trackCandidatesExtendedDC_->view(),
0495                       lstInputDC_->const_view<PixelSeedsSoA>(),
0496                       rangesDC_->const_view());
0497 
0498   // Pull nEligibleT5Modules from the device.
0499   auto rangesOccupancy = rangesDC_->view();
0500   auto nEligibleModules_buf_h = cms::alpakatools::make_host_buffer<uint16_t>(queue_);
0501   auto nEligibleModules_buf_d = cms::alpakatools::make_device_view(queue_, rangesOccupancy.nEligibleT5Modules());
0502   alpaka::memcpy(queue_, nEligibleModules_buf_h, nEligibleModules_buf_d);
0503   alpaka::wait(queue_);  // wait to get the value before using
0504   auto const nEligibleModules = *nEligibleModules_buf_h.data();
0505 
0506   constexpr int threadsPerBlockY = 16;
0507   constexpr int threadsPerBlockX = 32;
0508   auto const removeDupQuintupletsBeforeTC_workDiv = cms::alpakatools::make_workdiv<Acc2D>(
0509       {std::max(nEligibleModules / threadsPerBlockY, 1), std::max(nEligibleModules / threadsPerBlockX, 1)}, {16, 32});
0510 
0511   alpaka::exec<Acc2D>(queue_,
0512                       removeDupQuintupletsBeforeTC_workDiv,
0513                       RemoveDupQuintupletsBeforeTC{},
0514                       quintupletsDC_->view<QuintupletsSoA>(),
0515                       quintupletsDC_->view<QuintupletsOccupancySoA>(),
0516                       rangesDC_->const_view());
0517 
0518   constexpr int threadsPerBlock = 32;
0519   auto const crossCleanT5_workDiv = cms::alpakatools::make_workdiv<Acc3D>(
0520       {(nLowerModules_ / threadsPerBlock) + 1, 1, max_blocks}, {threadsPerBlock, 1, threadsPerBlock});
0521 
0522   alpaka::exec<Acc3D>(queue_,
0523                       crossCleanT5_workDiv,
0524                       CrossCleanT5{},
0525                       modules_.const_view<ModulesSoA>(),
0526                       quintupletsDC_->view<QuintupletsSoA>(),
0527                       quintupletsDC_->const_view<QuintupletsOccupancySoA>(),
0528                       pixelQuintupletsDC_->const_view(),
0529                       pixelTripletsDC_->const_view(),
0530                       rangesDC_->const_view());
0531 
0532   auto const addT5asTrackCandidate_workDiv = cms::alpakatools::make_workdiv<Acc2D>({8, 10}, {8, 128});
0533 
0534   alpaka::exec<Acc2D>(queue_,
0535                       addT5asTrackCandidate_workDiv,
0536                       AddT5asTrackCandidate{},
0537                       nLowerModules_,
0538                       quintupletsDC_->const_view<QuintupletsSoA>(),
0539                       quintupletsDC_->const_view<QuintupletsOccupancySoA>(),
0540                       trackCandidatesBaseDC_->view(),
0541                       trackCandidatesExtendedDC_->view(),
0542                       rangesDC_->const_view());
0543 
0544   if (!no_pls_dupclean) {
0545     auto const checkHitspLS_workDiv = cms::alpakatools::make_workdiv<Acc2D>({max_blocks * 4, max_blocks / 4}, {16, 16});
0546 
0547     alpaka::exec<Acc2D>(queue_,
0548                         checkHitspLS_workDiv,
0549                         CheckHitspLS{},
0550                         modules_.const_view<ModulesSoA>(),
0551                         segmentsDC_->const_view<SegmentsOccupancySoA>(),
0552                         lstInputDC_->const_view<PixelSeedsSoA>(),
0553                         pixelSegmentsDC_->view(),
0554                         true);
0555   }
0556 
0557   auto const crossCleanpLS_workDiv = cms::alpakatools::make_workdiv<Acc2D>({20, 4}, {32, 16});
0558 
0559   alpaka::exec<Acc2D>(queue_,
0560                       crossCleanpLS_workDiv,
0561                       CrossCleanpLS{},
0562                       modules_.const_view<ModulesSoA>(),
0563                       rangesDC_->const_view(),
0564                       pixelTripletsDC_->const_view(),
0565                       trackCandidatesBaseDC_->view(),
0566                       trackCandidatesExtendedDC_->view(),
0567                       segmentsDC_->const_view<SegmentsSoA>(),
0568                       segmentsDC_->const_view<SegmentsOccupancySoA>(),
0569                       lstInputDC_->const_view<PixelSeedsSoA>(),
0570                       pixelSegmentsDC_->view(),
0571                       miniDoubletsDC_->const_view<MiniDoubletsSoA>(),
0572                       lstInputDC_->const_view<HitsBaseSoA>(),
0573                       quintupletsDC_->const_view<QuintupletsSoA>());
0574 
0575   auto const addpLSasTrackCandidate_workDiv = cms::alpakatools::make_workdiv<Acc1D>(max_blocks, 384);
0576 
0577   alpaka::exec<Acc1D>(queue_,
0578                       addpLSasTrackCandidate_workDiv,
0579                       AddpLSasTrackCandidate{},
0580                       nLowerModules_,
0581                       trackCandidatesBaseDC_->view(),
0582                       trackCandidatesExtendedDC_->view(),
0583                       segmentsDC_->const_view<SegmentsOccupancySoA>(),
0584                       lstInputDC_->const_view<PixelSeedsSoA>(),
0585                       pixelSegmentsDC_->const_view(),
0586                       tc_pls_triplets);
0587 
0588   // Check if either n_max_pixel_track_candidates or n_max_nonpixel_track_candidates was reached
0589   auto nTrackCanpT5Host_buf = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0590   auto nTrackCanpT3Host_buf = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0591   auto nTrackCanpLSHost_buf = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0592   auto nTrackCanT5Host_buf = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0593   alpaka::memcpy(queue_,
0594                  nTrackCanpT5Host_buf,
0595                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatespT5()));
0596   alpaka::memcpy(queue_,
0597                  nTrackCanpT3Host_buf,
0598                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatespT3()));
0599   alpaka::memcpy(queue_,
0600                  nTrackCanpLSHost_buf,
0601                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatespLS()));
0602   alpaka::memcpy(queue_,
0603                  nTrackCanT5Host_buf,
0604                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatesT5()));
0605   alpaka::wait(queue_);  // wait to get the values before using them
0606 
0607   auto nTrackCandidatespT5 = *nTrackCanpT5Host_buf.data();
0608   auto nTrackCandidatespT3 = *nTrackCanpT3Host_buf.data();
0609   auto nTrackCandidatespLS = *nTrackCanpLSHost_buf.data();
0610   auto nTrackCandidatesT5 = *nTrackCanT5Host_buf.data();
0611   if ((nTrackCandidatespT5 + nTrackCandidatespT3 + nTrackCandidatespLS == n_max_pixel_track_candidates) ||
0612       (nTrackCandidatesT5 == n_max_nonpixel_track_candidates)) {
0613     lstWarning(
0614         "\
0615         ****************************************************************************************************\n\
0616         * Track candidates were possibly truncated.                                                        *\n\
0617         * You may need to increase either n_max_pixel_track_candidates or n_max_nonpixel_track_candidates. *\n\
0618         * Run the code with the WARNINGS flag activated for more details.                                  *\n\
0619         ****************************************************************************************************");
0620   }
0621 }
0622 
0623 void LSTEvent::createPixelTriplets() {
0624   if (!pixelTripletsDC_) {
0625     pixelTripletsDC_.emplace(n_max_pixel_triplets, queue_);
0626     auto nPixelTriplets_view = cms::alpakatools::make_device_view(queue_, (*pixelTripletsDC_)->nPixelTriplets());
0627     alpaka::memset(queue_, nPixelTriplets_view, 0u);
0628     auto totOccupancyPixelTriplets_view =
0629         cms::alpakatools::make_device_view(queue_, (*pixelTripletsDC_)->totOccupancyPixelTriplets());
0630     alpaka::memset(queue_, totOccupancyPixelTriplets_view, 0u);
0631   }
0632   SegmentsOccupancy segmentsOccupancy = segmentsDC_->view<SegmentsOccupancySoA>();
0633   PixelSeedsConst pixelSeeds = lstInputDC_->const_view<PixelSeedsSoA>();
0634 
0635   auto superbins_buf = cms::alpakatools::make_host_buffer<int[]>(queue_, n_max_pixel_segments_per_module);
0636   auto pixelTypes_buf = cms::alpakatools::make_host_buffer<PixelType[]>(queue_, n_max_pixel_segments_per_module);
0637 
0638   alpaka::memcpy(queue_, superbins_buf, cms::alpakatools::make_device_view(queue_, pixelSeeds.superbin(), pixelSize_));
0639   alpaka::memcpy(
0640       queue_, pixelTypes_buf, cms::alpakatools::make_device_view(queue_, pixelSeeds.pixelType(), pixelSize_));
0641   auto const* superbins = superbins_buf.data();
0642   auto const* pixelTypes = pixelTypes_buf.data();
0643 
0644   unsigned int nInnerSegments;
0645   auto nInnerSegments_src_view = cms::alpakatools::make_host_view(nInnerSegments);
0646 
0647   // Create a sub-view for the device buffer
0648   auto dev_view_nSegments = cms::alpakatools::make_device_view(queue_, segmentsOccupancy.nSegments()[nLowerModules_]);
0649 
0650   alpaka::memcpy(queue_, nInnerSegments_src_view, dev_view_nSegments);
0651   alpaka::wait(queue_);  // wait to get nInnerSegments (also superbins and pixelTypes) before using
0652 
0653   auto connectedPixelSize_host_buf = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nInnerSegments);
0654   auto connectedPixelIndex_host_buf = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nInnerSegments);
0655   auto connectedPixelSize_dev_buf = cms::alpakatools::make_device_buffer<unsigned int[]>(queue_, nInnerSegments);
0656   auto connectedPixelIndex_dev_buf = cms::alpakatools::make_device_buffer<unsigned int[]>(queue_, nInnerSegments);
0657 
0658   unsigned int* connectedPixelSize_host = connectedPixelSize_host_buf.data();
0659   unsigned int* connectedPixelIndex_host = connectedPixelIndex_host_buf.data();
0660 
0661   int pixelIndexOffsetPos =
0662       pixelMapping_.connectedPixelsIndex[size_superbins - 1] + pixelMapping_.connectedPixelsSizes[size_superbins - 1];
0663   int pixelIndexOffsetNeg = pixelMapping_.connectedPixelsIndexPos[size_superbins - 1] +
0664                             pixelMapping_.connectedPixelsSizesPos[size_superbins - 1] + pixelIndexOffsetPos;
0665 
0666   // TODO: check if a map/reduction to just eligible pLSs would speed up the kernel
0667   // the current selection still leaves a significant fraction of unmatchable pLSs
0668   for (unsigned int i = 0; i < nInnerSegments; i++) {  // loop over # pLS
0669     PixelType pixelType = pixelTypes[i];               // Get pixel type for this pLS
0670     int superbin = superbins[i];                       // Get superbin for this pixel
0671     if ((superbin < 0) or (superbin >= (int)size_superbins) or
0672         ((pixelType != PixelType::kHighPt) and (pixelType != PixelType::kLowPtPosCurv) and
0673          (pixelType != PixelType::kLowPtNegCurv))) {
0674       connectedPixelSize_host[i] = 0;
0675       connectedPixelIndex_host[i] = 0;
0676       continue;
0677     }
0678 
0679     // Used pixel type to select correct size-index arrays
0680     switch (pixelType) {
0681       case PixelType::kInvalid:
0682         break;
0683       case PixelType::kHighPt:
0684         // number of connected modules to this pixel
0685         connectedPixelSize_host[i] = pixelMapping_.connectedPixelsSizes[superbin];
0686         // index to get start of connected modules for this superbin in map
0687         connectedPixelIndex_host[i] = pixelMapping_.connectedPixelsIndex[superbin];
0688         break;
0689       case PixelType::kLowPtPosCurv:
0690         // number of connected modules to this pixel
0691         connectedPixelSize_host[i] = pixelMapping_.connectedPixelsSizesPos[superbin];
0692         // index to get start of connected modules for this superbin in map
0693         connectedPixelIndex_host[i] = pixelMapping_.connectedPixelsIndexPos[superbin] + pixelIndexOffsetPos;
0694         break;
0695       case PixelType::kLowPtNegCurv:
0696         // number of connected modules to this pixel
0697         connectedPixelSize_host[i] = pixelMapping_.connectedPixelsSizesNeg[superbin];
0698         // index to get start of connected modules for this superbin in map
0699         connectedPixelIndex_host[i] = pixelMapping_.connectedPixelsIndexNeg[superbin] + pixelIndexOffsetNeg;
0700         break;
0701     }
0702   }
0703 
0704   alpaka::memcpy(queue_, connectedPixelSize_dev_buf, connectedPixelSize_host_buf, nInnerSegments);
0705   alpaka::memcpy(queue_, connectedPixelIndex_dev_buf, connectedPixelIndex_host_buf, nInnerSegments);
0706 
0707   auto const createPixelTripletsFromMap_workDiv =
0708       cms::alpakatools::make_workdiv<Acc3D>({4096, 16 /* above median of connected modules*/, 1}, {4, 1, 32});
0709 
0710   alpaka::exec<Acc3D>(queue_,
0711                       createPixelTripletsFromMap_workDiv,
0712                       CreatePixelTripletsFromMap{},
0713                       modules_.const_view<ModulesSoA>(),
0714                       modules_.const_view<ModulesPixelSoA>(),
0715                       rangesDC_->const_view(),
0716                       miniDoubletsDC_->const_view<MiniDoubletsSoA>(),
0717                       segmentsDC_->const_view<SegmentsSoA>(),
0718                       lstInputDC_->const_view<PixelSeedsSoA>(),
0719                       pixelSegmentsDC_->const_view(),
0720                       tripletsDC_->view<TripletsSoA>(),
0721                       tripletsDC_->const_view<TripletsOccupancySoA>(),
0722                       pixelTripletsDC_->view(),
0723                       connectedPixelSize_dev_buf.data(),
0724                       connectedPixelIndex_dev_buf.data(),
0725                       nInnerSegments,
0726                       ptCut_);
0727 
0728 #ifdef WARNINGS
0729   auto nPixelTriplets_buf = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0730 
0731   alpaka::memcpy(
0732       queue_, nPixelTriplets_buf, cms::alpakatools::make_device_view(queue_, (*pixelTripletsDC_)->nPixelTriplets()));
0733   alpaka::wait(queue_);  // wait to get the value before using it
0734 
0735   std::cout << "number of pixel triplets = " << *nPixelTriplets_buf.data() << std::endl;
0736 #endif
0737 
0738   //pT3s can be cleaned here because they're not used in making pT5s!
0739   //seems like more blocks lead to conflicting writes
0740   auto const removeDupPixelTripletsFromMap_workDiv = cms::alpakatools::make_workdiv<Acc2D>({40, 1}, {16, 16});
0741 
0742   alpaka::exec<Acc2D>(
0743       queue_, removeDupPixelTripletsFromMap_workDiv, RemoveDupPixelTripletsFromMap{}, pixelTripletsDC_->view());
0744 }
0745 
0746 void LSTEvent::createQuintuplets() {
0747   auto const countConn_workDiv = cms::alpakatools::make_workdiv<Acc3D>({nLowerModules_, 1, 1}, {1, 8, 32});
0748 
0749   alpaka::exec<Acc3D>(queue_,
0750                       countConn_workDiv,
0751                       CountTripletConnections{},
0752                       modules_.const_view<ModulesSoA>(),
0753                       segmentsDC_->const_view<SegmentsSoA>(),
0754                       tripletsDC_->view<TripletsSoA>(),
0755                       tripletsDC_->const_view<TripletsOccupancySoA>(),
0756                       rangesDC_->const_view());
0757 
0758   auto const createEligibleModulesListForQuintuplets_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 1024);
0759 
0760   alpaka::exec<Acc1D>(queue_,
0761                       createEligibleModulesListForQuintuplets_workDiv,
0762                       CreateEligibleModulesListForQuintuplets{},
0763                       modules_.const_view<ModulesSoA>(),
0764                       tripletsDC_->const_view<TripletsOccupancySoA>(),
0765                       rangesDC_->view(),
0766                       tripletsDC_->view<TripletsSoA>());
0767 
0768   auto nEligibleT5Modules_buf = cms::alpakatools::make_host_buffer<uint16_t>(queue_);
0769   auto nTotalQuintuplets_buf = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0770   auto rangesOccupancy = rangesDC_->view();
0771   auto nEligibleT5Modules_view_d = cms::alpakatools::make_device_view(queue_, rangesOccupancy.nEligibleT5Modules());
0772   auto nTotalQuintuplets_view_d = cms::alpakatools::make_device_view(queue_, rangesOccupancy.nTotalQuints());
0773   alpaka::memcpy(queue_, nEligibleT5Modules_buf, nEligibleT5Modules_view_d);
0774   alpaka::memcpy(queue_, nTotalQuintuplets_buf, nTotalQuintuplets_view_d);
0775   alpaka::wait(queue_);  // wait for the values before using them
0776 
0777   auto nEligibleT5Modules = *nEligibleT5Modules_buf.data();
0778   auto nTotalQuintuplets = *nTotalQuintuplets_buf.data();
0779 
0780   if (!quintupletsDC_) {
0781     std::array<int, 2> const quintuplets_sizes{{static_cast<int>(nTotalQuintuplets), static_cast<int>(nLowerModules_)}};
0782     quintupletsDC_.emplace(quintuplets_sizes, queue_);
0783     auto quintupletsOccupancy = quintupletsDC_->view<QuintupletsOccupancySoA>();
0784     auto nQuintuplets_view = cms::alpakatools::make_device_view(
0785         queue_, quintupletsOccupancy.nQuintuplets(), quintupletsOccupancy.metadata().size());
0786     alpaka::memset(queue_, nQuintuplets_view, 0u);
0787     auto totOccupancyQuintuplets_view = cms::alpakatools::make_device_view(
0788         queue_, quintupletsOccupancy.totOccupancyQuintuplets(), quintupletsOccupancy.metadata().size());
0789     alpaka::memset(queue_, totOccupancyQuintuplets_view, 0u);
0790     auto quintuplets = quintupletsDC_->view<QuintupletsSoA>();
0791     auto isDup_view = cms::alpakatools::make_device_view(queue_, quintuplets.isDup(), quintuplets.metadata().size());
0792     alpaka::memset(queue_, isDup_view, 0u);
0793     auto tightCutFlag_view =
0794         cms::alpakatools::make_device_view(queue_, quintuplets.tightCutFlag(), quintuplets.metadata().size());
0795     alpaka::memset(queue_, tightCutFlag_view, 0u);
0796     auto partOfPT5_view =
0797         cms::alpakatools::make_device_view(queue_, quintuplets.partOfPT5(), quintuplets.metadata().size());
0798     alpaka::memset(queue_, partOfPT5_view, 0u);
0799   }
0800 
0801   auto const createQuintuplets_workDiv =
0802       cms::alpakatools::make_workdiv<Acc3D>({std::max((int)nEligibleT5Modules, 1), 1, 1}, {1, 8, 32});
0803 
0804   alpaka::exec<Acc3D>(queue_,
0805                       createQuintuplets_workDiv,
0806                       CreateQuintuplets{},
0807                       modules_.const_view<ModulesSoA>(),
0808                       miniDoubletsDC_->const_view<MiniDoubletsSoA>(),
0809                       segmentsDC_->const_view<SegmentsSoA>(),
0810                       tripletsDC_->view<TripletsSoA>(),
0811                       tripletsDC_->const_view<TripletsOccupancySoA>(),
0812                       quintupletsDC_->view<QuintupletsSoA>(),
0813                       quintupletsDC_->view<QuintupletsOccupancySoA>(),
0814                       rangesDC_->const_view(),
0815                       nEligibleT5Modules,
0816                       ptCut_);
0817 
0818   auto const removeDupQuintupletsAfterBuild_workDiv =
0819       cms::alpakatools::make_workdiv<Acc3D>({max_blocks, 1, 1}, {1, 16, 16});
0820 
0821   alpaka::exec<Acc3D>(queue_,
0822                       removeDupQuintupletsAfterBuild_workDiv,
0823                       RemoveDupQuintupletsAfterBuild{},
0824                       modules_.const_view<ModulesSoA>(),
0825                       quintupletsDC_->view<QuintupletsSoA>(),
0826                       quintupletsDC_->const_view<QuintupletsOccupancySoA>(),
0827                       rangesDC_->const_view());
0828 
0829   auto const addQuintupletRangesToEventExplicit_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 1024);
0830 
0831   alpaka::exec<Acc1D>(queue_,
0832                       addQuintupletRangesToEventExplicit_workDiv,
0833                       AddQuintupletRangesToEventExplicit{},
0834                       modules_.const_view<ModulesSoA>(),
0835                       quintupletsDC_->const_view<QuintupletsOccupancySoA>(),
0836                       rangesDC_->view());
0837 
0838   if (addObjects_) {
0839     addQuintupletsToEventExplicit();
0840   }
0841 }
0842 
0843 void LSTEvent::pixelLineSegmentCleaning(bool no_pls_dupclean) {
0844   if (!no_pls_dupclean) {
0845     auto const checkHitspLS_workDiv = cms::alpakatools::make_workdiv<Acc2D>({max_blocks * 4, max_blocks / 4}, {16, 16});
0846 
0847     alpaka::exec<Acc2D>(queue_,
0848                         checkHitspLS_workDiv,
0849                         CheckHitspLS{},
0850                         modules_.const_view<ModulesSoA>(),
0851                         segmentsDC_->const_view<SegmentsOccupancySoA>(),
0852                         lstInputDC_->const_view<PixelSeedsSoA>(),
0853                         pixelSegmentsDC_->view(),
0854                         false);
0855   }
0856 }
0857 
0858 void LSTEvent::createPixelQuintuplets() {
0859   if (!pixelQuintupletsDC_) {
0860     pixelQuintupletsDC_.emplace(n_max_pixel_quintuplets, queue_);
0861     auto nPixelQuintuplets_view =
0862         cms::alpakatools::make_device_view(queue_, (*pixelQuintupletsDC_)->nPixelQuintuplets());
0863     alpaka::memset(queue_, nPixelQuintuplets_view, 0u);
0864     auto totOccupancyPixelQuintuplets_view =
0865         cms::alpakatools::make_device_view(queue_, (*pixelQuintupletsDC_)->totOccupancyPixelQuintuplets());
0866     alpaka::memset(queue_, totOccupancyPixelQuintuplets_view, 0u);
0867   }
0868   if (!trackCandidatesBaseDC_) {
0869     trackCandidatesBaseDC_.emplace(n_max_nonpixel_track_candidates + n_max_pixel_track_candidates, queue_);
0870     trackCandidatesBaseDC_->zeroInitialise(queue_);
0871 
0872     trackCandidatesExtendedDC_.emplace(n_max_nonpixel_track_candidates + n_max_pixel_track_candidates, queue_);
0873     trackCandidatesExtendedDC_->zeroInitialise(queue_);
0874   }
0875   SegmentsOccupancy segmentsOccupancy = segmentsDC_->view<SegmentsOccupancySoA>();
0876   PixelSeedsConst pixelSeeds = lstInputDC_->const_view<PixelSeedsSoA>();
0877 
0878   auto superbins_buf = cms::alpakatools::make_host_buffer<int[]>(queue_, n_max_pixel_segments_per_module);
0879   auto pixelTypes_buf = cms::alpakatools::make_host_buffer<PixelType[]>(queue_, n_max_pixel_segments_per_module);
0880 
0881   alpaka::memcpy(queue_, superbins_buf, cms::alpakatools::make_device_view(queue_, pixelSeeds.superbin(), pixelSize_));
0882   alpaka::memcpy(
0883       queue_, pixelTypes_buf, cms::alpakatools::make_device_view(queue_, pixelSeeds.pixelType(), pixelSize_));
0884   auto const* superbins = superbins_buf.data();
0885   auto const* pixelTypes = pixelTypes_buf.data();
0886 
0887   unsigned int nInnerSegments;
0888   auto nInnerSegments_src_view = cms::alpakatools::make_host_view(nInnerSegments);
0889 
0890   // Create a sub-view for the device buffer
0891   unsigned int totalModules = nLowerModules_ + 1;
0892   auto dev_view_nSegments_buf = cms::alpakatools::make_device_view(queue_, segmentsOccupancy.nSegments(), totalModules);
0893   auto dev_view_nSegments = cms::alpakatools::make_device_view(queue_, segmentsOccupancy.nSegments()[nLowerModules_]);
0894 
0895   alpaka::memcpy(queue_, nInnerSegments_src_view, dev_view_nSegments);
0896   alpaka::wait(queue_);  // wait to get nInnerSegments (also superbins and pixelTypes) before using
0897 
0898   auto connectedPixelSize_host_buf = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nInnerSegments);
0899   auto connectedPixelIndex_host_buf = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nInnerSegments);
0900   auto connectedPixelSize_dev_buf = cms::alpakatools::make_device_buffer<unsigned int[]>(queue_, nInnerSegments);
0901   auto connectedPixelIndex_dev_buf = cms::alpakatools::make_device_buffer<unsigned int[]>(queue_, nInnerSegments);
0902 
0903   auto* connectedPixelSize_host = connectedPixelSize_host_buf.data();
0904   auto* connectedPixelIndex_host = connectedPixelIndex_host_buf.data();
0905 
0906   int pixelIndexOffsetPos = pixelMapping_.connectedPixelsIndex[::size_superbins - 1] +
0907                             pixelMapping_.connectedPixelsSizes[::size_superbins - 1];
0908   int pixelIndexOffsetNeg = pixelMapping_.connectedPixelsIndexPos[::size_superbins - 1] +
0909                             pixelMapping_.connectedPixelsSizesPos[::size_superbins - 1] + pixelIndexOffsetPos;
0910 
0911   // Loop over # pLS
0912   for (unsigned int i = 0; i < nInnerSegments; i++) {
0913     PixelType pixelType = pixelTypes[i];  // Get pixel type for this pLS
0914     int superbin = superbins[i];          // Get superbin for this pixel
0915     if ((superbin < 0) or (superbin >= (int)size_superbins) or
0916         ((pixelType != PixelType::kHighPt) and (pixelType != PixelType::kLowPtPosCurv) and
0917          (pixelType != PixelType::kLowPtNegCurv))) {
0918       connectedPixelSize_host[i] = 0;
0919       connectedPixelIndex_host[i] = 0;
0920       continue;
0921     }
0922 
0923     // Used pixel type to select correct size-index arrays
0924     switch (pixelType) {
0925       case PixelType::kInvalid:
0926         break;
0927       case PixelType::kHighPt:
0928         // number of connected modules to this pixel
0929         connectedPixelSize_host[i] = pixelMapping_.connectedPixelsSizes[superbin];
0930         // index to get start of connected modules for this superbin in map
0931         connectedPixelIndex_host[i] = pixelMapping_.connectedPixelsIndex[superbin];
0932         break;
0933       case PixelType::kLowPtPosCurv:
0934         // number of connected modules to this pixel
0935         connectedPixelSize_host[i] = pixelMapping_.connectedPixelsSizesPos[superbin];
0936         // index to get start of connected modules for this superbin in map
0937         connectedPixelIndex_host[i] = pixelMapping_.connectedPixelsIndexPos[superbin] + pixelIndexOffsetPos;
0938         break;
0939       case PixelType::kLowPtNegCurv:
0940         // number of connected modules to this pixel
0941         connectedPixelSize_host[i] = pixelMapping_.connectedPixelsSizesNeg[superbin];
0942         // index to get start of connected modules for this superbin in map
0943         connectedPixelIndex_host[i] = pixelMapping_.connectedPixelsIndexNeg[superbin] + pixelIndexOffsetNeg;
0944         break;
0945     }
0946   }
0947 
0948   alpaka::memcpy(queue_, connectedPixelSize_dev_buf, connectedPixelSize_host_buf, nInnerSegments);
0949   alpaka::memcpy(queue_, connectedPixelIndex_dev_buf, connectedPixelIndex_host_buf, nInnerSegments);
0950 
0951   auto const createPixelQuintupletsFromMap_workDiv =
0952       cms::alpakatools::make_workdiv<Acc3D>({max_blocks, 16, 1}, {16, 1, 16});
0953 
0954   alpaka::exec<Acc3D>(queue_,
0955                       createPixelQuintupletsFromMap_workDiv,
0956                       CreatePixelQuintupletsFromMap{},
0957                       modules_.const_view<ModulesSoA>(),
0958                       modules_.const_view<ModulesPixelSoA>(),
0959                       miniDoubletsDC_->const_view<MiniDoubletsSoA>(),
0960                       segmentsDC_->const_view<SegmentsSoA>(),
0961                       lstInputDC_->const_view<PixelSeedsSoA>(),
0962                       pixelSegmentsDC_->view(),
0963                       tripletsDC_->view<TripletsSoA>(),
0964                       quintupletsDC_->view<QuintupletsSoA>(),
0965                       quintupletsDC_->const_view<QuintupletsOccupancySoA>(),
0966                       pixelQuintupletsDC_->view(),
0967                       connectedPixelSize_dev_buf.data(),
0968                       connectedPixelIndex_dev_buf.data(),
0969                       nInnerSegments,
0970                       rangesDC_->const_view(),
0971                       ptCut_);
0972 
0973   auto const removeDupPixelQuintupletsFromMap_workDiv =
0974       cms::alpakatools::make_workdiv<Acc2D>({max_blocks, 1}, {16, 16});
0975 
0976   alpaka::exec<Acc2D>(queue_,
0977                       removeDupPixelQuintupletsFromMap_workDiv,
0978                       RemoveDupPixelQuintupletsFromMap{},
0979                       pixelQuintupletsDC_->view());
0980 
0981   auto const addpT5asTrackCandidate_workDiv = cms::alpakatools::make_workdiv<Acc1D>(1, 256);
0982 
0983   alpaka::exec<Acc1D>(queue_,
0984                       addpT5asTrackCandidate_workDiv,
0985                       AddpT5asTrackCandidate{},
0986                       nLowerModules_,
0987                       pixelQuintupletsDC_->const_view(),
0988                       trackCandidatesBaseDC_->view(),
0989                       trackCandidatesExtendedDC_->view(),
0990                       lstInputDC_->const_view<PixelSeedsSoA>(),
0991                       rangesDC_->const_view());
0992 
0993 #ifdef WARNINGS
0994   auto nPixelQuintuplets_buf = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
0995 
0996   alpaka::memcpy(queue_,
0997                  nPixelQuintuplets_buf,
0998                  cms::alpakatools::make_device_view(queue_, (*pixelQuintupletsDC_)->nPixelQuintuplets()));
0999   alpaka::wait(queue_);  // wait to get the value before using it
1000 
1001   std::cout << "number of pixel quintuplets = " << *nPixelQuintuplets_buf.data() << std::endl;
1002 #endif
1003 }
1004 
1005 void LSTEvent::addMiniDoubletsToEventExplicit() {
1006   auto nMDsCPU_buf = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nLowerModules_);
1007   auto mdsOccupancy = miniDoubletsDC_->const_view<MiniDoubletsOccupancySoA>();
1008   auto nMDs_view =
1009       cms::alpakatools::make_device_view(queue_, mdsOccupancy.nMDs(), nLowerModules_);  // exclude pixel part
1010   alpaka::memcpy(queue_, nMDsCPU_buf, nMDs_view, nLowerModules_);
1011 
1012   auto modules = modules_.const_view<ModulesSoA>();
1013 
1014   // FIXME: replace by ES host data
1015   auto module_subdets_buf = cms::alpakatools::make_host_buffer<short[]>(queue_, nLowerModules_);
1016   auto module_subdets_view =
1017       cms::alpakatools::make_device_view(queue_, modules.subdets(), nLowerModules_);  // only lower modules
1018   alpaka::memcpy(queue_, module_subdets_buf, module_subdets_view, nLowerModules_);
1019 
1020   auto module_layers_buf = cms::alpakatools::make_host_buffer<short[]>(queue_, nLowerModules_);
1021   auto module_layers_view =
1022       cms::alpakatools::make_device_view(queue_, modules.layers(), nLowerModules_);  // only lower modules
1023   alpaka::memcpy(queue_, module_layers_buf, module_layers_view, nLowerModules_);
1024 
1025   alpaka::wait(queue_);  // wait for inputs before using them
1026 
1027   auto const* nMDsCPU = nMDsCPU_buf.data();
1028   auto const* module_subdets = module_subdets_buf.data();
1029   auto const* module_layers = module_layers_buf.data();
1030 
1031   for (unsigned int i = 0; i < nLowerModules_; i++) {
1032     if (nMDsCPU[i] != 0) {
1033       if (module_subdets[i] == Barrel) {
1034         n_minidoublets_by_layer_barrel_[module_layers[i] - 1] += nMDsCPU[i];
1035       } else {
1036         n_minidoublets_by_layer_endcap_[module_layers[i] - 1] += nMDsCPU[i];
1037       }
1038     }
1039   }
1040 }
1041 
1042 void LSTEvent::addSegmentsToEventExplicit() {
1043   auto nSegmentsCPU_buf = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nLowerModules_);
1044   auto nSegments_buf = cms::alpakatools::make_device_view(
1045       queue_, segmentsDC_->const_view<SegmentsOccupancySoA>().nSegments(), nLowerModules_);
1046   alpaka::memcpy(queue_, nSegmentsCPU_buf, nSegments_buf, nLowerModules_);
1047 
1048   auto modules = modules_.const_view<ModulesSoA>();
1049 
1050   // FIXME: replace by ES host data
1051   auto module_subdets_buf = cms::alpakatools::make_host_buffer<short[]>(queue_, nLowerModules_);
1052   auto module_subdets_view =
1053       cms::alpakatools::make_device_view(queue_, modules.subdets(), nLowerModules_);  // only lower modules
1054   alpaka::memcpy(queue_, module_subdets_buf, module_subdets_view, nLowerModules_);
1055 
1056   auto module_layers_buf = cms::alpakatools::make_host_buffer<short[]>(queue_, nLowerModules_);
1057   auto module_layers_view =
1058       cms::alpakatools::make_device_view(queue_, modules.layers(), nLowerModules_);  // only lower modules
1059   alpaka::memcpy(queue_, module_layers_buf, module_layers_view, nLowerModules_);
1060 
1061   alpaka::wait(queue_);  // wait for inputs before using them
1062 
1063   auto const* nSegmentsCPU = nSegmentsCPU_buf.data();
1064   auto const* module_subdets = module_subdets_buf.data();
1065   auto const* module_layers = module_layers_buf.data();
1066 
1067   for (unsigned int i = 0; i < nLowerModules_; i++) {
1068     if (!(nSegmentsCPU[i] == 0)) {
1069       if (module_subdets[i] == Barrel) {
1070         n_segments_by_layer_barrel_[module_layers[i] - 1] += nSegmentsCPU[i];
1071       } else {
1072         n_segments_by_layer_endcap_[module_layers[i] - 1] += nSegmentsCPU[i];
1073       }
1074     }
1075   }
1076 }
1077 
1078 void LSTEvent::addQuintupletsToEventExplicit() {
1079   auto quintupletsOccupancy = quintupletsDC_->const_view<QuintupletsOccupancySoA>();
1080   auto nQuintuplets_view =
1081       cms::alpakatools::make_device_view(queue_, quintupletsOccupancy.nQuintuplets(), nLowerModules_);
1082   auto nQuintupletsCPU_buf = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nLowerModules_);
1083   alpaka::memcpy(queue_, nQuintupletsCPU_buf, nQuintuplets_view);
1084 
1085   auto modules = modules_.const_view<ModulesSoA>();
1086 
1087   // FIXME: replace by ES host data
1088   auto module_subdets_buf = cms::alpakatools::make_host_buffer<short[]>(queue_, nLowerModules_);
1089   auto module_subdets_view =
1090       cms::alpakatools::make_device_view(queue_, modules.subdets(), nLowerModules_);  // only lower modules
1091   alpaka::memcpy(queue_, module_subdets_buf, module_subdets_view, nLowerModules_);
1092 
1093   auto module_layers_buf = cms::alpakatools::make_host_buffer<short[]>(queue_, nLowerModules_);
1094   auto module_layers_view =
1095       cms::alpakatools::make_device_view(queue_, modules.layers(), nLowerModules_);  // only lower modules
1096   alpaka::memcpy(queue_, module_layers_buf, module_layers_view, nLowerModules_);
1097 
1098   auto module_quintupletModuleIndices_buf = cms::alpakatools::make_host_buffer<int[]>(queue_, nLowerModules_);
1099   auto rangesOccupancy = rangesDC_->view();
1100   auto quintupletModuleIndices_view_d =
1101       cms::alpakatools::make_device_view(queue_, rangesOccupancy.quintupletModuleIndices(), nLowerModules_);
1102   alpaka::memcpy(queue_, module_quintupletModuleIndices_buf, quintupletModuleIndices_view_d);
1103 
1104   alpaka::wait(queue_);  // wait for inputs before using them
1105 
1106   auto const* nQuintupletsCPU = nQuintupletsCPU_buf.data();
1107   auto const* module_subdets = module_subdets_buf.data();
1108   auto const* module_layers = module_layers_buf.data();
1109   auto const* module_quintupletModuleIndices = module_quintupletModuleIndices_buf.data();
1110 
1111   for (uint16_t i = 0; i < nLowerModules_; i++) {
1112     if (!(nQuintupletsCPU[i] == 0 or module_quintupletModuleIndices[i] == -1)) {
1113       if (module_subdets[i] == Barrel) {
1114         n_quintuplets_by_layer_barrel_[module_layers[i] - 1] += nQuintupletsCPU[i];
1115       } else {
1116         n_quintuplets_by_layer_endcap_[module_layers[i] - 1] += nQuintupletsCPU[i];
1117       }
1118     }
1119   }
1120 }
1121 
1122 void LSTEvent::addTripletsToEventExplicit() {
1123   auto tripletsOccupancy = tripletsDC_->const_view<TripletsOccupancySoA>();
1124   auto nTriplets_view = cms::alpakatools::make_device_view(queue_, tripletsOccupancy.nTriplets(), nLowerModules_);
1125   auto nTripletsCPU_buf = cms::alpakatools::make_host_buffer<unsigned int[]>(queue_, nLowerModules_);
1126   alpaka::memcpy(queue_, nTripletsCPU_buf, nTriplets_view);
1127 
1128   auto modules = modules_.const_view<ModulesSoA>();
1129 
1130   // FIXME: replace by ES host data
1131   auto module_subdets_buf = cms::alpakatools::make_host_buffer<short[]>(queue_, nLowerModules_);
1132   auto module_subdets_view =
1133       cms::alpakatools::make_device_view(queue_, modules.subdets(), nLowerModules_);  // only lower modules
1134   alpaka::memcpy(queue_, module_subdets_buf, module_subdets_view, nLowerModules_);
1135 
1136   auto module_layers_buf = cms::alpakatools::make_host_buffer<short[]>(queue_, nLowerModules_);
1137   auto module_layers_view =
1138       cms::alpakatools::make_device_view(queue_, modules.layers(), nLowerModules_);  // only lower modules
1139   alpaka::memcpy(queue_, module_layers_buf, module_layers_view, nLowerModules_);
1140 
1141   alpaka::wait(queue_);  // wait for inputs before using them
1142 
1143   auto const* nTripletsCPU = nTripletsCPU_buf.data();
1144   auto const* module_subdets = module_subdets_buf.data();
1145   auto const* module_layers = module_layers_buf.data();
1146 
1147   for (uint16_t i = 0; i < nLowerModules_; i++) {
1148     if (nTripletsCPU[i] != 0) {
1149       if (module_subdets[i] == Barrel) {
1150         n_triplets_by_layer_barrel_[module_layers[i] - 1] += nTripletsCPU[i];
1151       } else {
1152         n_triplets_by_layer_endcap_[module_layers[i] - 1] += nTripletsCPU[i];
1153       }
1154     }
1155   }
1156 }
1157 
1158 unsigned int LSTEvent::getNumberOfMiniDoublets() {
1159   unsigned int miniDoublets = 0;
1160   for (auto& it : n_minidoublets_by_layer_barrel_) {
1161     miniDoublets += it;
1162   }
1163   for (auto& it : n_minidoublets_by_layer_endcap_) {
1164     miniDoublets += it;
1165   }
1166 
1167   return miniDoublets;
1168 }
1169 
1170 unsigned int LSTEvent::getNumberOfMiniDoubletsByLayerBarrel(unsigned int layer) {
1171   return n_minidoublets_by_layer_barrel_[layer];
1172 }
1173 
1174 unsigned int LSTEvent::getNumberOfMiniDoubletsByLayerEndcap(unsigned int layer) {
1175   return n_minidoublets_by_layer_endcap_[layer];
1176 }
1177 
1178 unsigned int LSTEvent::getNumberOfSegments() {
1179   unsigned int segments = 0;
1180   for (auto& it : n_segments_by_layer_barrel_) {
1181     segments += it;
1182   }
1183   for (auto& it : n_segments_by_layer_endcap_) {
1184     segments += it;
1185   }
1186 
1187   return segments;
1188 }
1189 
1190 unsigned int LSTEvent::getNumberOfSegmentsByLayerBarrel(unsigned int layer) {
1191   return n_segments_by_layer_barrel_[layer];
1192 }
1193 
1194 unsigned int LSTEvent::getNumberOfSegmentsByLayerEndcap(unsigned int layer) {
1195   return n_segments_by_layer_endcap_[layer];
1196 }
1197 
1198 unsigned int LSTEvent::getNumberOfTriplets() {
1199   unsigned int triplets = 0;
1200   for (auto& it : n_triplets_by_layer_barrel_) {
1201     triplets += it;
1202   }
1203   for (auto& it : n_triplets_by_layer_endcap_) {
1204     triplets += it;
1205   }
1206 
1207   return triplets;
1208 }
1209 
1210 unsigned int LSTEvent::getNumberOfTripletsByLayerBarrel(unsigned int layer) {
1211   return n_triplets_by_layer_barrel_[layer];
1212 }
1213 
1214 unsigned int LSTEvent::getNumberOfTripletsByLayerEndcap(unsigned int layer) {
1215   return n_triplets_by_layer_endcap_[layer];
1216 }
1217 
1218 int LSTEvent::getNumberOfPixelTriplets() {
1219   auto nPixelTriplets_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1220 
1221   alpaka::memcpy(
1222       queue_, nPixelTriplets_buf_h, cms::alpakatools::make_device_view(queue_, (*pixelTripletsDC_)->nPixelTriplets()));
1223   alpaka::wait(queue_);
1224 
1225   return *nPixelTriplets_buf_h.data();
1226 }
1227 
1228 int LSTEvent::getNumberOfPixelQuintuplets() {
1229   auto nPixelQuintuplets_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1230 
1231   alpaka::memcpy(queue_,
1232                  nPixelQuintuplets_buf_h,
1233                  cms::alpakatools::make_device_view(queue_, (*pixelQuintupletsDC_)->nPixelQuintuplets()));
1234   alpaka::wait(queue_);
1235 
1236   return *nPixelQuintuplets_buf_h.data();
1237 }
1238 
1239 unsigned int LSTEvent::getNumberOfQuintuplets() {
1240   unsigned int quintuplets = 0;
1241   for (auto& it : n_quintuplets_by_layer_barrel_) {
1242     quintuplets += it;
1243   }
1244   for (auto& it : n_quintuplets_by_layer_endcap_) {
1245     quintuplets += it;
1246   }
1247 
1248   return quintuplets;
1249 }
1250 
1251 unsigned int LSTEvent::getNumberOfQuintupletsByLayerBarrel(unsigned int layer) {
1252   return n_quintuplets_by_layer_barrel_[layer];
1253 }
1254 
1255 unsigned int LSTEvent::getNumberOfQuintupletsByLayerEndcap(unsigned int layer) {
1256   return n_quintuplets_by_layer_endcap_[layer];
1257 }
1258 
1259 int LSTEvent::getNumberOfTrackCandidates() {
1260   auto nTrackCandidates_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1261 
1262   alpaka::memcpy(queue_,
1263                  nTrackCandidates_buf_h,
1264                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesBaseDC_)->nTrackCandidates()));
1265   alpaka::wait(queue_);
1266 
1267   return *nTrackCandidates_buf_h.data();
1268 }
1269 
1270 int LSTEvent::getNumberOfPT5TrackCandidates() {
1271   auto nTrackCandidatesPT5_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1272 
1273   alpaka::memcpy(queue_,
1274                  nTrackCandidatesPT5_buf_h,
1275                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatespT5()));
1276   alpaka::wait(queue_);
1277 
1278   return *nTrackCandidatesPT5_buf_h.data();
1279 }
1280 
1281 int LSTEvent::getNumberOfPT3TrackCandidates() {
1282   auto nTrackCandidatesPT3_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1283 
1284   alpaka::memcpy(queue_,
1285                  nTrackCandidatesPT3_buf_h,
1286                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatespT3()));
1287   alpaka::wait(queue_);
1288 
1289   return *nTrackCandidatesPT3_buf_h.data();
1290 }
1291 
1292 int LSTEvent::getNumberOfPLSTrackCandidates() {
1293   auto nTrackCandidatesPLS_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1294 
1295   alpaka::memcpy(queue_,
1296                  nTrackCandidatesPLS_buf_h,
1297                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatespLS()));
1298   alpaka::wait(queue_);
1299 
1300   return *nTrackCandidatesPLS_buf_h.data();
1301 }
1302 
1303 int LSTEvent::getNumberOfPixelTrackCandidates() {
1304   auto nTrackCandidates_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1305   auto nTrackCandidatesT5_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1306 
1307   alpaka::memcpy(queue_,
1308                  nTrackCandidates_buf_h,
1309                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesBaseDC_)->nTrackCandidates()));
1310   alpaka::memcpy(queue_,
1311                  nTrackCandidatesT5_buf_h,
1312                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatesT5()));
1313   alpaka::wait(queue_);
1314 
1315   return (*nTrackCandidates_buf_h.data()) - (*nTrackCandidatesT5_buf_h.data());
1316 }
1317 
1318 int LSTEvent::getNumberOfT5TrackCandidates() {
1319   auto nTrackCandidatesT5_buf_h = cms::alpakatools::make_host_buffer<unsigned int>(queue_);
1320 
1321   alpaka::memcpy(queue_,
1322                  nTrackCandidatesT5_buf_h,
1323                  cms::alpakatools::make_device_view(queue_, (*trackCandidatesExtendedDC_)->nTrackCandidatesT5()));
1324   alpaka::wait(queue_);
1325 
1326   return *nTrackCandidatesT5_buf_h.data();
1327 }
1328 
1329 template <typename TSoA, typename TDev>
1330 typename TSoA::ConstView LSTEvent::getInput(bool sync) {
1331   if constexpr (std::is_same_v<TDev, DevHost>) {
1332     return lstInputDC_->const_view<TSoA>();
1333   } else {
1334     // In case getTrimmedInput was called first
1335     if (!lstInputHC_ || lstInputHC_->sizes()[1] == 0) {
1336       lstInputHC_.emplace(
1337           cms::alpakatools::CopyToHost<PortableMultiCollection<TDev, HitsBaseSoA, PixelSeedsSoA>>::copyAsync(
1338               queue_, *lstInputDC_));
1339       if (sync)
1340         alpaka::wait(queue_);  // host consumers expect filled data
1341     }
1342     return lstInputHC_->const_view<TSoA>();
1343   }
1344 }
1345 template HitsBaseConst LSTEvent::getInput<HitsBaseSoA>(bool);
1346 template PixelSeedsConst LSTEvent::getInput<PixelSeedsSoA>(bool);
1347 
1348 template <typename TSoA, typename TDev>
1349 typename TSoA::ConstView LSTEvent::getHits(bool sync) {
1350   if constexpr (std::is_same_v<TDev, DevHost>) {
1351     return hitsDC_->const_view<TSoA>();
1352   } else {
1353     if (!hitsHC_) {
1354       hitsHC_.emplace(
1355           cms::alpakatools::CopyToHost<PortableMultiCollection<TDev, HitsExtendedSoA, HitsRangesSoA>>::copyAsync(
1356               queue_, *hitsDC_));
1357       if (sync)
1358         alpaka::wait(queue_);  // host consumers expect filled data
1359     }
1360     return hitsHC_->const_view<TSoA>();
1361   }
1362 }
1363 template HitsExtendedConst LSTEvent::getHits<HitsExtendedSoA>(bool);
1364 template HitsRangesConst LSTEvent::getHits<HitsRangesSoA>(bool);
1365 
1366 template <typename TDev>
1367 ObjectRangesConst LSTEvent::getRanges(bool sync) {
1368   if constexpr (std::is_same_v<TDev, DevHost>) {
1369     return rangesDC_->const_view();
1370   } else {
1371     if (!rangesHC_) {
1372       rangesHC_.emplace(
1373           cms::alpakatools::CopyToHost<PortableDeviceCollection<ObjectRangesSoA, TDev>>::copyAsync(queue_, *rangesDC_));
1374       if (sync)
1375         alpaka::wait(queue_);  // host consumers expect filled data
1376     }
1377     return rangesHC_->const_view();
1378   }
1379 }
1380 template ObjectRangesConst LSTEvent::getRanges<>(bool);
1381 
1382 template <typename TSoA, typename TDev>
1383 typename TSoA::ConstView LSTEvent::getMiniDoublets(bool sync) {
1384   if constexpr (std::is_same_v<TDev, DevHost>) {
1385     return miniDoubletsDC_->const_view<TSoA>();
1386   } else {
1387     if (!miniDoubletsHC_) {
1388       miniDoubletsHC_.emplace(
1389           cms::alpakatools::CopyToHost<
1390               PortableMultiCollection<TDev, MiniDoubletsSoA, MiniDoubletsOccupancySoA>>::copyAsync(queue_,
1391                                                                                                    *miniDoubletsDC_));
1392       if (sync)
1393         alpaka::wait(queue_);  // host consumers expect filled data
1394     }
1395     return miniDoubletsHC_->const_view<TSoA>();
1396   }
1397 }
1398 template MiniDoubletsConst LSTEvent::getMiniDoublets<MiniDoubletsSoA>(bool);
1399 template MiniDoubletsOccupancyConst LSTEvent::getMiniDoublets<MiniDoubletsOccupancySoA>(bool);
1400 
1401 template <typename TSoA, typename TDev>
1402 typename TSoA::ConstView LSTEvent::getSegments(bool sync) {
1403   if constexpr (std::is_same_v<TDev, DevHost>) {
1404     return segmentsDC_->const_view<TSoA>();
1405   } else {
1406     if (!segmentsHC_) {
1407       segmentsHC_.emplace(
1408           cms::alpakatools::CopyToHost<PortableMultiCollection<TDev, SegmentsSoA, SegmentsOccupancySoA>>::copyAsync(
1409               queue_, *segmentsDC_));
1410       if (sync)
1411         alpaka::wait(queue_);  // host consumers expect filled data
1412     }
1413     return segmentsHC_->const_view<TSoA>();
1414   }
1415 }
1416 template SegmentsConst LSTEvent::getSegments<SegmentsSoA>(bool);
1417 template SegmentsOccupancyConst LSTEvent::getSegments<SegmentsOccupancySoA>(bool);
1418 
1419 template <typename TDev>
1420 PixelSegmentsConst LSTEvent::getPixelSegments(bool sync) {
1421   if constexpr (std::is_same_v<TDev, DevHost>) {
1422     return pixelSegmentsDC_->const_view();
1423   } else {
1424     if (!pixelSegmentsHC_) {
1425       pixelSegmentsHC_.emplace(cms::alpakatools::CopyToHost<::PortableCollection<PixelSegmentsSoA, TDev>>::copyAsync(
1426           queue_, *pixelSegmentsDC_));
1427 
1428       if (sync)
1429         alpaka::wait(queue_);  // host consumers expect filled data
1430     }
1431   }
1432   return pixelSegmentsHC_->const_view();
1433 }
1434 template PixelSegmentsConst LSTEvent::getPixelSegments<>(bool);
1435 
1436 template <typename TSoA, typename TDev>
1437 typename TSoA::ConstView LSTEvent::getTriplets(bool sync) {
1438   if constexpr (std::is_same_v<TDev, DevHost>) {
1439     return tripletsDC_->const_view<TSoA>();
1440   } else {
1441     if (!tripletsHC_) {
1442       tripletsHC_.emplace(
1443           cms::alpakatools::CopyToHost<PortableMultiCollection<TDev, TripletsSoA, TripletsOccupancySoA>>::copyAsync(
1444               queue_, *tripletsDC_));
1445 
1446       if (sync)
1447         alpaka::wait(queue_);  // host consumers expect filled data
1448     }
1449   }
1450   return tripletsHC_->const_view<TSoA>();
1451 }
1452 template TripletsConst LSTEvent::getTriplets<TripletsSoA>(bool);
1453 template TripletsOccupancyConst LSTEvent::getTriplets<TripletsOccupancySoA>(bool);
1454 
1455 template <typename TSoA, typename TDev>
1456 typename TSoA::ConstView LSTEvent::getQuintuplets(bool sync) {
1457   if constexpr (std::is_same_v<TDev, DevHost>) {
1458     return quintupletsDC_->const_view<TSoA>();
1459   } else {
1460     if (!quintupletsHC_) {
1461       quintupletsHC_.emplace(
1462           cms::alpakatools::CopyToHost<PortableMultiCollection<TDev, QuintupletsSoA, QuintupletsOccupancySoA>>::copyAsync(
1463               queue_, *quintupletsDC_));
1464 
1465       if (sync)
1466         alpaka::wait(queue_);  // host consumers expect filled data
1467     }
1468   }
1469   return quintupletsHC_->const_view<TSoA>();
1470 }
1471 template QuintupletsConst LSTEvent::getQuintuplets<QuintupletsSoA>(bool);
1472 template QuintupletsOccupancyConst LSTEvent::getQuintuplets<QuintupletsOccupancySoA>(bool);
1473 
1474 template <typename TDev>
1475 PixelTripletsConst LSTEvent::getPixelTriplets(bool sync) {
1476   if constexpr (std::is_same_v<TDev, DevHost>) {
1477     return pixelTripletsDC_->const_view();
1478   } else {
1479     if (!pixelTripletsHC_) {
1480       pixelTripletsHC_.emplace(cms::alpakatools::CopyToHost<::PortableCollection<PixelTripletsSoA, TDev>>::copyAsync(
1481           queue_, *pixelTripletsDC_));
1482 
1483       if (sync)
1484         alpaka::wait(queue_);  // host consumers expect filled data
1485     }
1486   }
1487   return pixelTripletsHC_->const_view();
1488 }
1489 template PixelTripletsConst LSTEvent::getPixelTriplets<>(bool);
1490 
1491 template <typename TDev>
1492 PixelQuintupletsConst LSTEvent::getPixelQuintuplets(bool sync) {
1493   if constexpr (std::is_same_v<TDev, DevHost>) {
1494     return pixelQuintupletsDC_->const_view();
1495   } else {
1496     if (!pixelQuintupletsHC_) {
1497       pixelQuintupletsHC_.emplace(
1498           cms::alpakatools::CopyToHost<::PortableCollection<PixelQuintupletsSoA, TDev>>::copyAsync(
1499               queue_, *pixelQuintupletsDC_));
1500 
1501       if (sync)
1502         alpaka::wait(queue_);  // host consumers expect filled data
1503     }
1504   }
1505   return pixelQuintupletsHC_->const_view();
1506 }
1507 template PixelQuintupletsConst LSTEvent::getPixelQuintuplets<>(bool);
1508 
1509 template <typename TDev>
1510 TrackCandidatesBaseConst LSTEvent::getTrackCandidatesBase(bool sync) {
1511   if constexpr (std::is_same_v<TDev, DevHost>) {
1512     return trackCandidatesBaseDC_->const_view();
1513   } else {
1514     if (!trackCandidatesBaseHC_) {
1515       trackCandidatesBaseHC_.emplace(
1516           cms::alpakatools::CopyToHost<::PortableCollection<TrackCandidatesBaseSoA, TDev>>::copyAsync(
1517               queue_, *trackCandidatesBaseDC_));
1518 
1519       if (sync)
1520         alpaka::wait(queue_);  // host consumers expect filled data
1521     }
1522   }
1523   return trackCandidatesBaseHC_->const_view();
1524 }
1525 template TrackCandidatesBaseConst LSTEvent::getTrackCandidatesBase<>(bool);
1526 
1527 template <typename TDev>
1528 TrackCandidatesExtendedConst LSTEvent::getTrackCandidatesExtended(bool sync) {
1529   if constexpr (std::is_same_v<TDev, DevHost>) {
1530     return trackCandidatesExtendedDC_->const_view();
1531   } else {
1532     if (!trackCandidatesExtendedHC_) {
1533       trackCandidatesExtendedHC_.emplace(
1534           cms::alpakatools::CopyToHost<::PortableCollection<TrackCandidatesExtendedSoA, TDev>>::copyAsync(
1535               queue_, *trackCandidatesExtendedDC_));
1536 
1537       if (sync)
1538         alpaka::wait(queue_);  // host consumers expect filled data
1539     }
1540   }
1541   return trackCandidatesExtendedHC_->const_view();
1542 }
1543 template TrackCandidatesExtendedConst LSTEvent::getTrackCandidatesExtended<>(bool);
1544 
1545 std::unique_ptr<TrackCandidatesBaseDeviceCollection> LSTEvent::releaseTrackCandidatesBaseDeviceCollection() {
1546   return std::make_unique<TrackCandidatesBaseDeviceCollection>(std::move(trackCandidatesBaseDC_.value()));
1547 }
1548 
1549 template <typename TSoA, typename TDev>
1550 typename TSoA::ConstView LSTEvent::getModules(bool sync) {
1551   if constexpr (std::is_same_v<TDev, DevHost>) {
1552     return modules_.const_view<TSoA>();
1553   } else {
1554     if (!modulesHC_) {
1555       modulesHC_.emplace(
1556           cms::alpakatools::CopyToHost<PortableMultiCollection<TDev, ModulesSoA, ModulesPixelSoA>>::copyAsync(
1557               queue_, modules_));
1558       if (sync)
1559         alpaka::wait(queue_);  // host consumers expect filled data
1560     }
1561     return modulesHC_->const_view<TSoA>();
1562   }
1563 }
1564 template ModulesConst LSTEvent::getModules<ModulesSoA>(bool);
1565 template ModulesPixelConst LSTEvent::getModules<ModulesPixelSoA>(bool);