Skip to content
Snippets Groups Projects
Commit 11f7f3d2 authored by Sergei Zharko's avatar Sergei Zharko
Browse files

ca: new scheme of time window distribution over CPU threads

parent 4dfdfe09
No related branches found
No related tags found
1 merge request!1748ca: new scheme of time window distribution over CPU threads
Pipeline #28516 failed
......@@ -23,6 +23,8 @@
#include "CaTrack.h"
#include <chrono>
#include <fstream>
#include <sstream>
#include <thread>
using namespace cbm::algo::ca;
......@@ -193,19 +195,85 @@ void TrackFinder::FindTracks()
int nWindows = static_cast<int>((fStatTsEnd - fStatTsStart - fWindowOverlap - fWindowMargin)
/ (fWindowLength - fWindowOverlap - fWindowMargin))
+ 1;
LOG(info) << "CA: estimated number of time windows: " << nWindows;
int nWindowsThread = nWindows / frAlgo.GetNofThreads();
float windowDelta = fWindowLength - fWindowOverlap - fWindowMargin;
//LOG(info) << "CA: estimated number of time windows: " << nWindows;
{ // Estimation of number of hits in time windows
//Timer time;
//time.Start();
int nSt = frAlgo.GetParameters().GetNstationsActive();
// Count number of hits per window and station
double a = fStatTsStart + fWindowOverlap + fWindowMargin;
double b = fWindowLength - fWindowOverlap - fWindowMargin;
HitIndex_t nHitsTot = frAlgo.fInputData.GetNhits();
std::vector<HitIndex_t> nHitsWindowSta(nWindows * nSt, 0);
for (HitIndex_t iHit = 0; iHit < nHitsTot; ++iHit) {
const auto& hit = frAlgo.fInputData.GetHit(iHit);
//const auto& timeInfo = frAlgo.fHitTimeInfo[iHit];
size_t iWindow = static_cast<size_t>((hit.T() - a) / b);
if (iWindow >= static_cast<size_t>(nWindows)) {
LOG(error) << "ca: Hit out of range: iHit = " << iHit << ", time = " << hit.T() * 1.e-6
<< " ms, window = " << iWindow;
continue;
}
++nHitsWindowSta[hit.Station() + iWindow * nSt];
}
// Remove hits from the "monster events"
if (ca::Framework::TrackingMode::kMcbm == frAlgo.fTrackingMode) {
auto maxNofHitsSta = static_cast<HitIndex_t>(50 * fWindowLength / 1.e3);
for (auto& content : nHitsWindowSta) {
if (content > maxNofHitsSta) {
content = 0;
}
}
}
// Integrate number of hits per window
std::vector<HitIndex_t> nHitsWindow;
nHitsWindow.reserve(nWindows);
auto windowStaIt = nHitsWindowSta.begin();
HitIndex_t nHitsCollected = 0;
while (windowStaIt != nHitsWindowSta.end()) {
nHitsCollected = nHitsWindow.emplace_back(std::accumulate(windowStaIt, windowStaIt + nSt, nHitsCollected));
windowStaIt = windowStaIt + nSt;
}
// Get time range for threads
HitIndex_t nHitsPerThread = nHitsCollected / frAlgo.GetNofThreads();
auto windowIt = nHitsWindow.begin();
size_t iWbegin = 0;
fvWindowStartThread[0] = fStatTsStart;
for (int iTh = 1; iTh < frAlgo.GetNofThreads(); ++iTh) {
windowIt = std::lower_bound(windowIt, nHitsWindow.end(), iTh * nHitsPerThread);
iWbegin = std::distance(nHitsWindow.begin(), windowIt) + 1;
fvWindowStartThread[iTh] = fStatTsStart + iWbegin * windowDelta;
fvWindowEndThread[iTh - 1] = fvWindowStartThread[iTh];
}
//time.Stop();
//LOG(info) << "Thread boarders estimation time: " << time.GetTotalMs() << " ms";
LOG(info) << "Fraction of hits from monster events: " << static_cast<double>(nHitsTot - nHitsCollected) / nHitsTot;
}
// cut data into sub-timeslices and process them one by one
//for (int iThread = 0; iThread < frAlgo.GetNofThreads(); ++iThread) {
// fvWindowStartThread[iThread] = fStatTsStart + iThread * nWindowsThread * windowDelta;
// fvWindowEndThread[iThread] =
// fvWindowStartThread[iThread] + nWindowsThread * windowDelta + fWindowOverlap + fWindowMargin;
//}
fvWindowEndThread[frAlgo.GetNofThreads() - 1] = fStatTsEnd;
for (int iThread = 0; iThread < frAlgo.GetNofThreads(); ++iThread) {
fvWindowStartThread[iThread] = fStatTsStart + iThread * nWindowsThread * windowDelta;
fvWindowEndThread[iThread] =
fvWindowStartThread[iThread] + nWindowsThread * windowDelta + fWindowOverlap + fWindowMargin;
LOG(info) << "Thread: " << iThread << " from " << fvWindowStartThread[iThread] / 1.e6 << " ms to "
<< fvWindowEndThread[iThread] / 1.e6 << " ms";
double start = fvWindowStartThread[iThread] * 1.e-6;
double end = fvWindowEndThread[iThread] * 1.e-6;
LOG(info) << "Thread: " << iThread << " from " << start << " ms to " << end << " ms (delta = " << end - start
<< " ms)";
}
fvWindowEndThread[frAlgo.GetNofThreads() - 1] = fStatTsEnd;
frAlgo.fMonitorData.StopTimer(ETimer::PrepareTimeslice);
// Save tracks
......@@ -251,6 +319,7 @@ void TrackFinder::FindTracks()
// Add thread monitors to the main monitor
for (auto& monitor : frAlgo.fvMonitorDataThread) {
frAlgo.fMonitorData.AddMonitorData(monitor, true);
//frAlgo.fMonitorData.AddMonitorData(monitor);
monitor.Reset();
}
......@@ -277,7 +346,12 @@ void TrackFinder::FindTracks()
//
void TrackFinder::FindTracksThread(int iThread)
{
//std::stringstream filename;
//filename << "./dbg_caTrackFinder::FindTracksThread_" << iThread << ".txt";
//std::ofstream out(filename.str());
auto& monitor = frAlgo.fvMonitorDataThread[iThread];
Timer timer;
timer.Start();
monitor.StartTimer(ETimer::TrackingThread);
monitor.StartTimer(ETimer::PrepareThread);
......@@ -353,6 +427,7 @@ void TrackFinder::FindTracksThread(int iThread)
// TODO: SG: skip empty regions and start the subslice with the earliest hit
fvStatNwindows[iThread]++;
//out << fvStatNwindows[iThread] << ' ';
int statNwindowHits = 0;
......@@ -385,10 +460,30 @@ void TrackFinder::FindTracksThread(int iThread)
} // else the hit has been alread processed in previous sub-slices
}
}
//out << statNwindowHits << ' ';
//if (statNwindowHits == 0) { // Empty window
// frAlgo.fvMonitorDataThread[iThread].StopTimer(ETimer::PrepareWindow);
// out << 0 << ' ' << 0 << ' ' << 0 << '\n';
// continue;
//}
if (ca::Framework::TrackingMode::kMcbm == frAlgo.fTrackingMode) {
// cut at 50 hits per station per 1 us.
int maxStationHits = (int) (50 * fWindowLength / 1.e3);
for (int ista = 0; ista < frAlgo.GetParameters().GetNstationsActive(); ++ista) {
int nHitsSta = static_cast<int>(frAlgo.fvWData[iThread].TsHitIndices(ista).size());
if (nHitsSta > maxStationHits) {
statNwindowHits -= nHitsSta;
frAlgo.fvWData[iThread].TsHitIndices(ista).clear();
}
}
}
fvStatNhitsProcessed[iThread] += statNwindowHits;
// print the LOG for every 10 ms of data processed
{
if constexpr (0) {
int currentChunk = (int) ((fvWindowStartThread[iThread] - fStatTsStart) / 10.e6);
if (!areUntouchedDataLeft || currentChunk > statLastLogTimeChunk) {
statLastLogTimeChunk = currentChunk;
......@@ -406,21 +501,18 @@ void TrackFinder::FindTracksThread(int iThread)
}
}
if (ca::Framework::TrackingMode::kMcbm == frAlgo.fTrackingMode) {
// cut at 50 hits per station per 1 us.
int maxStationHits = (int) (50 * fWindowLength / 1.e3);
for (int ista = 0; ista < frAlgo.GetParameters().GetNstationsActive(); ++ista) {
if ((int) frAlgo.fvWData[iThread].TsHitIndices(ista).size() > maxStationHits) {
frAlgo.fvWData[iThread].TsHitIndices(ista).clear();
}
}
}
//out << statNwindowHits << ' ';
frAlgo.fvMonitorDataThread[iThread].StopTimer(ETimer::PrepareWindow);
//Timer trackingInWindow; //DBG
//trackingInWindow.Start();
frAlgo.fvMonitorDataThread[iThread].StartTimer(ETimer::TrackingWindow);
frAlgo.fvTrackFinderWindow[iThread].CaTrackFinderSlice();
frAlgo.fvMonitorDataThread[iThread].StopTimer(ETimer::TrackingWindow);
//trackingInWindow.Stop();
//out << trackingInWindow.GetTotalMs() << ' ';
// save reconstructed tracks with no hits in the overlap region
//if (fvWindowStartThread[iThread] > 13.23e6 && fvWindowStartThread[iThread] < 13.26e6) {
......@@ -428,6 +520,8 @@ void TrackFinder::FindTracksThread(int iThread)
// we should add hits from reconstructed but not stored tracks to the new sub-timeslice
// we do it in a simple way by extending the tsStartNew
// TODO: only add those hits from the region before tsStartNew that belong to the not stored tracks
//out << frAlgo.fvWData[iThread].RecoHitIndices().size() << ' ';
//out << frAlgo.fvWData[iThread].RecoTracks().size() << '\n';
frAlgo.fvMonitorDataThread[iThread].StartTimer(ETimer::StoreTracksWindow);
int trackFirstHit = 0;
......@@ -482,6 +576,10 @@ void TrackFinder::FindTracksThread(int iThread)
}
}
frAlgo.fvMonitorDataThread[iThread].StopTimer(ETimer::TrackingThread);
//timer.Stop();
//LOG(info) << "CA: finishing tracking on thread " << iThread << " (time: " << timer.GetTotalMs() << " ms, "
// << "hits processed: " << fvStatNhitsProcessed[iThread] << ", "
// << "hits used: " << fvRecoHitIndices[iThread].size() << ')';
}
// ---------------------------------------------------------------------------------------------------------------------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment