23#include "GPUParam.inc"
39 std::unique_ptr<GPUReconstruction>
mRec;
59 mNContexts = mConfig->configProcessing.doublePipeline ? 2 : 1;
62 mConfig->configGRP.needsClusterer = 1;
65 mConfig->configGRP.doCompClusterDecode = 1;
67 for (uint32_t
i = 0;
i < mNContexts;
i++) {
69 mConfig->configDeviceBackend.master = mCtx[0].mRec.get();
72 mConfig->configDeviceBackend.master =
nullptr;
73 if (mCtx[
i].mRec ==
nullptr) {
74 GPUError(
"Error obtaining instance of GPUReconstruction");
80 for (uint32_t
i = 0;
i < mNContexts;
i++) {
81 mCtx[
i].mChain = mCtx[
i].mRec->AddChain<
GPUChainTracking>(mConfig->configInterface.maxTPCHits, mConfig->configInterface.maxTRDTracklets);
83 mCtx[
i].mChain->SetQAFromForeignChain(mCtx[0].mChain);
85 mCtx[
i].mChain->mConfigDisplay = &mConfig->configDisplay;
86 mCtx[
i].mChain->mConfigQA = &mConfig->configQA;
87 mCtx[
i].mRec->SetSettings(&mConfig->configGRP, &mConfig->configReconstruction, &mConfig->configProcessing, &mConfig->configWorkflow);
88 mCtx[
i].mChain->SetCalibObjects(mConfig->configCalib);
95 if (mConfig->configInterface.outputToExternalBuffers) {
96 for (uint32_t
j = 0;
j < mCtx[
i].mOutputRegions->count();
j++) {
97 mCtx[
i].mChain->SetSubOutputControl(
j, &mCtx[
i].mOutputRegions->asArray()[
j]);
100 dummy.
set([](
size_t size) ->
void* {
throw std::runtime_error(
"invalid output memory request, no common output buffer set");
return nullptr; });
101 mCtx[
i].mRec->SetOutputControl(dummy);
104 for (uint32_t
i = 0;
i < mNContexts;
i++) {
105 if (
i == 0 && mCtx[
i].mRec->Init()) {
111 mCtx[
i].mRec->MemoryScalers()->factor *= 2;
114 if (mConfig->configProcessing.doublePipeline) {
115 mInternals->pipelineThread.reset(
new std::thread([
this]() { mCtx[0].mRec->RunPipelineWorker(); }));
123 if (mConfig->configProcessing.doublePipeline) {
124 mCtx[0].mRec->TerminatePipelineWorker();
125 mInternals->pipelineThread->join();
127 for (uint32_t
i = 0;
i < mNContexts;
i++) {
128 mCtx[
i].mRec->Finalize();
130 mCtx[0].mRec->Exit();
131 for (int32_t
i = mNContexts - 1;
i >= 0;
i--) {
132 mCtx[
i].mRec.reset();
140 mCtx[0].mChain->ClearIOPointers();
141 mCtx[0].mChain->mIOPtrs = *
data;
143 snprintf(fname, 1024,
"event.%d.dump", nEvent);
144 mCtx[0].mChain->DumpData(fname);
147 if (mConfig->configProcessing.runMC) {
148 mCtx[0].mChain->ForceInitQA();
149 snprintf(fname, 1024,
"mc.%d.dump", nEvent);
150 mCtx[0].mChain->GetQA()->UpdateChain(mCtx[0].mChain);
151 mCtx[0].mChain->GetQA()->DumpO2MCData(fname);
159 mCtx[0].mChain->DoQueuedUpdates(-1);
160 mCtx[0].mRec->DumpSettings();
165 if (mNContexts <= iThread) {
169 mCtx[iThread].mChain->mIOPtrs = *
data;
172 if (mConfig->configInterface.outputToExternalBuffers) {
173 for (uint32_t
i = 0;
i < mCtx[iThread].mOutputRegions->count();
i++) {
179 mCtx[iThread].mOutputRegions->asArray()[
i].reset();
185 auto inputWaitCallback = [
this, iThread, inputUpdateCallback, &
data, &outputs, &setOutputs]() {
188 if (inputUpdateCallback->
callback) {
189 inputUpdateCallback->
callback(updatedData, updatedOutputs);
190 mCtx[iThread].mChain->mIOPtrs = *updatedData;
191 outputs = updatedOutputs;
200 if (inputUpdateCallback) {
201 mCtx[iThread].mChain->SetFinalInputCallback(inputWaitCallback);
203 mCtx[iThread].mChain->SetFinalInputCallback(
nullptr);
205 if (!inputUpdateCallback || !inputUpdateCallback->
callback) {
209 int32_t
retVal = mCtx[iThread].mRec->RunChains();
213 if (mConfig->configQA.shipToQC && mCtx[iThread].mChain->QARanForTF()) {
214 outputs->
qa.
hist1 = &mCtx[iThread].mChain->GetQA()->getHistograms1D();
215 outputs->
qa.
hist2 = &mCtx[iThread].mChain->GetQA()->getHistograms2D();
216 outputs->
qa.
hist3 = &mCtx[iThread].mChain->GetQA()->getHistograms1Dd();
217 outputs->
qa.
hist4 = &mCtx[iThread].mChain->GetQA()->getGraphs();
220 *
data = mCtx[iThread].mChain->mIOPtrs;
225void GPUO2Interface::Clear(
bool clearOutputs, uint32_t iThread) { mCtx[iThread].mRec->ClearAllocatedMemory(clearOutputs); }
229 return mCtx[0].mRec->registerMemoryForGPU(
ptr,
size);
234 return mCtx[0].mRec->unregisterMemoryForGPU(
ptr);
239 for (uint32_t
i = 0;
i < mNContexts;
i++) {
240 mCtx[
i].mChain->SetUpdateCalibObjects(newCalib, newVals);
247 for (uint32_t
i = 0;
i < mNContexts;
i++) {
248 mCtx[
i].mRec->setErrorCodeOutput(
v);
261 return mCtx[iThread].mChain->GetDeviceO2Propagator();
266 prop->setGPUField(&mCtx[0].mRec->GetParam().polynomialField);
Class of a TPC cluster in TPC-native coordinates (row, time)
o2::its::VertexerTraits * GetITSVertexerTraits()
o2::its::TimeFrame * GetITSTimeframe()
o2::its::TrackerTraits * GetITSTrackerTraits()
int32_t unregisterMemoryForGPU(const void *ptr)
const o2::base::Propagator * GetDeviceO2Propagator(int32_t iThread=0) const
int32_t Initialize(const GPUO2InterfaceConfiguration &config)
void setErrorCodeOutput(std::vector< std::array< uint32_t, 4 > > *v)
void UseGPUPolynomialFieldInPropagator(o2::base::Propagator *prop) const
void DumpEvent(int32_t nEvent, GPUTrackingInOutPointers *data)
int32_t RunTracking(GPUTrackingInOutPointers *data, GPUInterfaceOutputs *outputs=nullptr, uint32_t iThread=0, GPUInterfaceInputUpdate *inputUpdateCallback=nullptr)
void GetITSTraits(o2::its::TrackerTraits *&trackerTraits, o2::its::VertexerTraits *&vertexerTraits, o2::its::TimeFrame *&timeFrame)
int32_t registerMemoryForGPU(const void *ptr, size_t size)
void Clear(bool clearOutputs, uint32_t iThread=0)
int32_t UpdateCalibration(const GPUCalibObjectsConst &newCalib, const GPUNewCalibValues &newVals, uint32_t iThread=0)
static GPUReconstruction * CreateInstance(const GPUSettingsDeviceBackend &cfg)
const std::vector< TH1F > * hist1
const std::vector< TGraphAsymmErrors > * hist4
const std::vector< TH1D > * hist3
const std::vector< TH2F > * hist2
std::unique_ptr< std::thread > pipelineThread
std::unique_ptr< GPUReconstruction > mRec
std::unique_ptr< GPUTrackingOutputs > mOutputRegions
GPUChainTracking * mChain
void set(void *p, size_t s)
std::function< void *(size_t)> allocator
GPUOutputControl * asArray()