@@ -471,26 +471,20 @@ template <int nLayers>
471471void TrackerTraits<nLayers>::processNeighbours(int iLayer, int iLevel, const bounded_vector<CellSeed>& currentCellSeed, const bounded_vector<int >& currentCellId, bounded_vector<CellSeed>& updatedCellSeeds, bounded_vector<int >& updatedCellsIds)
472472{
473473 CA_DEBUGGER (std::cout << " Processing neighbours layer " << iLayer << " level " << iLevel << " , size of the cell seeds: " << currentCellSeed.size () << std::endl);
474- updatedCellSeeds.reserve (mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ].size ()); // / This is not the correct value, we could do a loop to count the number of neighbours
475- updatedCellsIds.reserve (updatedCellSeeds.size ());
476474 auto propagator = o2::base::Propagator::Instance ();
475+
477476#ifdef CA_DEBUG
478477 int failed[5 ]{0 , 0 , 0 , 0 , 0 }, attempts{0 }, failedByMismatch{0 };
479478#endif
480479
481480 mTaskArena .execute ([&] {
482- // TODO better to use concurrent vector?
483- tbb::combinable<std::pair<bounded_vector<int >, bounded_vector<CellSeed>>> locUpdatedData ([&] {
484- return std::make_pair (bounded_vector<int >(mMemoryPool .get ()), bounded_vector<CellSeed>(mMemoryPool .get ()));
485- });
486-
481+ std::vector<int > perCellCount (currentCellSeed.size () + 1 , 0 );
487482 tbb::parallel_for (
488483 tbb::blocked_range<int >(0 , (int )currentCellSeed.size ()),
489484 [&](const tbb::blocked_range<int >& Cells) {
490- auto & [locUpdatedCellsIds, locUpdatedCellSeeds] = locUpdatedData.local ();
491-
492485 for (int iCell = Cells.begin (); iCell < Cells.end (); ++iCell) {
493486 const CellSeed& currentCell{currentCellSeed[iCell]};
487+ int foundSeeds{0 };
494488 if (currentCell.getLevel () != iLevel) {
495489 continue ;
496490 }
@@ -550,25 +544,83 @@ void TrackerTraits<nLayers>::processNeighbours(int iLayer, int iLevel, const bou
550544 CA_DEBUGGER (failed[4 ]++);
551545 continue ;
552546 }
547+ ++foundSeeds;
548+ }
549+ perCellCount[iCell] = foundSeeds;
550+ }
551+ });
552+
553+ std::exclusive_scan (perCellCount.begin (), perCellCount.end (), perCellCount.begin (), 0 );
554+ perCellCount.shrink_to_fit ();
555+ int total{perCellCount.back ()};
556+ if (total == 0 ) {
557+ return ;
558+ }
559+ updatedCellSeeds.resize (total);
560+ updatedCellsIds.resize (total);
561+
562+ tbb::parallel_for (
563+ tbb::blocked_range<int >(0 , (int )currentCellSeed.size ()),
564+ [&](const tbb::blocked_range<int >& Cells) {
565+ for (int iCell = Cells.begin (); iCell < Cells.end (); ++iCell) {
566+ if (perCellCount[iCell] == perCellCount[iCell + 1 ]) {
567+ continue ;
568+ }
569+ // no need for further checks on cell level
570+
571+ const CellSeed& currentCell{currentCellSeed[iCell]};
572+ const int cellId = currentCellId.empty () ? iCell : currentCellId[iCell];
573+ const int startNeighbourId{cellId ? mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ][cellId - 1 ] : 0 };
574+ const int endNeighbourId{mTimeFrame ->getCellsNeighboursLUT ()[iLayer - 1 ][cellId]};
575+
576+ int offset = perCellCount[iCell];
577+ int foundSeeds{0 };
578+
579+ for (int iNeighbourCell{startNeighbourId}; iNeighbourCell < endNeighbourId; ++iNeighbourCell) {
580+ const int neighbourCellId = mTimeFrame ->getCellsNeighbours ()[iLayer - 1 ][iNeighbourCell];
581+ const CellSeed& neighbourCell = mTimeFrame ->getCells ()[iLayer - 1 ][neighbourCellId];
582+ if (neighbourCell.getSecondTrackletIndex () != currentCell.getFirstTrackletIndex () ||
583+ mTimeFrame ->isClusterUsed (iLayer - 1 , neighbourCell.getFirstClusterIndex ()) ||
584+ currentCell.getLevel () - 1 != neighbourCell.getLevel ()) {
585+ continue ;
586+ }
587+
588+ auto seed = currentCell;
589+
590+ const auto & trHit = mTimeFrame ->getTrackingFrameInfoOnLayer (iLayer - 1 ).at (neighbourCell.getFirstClusterIndex ());
591+ 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 )) {
592+ continue ;
593+ }
594+
595+ if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) {
596+ float radl = 9 .36f ; // Radiation length of Si [cm]
597+ float rho = 2 .33f ; // Density of Si [g/cm^3]
598+ if (!seed.correctForMaterial (mTrkParams [0 ].LayerxX0 [iLayer - 1 ], mTrkParams [0 ].LayerxX0 [iLayer - 1 ] * radl * rho, true )) {
599+ continue ;
600+ }
601+ }
602+
603+ auto predChi2{seed.getPredictedChi2Quiet (trHit.positionTrackingFrame , trHit.covarianceTrackingFrame )};
604+ if ((predChi2 > mTrkParams [0 ].MaxChi2ClusterAttachment ) || predChi2 < 0 .f ) {
605+ continue ;
606+ }
607+ seed.setChi2 (seed.getChi2 () + predChi2);
608+ if (!seed.o2 ::track::TrackParCov::update (trHit.positionTrackingFrame , trHit.covarianceTrackingFrame )) {
609+ continue ;
610+ }
611+
553612 seed.getClusters ()[iLayer - 1 ] = neighbourCell.getFirstClusterIndex ();
554613 seed.setLevel (neighbourCell.getLevel ());
555614 seed.setFirstTrackletIndex (neighbourCell.getFirstTrackletIndex ());
556615 seed.setSecondTrackletIndex (neighbourCell.getSecondTrackletIndex ());
557616
558- locUpdatedCellSeeds.push_back (seed);
559- locUpdatedCellsIds.push_back (neighbourCellId);
617+ updatedCellSeeds[offset + foundSeeds] = seed;
618+ updatedCellsIds[offset + foundSeeds] = neighbourCellId;
619+ ++foundSeeds;
560620 }
561621 }
562622 });
563-
564- locUpdatedData.combine_each ([&](const auto & localData) {
565- const auto & [ids, seeds] = localData;
566- updatedCellsIds.insert (updatedCellsIds.begin (), ids.begin (), ids.end ());
567- updatedCellSeeds.insert (updatedCellSeeds.begin (), seeds.begin (), seeds.end ());
568- });
569623 });
570- updatedCellSeeds.shrink_to_fit ();
571- updatedCellsIds.shrink_to_fit ();
572624
573625#ifdef CA_DEBUG
574626 std::cout << " \t\t - Found " << updatedCellSeeds.size () << " cell seeds out of " << attempts << " attempts" << std::endl;
0 commit comments