diff --git a/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt b/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt index 0bdfc27afe004..c51dc7ec8d778 100644 --- a/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt @@ -36,6 +36,11 @@ o2_add_library(ITStracking O2::ITSMFTReconstruction O2::DataFormatsITS) +if (OpenMP_CXX_FOUND) + target_compile_definitions(${targetName} PRIVATE WITH_OPENMP) + target_link_libraries(${targetName} PRIVATE OpenMP::OpenMP_CXX) +endif() + o2_target_root_dictionary(ITStracking HEADERS include/ITStracking/ClusterLines.h include/ITStracking/Tracklet.h diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Tracker.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Tracker.h index 5c6d0337701bc..0d7edf1cd6d39 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Tracker.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Tracker.h @@ -79,6 +79,8 @@ class Tracker // GPU-specific interfaces TimeFrame* getTimeFrameGPU(); void loadToDevice(); + void setNThreads(int n); + int getNThreads() const { return mNThreads; } private: track::TrackParCov buildTrackSeed(const Cluster& cluster1, const Cluster& cluster2, const Cluster& cluster3, @@ -107,6 +109,7 @@ class Tracker std::vector mMemParams; std::vector mTrkParams; + int mNThreads = 1; bool mCUDA = false; bool mApplySmoothing = false; o2::base::PropagatorImpl::MatCorrType mCorrType = o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE; diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h index be07ecb86cd3c..910439094e8ab 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TrackingConfigParam.h @@ -41,6 +41,7 @@ struct TrackerParamConfig : public o2::conf::ConfigurableParamHelper #include +#ifdef WITH_OPENMP +#include +#endif + namespace o2 { namespace its @@ -80,6 +84,7 @@ void Tracker::clustersToTracks(std::function logger, std::f total += evaluateTask(&Tracker::findCellsNeighbours, "Neighbour finding", logger, iteration); total += evaluateTask(&Tracker::findRoads, "Road finding", logger, iteration); + logger(fmt::format("\t- Number of Roads: {}", mTimeFrame->getRoads().size())); total += evaluateTask(&Tracker::findTracks, "Track finding", logger); total += evaluateTask(&Tracker::extendTracks, "Extending tracks", logger); } @@ -90,7 +95,7 @@ void Tracker::clustersToTracks(std::function logger, std::f std::stringstream sstream; if (constants::DoTimeBenchmarks) { sstream << std::setw(2) << " - " - << "Timeframe " << mTimeFrameCounter++ << " processing completed in: " << total << "ms"; + << "Timeframe " << mTimeFrameCounter++ << " processing completed in: " << total << "ms using " << mNThreads << " threads."; } logger(sstream.str()); @@ -259,9 +264,12 @@ void Tracker::findRoads(int& iteration) void Tracker::findTracks() { - std::vector tracks; - tracks.reserve(mTimeFrame->getRoads().size()); + std::vector> tracks(mNThreads); + for (auto& tracksV : tracks) { + tracksV.reserve(mTimeFrame->getRoads().size() / mNThreads); + } +#pragma omp parallel for num_threads(mNThreads) for (auto& road : mTimeFrame->getRoads()) { std::vector clusters(mTrkParams[0].NLayers, constants::its::UnusedIndex); int lastCellLevel = constants::its::UnusedIndex; @@ -352,16 +360,25 @@ void Tracker::findTracks() continue; } // temporaryTrack.setROFrame(rof); - tracks.emplace_back(temporaryTrack); +#ifdef WITH_OPENMP + int iThread = omp_get_thread_num(); +#else + int iThread = 0; +#endif + tracks[iThread].emplace_back(temporaryTrack); + } + + for (int iV{1}; iV < mNThreads; ++iV) { + tracks[0].insert(tracks[0].end(), tracks[iV].begin(), tracks[iV].end()); } if (mApplySmoothing) { // Smoothing tracks } - std::sort(tracks.begin(), tracks.end(), + std::sort(tracks[0].begin(), tracks[0].end(), [](TrackITSExt& track1, TrackITSExt& track2) { return track1.isBetter(track2, 1.e6f); }); - for (auto& track : tracks) { + for (auto& track : tracks[0]) { int nShared = 0; for (int iLayer{0}; iLayer < mTrkParams[0].NLayers; ++iLayer) { if (track.getClusterIndex(iLayer) == constants::its::UnusedIndex) { @@ -831,7 +848,12 @@ void Tracker::getGlobalConfiguration() auto& tc = o2::its::TrackerParamConfig::Instance(); if (tc.useMatCorrTGeo) { setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrTGeo); + } else if (tc.useFastMaterial) { + setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrNONE); + } else { + setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); } + setNThreads(tc.nThreads); for (auto& params : mTrkParams) { if (params.NLayers == 7) { for (int i{0}; i < 7; ++i) { @@ -878,5 +900,14 @@ void Tracker::setBz(float bz) mTimeFrame->setBz(bz); } +void Tracker::setNThreads(int n) +{ +#ifdef WITH_OPENMP + mNThreads = n > 0 ? n : 1; +#else + mNThreads = 1; +#endif +} + } // namespace its } // namespace o2 diff --git a/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx index 5421f5b67c8c9..5d5f1b005816a 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx @@ -81,21 +81,24 @@ void TrackerDPL::init(InitContext& ic) } else if (mMode == "sync_misaligned") { - trackParams.resize(1); + trackParams.resize(3); trackParams[0].PhiBins = 32; trackParams[0].ZBins = 64; - trackParams[0].CellDeltaTanLambdaSigma *= 10; - trackParams[0].LayerMisalignment[0] = 3.e-2; - trackParams[0].LayerMisalignment[1] = 3.e-2; - trackParams[0].LayerMisalignment[2] = 3.e-2; - trackParams[0].LayerMisalignment[3] = 1.e-1; - trackParams[0].LayerMisalignment[4] = 1.e-1; - trackParams[0].LayerMisalignment[5] = 1.e-1; - trackParams[0].LayerMisalignment[6] = 1.e-1; - trackParams[0].FitIterationMaxChi2[0] = 100.; - trackParams[0].FitIterationMaxChi2[1] = 50.; - trackParams[0].MinTrackLength = 4; - memParams.resize(1); + trackParams[0].CellDeltaTanLambdaSigma *= 3.; + trackParams[0].LayerMisalignment[0] = 1.e-2; + trackParams[0].LayerMisalignment[1] = 1.e-2; + trackParams[0].LayerMisalignment[2] = 1.e-2; + trackParams[0].LayerMisalignment[3] = 3.e-2; + trackParams[0].LayerMisalignment[4] = 3.e-2; + trackParams[0].LayerMisalignment[5] = 3.e-2; + trackParams[0].LayerMisalignment[6] = 3.e-2; + trackParams[0].FitIterationMaxChi2[0] = 50.; + trackParams[0].FitIterationMaxChi2[1] = 25.; + trackParams[1] = trackParams[0]; + trackParams[2] = trackParams[0]; + trackParams[1].MinTrackLength = 6; + trackParams[2].MinTrackLength = 4; + memParams.resize(3); LOG(info) << "Initializing tracker in misaligned sync. phase reconstruction with " << trackParams.size() << " passes"; } else if (mMode == "sync") { @@ -112,15 +115,15 @@ void TrackerDPL::init(InitContext& ic) trackParams[0].PhiBins = 4; trackParams[0].ZBins = 16; trackParams[0].PVres = 1.e5f; - trackParams[0].LayerMisalignment[0] = 3.e-2; - trackParams[0].LayerMisalignment[1] = 3.e-2; - trackParams[0].LayerMisalignment[2] = 3.e-2; - trackParams[0].LayerMisalignment[3] = 1.e-1; - trackParams[0].LayerMisalignment[4] = 1.e-1; - trackParams[0].LayerMisalignment[5] = 1.e-1; - trackParams[0].LayerMisalignment[6] = 1.e-1; - trackParams[0].FitIterationMaxChi2[0] = 100.; - trackParams[0].FitIterationMaxChi2[1] = 50.; + trackParams[0].LayerMisalignment[0] = 1.e-2; + trackParams[0].LayerMisalignment[1] = 1.e-2; + trackParams[0].LayerMisalignment[2] = 1.e-2; + trackParams[0].LayerMisalignment[3] = 3.e-2; + trackParams[0].LayerMisalignment[4] = 3.e-2; + trackParams[0].LayerMisalignment[5] = 3.e-2; + trackParams[0].LayerMisalignment[6] = 3.e-2; + trackParams[0].FitIterationMaxChi2[0] = 50.; + trackParams[0].FitIterationMaxChi2[1] = 25.; trackParams[0].TrackletsPerClusterLimit = 100.; trackParams[0].CellsPerClusterLimit = 100.; LOG(info) << "Initializing tracker in reconstruction for cosmics with " << trackParams.size() << " passes"; @@ -318,7 +321,6 @@ void TrackerDPL::updateTimeDependentParams(ProcessingContext& pc) pc.inputs().get*>("alppar"); GeometryTGeo* geom = GeometryTGeo::Instance(); geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G)); - mTracker->setCorrType(o2::base::PropagatorImpl::MatCorrType::USEMatCorrLUT); /// TODO: eventually remove this in favour of the one below mVertexer->getGlobalConfiguration(); mTracker->getGlobalConfiguration(); }