1414// /
1515
1616#include < algorithm>
17+ #include < cwctype>
1718#include < iostream>
1819#include < iterator>
1920#include < ranges>
21+ #include < type_traits>
2022
2123#ifdef OPTIMISATION_OUTPUT
2224#include < format>
@@ -43,6 +45,12 @@ namespace o2::its
4345
4446static constexpr int debugLevel{0 };
4547
48+ struct PassMode {
49+ using OnePass = std::integral_constant<int , 0 >;
50+ using TwoPassCount = std::integral_constant<int , 1 >;
51+ using TwoPassInsert = std::integral_constant<int , 2 >;
52+ };
53+
4654template <int nLayers>
4755void TrackerTraits<nLayers>::computeLayerTracklets(const int iteration, int iROFslice, int iVertex)
4856{
@@ -622,140 +630,123 @@ void TrackerTraits<nLayers>::processNeighbours(int iLayer, int iLevel, const bou
622630#endif
623631
624632 mTaskArena ->execute ([&] {
625- bounded_vector<int > perCellCount (currentCellSeed.size () + 1 , 0 , mMemoryPool .get ());
626- tbb::parallel_for (
627- tbb::blocked_range<int >(0 , (int )currentCellSeed.size ()),
628- [&](const tbb::blocked_range<int >& Cells) {
629- for (int iCell = Cells.begin (); iCell < Cells.end (); ++iCell) {
630- const CellSeed& currentCell{currentCellSeed[iCell]};
631- int foundSeeds{0 };
632- if (currentCell.getLevel () != iLevel) {
633- continue ;
634- }
635- if (currentCellId.empty () && (mTimeFrame ->isClusterUsed (iLayer, currentCell.getFirstClusterIndex ()) ||
636- mTimeFrame ->isClusterUsed (iLayer + 1 , currentCell.getSecondClusterIndex ()) ||
637- mTimeFrame ->isClusterUsed (iLayer + 2 , currentCell.getThirdClusterIndex ()))) {
638- continue ; // / this we do only on the first iteration, hence the check on currentCellId
639- }
640- const int cellId = currentCellId.empty () ? iCell : currentCellId[iCell];
641- const int startNeighbourId{cellId ? mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ][cellId - 1 ] : 0 };
642- const int endNeighbourId{mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ][cellId]};
643-
644- for (int iNeighbourCell{startNeighbourId}; iNeighbourCell < endNeighbourId; ++iNeighbourCell) {
645- CA_DEBUGGER (attempts++);
646- const int neighbourCellId = mTimeFrame ->getCellsNeighbours ()[iLayer - 1 ][iNeighbourCell];
647- const CellSeed& neighbourCell = mTimeFrame ->getCells ()[iLayer - 1 ][neighbourCellId];
648- if (neighbourCell.getSecondTrackletIndex () != currentCell.getFirstTrackletIndex ()) {
649- CA_DEBUGGER (failedByMismatch++);
650- continue ;
651- }
652- if (mTimeFrame ->isClusterUsed (iLayer - 1 , neighbourCell.getFirstClusterIndex ())) {
653- continue ;
654- }
655- if (currentCell.getLevel () - 1 != neighbourCell.getLevel ()) {
656- CA_DEBUGGER (failed[0 ]++);
657- continue ;
658- }
659- // / Let's start the fitting procedure
660- CellSeed seed{currentCell};
661- auto & trHit = mTimeFrame ->getTrackingFrameInfoOnLayer (iLayer - 1 )[neighbourCell.getFirstClusterIndex ()];
662-
663- if (!seed.rotate (trHit.alphaTrackingFrame )) {
664- CA_DEBUGGER (failed[1 ]++);
665- continue ;
666- }
633+ auto forCellNeighbours = [&](auto Tag, int iCell, int offset = 0 ) -> int {
634+ const CellSeed& currentCell{currentCellSeed[iCell]};
635+ if (currentCell.getLevel () != iLevel) {
636+ return 0 ;
637+ }
638+ if (currentCellId.empty () && (mTimeFrame ->isClusterUsed (iLayer, currentCell.getFirstClusterIndex ()) ||
639+ mTimeFrame ->isClusterUsed (iLayer + 1 , currentCell.getSecondClusterIndex ()) ||
640+ mTimeFrame ->isClusterUsed (iLayer + 2 , currentCell.getThirdClusterIndex ()))) {
641+ return 0 ; // / this we do only on the first iteration, hence the check on currentCellId
642+ }
643+ const int cellId = currentCellId.empty () ? iCell : currentCellId[iCell];
644+ const int startNeighbourId{cellId ? mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ][cellId - 1 ] : 0 };
645+ const int endNeighbourId{mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ][cellId]};
646+ int foundSeeds{0 };
647+ for (int iNeighbourCell{startNeighbourId}; iNeighbourCell < endNeighbourId; ++iNeighbourCell) {
648+ CA_DEBUGGER (attempts++);
649+ const int neighbourCellId = mTimeFrame ->getCellsNeighbours ()[iLayer - 1 ][iNeighbourCell];
650+ const CellSeed& neighbourCell = mTimeFrame ->getCells ()[iLayer - 1 ][neighbourCellId];
651+ if (neighbourCell.getSecondTrackletIndex () != currentCell.getFirstTrackletIndex ()) {
652+ CA_DEBUGGER (failedByMismatch++);
653+ continue ;
654+ }
655+ if (mTimeFrame ->isClusterUsed (iLayer - 1 , neighbourCell.getFirstClusterIndex ())) {
656+ continue ;
657+ }
658+ if (currentCell.getLevel () - 1 != neighbourCell.getLevel ()) {
659+ CA_DEBUGGER (failed[0 ]++);
660+ continue ;
661+ }
662+ // / Let's start the fitting procedure
663+ CellSeed seed{currentCell};
664+ const auto & trHit = mTimeFrame ->getTrackingFrameInfoOnLayer (iLayer - 1 )[neighbourCell.getFirstClusterIndex ()];
667665
668- if (!propagator-> propagateToX ( seed, trHit. xTrackingFrame , getBz (), o2::base::PropagatorImpl< float >:: MAX_SIN_PHI , o2::base::PropagatorImpl< float >:: MAX_STEP , mCorrType )) {
669- CA_DEBUGGER (failed[2 ]++);
670- continue ;
671- }
666+ if (!seed. rotate (trHit. alphaTrackingFrame )) {
667+ CA_DEBUGGER (failed[1 ]++);
668+ continue ;
669+ }
672670
673- if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) {
674- if (!seed.correctForMaterial (mTrkParams [0 ].LayerxX0 [iLayer - 1 ], mTrkParams [0 ].LayerxX0 [iLayer - 1 ] * constants::Radl * constants::Rho, true )) {
675- continue ;
676- }
677- }
671+ if (!propagator->propagateToX (seed, trHit.xTrackingFrame , getBz (), o2::base::PropagatorImpl<float >::MAX_SIN_PHI , o2::base::PropagatorImpl<float >::MAX_STEP , mCorrType )) {
672+ CA_DEBUGGER (failed[2 ]++);
673+ continue ;
674+ }
678675
679- auto predChi2{seed.getPredictedChi2Quiet (trHit.positionTrackingFrame , trHit.covarianceTrackingFrame )};
680- if ((predChi2 > mTrkParams [0 ].MaxChi2ClusterAttachment ) || predChi2 < 0 .f ) {
681- CA_DEBUGGER (failed[3 ]++);
682- continue ;
683- }
684- seed.setChi2 (seed.getChi2 () + predChi2);
685- if (!seed.o2 ::track::TrackParCov::update (trHit.positionTrackingFrame , trHit.covarianceTrackingFrame )) {
686- CA_DEBUGGER (failed[4 ]++);
687- continue ;
688- }
689- ++foundSeeds;
676+ if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) {
677+ if (!seed.correctForMaterial (mTrkParams [0 ].LayerxX0 [iLayer - 1 ], mTrkParams [0 ].LayerxX0 [iLayer - 1 ] * constants::Radl * constants::Rho, true )) {
678+ continue ;
690679 }
691- perCellCount[iCell] = foundSeeds;
692680 }
693- });
694681
695- std::exclusive_scan (perCellCount.begin (), perCellCount.end (), perCellCount.begin (), 0 );
696- auto totalNeighbours{perCellCount.back ()};
697- if (totalNeighbours == 0 ) {
698- return ;
699- }
700- updatedCellSeeds.resize (totalNeighbours);
701- updatedCellsIds.resize (totalNeighbours);
682+ auto predChi2{seed.getPredictedChi2Quiet (trHit.positionTrackingFrame , trHit.covarianceTrackingFrame )};
683+ if ((predChi2 > mTrkParams [0 ].MaxChi2ClusterAttachment ) || predChi2 < 0 .f ) {
684+ CA_DEBUGGER (failed[3 ]++);
685+ continue ;
686+ }
687+ seed.setChi2 (seed.getChi2 () + predChi2);
688+ if (!seed.o2 ::track::TrackParCov::update (trHit.positionTrackingFrame , trHit.covarianceTrackingFrame )) {
689+ CA_DEBUGGER (failed[4 ]++);
690+ continue ;
691+ }
702692
703- tbb::parallel_for (
704- tbb::blocked_range<int >(0 , (int )currentCellSeed.size ()),
705- [&](const tbb::blocked_range<int >& Cells) {
706- for (int iCell = Cells.begin (); iCell < Cells.end (); ++iCell) {
707- if (perCellCount[iCell] == perCellCount[iCell + 1 ]) {
708- continue ;
709- }
710- // no need for further checks on cell level
711-
712- const CellSeed& currentCell{currentCellSeed[iCell]};
713- const int cellId = currentCellId.empty () ? iCell : currentCellId[iCell];
714- const int startNeighbourId{cellId ? mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ][cellId - 1 ] : 0 };
715- const int endNeighbourId{mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ][cellId]};
716-
717- int offset = perCellCount[iCell];
718- for (int iNeighbourCell{startNeighbourId}; iNeighbourCell < endNeighbourId; ++iNeighbourCell) {
719- const int neighbourCellId = mTimeFrame ->getCellsNeighbours ()[iLayer - 1 ][iNeighbourCell];
720- const CellSeed& neighbourCell = mTimeFrame ->getCells ()[iLayer - 1 ][neighbourCellId];
721- if (neighbourCell.getSecondTrackletIndex () != currentCell.getFirstTrackletIndex () ||
722- mTimeFrame ->isClusterUsed (iLayer - 1 , neighbourCell.getFirstClusterIndex ()) ||
723- currentCell.getLevel () - 1 != neighbourCell.getLevel ()) {
724- continue ;
725- }
693+ if constexpr (decltype (Tag)::value != PassMode::TwoPassCount::value) {
694+ seed.getClusters ()[iLayer - 1 ] = neighbourCell.getFirstClusterIndex ();
695+ seed.setLevel (neighbourCell.getLevel ());
696+ seed.setFirstTrackletIndex (neighbourCell.getFirstTrackletIndex ());
697+ seed.setSecondTrackletIndex (neighbourCell.getSecondTrackletIndex ());
698+ }
726699
727- auto seed = currentCell;
700+ if constexpr (decltype (Tag)::value == PassMode::OnePass::value) {
701+ updatedCellSeeds.push_back (seed);
702+ updatedCellsIds.push_back (neighbourCellId);
703+ } else if constexpr (decltype (Tag)::value == PassMode::TwoPassCount::value) {
704+ ++foundSeeds;
705+ } else if constexpr (decltype (Tag)::value == PassMode::TwoPassInsert::value) {
706+ updatedCellSeeds[offset] = seed;
707+ updatedCellsIds[offset++] = neighbourCellId;
708+ } else {
709+ static_assert (false , " Unknown mode!" );
710+ }
711+ }
712+ return foundSeeds;
713+ };
728714
729- const auto & trHit = mTimeFrame ->getTrackingFrameInfoOnLayer (iLayer - 1 )[neighbourCell.getFirstClusterIndex ()];
730- if (!seed.rotate (trHit.alphaTrackingFrame ) || !propagator->propagateToX (seed, trHit.xTrackingFrame , getBz (), o2::base::PropagatorImpl<float >::MAX_SIN_PHI , o2::base::PropagatorImpl<float >::MAX_STEP , mCorrType )) {
731- continue ;
732- }
715+ const int nCells = static_cast <int >(currentCellSeed.size ());
716+ if (mTaskArena ->max_concurrency () <= 1 ) {
717+ for (int iCell{0 }; iCell < nCells; ++iCell) {
718+ forCellNeighbours (PassMode::OnePass{}, iCell);
719+ }
720+ } else {
721+ bounded_vector<int > perCellCount (nCells + 1 , 0 , mMemoryPool .get ());
722+ tbb::parallel_for (
723+ tbb::blocked_range<int >(0 , nCells),
724+ [&](const tbb::blocked_range<int >& Cells) {
725+ for (int iCell = Cells.begin (); iCell < Cells.end (); ++iCell) {
726+ perCellCount[iCell] = forCellNeighbours (PassMode::TwoPassCount{}, iCell);
727+ }
728+ });
733729
734- if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) {
735- if (!seed.correctForMaterial (mTrkParams [0 ].LayerxX0 [iLayer - 1 ], mTrkParams [0 ].LayerxX0 [iLayer - 1 ] * constants::Radl * constants::Rho, true )) {
736- continue ;
737- }
738- }
730+ std::exclusive_scan (perCellCount.begin (), perCellCount.end (), perCellCount.begin (), 0 );
731+ auto totalNeighbours{perCellCount.back ()};
732+ if (totalNeighbours == 0 ) {
733+ return ;
734+ }
735+ updatedCellSeeds.resize (totalNeighbours);
736+ updatedCellsIds.resize (totalNeighbours);
739737
740- auto predChi2{seed. getPredictedChi2Quiet (trHit. positionTrackingFrame , trHit. covarianceTrackingFrame )};
741- if ((predChi2 > mTrkParams [ 0 ]. MaxChi2ClusterAttachment ) || predChi2 < 0 . f ) {
742- continue ;
743- }
744- seed. setChi2 (seed. getChi2 () + predChi2) ;
745- if (!seed. o2 ::track::TrackParCov::update (trHit. positionTrackingFrame , trHit. covarianceTrackingFrame ) ) {
738+ tbb::parallel_for (
739+ tbb::blocked_range< int >( 0 , nCells),
740+ [&]( const tbb::blocked_range< int >& Cells) {
741+ for ( int iCell = Cells. begin (); iCell < Cells. end (); ++iCell) {
742+ int offset = perCellCount[iCell] ;
743+ if (offset == perCellCount[iCell + 1 ] ) {
746744 continue ;
747745 }
748-
749- seed.getClusters ()[iLayer - 1 ] = neighbourCell.getFirstClusterIndex ();
750- seed.setLevel (neighbourCell.getLevel ());
751- seed.setFirstTrackletIndex (neighbourCell.getFirstTrackletIndex ());
752- seed.setSecondTrackletIndex (neighbourCell.getSecondTrackletIndex ());
753-
754- updatedCellSeeds[offset] = seed;
755- updatedCellsIds[offset++] = neighbourCellId;
746+ forCellNeighbours (PassMode::TwoPassInsert{}, iCell, offset);
756747 }
757- }
758- });
748+ });
749+ }
759750 });
760751
761752#ifdef CA_DEBUG
0 commit comments