Project
Loading...
Searching...
No Matches
standalone.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#include "utils/qconfig.h"
16#include "GPUReconstruction.h"
19#include "GPUChainTracking.h"
20#include "GPUChainTrackingGetters.inc"
21#include "GPUTPCDef.h"
22#include "GPUQA.h"
23#include "GPUParam.h"
25#include "genEvents.h"
26
27#include "GPUTPCGMMergedTrack.h"
28#include "GPUSettings.h"
29#include "GPUConstantMem.h"
30
31#include "GPUO2DataTypes.h"
32#include "GPUChainITS.h"
33
34// For creating default objects
36#include "CalibdEdxContainer.h"
37#include "TPCFastTransformPOD.h"
38#include "GPUTRDRecoParam.h"
39#include "TPCZSLinkMapping.h"
40
42
43#include <iostream>
44#include <fstream>
45#include <cstdio>
46#include <cstring>
47#include <chrono>
48#include <tuple>
49#include <algorithm>
50#include <thread>
51#include <future>
52#include <atomic>
53#include <vector>
54
55#ifndef _WIN32
56#include <unistd.h>
57#include <sched.h>
58#include <csignal>
59#include <sys/types.h>
60#include <sys/wait.h>
61#include <sys/select.h>
62#include <cfenv>
63#include <clocale>
64#include <sys/stat.h>
65#endif
66#include "utils/timer.h"
68#include "utils/vecpod.h"
69
70using namespace o2::gpu;
71
72// #define BROKEN_EVENTS
73
74namespace o2::gpu
75{
76extern GPUSettingsStandalone configStandalone;
77}
78
83std::string eventsDir;
85std::unique_ptr<GPUDisplayFrontendInterface> eventDisplay;
86std::unique_ptr<GPUReconstructionTimeframe> tf;
88std::atomic<uint32_t> nIteration, nIterationEnd;
89
90std::vector<GPUTrackingInOutPointers> ioPtrEvents;
91std::vector<GPUChainTracking::InOutMemory> ioMemEvents;
92
93int32_t ReadConfiguration(int argc, char** argv)
94{
95 int32_t qcRet = qConfigParse(argc, (const char**)argv);
96 if (qcRet) {
97 if (qcRet != qConfig::qcrHelp) {
98 printf("Error parsing command line parameters\n");
99 }
100 return 1;
101 }
102 if (configStandalone.printSettings > 1) {
103 printf("Config Dump before ReadConfiguration\n");
104 qConfigPrint();
105 }
106 if (configStandalone.proc.debugLevel == -1) {
107 configStandalone.proc.debugLevel = 0;
108 }
109#ifndef _WIN32
110 setlocale(LC_ALL, "en_US.utf-8");
111 setlocale(LC_NUMERIC, "en_US.utf-8");
112 if (configStandalone.cpuAffinity != -1) {
113 cpu_set_t mask;
114 CPU_ZERO(&mask);
115 CPU_SET(configStandalone.cpuAffinity, &mask);
116
117 printf("Setting affinitiy to restrict on CPU core %d\n", configStandalone.cpuAffinity);
118 if (0 != sched_setaffinity(0, sizeof(mask), &mask)) {
119 printf("Error setting CPU affinity\n");
120 return 1;
121 }
122 }
123 if (configStandalone.fifoScheduler) {
124 printf("Setting FIFO scheduler\n");
125 sched_param param;
126 sched_getparam(0, &param);
127 param.sched_priority = 1;
128 if (0 != sched_setscheduler(0, SCHED_FIFO, &param)) {
129 printf("Error setting scheduler\n");
130 return 1;
131 }
132 }
133#ifdef __FAST_MATH__
134 if (configStandalone.fpe == 1) {
135#else
136 if (configStandalone.fpe) {
137#endif
138 feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
139 }
140 bool detMode = false, noFTZMode = false;
141#ifdef GPUCA_DETERMINISTIC_MODE
142 detMode = true;
143#endif
144#ifdef GPUCA_DETERMINISTIC_NO_FTZ
145 noFTZMode = true;
146#endif
147 if (configStandalone.flushDenormals >= 1 || (configStandalone.flushDenormals == -1 && (configStandalone.proc.deterministicGPUReconstruction >= 1 || (configStandalone.proc.deterministicGPUReconstruction == -1 && detMode)) && !noFTZMode)) {
148 disable_denormals();
149 }
150
151#else
152 if (configStandalone.cpuAffinity != -1) {
153 printf("Affinity setting not supported on Windows\n");
154 return 1;
155 }
156 if (configStandalone.fifoScheduler) {
157 printf("FIFO Scheduler setting not supported on Windows\n");
158 return 1;
159 }
160 if (configStandalone.fpe == 1) {
161 printf("FPE not supported on Windows\n");
162 return 1;
163 }
164#endif
165#ifdef GPUCA_RUN2
166#warning Why was configStandalone.rec.tpc.mergerReadFromTrackerDirectly = 0 needed?
167 configStandalone.proc.inKernelParallel = false;
168 configStandalone.proc.createO2Output = 0;
169 if (configStandalone.rundEdx == -1) {
170 configStandalone.rundEdx = 0;
171 }
172#endif
173#ifndef GPUCA_BUILD_QA
174 if (configStandalone.proc.runQA || configStandalone.eventGenerator) {
175 printf("QA not enabled in build\n");
176 return 1;
177 }
178#endif
179 if (configStandalone.proc.doublePipeline && configStandalone.testSyncAsync) {
180 printf("Cannot run asynchronous processing with double pipeline\n");
181 return 1;
182 }
183 if (configStandalone.proc.doublePipeline && (configStandalone.runs < 4 || !configStandalone.outputcontrolmem)) {
184 printf("Double pipeline mode needs at least 4 runs per event and external output. To cycle though multiple events, use --preloadEvents and --runs n for n iterations round-robin\n");
185 return 1;
186 }
187 if (configStandalone.TF.bunchSim && configStandalone.TF.nMerge) {
188 printf("Cannot run --MERGE and --SIMBUNCHES togeterh\n");
189 return 1;
190 }
191 if (configStandalone.TF.bunchSim > 1) {
192 configStandalone.TF.timeFrameLen = 1.e9 * configStandalone.TF.bunchSim / configStandalone.TF.interactionRate;
193 }
194 if (configStandalone.TF.nMerge) {
195 double len = configStandalone.TF.nMerge - 1;
196 if (configStandalone.TF.randomizeDistance) {
197 len += 0.5;
198 }
199 if (configStandalone.TF.shiftFirstEvent) {
200 len += 0.5;
201 }
203 }
204 if (configStandalone.QA.inputHistogramsOnly && configStandalone.QA.compareInputs.size() == 0) {
205 printf("Can only produce QA pdf output when input files are specified!\n");
206 return 1;
207 }
208 if (configStandalone.QA.enableLocalOutput && !configStandalone.QA.inputHistogramsOnly && configStandalone.QA.output == "" && configStandalone.QA.plotsDir != "") {
209 configStandalone.QA.output = configStandalone.QA.plotsDir + "/output.root";
210 }
211 if (configStandalone.QA.inputHistogramsOnly) {
212 configStandalone.rundEdx = false;
213 configStandalone.noEvents = true;
214 }
215 if (configStandalone.QA.dumpToROOT) {
216 configStandalone.proc.outputSharedClusterMap = true;
217 }
218 if (configStandalone.eventDisplay) {
219 configStandalone.noprompt = 1;
220 }
221 if (configStandalone.proc.debugLevel >= 4) {
222 if (configStandalone.proc.inKernelParallel) {
223 configStandalone.proc.inKernelParallel = 1;
224 } else {
225 configStandalone.proc.nHostThreads = 1;
226 }
227 }
228 if (configStandalone.setO2Settings) {
229 if (configStandalone.runGPU && configStandalone.proc.debugLevel <= 1) {
230 if (!(configStandalone.inputcontrolmem && configStandalone.outputcontrolmem)) {
231 printf("setO2Settings requires the usage of --inputMemory and --outputMemory as in O2\n");
232 return 1;
233 }
234 configStandalone.proc.forceHostMemoryPoolSize = 1024 * 1024 * 1024;
235 }
236 configStandalone.rec.tpc.trackReferenceX = 83;
237 configStandalone.proc.outputSharedClusterMap = 1;
238 configStandalone.proc.clearO2OutputFromGPU = 1;
239 configStandalone.QA.clusterRejectionHistograms = 1;
240 configStandalone.proc.tpcIncreasedMinClustersPerRow = 500000;
241 configStandalone.proc.ignoreNonFatalGPUErrors = 1;
242 // TODO: rundEdx=1
243 // GPU_proc.qcRunFraction=$TPC_TRACKING_QC_RUN_FRACTION;"
244 // [[ $CTFINPUT == 1 ]] && GPU_CONFIG_KEY+="GPU_proc.tpcInputWithClusterRejection=1;"
245 // double pipeline / rtc
246 }
247
248 if (configStandalone.outputcontrolmem) {
249 bool forceEmptyMemory = getenv("LD_PRELOAD") && strstr(getenv("LD_PRELOAD"), "valgrind") != nullptr;
250 outputmemory.reset(GPUReconstruction::alignedDefaultBufferAllocator<char>(configStandalone.outputcontrolmem));
251 if (forceEmptyMemory) {
252 printf("Valgrind detected, emptying GPU output memory to avoid false positive undefined reads");
253 memset(outputmemory.get(), 0, configStandalone.outputcontrolmem);
254 }
255 if (configStandalone.proc.doublePipeline) {
256 outputmemoryPipeline.reset(GPUReconstruction::alignedDefaultBufferAllocator<char>(configStandalone.outputcontrolmem));
257 if (forceEmptyMemory) {
258 memset(outputmemoryPipeline.get(), 0, configStandalone.outputcontrolmem);
259 }
260 }
261 }
262 if (configStandalone.inputcontrolmem) {
263 inputmemory.reset(GPUReconstruction::alignedDefaultBufferAllocator<char>(configStandalone.inputcontrolmem));
264 }
265
266 configStandalone.proc.showOutputStat = true;
267
268 if (configStandalone.runGPU && configStandalone.gpuType == "AUTO") {
269 if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::CUDA, configStandalone.proc.debugLevel >= 2)) {
270 configStandalone.gpuType = "CUDA";
271 } else if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::HIP, configStandalone.proc.debugLevel >= 2)) {
272 configStandalone.gpuType = "HIP";
273 } else if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::OCL, configStandalone.proc.debugLevel >= 2)) {
274 configStandalone.gpuType = "OCL";
275 } else if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::OCL, configStandalone.proc.debugLevel >= 2)) {
276 configStandalone.gpuType = "OCL";
277 } else {
278 if (configStandalone.runGPU > 1 && configStandalone.runGPUforce) {
279 printf("No GPU backend / device found, running on CPU is disabled due to runGPUforce\n");
280 return 1;
281 }
282 configStandalone.runGPU = false;
283 configStandalone.gpuType = "CPU";
284 }
285 }
286
287 if (configStandalone.printSettings) {
288 configStandalone.proc.printSettings = true;
289 }
290 if (configStandalone.printSettings > 1) {
291 printf("Config Dump after ReadConfiguration\n");
292 qConfigPrint();
293 }
294
295 return (0);
296}
297
299{
301
304 calib.fastTransform = tmpFastTransformBuffer.get();
305 auto tmpTRDGeometry = std::make_unique<o2::trd::GeometryFlat>();
306 calib.trdGeometry = tmpTRDGeometry.get();
307 auto tmpTRDRecoParam = std::make_unique<GPUTRDRecoParam>();
308 calib.trdRecoParam = tmpTRDRecoParam.get();
309 auto tmpdEdxCalibContainer = std::make_unique<o2::tpc::CalibdEdxContainer>();
310 tmpdEdxCalibContainer->setDefaultZeroSupresssionThreshold();
311 tmpdEdxCalibContainer->setDefaultPolTopologyCorrection();
312 calib.dEdxCalibContainer = tmpdEdxCalibContainer.get();
313 auto tmpTPCPadGainCalib = std::make_unique<TPCPadGainCalib>();
314 calib.tpcPadGain = tmpTPCPadGainCalib.get();
315 auto tmpTPCZSLinkMapping = std::make_unique<TPCZSLinkMapping>();
316 calib.tpcZSLinkMapping = tmpTPCZSLinkMapping.get();
317
319 rec->DumpSettings("./");
320 printf("Wrote trivial calibration objects to current folder\n");
321}
322
324{
325 if (!configStandalone.eventGenerator) {
326 if (configStandalone.noEvents) {
327 eventsDir = "NON_EXISTING";
328 configStandalone.rundEdx = false;
329 } else if (rec->ReadSettings(eventsDir.c_str())) {
330 printf("Error reading event config file\n");
331 return 1;
332 }
333 const char* tmptext = configStandalone.noEvents ? "Using default event settings, no event dir loaded" : "Read event settings from dir ";
334 printf("%s%s (solenoidBz: %f, constBz %d, maxTimeBin %d)\n", tmptext, configStandalone.noEvents ? "" : eventsDir.c_str(), rec->GetGRPSettings().solenoidBzNominalGPU, (int32_t)rec->GetGRPSettings().constBz, rec->GetGRPSettings().grpContinuousMaxTimeBin);
335 if (configStandalone.testSyncAsync) {
337 }
338 if (configStandalone.proc.doublePipeline) {
340 }
341 }
342
345 if (configStandalone.testSyncAsync) {
348 }
349
351 GPUSettingsRec recSet;
352 GPUSettingsProcessing procSet;
353 recSet = configStandalone.rec;
354 procSet = configStandalone.proc;
356
357 if (configStandalone.solenoidBzNominalGPU != -1e6f) {
358 grp.solenoidBzNominalGPU = configStandalone.solenoidBzNominalGPU;
359 }
360 if (configStandalone.constBz) {
361 grp.constBz = true;
362 }
363 if (configStandalone.TF.nMerge || configStandalone.TF.bunchSim) {
364 if (grp.grpContinuousMaxTimeBin) {
365 printf("ERROR: requested to overlay continuous data - not supported\n");
366 return 1;
367 }
368 if (!configStandalone.cont) {
369 printf("Continuous mode forced\n");
370 configStandalone.cont = true;
371 }
374 }
375 }
376 if (configStandalone.setMaxTimeBin != -2) {
377 grp.grpContinuousMaxTimeBin = configStandalone.setMaxTimeBin;
378 } else if (configStandalone.cont && grp.grpContinuousMaxTimeBin == 0) {
380 }
381 if (grp.grpContinuousMaxTimeBin < -1 && !configStandalone.noEvents) {
382 printf("Invalid maxTimeBin %d\n", grp.grpContinuousMaxTimeBin);
383 return 1;
384 }
385 if (rec->GetDeviceType() == GPUReconstruction::DeviceType::CPU) {
386 printf("Standalone Test Framework for CA Tracker - Using CPU\n");
387 } else {
388 printf("Standalone Test Framework for CA Tracker - Using GPU\n");
389 }
390
391 configStandalone.proc.forceMemoryPoolSize = (configStandalone.proc.forceMemoryPoolSize == 1 && configStandalone.eventDisplay) ? 2 : configStandalone.proc.forceMemoryPoolSize;
392 if (configStandalone.eventDisplay) {
393 eventDisplay.reset(GPUDisplayFrontendInterface::getFrontend(configStandalone.display.displayFrontend.c_str()));
394 if (eventDisplay.get() == nullptr) {
395 throw std::runtime_error("Requested display not available");
396 }
397 printf("Enabling event display (%s backend)\n", eventDisplay->frontendName());
398 procSet.eventDisplay = eventDisplay.get();
399 if (!configStandalone.QA.noMC) {
400 procSet.runMC = true;
401 }
402 }
403
404 if (procSet.runQA && !configStandalone.QA.noMC) {
405 procSet.runMC = true;
406 }
407
408 steps.steps = gpudatatypes::RecoStep::AllRecoSteps;
409 if (configStandalone.runTRD != -1) {
410 steps.steps.setBits(gpudatatypes::RecoStep::TRDTracking, configStandalone.runTRD > 0);
411 } else if (chainTracking->GetTRDGeometry() == nullptr) {
412 steps.steps.setBits(gpudatatypes::RecoStep::TRDTracking, false);
413 }
414 if (configStandalone.runCompression != -1) {
415 steps.steps.setBits(gpudatatypes::RecoStep::TPCCompression, configStandalone.runCompression > 0);
416 }
417 if (configStandalone.runTransformation != -1) {
418 steps.steps.setBits(gpudatatypes::RecoStep::TPCConversion, configStandalone.runTransformation > 0);
419 }
420 steps.steps.setBits(gpudatatypes::RecoStep::Refit, configStandalone.runRefit);
421 if (!configStandalone.runMerger) {
422 steps.steps.setBits(gpudatatypes::RecoStep::TPCMerging, false);
423 steps.steps.setBits(gpudatatypes::RecoStep::TRDTracking, false);
424 steps.steps.setBits(gpudatatypes::RecoStep::TPCdEdx, false);
425 steps.steps.setBits(gpudatatypes::RecoStep::TPCCompression, false);
426 steps.steps.setBits(gpudatatypes::RecoStep::Refit, false);
427 }
428
429 if (configStandalone.TF.bunchSim || configStandalone.TF.nMerge) {
430 steps.steps.setBits(gpudatatypes::RecoStep::TRDTracking, false);
431 }
432 steps.inputs.set(gpudatatypes::InOutType::TPCClusters, gpudatatypes::InOutType::TRDTracklets);
433 steps.steps.setBits(gpudatatypes::RecoStep::TPCDecompression, false);
434 steps.inputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, false);
435 if (grp.doCompClusterDecode) {
436 steps.inputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, true);
437 steps.inputs.setBits(gpudatatypes::InOutType::TPCClusters, false);
438 steps.steps.setBits(gpudatatypes::RecoStep::TPCCompression, false);
439 steps.steps.setBits(gpudatatypes::RecoStep::TPCClusterFinding, false);
440 steps.steps.setBits(gpudatatypes::RecoStep::TPCDecompression, true);
441 steps.outputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, false);
442 } else if (grp.needsClusterer) {
443 steps.inputs.setBits(gpudatatypes::InOutType::TPCRaw, true);
444 steps.inputs.setBits(gpudatatypes::InOutType::TPCClusters, false);
445 } else {
446 steps.steps.setBits(gpudatatypes::RecoStep::TPCClusterFinding, false);
447 }
448
449 // Set settings for synchronous
450 GPUChainTracking::ApplySyncSettings(procSet, recSet, steps.steps, configStandalone.testSyncAsync || configStandalone.testSync, configStandalone.rundEdx);
451 int32_t runAsyncQA = procSet.runQA && !configStandalone.testSyncAsyncQcInSync ? procSet.runQA : 0;
452 if (configStandalone.testSyncAsync) {
453 procSet.eventDisplay = nullptr;
454 if (!configStandalone.testSyncAsyncQcInSync) {
455 procSet.runQA = false;
456 }
457 }
458
459 // Apply --recoSteps flag last so it takes precedence
460 // E.g. ApplySyncSettings might enable TPCdEdx, but might not be needed if only clusterizer was requested
461 if (configStandalone.recoSteps >= 0) {
462 steps.steps &= configStandalone.recoSteps;
463 }
464 if (configStandalone.recoStepsGPU >= 0) {
465 steps.stepsGPUMask &= configStandalone.recoStepsGPU;
466 }
467
468 steps.outputs.clear();
469 steps.outputs.setBits(gpudatatypes::InOutType::TPCMergedTracks, steps.steps.isSet(gpudatatypes::RecoStep::TPCMerging));
470 steps.outputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, steps.steps.isSet(gpudatatypes::RecoStep::TPCCompression));
471 steps.outputs.setBits(gpudatatypes::InOutType::TRDTracks, steps.steps.isSet(gpudatatypes::RecoStep::TRDTracking));
472 steps.outputs.setBits(gpudatatypes::InOutType::TPCClusters, steps.steps.isSet(gpudatatypes::RecoStep::TPCClusterFinding));
473
474 if (steps.steps.isSet(gpudatatypes::RecoStep::TRDTracking)) {
475 if (procSet.createO2Output && !procSet.trdTrackModelO2) {
476 procSet.createO2Output = 1; // Must not be 2, to make sure TPC GPU tracks are still available for TRD
477 }
478 }
479
480 rec->SetSettings(&grp, &recSet, &procSet, &steps);
481 if (configStandalone.proc.doublePipeline) {
482 recPipeline->SetSettings(&grp, &recSet, &procSet, &steps);
483 }
484 if (configStandalone.testSyncAsync) { // TODO: Add --async mode / flag
485 // Set settings for asynchronous
486 steps.steps.setBits(gpudatatypes::RecoStep::TPCDecompression, true);
487 steps.steps.setBits(gpudatatypes::RecoStep::TPCdEdx, true);
488 steps.steps.setBits(gpudatatypes::RecoStep::TPCCompression, false);
489 steps.steps.setBits(gpudatatypes::RecoStep::TPCClusterFinding, false);
490 steps.inputs.setBits(gpudatatypes::InOutType::TPCRaw, false);
491 steps.inputs.setBits(gpudatatypes::InOutType::TPCClusters, false);
492 steps.inputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, true);
493 steps.outputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, false);
494 procSet.runMC = false;
495 procSet.runQA = runAsyncQA;
496 procSet.eventDisplay = eventDisplay.get();
497 procSet.runCompressionStatistics = 0;
498 if (recSet.tpc.rejectionStrategy >= GPUSettings::RejectionStrategyB) {
499 procSet.tpcInputWithClusterRejection = 1;
500 }
501 recSet.tpc.disableRefitAttachment = 0xFF;
502 recSet.maxTrackQPtB5 = CAMath::Min(recSet.maxTrackQPtB5, recSet.tpc.rejectQPtB5);
503 GPUChainTracking::ApplySyncSettings(procSet, recSet, steps.steps, false, configStandalone.rundEdx);
504 recAsync->SetSettings(&grp, &recSet, &procSet, &steps);
505 }
506
507 if (configStandalone.outputcontrolmem) {
508 rec->SetOutputControl(outputmemory.get(), configStandalone.outputcontrolmem);
509 if (configStandalone.proc.doublePipeline) {
511 }
512 }
513
514 o2::base::Propagator* prop = nullptr;
516 prop->setGPUField(&rec->GetParam().polynomialField);
517 prop->setNominalBz(rec->GetParam().bzkG);
518 prop->setMatLUT(chainTracking->GetMatLUT());
520 if (chainTrackingAsync) {
522 }
525 }
526 procSet.o2PropagatorUseGPUField = true;
527
528 if (rec->Init()) {
529 printf("Error initializing GPUReconstruction!\n");
530 return 1;
531 }
532 if (configStandalone.outputcontrolmem && rec->IsGPU()) {
533 if (rec->registerMemoryForGPU(outputmemory.get(), configStandalone.outputcontrolmem) || (configStandalone.proc.doublePipeline && recPipeline->registerMemoryForGPU(outputmemoryPipeline.get(), configStandalone.outputcontrolmem))) {
534 printf("ERROR registering memory for the GPU!!!\n");
535 return 1;
536 }
537 }
538 if (configStandalone.inputcontrolmem && rec->IsGPU()) {
539 if (rec->registerMemoryForGPU(inputmemory.get(), configStandalone.inputcontrolmem)) {
540 printf("ERROR registering input memory for the GPU!!!\n");
541 return 1;
542 }
543 }
544 if (configStandalone.proc.debugLevel >= 4) {
546 }
547 return (0);
548}
549
550int32_t ReadEvent(int32_t n)
551{
552 if (configStandalone.inputcontrolmem && !configStandalone.preloadEvents) {
553 rec->SetInputControl(inputmemory.get(), configStandalone.inputcontrolmem);
554 }
555 int32_t r = chainTracking->ReadData((eventsDir + GPUCA_EVDUMP_FILE "." + std::to_string(n) + ".dump").c_str());
556 if (r) {
557 return r;
558 }
559#if !defined(GPUCA_RUN2) && defined(GPUCA_BUILD_QA) && defined(GPUCA_STANDALONE)
560 if ((configStandalone.proc.runQA || configStandalone.eventDisplay) && !configStandalone.QA.noMC) {
563 if (chainTracking->GetQA()->ReadO2MCData((eventsDir + "mc." + std::to_string(n) + ".dump").c_str()) &&
564 chainTracking->GetQA()->ReadO2MCData((eventsDir + "mc.0.dump").c_str()) && configStandalone.proc.runQA) {
565 throw std::runtime_error("Error reading O2 MC dump");
566 }
567 }
568#endif
569 if (chainTracking->mIOPtrs.clustersNative && (configStandalone.TF.bunchSim || configStandalone.TF.nMerge || !configStandalone.runTransformation)) {
570 if (configStandalone.proc.debugLevel >= 2) {
571 printf("Converting Native to Legacy ClusterData for overlaying - WARNING: No raw clusters produced - Compression etc will not run!!!\n");
572 }
574 }
575 return 0;
576}
577
578int32_t LoadEvent(int32_t iEvent, int32_t x)
579{
580 if (configStandalone.TF.bunchSim) {
581 if (tf->LoadCreateTimeFrame(iEvent)) {
582 return 1;
583 }
584 } else if (configStandalone.TF.nMerge) {
585 if (tf->LoadMergedEvents(iEvent)) {
586 return 1;
587 }
588 } else {
589 if (ReadEvent(iEvent)) {
590 return 1;
591 }
592 }
593 bool encodeZS = configStandalone.encodeZS == -1 ? (chainTracking->mIOPtrs.tpcPackedDigits && !chainTracking->mIOPtrs.tpcZS) : (bool)configStandalone.encodeZS;
594 bool zsFilter = configStandalone.zsFilter == -1 ? (!encodeZS && chainTracking->mIOPtrs.tpcPackedDigits && !chainTracking->mIOPtrs.tpcZS) : (bool)configStandalone.zsFilter;
595 if (encodeZS || zsFilter) {
597 printf("Need digit input to run ZS\n");
598 return 1;
599 }
600 if (zsFilter) {
602 }
603 if (encodeZS) {
605 }
606 }
607 if (!configStandalone.runTransformation) {
609 } else {
610 for (int32_t i = 0; i < chainTracking->NSECTORS; i++) {
612 if (configStandalone.proc.debugLevel >= 2) {
613 printf("Converting Legacy Raw Cluster to Native\n");
614 }
616 break;
617 }
618 }
619 }
620
621 if (configStandalone.stripDumpedEvents) {
624 }
625 }
626
628 printf("Need cluster native data for on-the-fly TPC transform\n");
629 return 1;
630 }
631
633 ioMemEvents[x] = std::move(chainTracking->mIOMem);
635 return 0;
636}
637
638void OutputStat(GPUChainTracking* t, int64_t* nTracksTotal = nullptr, int64_t* nClustersTotal = nullptr)
639{
640 int32_t nTracks = 0;
641 if (t->GetProcessingSettings().createO2Output) {
642 nTracks += t->mIOPtrs.nOutputTracksTPCO2;
643 } else {
644 for (uint32_t k = 0; k < t->mIOPtrs.nMergedTracks; k++) {
645 if (t->mIOPtrs.mergedTracks[k].OK()) {
646 nTracks++;
647 }
648 }
649 }
650 if (nTracksTotal && nClustersTotal) {
651 *nTracksTotal += nTracks;
652 *nClustersTotal += t->mIOPtrs.nMergedTrackHits;
653 }
654}
655
656int32_t RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingUse, int32_t runs, int32_t iEvent, int64_t* nTracksTotal, int64_t* nClustersTotal, int32_t threadId = 0, HighResTimer* timerPipeline = nullptr)
657{
658 int32_t iRun = 0, iteration = 0;
659 while ((iteration = nIteration.fetch_add(1)) < runs) {
660 if (configStandalone.runs > 1) {
661 printf("Run %d (thread %d)\n", iteration + 1, threadId);
662 }
663 if (configStandalone.runsInit > 0 && configStandalone.proc.debugCSV.empty()) {
664 recUse->SetResetTimers(iRun < configStandalone.runsInit);
665 }
666 if (configStandalone.outputcontrolmem) {
667 recUse->SetOutputControl(threadId ? outputmemoryPipeline.get() : outputmemory.get(), configStandalone.outputcontrolmem);
668 }
669
670 if (configStandalone.testSyncAsync) {
671 printf("Running synchronous phase\n");
672 }
673 const GPUTrackingInOutPointers& ioPtrs = ioPtrEvents[!configStandalone.preloadEvents ? 0 : configStandalone.proc.doublePipeline ? (iteration % ioPtrEvents.size()) : (iEvent - configStandalone.StartEvent)];
674 chainTrackingUse->mIOPtrs = ioPtrs;
675 if (iteration == (configStandalone.proc.doublePipeline ? 2 : (configStandalone.runs - 1))) {
676 if (configStandalone.proc.doublePipeline && timerPipeline) {
677 timerPipeline->Start();
678 }
679 if (configStandalone.controlProfiler) {
681 }
682 }
683 int32_t tmpRetVal = recUse->RunChains();
684 int32_t iterationEnd = nIterationEnd.fetch_add(1);
685 if (iterationEnd == configStandalone.runs - 1) {
686 if (configStandalone.proc.doublePipeline && timerPipeline) {
687 timerPipeline->Stop();
688 }
689 if (configStandalone.controlProfiler) {
691 }
692 }
693
694 if (tmpRetVal == 0 || tmpRetVal == 2) {
695 OutputStat(chainTrackingUse, iRun == 0 ? nTracksTotal : nullptr, iRun == 0 ? nClustersTotal : nullptr);
696 }
697
698 if (tmpRetVal == 0 && configStandalone.testSyncAsync) {
699
704 printf("Running asynchronous phase from %'u compressed clusters\n", syncAsyncDecodedClusters);
705
706 chainTrackingAsync->mIOPtrs = ioPtrs;
716 for (int32_t i = 0; i < chainTracking->NSECTORS; i++) {
721 }
723 if (configStandalone.runsInit > 0 && configStandalone.proc.debugCSV.empty()) {
724 recAsync->SetResetTimers(iRun < configStandalone.runsInit);
725 }
726 tmpRetVal = recAsync->RunChains();
727 if (tmpRetVal == 0 || tmpRetVal == 2) {
728 OutputStat(chainTrackingAsync, nullptr, nullptr);
729 }
731 }
732 if (!configStandalone.proc.doublePipeline) {
733 recUse->ClearAllocatedMemory();
734 }
735
736 if (tmpRetVal == 2) {
737 configStandalone.continueOnError = 0; // Forced exit from event display loop
738 configStandalone.noprompt = 1;
739 }
740 if (tmpRetVal == 3 && configStandalone.proc.ignoreNonFatalGPUErrors) {
741 printf("GPU Standalone Benchmark: Non-FATAL GPU error occured, ignoring\n");
742 } else if (tmpRetVal && !configStandalone.continueOnError) {
743 if (tmpRetVal != 2) {
744 printf("GPU Standalone Benchmark: Error occured\n");
745 }
746 return 1;
747 }
748 iRun++;
749 }
750 if (configStandalone.proc.doublePipeline) {
751 recUse->ClearAllocatedMemory();
752 }
753 nIteration.store(runs);
754 return 0;
755}
756
757int32_t main(int argc, char** argv)
758{
759 std::unique_ptr<GPUReconstruction> recUnique, recUniqueAsync, recUniquePipeline;
760
761 if (ReadConfiguration(argc, argv)) {
762 return 1;
763 }
764 eventsDir = std::string(configStandalone.absoluteEventsDir ? "" : "events/") + configStandalone.eventsDir + "/";
765
766 GPUSettingsDeviceBackend deviceSet;
767 deviceSet.deviceType = configStandalone.runGPU ? gpudatatypes::GetDeviceType(configStandalone.gpuType.c_str()) : gpudatatypes::DeviceType::CPU;
768 deviceSet.forceDeviceType = configStandalone.runGPUforce;
769 deviceSet.master = nullptr;
770 recUnique.reset(GPUReconstruction::CreateInstance(deviceSet));
771 rec = recUnique.get();
772 deviceSet.master = rec;
773 if (configStandalone.testSyncAsync) {
774 recUniqueAsync.reset(GPUReconstruction::CreateInstance(deviceSet));
775 recAsync = recUniqueAsync.get();
776 }
777 if (configStandalone.proc.doublePipeline) {
778 recUniquePipeline.reset(GPUReconstruction::CreateInstance(deviceSet));
779 recPipeline = recUniquePipeline.get();
780 }
781 if (rec == nullptr || (configStandalone.testSyncAsync && recAsync == nullptr)) {
782 printf("Error initializing GPUReconstruction\n");
783 return 1;
784 }
785 rec->SetDebugLevelTmp(configStandalone.proc.debugLevel);
787 if (configStandalone.testSyncAsync) {
788 if (configStandalone.proc.debugLevel >= 3) {
790 }
792 }
793 if (configStandalone.proc.doublePipeline) {
794 if (configStandalone.proc.debugLevel >= 3) {
796 }
799 }
800 if (!configStandalone.proc.doublePipeline) {
802 if (configStandalone.testSyncAsync) {
804 }
805 }
806
807 if (configStandalone.recreateTrivialCalibObjects) {
809 return 0;
810 }
811
812 if (SetupReconstruction()) {
813 return 1;
814 }
815
816 std::unique_ptr<std::thread> pipelineThread;
817 if (configStandalone.proc.doublePipeline) {
818 pipelineThread.reset(new std::thread([]() { rec->RunPipelineWorker(); }));
819 }
820
821 if (configStandalone.seed == -1) {
822 std::random_device rd;
823 configStandalone.seed = (int32_t)rd();
824 printf("Using random seed %d\n", configStandalone.seed);
825 }
826
827 srand(configStandalone.seed);
828
830 if (!configStandalone.noEvents) {
831 while (true) {
832 std::ifstream in;
833 in.open((eventsDir + GPUCA_EVDUMP_FILE "." + std::to_string(nEventsInDirectory) + ".dump").c_str(), std::ifstream::binary);
834 if (in.fail()) {
835 break;
836 }
837 in.close();
839 }
840 }
841
842 if (configStandalone.TF.bunchSim || configStandalone.TF.nMerge) {
844 }
845
846 if (configStandalone.eventGenerator) {
848 return 0;
849 }
850
851 int32_t nEvents = configStandalone.nEvents;
852 if (configStandalone.TF.bunchSim) {
853 nEvents = configStandalone.nEvents > 0 ? configStandalone.nEvents : 1;
854 } else {
855 if (nEvents == -1 || nEvents > nEventsInDirectory) {
856 if (nEvents >= 0) {
857 printf("Only %d events available in directory %s (%d events requested)\n", nEventsInDirectory, eventsDir.c_str(), nEvents);
858 }
860 }
861 if (nEvents == 0 && !configStandalone.noEvents) {
862 printf("No event data found in event folder\n");
863 }
864 if (configStandalone.TF.nMerge > 1) {
865 nEvents /= configStandalone.TF.nMerge;
866 }
867 }
868
869 ioPtrEvents.resize(configStandalone.preloadEvents ? (nEvents - configStandalone.StartEvent) : 1);
870 ioMemEvents.resize(configStandalone.preloadEvents ? (nEvents - configStandalone.StartEvent) : 1);
871 if (configStandalone.preloadEvents) {
872 printf("Preloading events%s", configStandalone.proc.debugLevel >= 2 ? "\n" : "");
873 fflush(stdout);
874 for (int32_t i = 0; i < nEvents - configStandalone.StartEvent; i++) {
875 LoadEvent(configStandalone.StartEvent + i, i);
876 printf(configStandalone.proc.debugLevel >= 2 ? "Loading event %d\n" : " %d", i + configStandalone.StartEvent);
877 fflush(stdout);
878 }
879 printf("\n");
880 }
881
882 for (int32_t iRunOuter = 0; iRunOuter < configStandalone.runs2; iRunOuter++) {
883 if (configStandalone.QA.inputHistogramsOnly) {
885 break;
886 }
887 if (configStandalone.runs2 > 1) {
888 printf("\nRUN2: %d\n", iRunOuter);
889 }
890 int64_t nTracksTotal = 0;
891 int64_t nClustersTotal = 0;
892 int32_t nEventsProcessed = 0;
893
894 if (configStandalone.noEvents) {
895 nEvents = 1;
896 configStandalone.StartEvent = 0;
898 }
899
900 for (int32_t iEvent = configStandalone.StartEvent; iEvent < nEvents; iEvent++) {
901 if (iEvent != configStandalone.StartEvent) {
902 printf("\n");
903 }
904 if (!configStandalone.noEvents && !configStandalone.preloadEvents) {
905 HighResTimer timerLoad;
906 timerLoad.Start();
907 if (LoadEvent(iEvent, 0)) {
908 goto breakrun;
909 }
910 if (configStandalone.dumpEvents) {
911 char fname[1024];
912 snprintf(fname, 1024, "event.%d.dump", nEventsProcessed);
913 chainTracking->DumpData(fname);
914 if (nEventsProcessed == 0) {
915 rec->DumpSettings();
916 }
917 }
918
921 if (grp.grpContinuousMaxTimeBin == 0) {
922 printf("Cannot override max time bin for non-continuous data!\n");
923 } else {
925 printf("Max time bin set to %d\n", grp.grpContinuousMaxTimeBin);
926 rec->UpdateSettings(&grp);
927 if (recAsync) {
929 }
930 if (recPipeline) {
932 }
933 }
934 }
935 printf("Loading time: %'d us\n", (int32_t)(1000000 * timerLoad.GetCurrentElapsedTime()));
936 }
937
938 nIteration.store(0);
939 nIterationEnd.store(0);
940 double pipelineWalltime = 1.;
941 if (configStandalone.noEvents) {
942 printf("No processing, no events loaded\n");
943 } else if (configStandalone.proc.doublePipeline) {
944 printf(configStandalone.preloadEvents ? "Processing Events %d to %d in Pipeline\n" : "Processing Event %d in Pipeline %d times\n", iEvent, configStandalone.preloadEvents ? std::min(iEvent + configStandalone.runs - 1, nEvents - 1) : configStandalone.runs);
945 HighResTimer timerPipeline;
946 if (configStandalone.proc.debugLevel < 2 && (RunBenchmark(rec, chainTracking, 1, iEvent, &nTracksTotal, &nClustersTotal) || RunBenchmark(recPipeline, chainTrackingPipeline, 2, iEvent, &nTracksTotal, &nClustersTotal))) {
947 goto breakrun;
948 }
949 auto pipeline1 = std::async(std::launch::async, RunBenchmark, rec, chainTracking, configStandalone.runs, iEvent, &nTracksTotal, &nClustersTotal, 0, &timerPipeline);
950 auto pipeline2 = std::async(std::launch::async, RunBenchmark, recPipeline, chainTrackingPipeline, configStandalone.runs, iEvent, &nTracksTotal, &nClustersTotal, 1, &timerPipeline);
951 if (pipeline1.get() || pipeline2.get()) {
952 goto breakrun;
953 }
954 pipelineWalltime = timerPipeline.GetElapsedTime() / (configStandalone.runs - 2);
955 printf("Pipeline wall time: %f, %d iterations, %f per event\n", timerPipeline.GetElapsedTime(), configStandalone.runs - 2, pipelineWalltime);
956 } else {
957 printf("Processing Event %d\n", iEvent);
958 if (RunBenchmark(rec, chainTracking, configStandalone.runs, iEvent, &nTracksTotal, &nClustersTotal)) {
959 goto breakrun;
960 }
961 }
962 nEventsProcessed++;
963
964 if (configStandalone.timeFrameTime) {
965 double nClusters = chainTracking->GetProcessors()->tpcMerger.NMaxClusters();
966 if (nClusters > 0) {
967 const int32_t nOrbits = 32;
968 const double colRate = 50000;
969 const double orbitRate = 11245;
970 const double nClsPerTF = 755851. * nOrbits * colRate / orbitRate;
971 double timePerTF = (configStandalone.proc.doublePipeline ? pipelineWalltime : ((configStandalone.proc.debugLevel ? rec->GetStatKernelTime() : rec->GetStatWallTime()) / 1000000.)) * nClsPerTF / nClusters;
972 const double nGPUsReq = timePerTF * orbitRate / nOrbits;
973 char stat[1024];
974 snprintf(stat, 1024, "Sync phase: %.2f sec per %d orbit TF, %.1f GPUs required", timePerTF, nOrbits, nGPUsReq);
975 if (configStandalone.testSyncAsync) {
976 timePerTF = (configStandalone.proc.debugLevel ? recAsync->GetStatKernelTime() : recAsync->GetStatWallTime()) / 1000000. * nClsPerTF / nClusters;
977 snprintf(stat + strlen(stat), 1024 - strlen(stat), " - Async phase: %f sec per TF", timePerTF);
978 }
979 printf("%s (Measured %s time - Extrapolated from %d clusters to %d)\n", stat, configStandalone.proc.debugLevel ? "kernel" : "wall", (int32_t)nClusters, (int32_t)nClsPerTF);
980 }
981 }
984 float rejectionPercentage = (rejected) * 100.f / chainTracking->mIOPtrs.clustersNative->nClustersTotal;
985 printf("Cluster Rejection: Sync: %'u, Compressed %'u, Async %'u, Rejected %'u (%7.2f%%)\n", chainTracking->mIOPtrs.clustersNative->nClustersTotal, syncAsyncDecodedClusters, chainTrackingAsync->mIOPtrs.clustersNative->nClustersTotal, rejected, rejectionPercentage);
986 }
987
988 if (configStandalone.preloadEvents && configStandalone.proc.doublePipeline) {
989 break;
990 }
991 }
992 if (nEventsProcessed > 1) {
993 printf("Total: %ld clusters, %ld tracks\n", nClustersTotal, nTracksTotal);
994 }
995 }
996
997breakrun:
998 if (rec->GetProcessingSettings().memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_GLOBAL) {
1000 }
1001
1002#ifndef _WIN32
1003 if (configStandalone.proc.runQA && configStandalone.fpe) {
1004 fedisableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
1005 }
1006#endif
1007
1008 if (configStandalone.proc.doublePipeline) {
1010 pipelineThread->join();
1011 }
1012
1013 rec->Finalize();
1014 if (configStandalone.testSyncAsync) {
1015 recAsync->Finalize();
1016 }
1017 if (configStandalone.outputcontrolmem && rec->IsGPU()) {
1019 printf("Error unregistering memory\n");
1020 }
1021 }
1022 rec->Exit();
1023
1024 if (!configStandalone.noprompt) {
1025 printf("Press a key to exit!\n");
1026 getchar();
1027 }
1028 return (0);
1029}
Definition of container class for dE/dx corrections.
Container to store compressed TPC cluster data.
int32_t i
#define GPUCA_EVDUMP_FILE
Definition GPUDef.h:37
class to create TPC fast transformation
POD correction map.
int nClusters
void Start()
Definition timer.cxx:64
double GetCurrentElapsedTime(bool reset=false)
Definition timer.cxx:117
void set(S v)
Definition bitfield.h:55
void clear()
Definition bitfield.h:54
S get() const
Definition bitfield.h:63
bitfield & setBits(const bitfield v, bool w)
Definition bitfield.h:45
bool isSet(const bitfield &v) const
Definition bitfield.h:66
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:178
static void ApplySyncSettings(GPUSettingsProcessing &proc, GPUSettingsRec &rec, gpudatatypes::RecoStepField &steps, bool syncMode, int32_t dEdxMode=-2)
void SetQAFromForeignChain(GPUChainTracking *chain)
void SetCalibObjects(const GPUCalibObjectsConst &obj)
void SetO2Propagator(const o2::base::Propagator *prop)
const GPUTRDGeometry * GetTRDGeometry() const
const TPCFastTransformPOD * GetTPCTransform() const
const o2::base::MatLayerCylSet * GetMatLUT() const
const GPUSettingsDisplay * mConfigDisplay
void DumpData(const char *filename, const GPUTrackingInOutPointers *ioPtrs=nullptr)
const GPUQA * GetQA() const
GPUTrackingInOutPointers & mIOPtrs
struct o2::gpu::GPUChainTracking::InOutMemory mIOMem
int32_t ReadData(const char *filename)
const GPUSettingsQA * mConfigQA
const GPUSettingsProcessing & GetProcessingSettings() const
Definition GPUChain.h:76
static constexpr int32_t NSECTORS
Definition GPUChain.h:58
const GPUConstantMem * GetProcessors() const
Definition GPUChain.h:68
static GPUDisplayFrontendInterface * getFrontend(const char *type)
int32_t ReadO2MCData(const char *filename)
Definition GPUQA.h:55
void UpdateChain(GPUChainTracking *chain)
Definition GPUQA.h:59
static int32_t GetMaxTimeBin(const o2::tpc::ClusterNativeAccess &native)
static DeviceType GetDeviceType(const char *type)
void SetInputControl(void *ptr, size_t size)
static bool CheckInstanceAvailable(DeviceType type, bool verbose)
void SetSettings(float solenoidBzNominalGPU, const GPURecoStepConfiguration *workflow=nullptr)
static GPUReconstruction * CreateInstance(const GPUSettingsDeviceBackend &cfg)
void UpdateSettings(const GPUSettingsGRP *g, const GPUSettingsProcessing *p=nullptr, const GPUSettingsRecDynamic *d=nullptr)
virtual int32_t RunChains()=0
const GPUParam & GetParam() const
void ClearAllocatedMemory(bool clearOutputs=true)
const GPUSettingsProcessing & GetProcessingSettings() const
void DumpSettings(const char *dir="")
int32_t unregisterMemoryForGPU(const void *ptr)
int32_t registerMemoryForGPU(const void *ptr, size_t size)
const GPUSettingsGRP & GetGRPSettings() const
void SetDebugLevelTmp(int32_t level)
int32_t ReadSettings(const char *dir="")
void SetOutputControl(const GPUOutputControl &v)
static TPCFastTransformPOD * create(aligned_unique_buffer_ptr< TPCFastTransformPOD > &destVector, const TPCFastTransform &src)
Create POD transform from old flat-buffer one. Provided vector will serve as a buffer.
static void RunEventGenerator(GPUChainTracking *rec, const std::string &dir)
Definition genEvents.h:35
static TPCFastTransformHelperO2 * instance()
Singleton.
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLboolean r
Definition glcorearb.h:1233
GLenum GLenum GLsizei len
Definition glcorearb.h:4232
GLenum GLfloat param
Definition glcorearb.h:271
GLint GLuint mask
Definition glcorearb.h:291
DeviceType GetDeviceType(const char *type)
GPUSettingsStandalone configStandalone
Definition genEvents.cxx:47
@ qcrHelp
Definition qconfig.h:29
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
void qConfigPrint()
Definition qconfig.cxx:515
int32_t qConfigParse(int argc, const char **argv, const char *filename)
Definition qconfig.cxx:513
std::unique_ptr< GPUReconstructionTimeframe > tf
std::unique_ptr< char, GPUReconstruction::alignedDefaultBufferDeleter > outputmemoryPipeline(nullptr, GPUReconstruction::alignedDefaultBufferDeleter())
std::unique_ptr< char, GPUReconstruction::alignedDefaultBufferDeleter > inputmemory(nullptr, GPUReconstruction::alignedDefaultBufferDeleter())
int32_t RunBenchmark(GPUReconstruction *recUse, GPUChainTracking *chainTrackingUse, int32_t runs, int32_t iEvent, int64_t *nTracksTotal, int64_t *nClustersTotal, int32_t threadId=0, HighResTimer *timerPipeline=nullptr)
int32_t SetupReconstruction()
std::atomic< uint32_t > nIteration
GPUReconstruction * recPipeline
int32_t nEventsInDirectory
uint32_t syncAsyncDecodedClusters
int32_t ReadConfiguration(int argc, char **argv)
std::unique_ptr< char, GPUReconstruction::alignedDefaultBufferDeleter > outputmemory(nullptr, GPUReconstruction::alignedDefaultBufferDeleter())
int32_t LoadEvent(int32_t iEvent, int32_t x)
std::vector< GPUTrackingInOutPointers > ioPtrEvents
GPUChainITS * chainITSPipeline
int32_t ReadEvent(int32_t n)
std::vector< GPUChainTracking::InOutMemory > ioMemEvents
std::unique_ptr< GPUDisplayFrontendInterface > eventDisplay
GPUReconstruction * rec
GPUChainITS * chainITS
GPUChainTracking * chainTrackingAsync
GPUChainITS * chainITSAsync
GPUChainTracking * chainTrackingPipeline
GPUReconstruction * recAsync
void OutputStat(GPUChainTracking *t, int64_t *nTracksTotal=nullptr, int64_t *nClustersTotal=nullptr)
std::atomic< uint32_t > nIterationEnd
std::string eventsDir
GPUChainTracking * chainTracking
void CreateTrivialCalibObjects()
S< o2::trd::GeometryFlat >::type * trdGeometry
S< o2::tpc::CalibdEdxContainer >::type * dEdxCalibContainer
S< TPCZSLinkMapping >::type * tpcZSLinkMapping
S< TPCFastTransformPOD >::type * fastTransform
S< GPUTRDRecoParam >::type * trdRecoParam
S< TPCPadGainCalib >::type * tpcPadGain
gpudatatypes::RecoStepField steps
gpudatatypes::InOutTypeField inputs
gpudatatypes::RecoStepField stepsGPUMask
gpudatatypes::InOutTypeField outputs
const o2::tpc::ClusterNativeAccess * clustersNative
const o2::tpc::CompressedClustersFlat * tpcCompressedClusters
const AliHLTTPCClusterMCLabel * mcLabelsTPC
const GPUTrackingInOutZS * tpcZS
const AliHLTTPCRawCluster * rawClusters[NSECTORS]
const GPUTPCClusterData * clusterData[NSECTORS]
const GPUTrackingInOutDigits * tpcPackedDigits
const GPUTPCMCInfoCol * mcInfosTPCCol
const GPUTPCGMMergedTrack * mergedTracks
GPUTPCGMPolynomialField polynomialField
Definition GPUParam.h:57
const int nEvents
Definition test_Fifo.cxx:27
#define main
std::random_device rd
typename std::vector< T, vecpod_allocator< T > > vecpod
Definition vecpod.h:31