diff --git a/GPU/GPUTracking/Benchmark/standalone.cxx b/GPU/GPUTracking/Benchmark/standalone.cxx index ad0ac17b83565..9dc4c5a4908bf 100644 --- a/GPU/GPUTracking/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Benchmark/standalone.cxx @@ -501,6 +501,7 @@ int ReadEvent(int n) if ((configStandalone.proc.runQA || configStandalone.eventDisplay) && !configStandalone.QA.noMC) { chainTracking->ForceInitQA(); snprintf(filename, 256, "events/%s/mc.%d.dump", configStandalone.eventsDir, n); + chainTracking->GetQA()->UpdateChain(chainTracking); if (chainTracking->GetQA()->ReadO2MCData(filename)) { snprintf(filename, 256, "events/%s/mc.%d.dump", configStandalone.eventsDir, 0); if (chainTracking->GetQA()->ReadO2MCData(filename) && configStandalone.proc.runQA) { @@ -734,12 +735,14 @@ int main(int argc, char** argv) recAsync->SetDebugLevelTmp(configStandalone.proc.debugLevel); } chainTrackingAsync = recAsync->AddChain(); + chainTrackingAsync->SetQAFromForeignChain(chainTracking); } if (configStandalone.proc.doublePipeline) { if (configStandalone.proc.debugLevel >= 3) { recPipeline->SetDebugLevelTmp(configStandalone.proc.debugLevel); } chainTrackingPipeline = recPipeline->AddChain(); + chainTrackingPipeline->SetQAFromForeignChain(chainTracking); } #ifdef GPUCA_HAVE_O2HEADERS if (!configStandalone.proc.doublePipeline) { diff --git a/GPU/GPUTracking/Global/GPUChainTracking.cxx b/GPU/GPUTracking/Global/GPUChainTracking.cxx index 33c267519470f..0ea5603c2efb2 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.cxx +++ b/GPU/GPUTracking/Global/GPUChainTracking.cxx @@ -373,11 +373,14 @@ int GPUChainTracking::Init() } if (GPUQA::QAAvailable() && (GetProcessingSettings().runQA || GetProcessingSettings().eventDisplay)) { - mQA.reset(new GPUQA(this)); + auto& qa = mQAFromForeignChain ? mQAFromForeignChain->mQA : mQA; + if (!qa) { + qa.reset(new GPUQA(this)); + } } if (GetProcessingSettings().eventDisplay) { #ifndef GPUCA_ALIROOT_LIB - mEventDisplay.reset(GPUDisplayInterface::getDisplay(GetProcessingSettings().eventDisplay, this, mQA.get())); + mEventDisplay.reset(GPUDisplayInterface::getDisplay(GetProcessingSettings().eventDisplay, this, GetQA())); #endif if (mEventDisplay == nullptr) { throw std::runtime_error("Error loading event display"); @@ -479,19 +482,21 @@ int GPUChainTracking::PrepareEvent() int GPUChainTracking::ForceInitQA() { - if (!mQA) { - mQA.reset(new GPUQA(this)); + auto& qa = mQAFromForeignChain ? mQAFromForeignChain->mQA : mQA; + if (!qa) { + qa.reset(new GPUQA(this)); } - if (!mQA->IsInitialized()) { - return mQA->InitQA(); + if (!GetQA()->IsInitialized()) { + return GetQA()->InitQA(); } return 0; } int GPUChainTracking::Finalize() { - if (GetProcessingSettings().runQA && mQA->IsInitialized() && !(mConfigQA && mConfigQA->shipToQC)) { - mQA->DrawQAHistograms(); + if (GetProcessingSettings().runQA && GetQA()->IsInitialized() && !(mConfigQA && mConfigQA->shipToQC) && !mQAFromForeignChain) { + GetQA()->UpdateChain(this); + GetQA()->DrawQAHistograms(); } if (GetProcessingSettings().debugLevel >= 6) { mDebugFile->close(); @@ -670,8 +675,8 @@ int GPUChainTracking::RunChain() mCompressionStatistics.reset(new GPUTPCClusterStatistics); } const bool needQA = GPUQA::QAAvailable() && (GetProcessingSettings().runQA || (GetProcessingSettings().eventDisplay && (mIOPtrs.nMCInfosTPC || GetProcessingSettings().runMC))); - if (needQA && mQA->IsInitialized() == false) { - if (mQA->InitQA(GetProcessingSettings().runQA ? -GetProcessingSettings().runQA : -1)) { + if (needQA && GetQA()->IsInitialized() == false) { + if (GetQA()->InitQA(GetProcessingSettings().runQA ? -GetProcessingSettings().runQA : -1)) { return 1; } } @@ -796,7 +801,8 @@ int GPUChainTracking::RunChainFinalize() const bool needQA = GPUQA::QAAvailable() && (GetProcessingSettings().runQA || (GetProcessingSettings().eventDisplay && mIOPtrs.nMCInfosTPC)); if (needQA && mFractionalQAEnabled) { mRec->getGeneralStepTimer(GeneralStep::QA).Start(); - mQA->RunQA(!GetProcessingSettings().runQA); + GetQA()->UpdateChain(this); + GetQA()->RunQA(!GetProcessingSettings().runQA); mRec->getGeneralStepTimer(GeneralStep::QA).Stop(); if (GetProcessingSettings().debugLevel == 0) { GPUInfo("Total QA runtime: %d us", (int)(mRec->getGeneralStepTimer(GeneralStep::QA).GetElapsedTime() * 1000000)); diff --git a/GPU/GPUTracking/Global/GPUChainTracking.h b/GPU/GPUTracking/Global/GPUChainTracking.h index 944a891e5c1f6..acdf9f7b446c2 100644 --- a/GPU/GPUTracking/Global/GPUChainTracking.h +++ b/GPU/GPUTracking/Global/GPUChainTracking.h @@ -156,9 +156,10 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega const GPUTPCGMMerger& GetTPCMerger() const { return processors()->tpcMerger; } GPUTPCGMMerger& GetTPCMerger() { return processors()->tpcMerger; } GPUDisplayInterface* GetEventDisplay() { return mEventDisplay.get(); } - const GPUQA* GetQA() const { return mQA.get(); } - GPUQA* GetQA() { return mQA.get(); } + const GPUQA* GetQA() const { return mQAFromForeignChain ? mQAFromForeignChain->mQA.get() : mQA.get(); } + GPUQA* GetQA() { return mQAFromForeignChain ? mQAFromForeignChain->mQA.get() : mQA.get(); } int ForceInitQA(); + void SetQAFromForeignChain(GPUChainTracking* chain) { mQAFromForeignChain = chain; } // Processing functions int RunTPCClusterizer(bool synchronizeOutput = true); @@ -254,6 +255,7 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega // Display / QA bool mDisplayRunning = false; std::unique_ptr mEventDisplay; + GPUChainTracking* mQAFromForeignChain = nullptr; std::unique_ptr mQA; std::unique_ptr mCompressionStatistics; diff --git a/GPU/GPUTracking/Interface/GPUO2Interface.cxx b/GPU/GPUTracking/Interface/GPUO2Interface.cxx index f2e91b633c7bf..2dd001725ee7f 100644 --- a/GPU/GPUTracking/Interface/GPUO2Interface.cxx +++ b/GPU/GPUTracking/Interface/GPUO2Interface.cxx @@ -80,6 +80,9 @@ int GPUO2Interface::Initialize(const GPUO2InterfaceConfiguration& config) } for (unsigned int i = 0; i < mNContexts; i++) { mCtx[i].mChain = mCtx[i].mRec->AddChain(mConfig->configInterface.maxTPCHits, mConfig->configInterface.maxTRDTracklets); + if (i) { + mCtx[i].mChain->SetQAFromForeignChain(mCtx[0].mChain); + } mCtx[i].mChain->mConfigDisplay = &mConfig->configDisplay; mCtx[i].mChain->mConfigQA = &mConfig->configQA; mCtx[i].mRec->SetSettings(&mConfig->configGRP, &mConfig->configReconstruction, &mConfig->configProcessing, &mConfig->configWorkflow); @@ -145,6 +148,7 @@ void GPUO2Interface::DumpEvent(int nEvent, GPUTrackingInOutPointers* data) if (mConfig->configProcessing.runMC) { mCtx[0].mChain->ForceInitQA(); snprintf(fname, 1024, "mc.%d.dump", nEvent); + mCtx[0].mChain->GetQA()->UpdateChain(mCtx[0].mChain); mCtx[0].mChain->GetQA()->DumpO2MCData(fname); } #endif diff --git a/GPU/GPUTracking/qa/GPUQA.h b/GPU/GPUTracking/qa/GPUQA.h index 0084c6dfff290..d5fef788c099c 100644 --- a/GPU/GPUTracking/qa/GPUQA.h +++ b/GPU/GPUTracking/qa/GPUQA.h @@ -113,6 +113,7 @@ class GPUQA int ReadO2MCData(const char* filename); static bool QAAvailable() { return true; } bool IsInitialized() { return mQAInitialized; } + void UpdateChain(GPUChainTracking* chain) { mTracking = chain; } const std::vector& getHistograms1D() const { return *mHist1D; } const std::vector& getHistograms2D() const { return *mHist2D; }