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#ifndef GPUCA_STANDALONE
16#include "GPUO2ExternalUser.h" // Compiled like O2 code using the GPU interface: full O2 headers (e.g. MatLayerCylSet::rectifyPtrFromFile), ROOT before the GPU headers
19#include "TPCBase/Mapper.h"
20#endif
21
22#include "utils/qconfig.h"
23#include "GPUReconstruction.h"
26#include "GPUChainTracking.h"
27#include "GPUChainTrackingGetters.inc"
28#include "GPUTPCDef.h"
29#include "GPUQA.h"
30#include "GPUParam.h"
32#include "genEvents.h"
33
34#include "GPUTPCGMMergedTrack.h"
35#define GPUSETTINGS_ALL
36#include "GPUSettings.h"
37#include "GPUConstantMem.h"
38
39#include "GPUO2DataTypes.h"
40#include "GPUChainITS.h"
41
42// For creating default objects
44#include "CalibdEdxContainer.h"
45#include "TPCFastTransformPOD.h"
46#include "GPUTRDRecoParam.h"
47#include "TPCZSLinkMapping.h"
48
50
51#include <iostream>
52#include <fstream>
53#include <cstdio>
54#include <cstring>
55#include <chrono>
56#include <tuple>
57#include <algorithm>
58#include <thread>
59#include <future>
60#include <atomic>
61#include <vector>
62
63#ifndef _WIN32
64#include <unistd.h>
65#include <sched.h>
66#include <csignal>
67#include <sys/types.h>
68#include <sys/wait.h>
69#include <sys/select.h>
70#include <cfenv>
71#include <clocale>
72#include <sys/stat.h>
73#endif
74#include "utils/timer.h"
76#include "utils/vecpod.h"
77
78using namespace o2::gpu;
79
80// #define BROKEN_EVENTS
81
82namespace o2::gpu
83{
84extern GPUSettingsStandalone configStandalone;
85}
86
91std::string eventsDir;
93std::unique_ptr<GPUDisplayFrontendInterface> eventDisplay;
94std::unique_ptr<GPUReconstructionTimeframe> tf;
96std::atomic<uint32_t> nIteration, nIterationEnd;
97
98std::vector<GPUTrackingInOutPointers> ioPtrEvents;
99std::vector<GPUChainTracking::InOutMemory> ioMemEvents;
100
101int32_t ReadConfiguration(int argc, char** argv)
102{
103 int32_t qcRet = qConfig::qConfigParse(argc, (const char**)argv);
104 if (qcRet) {
105 if (qcRet != qConfig::qcrHelp) {
106 printf("Error parsing command line parameters\n");
107 }
108 return 1;
109 }
110 if (configStandalone.listRecoSteps) {
111 printf("RecoSteps (bitmask for --recoSteps / --recoStepsGPU):\n");
112 for (int32_t i = 0; i < gpudatatypes::N_RECO_STEPS; i++) {
113 printf("%10d (0x%04x): %s\n", 1 << i, 1 << i, gpudatatypes::RECO_STEP_NAMES[i]);
114 }
115 }
116 if (configStandalone.printSettings > 1) {
117 printf("Config Dump before ReadConfiguration\n");
119 }
120 if (configStandalone.proc.debugLevel == -1) {
121 configStandalone.proc.debugLevel = 0;
122 }
123#ifndef _WIN32
124 setlocale(LC_ALL, "en_US.utf-8");
125 setlocale(LC_NUMERIC, "en_US.utf-8");
126 if (configStandalone.cpuAffinity != -1) {
127 cpu_set_t mask;
128 CPU_ZERO(&mask);
129 CPU_SET(configStandalone.cpuAffinity, &mask);
130
131 printf("Setting affinitiy to restrict on CPU core %d\n", configStandalone.cpuAffinity);
132 if (0 != sched_setaffinity(0, sizeof(mask), &mask)) {
133 printf("Error setting CPU affinity\n");
134 return 1;
135 }
136 }
137 if (configStandalone.fifoScheduler) {
138 printf("Setting FIFO scheduler\n");
139 sched_param param;
140 sched_getparam(0, &param);
141 param.sched_priority = 1;
142 if (0 != sched_setscheduler(0, SCHED_FIFO, &param)) {
143 printf("Error setting scheduler\n");
144 return 1;
145 }
146 }
147#ifdef __FAST_MATH__
148 if (configStandalone.fpe == 1) {
149#else
150 if (configStandalone.fpe) {
151#endif
152 feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
153 }
154 bool detMode = false, noFTZMode = false;
155#ifdef GPUCA_DETERMINISTIC_MODE
156 detMode = true;
157#endif
158#ifdef GPUCA_DETERMINISTIC_NO_FTZ
159 noFTZMode = true;
160#endif
161 if (configStandalone.flushDenormals >= 1 || (configStandalone.flushDenormals == -1 && (configStandalone.proc.deterministicGPUReconstruction >= 1 || (configStandalone.proc.deterministicGPUReconstruction == -1 && detMode)) && !noFTZMode)) {
162 disable_denormals();
163 }
164
165#else
166 if (configStandalone.cpuAffinity != -1) {
167 printf("Affinity setting not supported on Windows\n");
168 return 1;
169 }
170 if (configStandalone.fifoScheduler) {
171 printf("FIFO Scheduler setting not supported on Windows\n");
172 return 1;
173 }
174 if (configStandalone.fpe == 1) {
175 printf("FPE not supported on Windows\n");
176 return 1;
177 }
178#endif
179#ifdef GPUCA_RUN2
180#warning Why was configStandalone.rec.tpc.mergerReadFromTrackerDirectly = 0 needed?
181 configStandalone.proc.inKernelParallel = false;
182 configStandalone.proc.createO2Output = 0;
183 if (configStandalone.rundEdx == -1) {
184 configStandalone.rundEdx = 0;
185 }
186#endif
187#ifndef GPUCA_BUILD_QA
188 if (configStandalone.proc.runQA || configStandalone.eventGenerator) {
189 printf("QA not enabled in build\n");
190 return 1;
191 }
192#endif
193 if (configStandalone.proc.doublePipeline && configStandalone.testSyncAsync) {
194 printf("Cannot run asynchronous processing with double pipeline\n");
195 return 1;
196 }
197 if (configStandalone.proc.doublePipeline && (configStandalone.runs < 4 || !configStandalone.outputcontrolmem)) {
198 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");
199 return 1;
200 }
201 if (configStandalone.TF.bunchSim && configStandalone.TF.nMerge) {
202 printf("Cannot run --MERGE and --SIMBUNCHES togeterh\n");
203 return 1;
204 }
205 if (configStandalone.TF.bunchSim > 1) {
206 configStandalone.TF.timeFrameLen = 1.e9 * configStandalone.TF.bunchSim / configStandalone.TF.interactionRate;
207 }
208 if (configStandalone.TF.nMerge) {
209 double len = configStandalone.TF.nMerge - 1;
210 if (configStandalone.TF.randomizeDistance) {
211 len += 0.5;
212 }
213 if (configStandalone.TF.shiftFirstEvent) {
214 len += 0.5;
215 }
217 }
218 if (configStandalone.QA.inputHistogramsOnly && configStandalone.QA.compareInputs.size() == 0) {
219 printf("Can only produce QA pdf output when input files are specified!\n");
220 return 1;
221 }
222 if (configStandalone.QA.enableLocalOutput && !configStandalone.QA.inputHistogramsOnly && configStandalone.QA.output == "" && configStandalone.QA.plotsDir != "") {
223 configStandalone.QA.output = configStandalone.QA.plotsDir + "/output.root";
224 }
225 if (configStandalone.QA.inputHistogramsOnly) {
226 configStandalone.rundEdx = false;
227 configStandalone.noEvents = true;
228 }
229 if (configStandalone.QA.dumpToROOTLevel >= 1) {
230 configStandalone.proc.outputSharedClusterMap = true;
231 }
232 if (configStandalone.eventDisplay) {
233 configStandalone.promptOnExit = 0;
234 }
235 if (configStandalone.proc.debugLevel >= 4) {
236 if (configStandalone.proc.inKernelParallel) {
237 configStandalone.proc.inKernelParallel = 1;
238 } else {
239 configStandalone.proc.nHostThreads = 1;
240 }
241 }
242 if (configStandalone.setO2Settings) {
243 if (configStandalone.runGPU && configStandalone.proc.debugLevel <= 1) {
244 if (!(configStandalone.inputcontrolmem && configStandalone.outputcontrolmem)) {
245 printf("setO2Settings requires the usage of --inputMemory and --outputMemory as in O2\n");
246 return 1;
247 }
248 configStandalone.proc.forceHostMemoryPoolSize = 1024 * 1024 * 1024;
249 }
250 configStandalone.rec.tpc.trackReferenceX = 83;
251 configStandalone.proc.outputSharedClusterMap = 1;
252 configStandalone.proc.clearO2OutputFromGPU = 1;
253 configStandalone.QA.clusterRejectionHistograms = 1;
254 configStandalone.proc.tpcIncreasedMinClustersPerRow = 500000;
255 configStandalone.proc.ignoreNonFatalGPUErrors = 1;
256 // TODO: rundEdx=1
257 // GPU_proc.qcRunFraction=$TPC_TRACKING_QC_RUN_FRACTION;"
258 // [[ $CTFINPUT == 1 ]] && GPU_CONFIG_KEY+="GPU_proc.tpcInputWithClusterRejection=1;"
259 // double pipeline / rtc
260 }
261
262 if (configStandalone.outputcontrolmem) {
263 bool forceEmptyMemory = getenv("LD_PRELOAD") && strstr(getenv("LD_PRELOAD"), "valgrind") != nullptr;
264 outputmemory.reset(GPUReconstruction::alignedDefaultBufferAllocator<char>(configStandalone.outputcontrolmem));
265 if (forceEmptyMemory) {
266 printf("Valgrind detected, emptying GPU output memory to avoid false positive undefined reads");
267 memset(outputmemory.get(), 0, configStandalone.outputcontrolmem);
268 }
269 if (configStandalone.proc.doublePipeline) {
270 outputmemoryPipeline.reset(GPUReconstruction::alignedDefaultBufferAllocator<char>(configStandalone.outputcontrolmem));
271 if (forceEmptyMemory) {
272 memset(outputmemoryPipeline.get(), 0, configStandalone.outputcontrolmem);
273 }
274 }
275 }
276 if (configStandalone.inputcontrolmem) {
277 inputmemory.reset(GPUReconstruction::alignedDefaultBufferAllocator<char>(configStandalone.inputcontrolmem));
278 }
279
280 configStandalone.proc.showOutputStat = true;
281
282 if (configStandalone.runGPU && configStandalone.gpuType == "AUTO") {
283 if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::CUDA, configStandalone.proc.debugLevel >= 2)) {
284 configStandalone.gpuType = "CUDA";
285 } else if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::HIP, configStandalone.proc.debugLevel >= 2)) {
286 configStandalone.gpuType = "HIP";
287 } else if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::OCL, configStandalone.proc.debugLevel >= 2)) {
288 configStandalone.gpuType = "OCL";
289 } else if (GPUReconstruction::CheckInstanceAvailable(GPUReconstruction::DeviceType::OCL, configStandalone.proc.debugLevel >= 2)) {
290 configStandalone.gpuType = "OCL";
291 } else {
292 if (configStandalone.runGPU > 1 && configStandalone.runGPUforce) {
293 printf("No GPU backend / device found, running on CPU is disabled due to runGPUforce\n");
294 return 1;
295 }
296 configStandalone.runGPU = false;
297 configStandalone.gpuType = "CPU";
298 }
299 }
300
301 if (configStandalone.printSettings) {
302 configStandalone.proc.printSettings = true;
303 }
304 if (configStandalone.printSettings > 1) {
305 printf("Config Dump after ReadConfiguration\n");
307 }
308
309 return (0);
310}
311
312void CreateTrivialCalibObjects([[maybe_unused]] int64_t timestamp) // Timestamp of the CCDB objects (O2 build), 1: now
313{
315
318 calib.fastTransform = tmpFastTransformBuffer.get();
319 auto tmpTRDGeometry = std::make_unique<o2::trd::GeometryFlat>();
320 calib.trdGeometry = tmpTRDGeometry.get();
321 auto tmpTRDRecoParam = std::make_unique<GPUTRDRecoParam>();
322 calib.trdRecoParam = tmpTRDRecoParam.get();
323 auto tmpdEdxCalibContainer = std::make_unique<o2::tpc::CalibdEdxContainer>();
324 tmpdEdxCalibContainer->setDefaultZeroSupresssionThreshold();
325 tmpdEdxCalibContainer->setDefaultPolTopologyCorrection();
326 calib.dEdxCalibContainer = tmpdEdxCalibContainer.get();
327 auto tmpTPCPadGainCalib = std::make_unique<TPCPadGainCalib>();
328 calib.tpcPadGain = tmpTPCPadGainCalib.get();
329#ifndef GPUCA_STANDALONE
330 auto tmpTPCZSLinkMapping = std::make_unique<TPCZSLinkMapping>(o2::tpc::Mapper::instance());
331 calib.tpcZSLinkMapping = tmpTPCZSLinkMapping.get();
332 auto& ccdb = o2::ccdb::BasicCCDBManager::instance(); // Default CCDB server (NameConf), objects owned by the manager
333 ccdb.setFatalWhenNull(false); // Without CCDB access, write the other objects
334 if (timestamp != 1) {
335 ccdb.setTimestamp(timestamp);
336 }
337 if (auto* matLUT = ccdb.get<o2::base::MatLayerCylSet>("GLO/Param/MatLUT")) {
339 } else {
340 printf("Could not fetch the material LUT from the CCDB, not written\n");
341 }
342#endif
343
345 rec->DumpSettings("./");
346 printf("Wrote trivial calibration objects to current folder\n");
347}
348
350{
351 if (!configStandalone.eventGenerator) {
352 if (configStandalone.noEvents) {
353 eventsDir = "NON_EXISTING";
354 configStandalone.rundEdx = false;
355 } else if (rec->ReadSettings(eventsDir.c_str())) {
356 printf("Error reading event config file\n");
357 return 1;
358 }
359 const char* tmptext = configStandalone.noEvents ? "Using default event settings, no event dir loaded" : "Read event settings from dir ";
360 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);
361 if (configStandalone.testSyncAsync) {
363 }
364 if (configStandalone.proc.doublePipeline) {
366 }
367 }
368
371 if (configStandalone.testSyncAsync) {
374 }
375
377 GPUSettingsRec recSet;
378 GPUSettingsProcessing procSet;
379 recSet = configStandalone.rec;
380 procSet = configStandalone.proc;
382
383 if (configStandalone.solenoidBzNominalGPU != -1e6f) {
384 grp.solenoidBzNominalGPU = configStandalone.solenoidBzNominalGPU;
385 }
386 if (configStandalone.constBz) {
387 grp.constBz = true;
388 }
389 if (configStandalone.TF.nMerge || configStandalone.TF.bunchSim) {
390 if (grp.grpContinuousMaxTimeBin) {
391 printf("ERROR: requested to overlay continuous data - not supported\n");
392 return 1;
393 }
394 if (!configStandalone.cont) {
395 printf("Continuous mode forced\n");
396 configStandalone.cont = true;
397 }
400 }
401 }
402 if (configStandalone.setMaxTimeBin != -2) {
403 grp.grpContinuousMaxTimeBin = configStandalone.setMaxTimeBin;
404 } else if (configStandalone.cont && grp.grpContinuousMaxTimeBin == 0) {
406 }
407 if (grp.grpContinuousMaxTimeBin < -1 && !configStandalone.noEvents) {
408 printf("Invalid maxTimeBin %d\n", grp.grpContinuousMaxTimeBin);
409 return 1;
410 }
411 if (rec->GetDeviceType() == GPUReconstruction::DeviceType::CPU) {
412 printf("Standalone Test Framework for CA Tracker - Using CPU\n");
413 } else {
414 printf("Standalone Test Framework for CA Tracker - Using GPU\n");
415 }
416
417 configStandalone.proc.forceMemoryPoolSize = (configStandalone.proc.forceMemoryPoolSize == 1 && configStandalone.eventDisplay) ? 2 : configStandalone.proc.forceMemoryPoolSize;
418 if (configStandalone.eventDisplay) {
419 eventDisplay.reset(GPUDisplayFrontendInterface::getFrontend(configStandalone.display.displayFrontend.c_str()));
420 if (eventDisplay.get() == nullptr) {
421 throw std::runtime_error("Requested display not available");
422 }
423 printf("Enabling event display (%s backend)\n", eventDisplay->frontendName());
424 procSet.eventDisplay = eventDisplay.get();
425 if (!configStandalone.QA.noMC) {
426 procSet.runMC = true;
427 }
428 }
429
430 if (procSet.runQA && !configStandalone.QA.noMC) {
431 procSet.runMC = true;
432 }
433
434 steps.steps = gpudatatypes::RecoStep::AllRecoSteps;
435 if (configStandalone.runTRD != -1) {
436 steps.steps.setBits(gpudatatypes::RecoStep::TRDTracking, configStandalone.runTRD > 0);
437 } else if (chainTracking->GetTRDGeometry() == nullptr) {
438 steps.steps.setBits(gpudatatypes::RecoStep::TRDTracking, false);
439 }
440 if (configStandalone.runCompression != -1) {
441 steps.steps.setBits(gpudatatypes::RecoStep::TPCCompression, configStandalone.runCompression > 0);
442 }
443 if (configStandalone.runTransformation != -1) {
444 steps.steps.setBits(gpudatatypes::RecoStep::TPCConversion, configStandalone.runTransformation > 0);
445 }
446 steps.steps.setBits(gpudatatypes::RecoStep::Refit, configStandalone.runRefit);
447 if (!configStandalone.runMerger) {
448 steps.steps.setBits(gpudatatypes::RecoStep::TPCMerging, false);
449 steps.steps.setBits(gpudatatypes::RecoStep::TRDTracking, false);
450 steps.steps.setBits(gpudatatypes::RecoStep::TPCdEdx, false);
451 steps.steps.setBits(gpudatatypes::RecoStep::TPCCompression, false);
452 steps.steps.setBits(gpudatatypes::RecoStep::Refit, false);
453 }
454
455 if (configStandalone.TF.bunchSim || configStandalone.TF.nMerge) {
456 steps.steps.setBits(gpudatatypes::RecoStep::TRDTracking, false);
457 }
458 steps.inputs.set(gpudatatypes::InOutType::TPCClusters, gpudatatypes::InOutType::TRDTracklets);
459 steps.steps.setBits(gpudatatypes::RecoStep::TPCDecompression, false);
460 steps.inputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, false);
461 if (grp.doCompClusterDecode) {
462 steps.inputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, true);
463 steps.inputs.setBits(gpudatatypes::InOutType::TPCClusters, false);
464 steps.steps.setBits(gpudatatypes::RecoStep::TPCCompression, false);
465 steps.steps.setBits(gpudatatypes::RecoStep::TPCClusterFinding, false);
466 steps.steps.setBits(gpudatatypes::RecoStep::TPCDecompression, true);
467 steps.outputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, false);
468 } else if (grp.needsClusterer) {
469 steps.inputs.setBits(gpudatatypes::InOutType::TPCRaw, true);
470 steps.inputs.setBits(gpudatatypes::InOutType::TPCClusters, false);
471 } else {
472 steps.steps.setBits(gpudatatypes::RecoStep::TPCClusterFinding, false);
473 }
474
475 // Set settings for synchronous
476 GPUChainTracking::ApplySyncSettings(procSet, recSet, steps.steps, configStandalone.testSyncAsync || configStandalone.testSync, configStandalone.rundEdx);
477 int32_t runAsyncQA = procSet.runQA && !configStandalone.testSyncAsyncQcInSync ? procSet.runQA : 0;
478 if (configStandalone.testSyncAsync) {
479 procSet.eventDisplay = nullptr;
480 if (!configStandalone.testSyncAsyncQcInSync) {
481 procSet.runQA = false;
482 }
483 }
484
485 // Apply --recoSteps flag last so it takes precedence
486 // E.g. ApplySyncSettings might enable TPCdEdx, but might not be needed if only clusterizer was requested
487 if (configStandalone.recoSteps >= 0) {
488 steps.steps &= configStandalone.recoSteps;
489 }
490 if (configStandalone.recoStepsGPU >= 0) {
491 steps.stepsGPUMask &= configStandalone.recoStepsGPU;
492 }
493
494 steps.outputs.clear();
495 steps.outputs.setBits(gpudatatypes::InOutType::TPCMergedTracks, steps.steps.isSet(gpudatatypes::RecoStep::TPCMerging));
496 steps.outputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, steps.steps.isSet(gpudatatypes::RecoStep::TPCCompression));
497 steps.outputs.setBits(gpudatatypes::InOutType::TRDTracks, steps.steps.isSet(gpudatatypes::RecoStep::TRDTracking));
498 steps.outputs.setBits(gpudatatypes::InOutType::TPCClusters, steps.steps.isSet(gpudatatypes::RecoStep::TPCClusterFinding));
499
500 if (steps.steps.isSet(gpudatatypes::RecoStep::TRDTracking)) {
501 if (procSet.createO2Output && !procSet.trdTrackModelO2) {
502 procSet.createO2Output = 1; // Must not be 2, to make sure TPC GPU tracks are still available for TRD
503 }
504 }
505
506 rec->SetSettings(&grp, &recSet, &procSet, &steps);
507 if (configStandalone.proc.doublePipeline) {
508 recPipeline->SetSettings(&grp, &recSet, &procSet, &steps);
509 }
510 if (configStandalone.testSyncAsync) { // TODO: Add --async mode / flag
511 // Set settings for asynchronous
512 steps.steps.setBits(gpudatatypes::RecoStep::TPCDecompression, true);
513 steps.steps.setBits(gpudatatypes::RecoStep::TPCdEdx, true);
514 steps.steps.setBits(gpudatatypes::RecoStep::TPCCompression, false);
515 steps.steps.setBits(gpudatatypes::RecoStep::TPCClusterFinding, false);
516 steps.inputs.setBits(gpudatatypes::InOutType::TPCRaw, false);
517 steps.inputs.setBits(gpudatatypes::InOutType::TPCClusters, false);
518 steps.inputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, true);
519 steps.outputs.setBits(gpudatatypes::InOutType::TPCCompressedClusters, false);
520 procSet.runMC = false;
521 procSet.runQA = runAsyncQA;
522 procSet.eventDisplay = eventDisplay.get();
523 procSet.runCompressionStatistics = 0;
524 if (recSet.tpc.rejectionStrategy >= GPUSettings::RejectionStrategyB) {
525 procSet.tpcInputWithClusterRejection = 1;
526 }
527 recSet.tpc.disableRefitAttachment = 0xFF;
528 recSet.maxTrackQPtB5 = CAMath::Min(recSet.maxTrackQPtB5, recSet.tpc.rejectQPtB5);
529 GPUChainTracking::ApplySyncSettings(procSet, recSet, steps.steps, false, configStandalone.rundEdx);
530 recAsync->SetSettings(&grp, &recSet, &procSet, &steps);
531 }
532
533 if (configStandalone.outputcontrolmem) {
534 rec->SetOutputControl(outputmemory.get(), configStandalone.outputcontrolmem);
535 if (configStandalone.proc.doublePipeline) {
537 }
538 }
539
540 o2::base::Propagator* prop = nullptr;
542 prop->setGPUField(&rec->GetParam().polynomialField);
543 prop->setNominalBz(rec->GetParam().bzkG);
544 prop->setMatLUT(chainTracking->GetMatLUT());
546 if (chainTrackingAsync) {
548 }
551 }
552 procSet.o2PropagatorUseGPUField = true;
553
554 if (rec->Init()) {
555 printf("Error initializing GPUReconstruction!\n");
556 return 1;
557 }
558 if (configStandalone.outputcontrolmem && rec->IsGPU()) {
559 if (rec->registerMemoryForGPU(outputmemory.get(), configStandalone.outputcontrolmem) || (configStandalone.proc.doublePipeline && recPipeline->registerMemoryForGPU(outputmemoryPipeline.get(), configStandalone.outputcontrolmem))) {
560 printf("ERROR registering memory for the GPU!!!\n");
561 return 1;
562 }
563 }
564 if (configStandalone.inputcontrolmem && rec->IsGPU()) {
565 if (rec->registerMemoryForGPU(inputmemory.get(), configStandalone.inputcontrolmem)) {
566 printf("ERROR registering input memory for the GPU!!!\n");
567 return 1;
568 }
569 }
570 if (configStandalone.proc.debugLevel >= 4) {
572 }
573 return (0);
574}
575
577{
578 if (configStandalone.inputcontrolmem && !configStandalone.preloadEvents) {
579 rec->SetInputControl(inputmemory.get(), configStandalone.inputcontrolmem);
580 }
582 if (r) {
583 return r;
584 }
585#if !defined(GPUCA_RUN2) && defined(GPUCA_BUILD_QA) && defined(GPUCA_STANDALONE)
586 if ((configStandalone.proc.runQA || configStandalone.eventDisplay) && !configStandalone.QA.noMC) {
589 if (chainTracking->GetQA()->ReadO2MCData((eventsDir + "mc." + std::to_string(n) + ".dump").c_str()) &&
590 chainTracking->GetQA()->ReadO2MCData((eventsDir + "mc.0.dump").c_str()) && configStandalone.proc.runQA) {
591 throw std::runtime_error("Error reading O2 MC dump");
592 }
593 }
594#endif
595 return 0;
596}
597
598int32_t LoadEvent(int32_t iEvent, int32_t x)
599{
600 if (configStandalone.TF.bunchSim) {
601 if (tf->LoadCreateTimeFrame(iEvent)) {
602 return 1;
603 }
604 } else if (configStandalone.TF.nMerge) {
605 if (tf->LoadMergedEvents(iEvent)) {
606 return 1;
607 }
608 } else {
609 if (ReadEvent(iEvent)) {
610 return 1;
611 }
612 }
613 bool encodeZS = configStandalone.encodeZS == -1 ? (chainTracking->mIOPtrs.tpcPackedDigits && !chainTracking->mIOPtrs.tpcZS) : (bool)configStandalone.encodeZS;
614 bool zsFilter = configStandalone.zsFilter == -1 ? (!encodeZS && chainTracking->mIOPtrs.tpcPackedDigits && !chainTracking->mIOPtrs.tpcZS) : (bool)configStandalone.zsFilter;
615 if (encodeZS || zsFilter) {
617 printf("Need digit input to run ZS\n");
618 return 1;
619 }
620 if (zsFilter) {
622 }
623 if (encodeZS) {
625 }
626 }
627 if (!configStandalone.runTransformation) {
629 } else {
630 for (int32_t i = 0; i < chainTracking->NSECTORS; i++) {
632 if (configStandalone.proc.debugLevel >= 2) {
633 printf("Converting Legacy Raw Cluster to Native\n");
634 }
636 break;
637 }
638 }
639 }
640
641 if (configStandalone.stripDumpedEvents) {
644 }
645 }
646
648 printf("Need cluster native data for on-the-fly TPC transform\n");
649 return 1;
650 }
651
653 ioMemEvents[x] = std::move(chainTracking->mIOMem);
655 return 0;
656}
657
658void OutputStat(GPUChainTracking* t, int64_t* nTracksTotal = nullptr, int64_t* nClustersTotal = nullptr)
659{
660 int32_t nTracks = 0;
661 if (t->GetProcessingSettings().createO2Output) {
662 nTracks += t->mIOPtrs.nOutputTracksTPCO2;
663 } else {
664 for (uint32_t k = 0; k < t->mIOPtrs.nMergedTracks; k++) {
665 if (t->mIOPtrs.mergedTracks[k].OK()) {
666 nTracks++;
667 }
668 }
669 }
670 if (nTracksTotal && nClustersTotal) {
671 *nTracksTotal += nTracks;
672 *nClustersTotal += t->mIOPtrs.nMergedTrackHits;
673 }
674}
675
676int32_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)
677{
678 int32_t iRun = 0, iteration = 0;
679 while ((iteration = nIteration.fetch_add(1)) < runs) {
680 if (configStandalone.runs > 1) {
681 printf("Run %d (thread %d)\n", iteration + 1, threadId);
682 }
683 if (configStandalone.runsInit > 0 && configStandalone.proc.debugCSV.empty()) {
684 recUse->SetResetTimers(iRun < configStandalone.runsInit);
685 }
686 if (configStandalone.outputcontrolmem) {
687 recUse->SetOutputControl(threadId ? outputmemoryPipeline.get() : outputmemory.get(), configStandalone.outputcontrolmem);
688 }
689
690 if (configStandalone.testSyncAsync) {
691 printf("Running synchronous phase\n");
692 }
693 const GPUTrackingInOutPointers& ioPtrs = ioPtrEvents[!configStandalone.preloadEvents ? 0 : (configStandalone.proc.doublePipeline ? (iteration % ioPtrEvents.size()) : (iEvent - configStandalone.StartEvent))];
694 chainTrackingUse->mIOPtrs = ioPtrs;
695 if (iteration == (configStandalone.proc.doublePipeline ? 2 : (configStandalone.runs - 1))) {
696 if (configStandalone.proc.doublePipeline && timerPipeline) {
697 timerPipeline->Start();
698 }
699 if (configStandalone.controlProfiler) {
701 }
702 }
703 int32_t tmpRetVal = recUse->RunChains();
704 int32_t iterationEnd = nIterationEnd.fetch_add(1);
705 if (iterationEnd == configStandalone.runs - 1) {
706 if (configStandalone.proc.doublePipeline && timerPipeline) {
707 timerPipeline->Stop();
708 }
709 if (configStandalone.controlProfiler) {
711 }
712 }
713
714 if (tmpRetVal == GPUReconstruction::retValValue::retOk || tmpRetVal == GPUReconstruction::retValValue::retDoExit) {
715 OutputStat(chainTrackingUse, iRun == 0 ? nTracksTotal : nullptr, iRun == 0 ? nClustersTotal : nullptr);
716 }
717
718 if (tmpRetVal == GPUReconstruction::retValValue::retOk && configStandalone.testSyncAsync) {
723 printf("Running asynchronous phase from %'u compressed clusters\n", syncAsyncDecodedClusters);
724
725 chainTrackingAsync->mIOPtrs = ioPtrs;
735 for (int32_t i = 0; i < chainTracking->NSECTORS; i++) {
740 }
742 if (configStandalone.runsInit > 0 && configStandalone.proc.debugCSV.empty()) {
743 recAsync->SetResetTimers(iRun < configStandalone.runsInit);
744 }
745 tmpRetVal = recAsync->RunChains();
746 if (tmpRetVal == GPUReconstruction::retValValue::retOk || tmpRetVal == GPUReconstruction::retValValue::retDoExit) {
747 OutputStat(chainTrackingAsync, nullptr, nullptr);
748 }
750 }
751 if (!configStandalone.proc.doublePipeline) {
752 recUse->ClearAllocatedMemory();
753 }
754
755 if (tmpRetVal == GPUReconstruction::retValValue::retDoExit) {
756 configStandalone.continueOnError = 0; // Forced exit from event display loop
757 configStandalone.promptOnExit = 0;
758 }
759 if (tmpRetVal == GPUReconstruction::retValValue::retNonFatalErrorCode && configStandalone.proc.ignoreNonFatalGPUErrors) {
760 printf("GPU Standalone Benchmark: Non-FATAL GPU error occured, ignoring\n");
761 } else if (tmpRetVal && !configStandalone.continueOnError) {
762 if (tmpRetVal != GPUReconstruction::retValValue::retDoExit) {
763 printf("GPU Standalone Benchmark: Error occured\n");
764 }
765 return 1;
766 }
767 iRun++;
768 }
769 if (configStandalone.proc.doublePipeline) {
770 recUse->ClearAllocatedMemory();
771 }
772 nIteration.store(runs);
773 return 0;
774}
775
776int32_t main(int argc, char** argv)
777{
778 std::unique_ptr<GPUReconstruction> recUnique, recUniqueAsync, recUniquePipeline;
779
780 if (ReadConfiguration(argc, argv)) {
781 return 1;
782 }
783 configStandalone.proc.runsStandalone = true;
784 eventsDir = std::string(configStandalone.absoluteEventsDir ? "" : "events/") + configStandalone.eventsDir + "/";
785
786 GPUSettingsDeviceBackend deviceSet;
787 deviceSet.deviceType = configStandalone.runGPU ? gpudatatypes::GetDeviceType(configStandalone.gpuType.c_str()) : gpudatatypes::DeviceType::CPU;
788 deviceSet.forceDeviceType = configStandalone.runGPUforce;
789 deviceSet.master = nullptr;
790 recUnique.reset(GPUReconstruction::CreateInstance(deviceSet));
791 rec = recUnique.get();
792 deviceSet.master = rec;
793 if (configStandalone.testSyncAsync) {
794 recUniqueAsync.reset(GPUReconstruction::CreateInstance(deviceSet));
795 recAsync = recUniqueAsync.get();
796 }
797 if (configStandalone.proc.doublePipeline) {
798 recUniquePipeline.reset(GPUReconstruction::CreateInstance(deviceSet));
799 recPipeline = recUniquePipeline.get();
800 }
801 if (rec == nullptr || (configStandalone.testSyncAsync && recAsync == nullptr)) {
802 printf("Error initializing GPUReconstruction\n");
803 return 1;
804 }
805 rec->SetDebugLevelTmp(configStandalone.proc.debugLevel);
807 if (configStandalone.testSyncAsync) {
808 if (configStandalone.proc.debugLevel >= 3) {
810 }
812 }
813 if (configStandalone.proc.doublePipeline) {
814 if (configStandalone.proc.debugLevel >= 3) {
816 }
819 }
820 if (!configStandalone.proc.doublePipeline) {
822 if (configStandalone.testSyncAsync) {
824 }
825 }
826
827 if (configStandalone.recreateTrivialCalibObjects) {
828 CreateTrivialCalibObjects(configStandalone.recreateTrivialCalibObjects);
829 return 0;
830 }
831
832 if (SetupReconstruction()) {
833 return 1;
834 }
835
836 std::unique_ptr<std::thread> pipelineThread;
837 if (configStandalone.proc.doublePipeline) {
838 pipelineThread.reset(new std::thread([]() { rec->RunPipelineWorker(); }));
839 }
840
841 if (configStandalone.seed == -1) {
842 std::random_device rd;
843 configStandalone.seed = (int32_t)rd();
844 printf("Using random seed %d\n", configStandalone.seed);
845 }
846
848
850 if (!configStandalone.noEvents) {
851 while (true) {
852 std::ifstream in;
853 in.open((eventsDir + GPUCA_EVDUMP_FILE "." + std::to_string(nEventsInDirectory) + ".dump").c_str(), std::ifstream::binary);
854 if (in.fail()) {
855 break;
856 }
857 in.close();
859 }
860 }
861
862 if (configStandalone.TF.bunchSim || configStandalone.TF.nMerge) {
864 }
865
866 if (configStandalone.eventGenerator) {
868 return 0;
869 }
870
872 if (configStandalone.TF.bunchSim) {
873 nEvents = configStandalone.nEvents > 0 ? configStandalone.nEvents : 1;
874 } else {
875 if (nEvents == -1 || nEvents > nEventsInDirectory) {
876 if (nEvents >= 0) {
877 printf("Only %d events available in directory %s (%d events requested)\n", nEventsInDirectory, eventsDir.c_str(), nEvents);
878 }
880 }
881 if (nEvents == 0 && !configStandalone.noEvents) {
882 printf("No event data found in event folder\n");
883 }
884 if (configStandalone.TF.nMerge > 1) {
885 nEvents /= configStandalone.TF.nMerge;
886 }
887 }
888
889 ioPtrEvents.resize(configStandalone.preloadEvents ? (nEvents - configStandalone.StartEvent) : 1);
890 ioMemEvents.resize(configStandalone.preloadEvents ? (nEvents - configStandalone.StartEvent) : 1);
891 if (configStandalone.preloadEvents) {
892 printf("Preloading events%s", configStandalone.proc.debugLevel >= 2 ? "\n" : "");
893 fflush(stdout);
894 for (int32_t i = 0; i < nEvents - configStandalone.StartEvent; i++) {
895 LoadEvent(configStandalone.StartEvent + i, i);
896 printf(configStandalone.proc.debugLevel >= 2 ? "Loading event %d\n" : " %d", i + configStandalone.StartEvent);
897 fflush(stdout);
898 }
899 printf("\n");
900 }
901
902 for (int32_t iRunOuter = 0; iRunOuter < configStandalone.runs2; iRunOuter++) {
903 if (configStandalone.QA.inputHistogramsOnly) {
905 break;
906 }
907 if (configStandalone.runs2 > 1) {
908 printf("\nRUN2: %d\n", iRunOuter);
909 }
910 int64_t nTracksTotal = 0;
911 int64_t nClustersTotal = 0;
912 int32_t nEventsProcessed = 0;
913
914 if (configStandalone.noEvents) {
915 nEvents = 1;
916 configStandalone.StartEvent = 0;
918 }
919
920 for (int32_t iEvent = configStandalone.StartEvent; iEvent < nEvents; iEvent++) {
921 if (iEvent != configStandalone.StartEvent) {
922 printf("\n");
923 }
924 if (!configStandalone.noEvents && !configStandalone.preloadEvents) {
925 HighResTimer timerLoad;
926 timerLoad.Start();
927 if (LoadEvent(iEvent, 0)) {
928 goto breakrun;
929 }
930 if (configStandalone.dumpEvents) {
931 char fname[1024];
932 snprintf(fname, 1024, "event.%d.dump", nEventsProcessed);
933 chainTracking->DumpData(fname);
934 if (nEventsProcessed == 0) {
935 rec->DumpSettings();
936 }
937 }
938
941 if (grp.grpContinuousMaxTimeBin == 0) {
942 printf("Cannot override max time bin for non-continuous data!\n");
943 } else {
945 printf("Max time bin set to %d\n", grp.grpContinuousMaxTimeBin);
946 rec->UpdateSettings(&grp);
947 if (recAsync) {
949 }
950 if (recPipeline) {
952 }
953 }
954 }
955 printf("Loading time: %'d us\n", (int32_t)(1000000 * timerLoad.GetCurrentElapsedTime()));
956 }
957
958 nIteration.store(0);
959 nIterationEnd.store(0);
960 double pipelineWalltime = 1.;
961 if (configStandalone.noEvents) {
962 printf("No processing, no events loaded\n");
963 } else if (configStandalone.proc.doublePipeline) {
964 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);
965 HighResTimer timerPipeline;
966 if (configStandalone.proc.debugLevel < 2 && (RunBenchmark(rec, chainTracking, 1, iEvent, &nTracksTotal, &nClustersTotal) || RunBenchmark(recPipeline, chainTrackingPipeline, 2, iEvent, &nTracksTotal, &nClustersTotal))) {
967 goto breakrun;
968 }
969 auto pipeline1 = std::async(std::launch::async, RunBenchmark, rec, chainTracking, configStandalone.runs, iEvent, &nTracksTotal, &nClustersTotal, 0, &timerPipeline);
970 auto pipeline2 = std::async(std::launch::async, RunBenchmark, recPipeline, chainTrackingPipeline, configStandalone.runs, iEvent, &nTracksTotal, &nClustersTotal, 1, &timerPipeline);
971 if (pipeline1.get() || pipeline2.get()) {
972 goto breakrun;
973 }
974 pipelineWalltime = timerPipeline.GetElapsedTime() / (configStandalone.runs - 2);
975 printf("Pipeline wall time: %f, %d iterations, %f per event\n", timerPipeline.GetElapsedTime(), configStandalone.runs - 2, pipelineWalltime);
976 } else {
977 printf("Processing Event %d\n", iEvent);
978 if (RunBenchmark(rec, chainTracking, configStandalone.runs, iEvent, &nTracksTotal, &nClustersTotal)) {
979 goto breakrun;
980 }
981 }
982 nEventsProcessed++;
983
984 if (configStandalone.timeFrameTime) {
985 double nClusters = chainTracking->GetProcessors()->tpcMerger.NMaxClusters();
986 if (nClusters > 0) {
987 const int32_t nOrbits = 32;
988 const double colRate = 50000;
989 const double orbitRate = 11245;
990 const double nClsPerTF = 755851. * nOrbits * colRate / orbitRate;
991 double timePerTF = (configStandalone.proc.doublePipeline ? pipelineWalltime : ((configStandalone.proc.debugLevel ? rec->GetStatKernelTime() : rec->GetStatWallTime()) / 1000000.)) * nClsPerTF / nClusters;
992 const double nGPUsReq = timePerTF * orbitRate / nOrbits;
993 char stat[1024];
994 snprintf(stat, 1024, "Sync phase: %.2f sec per %d orbit TF, %.1f GPUs required", timePerTF, nOrbits, nGPUsReq);
995 if (configStandalone.testSyncAsync) {
996 timePerTF = (configStandalone.proc.debugLevel ? recAsync->GetStatKernelTime() : recAsync->GetStatWallTime()) / 1000000. * nClsPerTF / nClusters;
997 snprintf(stat + strlen(stat), 1024 - strlen(stat), " - Async phase: %f sec per TF", timePerTF);
998 }
999 printf("%s (Measured %s time - Extrapolated from %d clusters to %d)\n", stat, configStandalone.proc.debugLevel ? "kernel" : "wall", (int32_t)nClusters, (int32_t)nClsPerTF);
1000 }
1001 }
1004 float rejectionPercentage = (rejected) * 100.f / chainTracking->mIOPtrs.clustersNative->nClustersTotal;
1005 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);
1006 }
1007
1008 if (configStandalone.preloadEvents && configStandalone.proc.doublePipeline) {
1009 break;
1010 }
1011 }
1012 if (nEventsProcessed > 1) {
1013 printf("Total: %ld clusters, %ld tracks\n", nClustersTotal, nTracksTotal);
1014 }
1015 }
1016
1017breakrun:
1018 if (rec->GetProcessingSettings().memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_GLOBAL) {
1020 }
1021
1022#ifndef _WIN32
1023 if (configStandalone.proc.runQA && configStandalone.fpe) {
1024 fedisableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
1025 }
1026#endif
1027
1028 if (configStandalone.proc.doublePipeline) {
1030 pipelineThread->join();
1031 }
1032
1033 rec->Finalize();
1034 if (configStandalone.testSyncAsync) {
1035 recAsync->Finalize();
1036 }
1037 if (configStandalone.outputcontrolmem && rec->IsGPU()) {
1039 printf("Error unregistering memory\n");
1040 }
1041 }
1042 rec->Exit();
1043
1044 if (configStandalone.promptOnExit) {
1045 printf("Press a key to exit!\n");
1046 getchar();
1047 }
1048 return (0);
1049}
Definition of container class for dE/dx corrections.
Container to store compressed TPC cluster data.
#define srand(x)
int32_t i
#define GPUCA_EVDUMP_FILE
Definition GPUDef.h:47
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to runs
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions Compile RTC in deterministic with NO_FAST_MATH flags and GPUCA_DETERMINISTIC_MODE define Use RTC to optimize GPU code h configStandalone Processing proc_rtctech Use a file lock to serialize access to the cache folder int32_t
Declarations for the wrapper for the set of cylindrical material layers.
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
static MatLayerCylSet * rectifyPtrFromFile(MatLayerCylSet *ptr)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:180
static BasicCCDBManager & instance()
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
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 Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
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:49
void qConfigPrint()
Definition qconfig.cxx:430
int32_t qConfigParse(int argc, const char **argv, const char *)
Definition qconfig.cxx:410
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
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
void CreateTrivialCalibObjects(int64_t timestamp)
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
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
S< o2::base::MatLayerCylSet >::type * matLUT
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
GPUTPCGMPolynomialField polynomialField
Definition GPUParam.h:58
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