|
12 | 12 | /// \file TrackerTraits.cxx |
13 | 13 | /// \brief |
14 | 14 | /// |
| 15 | + |
15 | 16 | #include <algorithm> |
16 | | -#include <cassert> |
17 | 17 | #include <iostream> |
| 18 | +#include <iterator> |
| 19 | +#include <ranges> |
18 | 20 |
|
19 | 21 | #ifdef OPTIMISATION_OUTPUT |
20 | 22 | #include <format> |
@@ -498,63 +500,125 @@ void TrackerTraits<nLayers>::findCellsNeighbours(const int iteration) |
498 | 500 | #endif |
499 | 501 | for (int iLayer{0}; iLayer < mTrkParams[iteration].CellsPerRoad() - 1; ++iLayer) { |
500 | 502 | const int nextLayerCellsNum{static_cast<int>(mTimeFrame->getCells()[iLayer + 1].size())}; |
501 | | - mTimeFrame->getCellsNeighboursLUT()[iLayer].clear(); |
502 | | - mTimeFrame->getCellsNeighboursLUT()[iLayer].resize(nextLayerCellsNum, 0); |
| 503 | + deepVectorClear(mTimeFrame->getCellsNeighbours()[iLayer]); |
| 504 | + deepVectorClear(mTimeFrame->getCellsNeighboursLUT()[iLayer]); |
503 | 505 | if (mTimeFrame->getCells()[iLayer + 1].empty() || |
504 | 506 | mTimeFrame->getCellsLookupTable()[iLayer].empty()) { |
505 | | - mTimeFrame->getCellsNeighbours()[iLayer].clear(); |
506 | 507 | continue; |
507 | 508 | } |
508 | 509 |
|
509 | | - int layerCellsNum{static_cast<int>(mTimeFrame->getCells()[iLayer].size())}; |
510 | | - bounded_vector<std::pair<int, int>> cellsNeighbours(mMemoryPool.get()); |
511 | | - cellsNeighbours.reserve(nextLayerCellsNum); |
512 | | - |
513 | | - for (int iCell{0}; iCell < layerCellsNum; ++iCell) { |
514 | | - const auto& currentCellSeed{mTimeFrame->getCells()[iLayer][iCell]}; |
515 | | - const int nextLayerTrackletIndex{currentCellSeed.getSecondTrackletIndex()}; |
516 | | - const int nextLayerFirstCellIndex{mTimeFrame->getCellsLookupTable()[iLayer][nextLayerTrackletIndex]}; |
517 | | - const int nextLayerLastCellIndex{mTimeFrame->getCellsLookupTable()[iLayer][nextLayerTrackletIndex + 1]}; |
518 | | - for (int iNextCell{nextLayerFirstCellIndex}; iNextCell < nextLayerLastCellIndex; ++iNextCell) { |
| 510 | + mTaskArena.execute([&] { |
| 511 | + int layerCellsNum{static_cast<int>(mTimeFrame->getCells()[iLayer].size())}; |
519 | 512 |
|
520 | | - auto nextCellSeed{mTimeFrame->getCells()[iLayer + 1][iNextCell]}; /// copy |
521 | | - if (nextCellSeed.getFirstTrackletIndex() != nextLayerTrackletIndex) { |
522 | | - break; |
523 | | - } |
| 513 | + bounded_vector<int> perCellCount(layerCellsNum + 1, 0, mMemoryPool.get()); |
| 514 | + tbb::parallel_for( |
| 515 | + tbb::blocked_range<int>(0, layerCellsNum), |
| 516 | + [&](const tbb::blocked_range<int>& Cells) { |
| 517 | + for (int iCell = Cells.begin(); iCell < Cells.end(); ++iCell) { |
| 518 | + const auto& currentCellSeed{mTimeFrame->getCells()[iLayer][iCell]}; |
| 519 | + const int nextLayerTrackletIndex{currentCellSeed.getSecondTrackletIndex()}; |
| 520 | + const int nextLayerFirstCellIndex{mTimeFrame->getCellsLookupTable()[iLayer][nextLayerTrackletIndex]}; |
| 521 | + const int nextLayerLastCellIndex{mTimeFrame->getCellsLookupTable()[iLayer][nextLayerTrackletIndex + 1]}; |
| 522 | + |
| 523 | + int foundNextCells{0}; |
| 524 | + for (int iNextCell{nextLayerFirstCellIndex}; iNextCell < nextLayerLastCellIndex; ++iNextCell) { |
| 525 | + auto nextCellSeed{mTimeFrame->getCells()[iLayer + 1][iNextCell]}; /// copy |
| 526 | + if (nextCellSeed.getFirstTrackletIndex() != nextLayerTrackletIndex) { |
| 527 | + break; |
| 528 | + } |
524 | 529 |
|
525 | | - if (!nextCellSeed.rotate(currentCellSeed.getAlpha()) || |
526 | | - !nextCellSeed.propagateTo(currentCellSeed.getX(), getBz())) { |
527 | | - continue; |
528 | | - } |
529 | | - float chi2 = currentCellSeed.getPredictedChi2(nextCellSeed); /// TODO: switch to the chi2 wrt cluster to avoid correlation |
| 530 | + if (!nextCellSeed.rotate(currentCellSeed.getAlpha()) || |
| 531 | + !nextCellSeed.propagateTo(currentCellSeed.getX(), getBz())) { |
| 532 | + continue; |
| 533 | + } |
| 534 | + float chi2 = currentCellSeed.getPredictedChi2(nextCellSeed); /// TODO: switch to the chi2 wrt cluster to avoid correlation |
530 | 535 |
|
531 | 536 | #ifdef OPTIMISATION_OUTPUT |
532 | | - bool good{mTimeFrame->getCellsLabel(iLayer)[iCell] == mTimeFrame->getCellsLabel(iLayer + 1)[iNextCell]}; |
533 | | - off << std::format("{}\t{:d}\t{}", iLayer, good, chi2) << std::endl; |
| 537 | + bool good{mTimeFrame->getCellsLabel(iLayer)[iCell] == mTimeFrame->getCellsLabel(iLayer + 1)[iNextCell]}; |
| 538 | + off << std::format("{}\t{:d}\t{}", iLayer, good, chi2) << std::endl; |
534 | 539 | #endif |
535 | 540 |
|
536 | | - if (chi2 > mTrkParams[0].MaxChi2ClusterAttachment) { |
537 | | - continue; |
538 | | - } |
| 541 | + if (chi2 > mTrkParams[0].MaxChi2ClusterAttachment) { |
| 542 | + continue; |
| 543 | + } |
| 544 | + ++foundNextCells; |
| 545 | + } |
| 546 | + perCellCount[iCell] = foundNextCells; |
| 547 | + } |
| 548 | + }); |
539 | 549 |
|
540 | | - mTimeFrame->getCellsNeighboursLUT()[iLayer][iNextCell]++; |
541 | | - cellsNeighbours.push_back(std::make_pair(iCell, iNextCell)); |
542 | | - const int currentCellLevel{currentCellSeed.getLevel()}; |
| 550 | + std::exclusive_scan(perCellCount.begin(), perCellCount.end(), perCellCount.begin(), 0); |
| 551 | + int totalCellNeighbours = perCellCount.back(); |
| 552 | + if (totalCellNeighbours == 0) { |
| 553 | + deepVectorClear(mTimeFrame->getCellsNeighbours()[iLayer]); |
| 554 | + return; |
| 555 | + } |
543 | 556 |
|
544 | | - if (currentCellLevel >= nextCellSeed.getLevel()) { |
545 | | - mTimeFrame->getCells()[iLayer + 1][iNextCell].setLevel(currentCellLevel + 1); |
546 | | - } |
| 557 | + struct Neighbor { |
| 558 | + int cell{-1}, nextCell{-1}, level{-1}; |
| 559 | + }; |
| 560 | + bounded_vector<Neighbor> cellsNeighbours(mMemoryPool.get()); |
| 561 | + cellsNeighbours.resize(totalCellNeighbours); |
| 562 | + |
| 563 | + tbb::parallel_for( |
| 564 | + tbb::blocked_range<int>(0, layerCellsNum), |
| 565 | + [&](const tbb::blocked_range<int>& Cells) { |
| 566 | + for (int iCell = Cells.begin(); iCell < Cells.end(); ++iCell) { |
| 567 | + if (perCellCount[iCell] == perCellCount[iCell + 1]) { |
| 568 | + continue; |
| 569 | + } |
| 570 | + const auto& currentCellSeed{mTimeFrame->getCells()[iLayer][iCell]}; |
| 571 | + const int nextLayerTrackletIndex{currentCellSeed.getSecondTrackletIndex()}; |
| 572 | + const int nextLayerFirstCellIndex{mTimeFrame->getCellsLookupTable()[iLayer][nextLayerTrackletIndex]}; |
| 573 | + const int nextLayerLastCellIndex{mTimeFrame->getCellsLookupTable()[iLayer][nextLayerTrackletIndex + 1]}; |
| 574 | + |
| 575 | + int position = perCellCount[iCell]; |
| 576 | + for (int iNextCell{nextLayerFirstCellIndex}; iNextCell < nextLayerLastCellIndex; ++iNextCell) { |
| 577 | + auto nextCellSeed{mTimeFrame->getCells()[iLayer + 1][iNextCell]}; /// copy |
| 578 | + if (nextCellSeed.getFirstTrackletIndex() != nextLayerTrackletIndex) { |
| 579 | + break; |
| 580 | + } |
| 581 | + |
| 582 | + if (!nextCellSeed.rotate(currentCellSeed.getAlpha()) || |
| 583 | + !nextCellSeed.propagateTo(currentCellSeed.getX(), getBz())) { |
| 584 | + continue; |
| 585 | + } |
| 586 | + |
| 587 | + float chi2 = currentCellSeed.getPredictedChi2(nextCellSeed); /// TODO: switch to the chi2 wrt cluster to avoid correlation |
| 588 | + if (chi2 > mTrkParams[0].MaxChi2ClusterAttachment) { |
| 589 | + continue; |
| 590 | + } |
| 591 | + |
| 592 | + cellsNeighbours[position++] = {iCell, iNextCell, currentCellSeed.getLevel() + 1}; |
| 593 | + } |
| 594 | + } |
| 595 | + }); |
| 596 | + |
| 597 | + tbb::parallel_sort(cellsNeighbours.begin(), cellsNeighbours.end(), [](const auto& a, const auto& b) { |
| 598 | + return a.nextCell < b.nextCell; |
| 599 | + }); |
| 600 | + |
| 601 | + auto& cellsNeighbourLUT = mTimeFrame->getCellsNeighboursLUT()[iLayer]; |
| 602 | + cellsNeighbourLUT.assign(nextLayerCellsNum, 0); |
| 603 | + for (const auto& neigh : cellsNeighbours) { |
| 604 | + ++cellsNeighbourLUT[neigh.nextCell]; |
| 605 | + } |
| 606 | + std::inclusive_scan(cellsNeighbourLUT.begin(), cellsNeighbourLUT.end(), cellsNeighbourLUT.begin()); |
| 607 | + |
| 608 | + mTimeFrame->getCellsNeighbours()[iLayer].reserve(totalCellNeighbours); |
| 609 | + std::ranges::transform(cellsNeighbours, std::back_inserter(mTimeFrame->getCellsNeighbours()[iLayer]), [](const auto& neigh) { return neigh.cell; }); |
| 610 | + |
| 611 | + auto it = cellsNeighbours.begin(); |
| 612 | + while (it != cellsNeighbours.end()) { |
| 613 | + const int current_nextCell = it->nextCell; |
| 614 | + auto group_end = std::find_if_not(it, cellsNeighbours.end(), |
| 615 | + [current_nextCell](const auto& nb) { return nb.nextCell == current_nextCell; }); |
| 616 | + const auto max_level_it = std::max_element(it, group_end, |
| 617 | + [](const auto& a, const auto& b) { return a.level < b.level; }); |
| 618 | + mTimeFrame->getCells()[iLayer + 1][current_nextCell].setLevel(max_level_it->level); |
| 619 | + it = group_end; |
547 | 620 | } |
548 | | - } |
549 | | - std::sort(cellsNeighbours.begin(), cellsNeighbours.end(), [](const std::pair<int, int>& a, const std::pair<int, int>& b) { |
550 | | - return a.second < b.second; |
551 | 621 | }); |
552 | | - mTimeFrame->getCellsNeighbours()[iLayer].clear(); |
553 | | - mTimeFrame->getCellsNeighbours()[iLayer].reserve(cellsNeighbours.size()); |
554 | | - for (auto& cellNeighboursIndex : cellsNeighbours) { |
555 | | - mTimeFrame->getCellsNeighbours()[iLayer].push_back(cellNeighboursIndex.first); |
556 | | - } |
557 | | - std::inclusive_scan(mTimeFrame->getCellsNeighboursLUT()[iLayer].begin(), mTimeFrame->getCellsNeighboursLUT()[iLayer].end(), mTimeFrame->getCellsNeighboursLUT()[iLayer].begin()); |
558 | 622 | } |
559 | 623 | } |
560 | 624 |
|
|
0 commit comments