20#include "GPUChainTrackingGetters.inc"
56#include <sys/select.h>
84std::unique_ptr<GPUReconstructionTimeframe>
tf;
96 printf(
"Error parsing command line parameters\n");
101 printf(
"Config Dump before ReadConfiguration\n");
108 setlocale(LC_ALL,
"en_US.utf-8");
109 setlocale(LC_NUMERIC,
"en_US.utf-8");
115 printf(
"Setting affinitiy to restrict on CPU core %d\n",
configStandalone.cpuAffinity);
116 if (0 != sched_setaffinity(0,
sizeof(
mask), &
mask)) {
117 printf(
"Error setting CPU affinity\n");
122 printf(
"Setting FIFO scheduler\n");
124 sched_getparam(0, &
param);
125 param.sched_priority = 1;
126 if (0 != sched_setscheduler(0, SCHED_FIFO, &
param)) {
127 printf(
"Error setting scheduler\n");
136 feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
144 printf(
"Affinity setting not supported on Windows\n");
148 printf(
"FIFO Scheduler setting not supported on Windows\n");
152 printf(
"FPE not supported on Windows\n");
156#ifndef GPUCA_TPC_GEOMETRY_O2
157#error Why was configStandalone.rec.tpc.mergerReadFromTrackerDirectly = 0 needed?
164#ifndef GPUCA_BUILD_QA
166 printf(
"QA not enabled in build\n");
171 printf(
"Cannot run asynchronous processing with double pipeline\n");
175 printf(
"Double pipeline mode needs at least 3 runs per event and external output. To cycle though multiple events, use --preloadEvents and --runs n for n iterations round-robin\n");
179 printf(
"Cannot run --MERGE and --SIMBUNCHES togeterh\n");
196 printf(
"Can only produce QA pdf output when input files are specified!\n");
217 printf(
"setO2Settings requires the usage of --inputMemory and --outputMemory as in O2\n");
237 bool forceEmptyMemory = getenv(
"LD_PRELOAD") && strstr(getenv(
"LD_PRELOAD"),
"valgrind") !=
nullptr;
239 if (forceEmptyMemory) {
240 printf(
"Valgrind detected, emptying GPU output memory to avoid false positive undefined reads");
245 if (forceEmptyMemory) {
267 printf(
"No GPU backend / device found, running on CPU is disabled due to runGPUforce\n");
279 printf(
"Config Dump after ReadConfiguration\n");
293 printf(
"Error reading event config file\n");
310 GPUSettingsProcessing procSet;
323 printf(
"ERROR: requested to overlay continuous data - not supported\n");
327 printf(
"Continuous mode forced\n");
338 printf(
"Standalone Test Framework for CA Tracker - Using CPU\n");
340 printf(
"Standalone Test Framework for CA Tracker - Using GPU\n");
347 throw std::runtime_error(
"Requested display not available");
349 printf(
"Enabling event display (%s backend)\n",
eventDisplay->frontendName());
352 procSet.runMC =
true;
357 procSet.runMC =
true;
360 steps.
steps = GPUDataTypes::RecoStep::AllRecoSteps;
364 steps.
steps.
setBits(GPUDataTypes::RecoStep::TRDTracking,
false);
377 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCMerging,
false);
378 steps.
steps.
setBits(GPUDataTypes::RecoStep::TRDTracking,
false);
379 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCdEdx,
false);
380 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCCompression,
false);
381 steps.
steps.
setBits(GPUDataTypes::RecoStep::Refit,
false);
385 steps.
steps.
setBits(GPUDataTypes::RecoStep::TRDTracking,
false);
387 steps.
inputs.
set(GPUDataTypes::InOutType::TPCClusters, GPUDataTypes::InOutType::TRDTracklets);
388 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCDecompression,
false);
389 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
false);
391 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
true);
392 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCClusters,
false);
393 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCCompression,
false);
394 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCClusterFinding,
false);
395 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCDecompression,
true);
396 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
false);
399 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCClusters,
false);
401 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCClusterFinding,
false);
412 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCMergedTracks, steps.
steps.
isSet(GPUDataTypes::RecoStep::TPCMerging));
413 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters, steps.
steps.
isSet(GPUDataTypes::RecoStep::TPCCompression));
415 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCClusters, steps.
steps.
isSet(GPUDataTypes::RecoStep::TPCClusterFinding));
417 if (steps.
steps.
isSet(GPUDataTypes::RecoStep::TRDTracking)) {
418 if (recSet.tpc.nWays > 1) {
419 recSet.tpc.nWaysOuter = 1;
421 if (procSet.createO2Output && !procSet.trdTrackModelO2) {
422 procSet.createO2Output = 1;
429 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCdEdx, 0);
431 recSet.useMatLUT =
false;
433 procSet.eventDisplay =
nullptr;
446 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCDecompression,
true);
447 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCdEdx,
true);
448 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCCompression,
false);
449 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCClusterFinding,
false);
450 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCRaw,
false);
451 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCClusters,
false);
452 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
true);
453 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
false);
454 procSet.runMC =
false;
455 procSet.runQA =
false;
457 procSet.runCompressionStatistics = 0;
458 procSet.rtc.optSpecialCode = 0;
460 procSet.tpcInputWithClusterRejection = 1;
462 recSet.tpc.disableRefitAttachment = 0xFF;
463 recSet.tpc.looperInterpolationInExtraPass = 0;
464 recSet.maxTrackQPtB5 = CAMath::Min(recSet.maxTrackQPtB5, recSet.tpc.rejectQPtB5);
465 recSet.useMatLUT =
true;
488 procSet.o2PropagatorUseGPUField =
true;
491 printf(
"Error initializing GPUReconstruction!\n");
496 printf(
"ERROR registering memory for the GPU!!!\n");
502 printf(
"ERROR registering input memory for the GPU!!!\n");
521#if defined(GPUCA_TPC_GEOMETRY_O2) && defined(GPUCA_BUILD_QA) && !defined(GPUCA_O2_LIB)
527 throw std::runtime_error(
"Error reading O2 MC dump");
533 printf(
"Converting Native to Legacy ClusterData for overlaying - WARNING: No raw clusters produced - Compression etc will not run!!!\n");
543 if (
tf->LoadCreateTimeFrame(iEvent)) {
547 if (
tf->LoadMergedEvents(iEvent)) {
557 if (encodeZS || zsFilter) {
559 printf(
"Need digit input to run ZS\n");
575 printf(
"Converting Legacy Raw Cluster to Native\n");
590 printf(
"Need cluster native data for on-the-fly TPC transform\n");
612 if (nTracksTotal && nClustersTotal) {
613 *nTracksTotal += nTracks;
620 int32_t iRun = 0, iteration = 0;
621 while ((iteration =
nIteration.fetch_add(1)) < runs) {
623 printf(
"Run %d (thread %d)\n", iteration + 1, threadId);
631 printf(
"Running synchronous phase\n");
634 chainTrackingUse->
mIOPtrs = ioPtrs;
637 timerPipeline->Start();
647 timerPipeline->Stop();
654 if (tmpRetVal == 0 || tmpRetVal == 2) {
655 OutputStat(chainTrackingUse, iRun == 0 ? nTracksTotal :
nullptr, iRun == 0 ? nClustersTotal :
nullptr);
665 printf(
"Running asynchronous phase\n");
690 if (tmpRetVal == 0 || tmpRetVal == 2) {
702 if (tmpRetVal == 2) {
707 printf(
"Non-FATAL GPU error occured, ignoring\n");
709 if (tmpRetVal != 2) {
710 printf(
"Error occured\n");
723int32_t
main(
int argc,
char** argv)
725 std::unique_ptr<GPUReconstruction> recUnique, recUniqueAsync, recUniquePipeline;
735 deviceSet.
master =
nullptr;
737 rec = recUnique.get();
748 printf(
"Error initializing GPUReconstruction\n");
778 std::unique_ptr<std::thread> pipelineThread;
784 std::random_device
rd;
820 printf(
"No event data found in event folder\n");
830 printf(
"Preloading events%s",
configStandalone.proc.debugLevel >= 2 ?
"\n" :
"");
835 printf(
"Loading event %d\n",
i);
844 for (int32_t iRunOuter = 0; iRunOuter <
configStandalone.runs2; iRunOuter++) {
850 printf(
"RUN2: %d\n", iRunOuter);
852 int64_t nTracksTotal = 0;
853 int64_t nClustersTotal = 0;
854 int32_t nEventsProcessed = 0;
874 snprintf(fname, 1024,
"event.%d.dump", nEventsProcessed);
876 if (nEventsProcessed == 0) {
884 printf(
"Cannot override max time bin for non-continuous data!\n");
899 printf(
"Processing Event %d\n", iEvent);
903 double pipelineWalltime = 1.;
906 if (
configStandalone.proc.debugLevel < 2 && (
RunBenchmark(
rec,
chainTracking, 1, iEvent, &nTracksTotal, &nClustersTotal) ||
RunBenchmark(
recPipeline,
chainTrackingPipeline, 2, iEvent, &nTracksTotal, &nClustersTotal))) {
911 if (pipeline1.get() || pipeline2.get()) {
926 const int32_t nOrbits = 32;
927 const double colRate = 50000;
928 const double orbitRate = 11245;
929 const double nClsPerTF = 755851. * nOrbits * colRate / orbitRate;
931 const double nGPUsReq = timePerTF * orbitRate / nOrbits;
933 snprintf(stat, 1024,
"Sync phase: %.2f sec per %d orbit TF, %.1f GPUs required", timePerTF, nOrbits, nGPUsReq);
936 snprintf(stat + strlen(stat), 1024 - strlen(stat),
" - Async phase: %f sec per TF", timePerTF);
938 printf(
"%s (Measured %s time - Extrapolated from %d clusters to %d)\n", stat,
configStandalone.proc.debugLevel ?
"kernel" :
"wall", (int32_t)
nClusters, (int32_t)nClsPerTF);
946 if (nEventsProcessed > 1) {
947 printf(
"Total: %ld clusters, %ld tracks\n", nClustersTotal, nTracksTotal);
958 fedisableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
964 pipelineThread->join();
970 printf(
"Error unregistering memory\n");
976 printf(
"Press a key to exit!\n");
Container to store compressed TPC cluster data.
Helper class to access correction maps.
#define GPUCA_BUFFER_ALIGNMENT
#define GPUCA_EVDUMP_FILE
double GetCurrentElapsedTime(bool reset=false)
bitfield & setBits(const bitfield v, bool w)
bool isSet(const bitfield &v) const
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
void SetQAFromForeignChain(GPUChainTracking *chain)
const CorrectionMapsHelper * GetTPCTransformHelper() const
void ConvertNativeToClusterDataLegacy()
void ConvertZSFilter(bool zs12bit)
void SetO2Propagator(const o2::base::Propagator *prop)
const GPUTRDGeometry * GetTRDGeometry() const
const o2::base::MatLayerCylSet * GetMatLUT() const
void ConvertRun2RawToNative()
const GPUSettingsDisplay * mConfigDisplay
void DumpData(const char *filename, const GPUTrackingInOutPointers *ioPtrs=nullptr)
const GPUQA * GetQA() const
void ConvertZSEncoder(int32_t version)
GPUTrackingInOutPointers & mIOPtrs
struct o2::gpu::GPUChainTracking::InOutMemory mIOMem
int32_t ReadData(const char *filename)
const GPUSettingsQA * mConfigQA
const GPUSettingsProcessing & GetProcessingSettings() const
static constexpr int32_t NSECTORS
const GPUConstantMem * GetProcessors() const
static DeviceType GetDeviceType(const char *type)
static GPUDisplayFrontendInterface * getFrontend(const char *type)
int32_t ReadO2MCData(const char *filename)
void UpdateChain(GPUChainTracking *chain)
static int32_t GetMaxTimeBin(const o2::tpc::ClusterNativeAccess &native)
static constexpr int32_t TPCZ
static constexpr int32_t DRIFT_TIME
static DeviceType GetDeviceType(const char *type)
void SetInputControl(void *ptr, size_t size)
void TerminatePipelineWorker()
virtual void startGPUProfiling()
void SetResetTimers(bool reset)
static bool CheckInstanceAvailable(DeviceType type, bool verbose)
void SetSettings(float solenoidBzNominalGPU, const GPURecoStepConfiguration *workflow=nullptr)
T * AddChain(Args... args)
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)
void PrintMemoryOverview()
void PrintMemoryStatistics()
double GetStatKernelTime()
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)
virtual void PrintKernelOccupancies()
virtual void endGPUProfiling()
int32_t ReadSettings(const char *dir="")
void SetOutputControl(const GPUOutputControl &v)
static void RunEventGenerator(GPUChainTracking *rec, const std::string &dir)
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLenum GLenum GLsizei len
GPUSettingsStandalone configStandalone
std::string to_string(gsl::span< T, Size > span)
int32_t qConfigParse(int argc, const char **argv, const char *filename)
std::unique_ptr< GPUReconstructionTimeframe > tf
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::unique_ptr< char, void(*)(char *)> outputmemoryPipeline(nullptr, unique_ptr_aligned_delete)
std::atomic< uint32_t > nIteration
GPUReconstruction * recPipeline
std::unique_ptr< char, void(*)(char *)> outputmemory(nullptr, unique_ptr_aligned_delete)
int32_t nEventsInDirectory
int32_t ReadConfiguration(int argc, char **argv)
std::unique_ptr< char, void(*)(char *)> inputmemory(nullptr, unique_ptr_aligned_delete)
int32_t LoadEvent(int32_t iEvent, int32_t x)
std::vector< GPUTrackingInOutPointers > ioPtrEvents
GPUChainITS * chainITSPipeline
int32_t ReadEvent(int32_t n)
void unique_ptr_aligned_delete(char *v)
std::vector< GPUChainTracking::InOutMemory > ioMemEvents
std::unique_ptr< GPUDisplayFrontendInterface > eventDisplay
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
GPUChainTracking * chainTracking
GPUDataTypes::RecoStepField stepsGPUMask
GPUDataTypes::InOutTypeField outputs
GPUDataTypes::RecoStepField steps
GPUDataTypes::InOutTypeField inputs
GPUReconstruction * master
int32_t doCompClusterDecode
int32_t grpContinuousMaxTimeBin
float solenoidBzNominalGPU
const o2::tpc::ClusterNativeAccess * clustersNative
const GPUTPCMCInfo * mcInfosTPC
uint32_t nClusterData[NSECTORS]
uint32_t nRawClusters[NSECTORS]
const o2::tpc::CompressedClustersFlat * tpcCompressedClusters
const AliHLTTPCClusterMCLabel * mcLabelsTPC
const GPUTrackingInOutZS * tpcZS
const AliHLTTPCRawCluster * rawClusters[NSECTORS]
const GPUTPCClusterData * clusterData[NSECTORS]
uint32_t nOutputTracksTPCO2
uint32_t nMergedTrackHits
const GPUTrackingInOutDigits * tpcPackedDigits
const GPUTPCMCInfoCol * mcInfosTPCCol
const GPUTPCGMMergedTrack * mergedTracks
GPUTPCGMPolynomialField polynomialField
typename std::vector< T, vecpod_allocator< T > > vecpod