20#include "GPUChainTrackingGetters.inc"
56#include <sys/select.h>
83std::unique_ptr<GPUReconstructionTimeframe>
tf;
95 printf(
"Error parsing command line parameters\n");
100 printf(
"Config Dump before ReadConfiguration\n");
107 setlocale(LC_ALL,
"en_US.utf-8");
108 setlocale(LC_NUMERIC,
"en_US.utf-8");
114 printf(
"Setting affinitiy to restrict on CPU core %d\n",
configStandalone.cpuAffinity);
115 if (0 != sched_setaffinity(0,
sizeof(
mask), &
mask)) {
116 printf(
"Error setting CPU affinity\n");
121 printf(
"Setting FIFO scheduler\n");
123 sched_getparam(0, &
param);
124 param.sched_priority = 1;
125 if (0 != sched_setscheduler(0, SCHED_FIFO, &
param)) {
126 printf(
"Error setting scheduler\n");
135 feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
143 printf(
"Affinity setting not supported on Windows\n");
147 printf(
"FIFO Scheduler setting not supported on Windows\n");
151 printf(
"FPE not supported on Windows\n");
155#ifndef GPUCA_TPC_GEOMETRY_O2
156#error Why was configStandalone.rec.tpc.mergerReadFromTrackerDirectly = 0 needed?
163#ifndef GPUCA_BUILD_QA
165 printf(
"QA not enabled in build\n");
170 printf(
"Cannot run asynchronous processing with double pipeline\n");
174 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");
178 printf(
"Cannot run --MERGE and --SIMBUNCHES togeterh\n");
195 printf(
"Can only produce QA pdf output when input files are specified!\n");
216 printf(
"setO2Settings requires the usage of --inputMemory and --outputMemory as in O2\n");
228 bool forceEmptyMemory = getenv(
"LD_PRELOAD") && strstr(getenv(
"LD_PRELOAD"),
"valgrind") !=
nullptr;
230 if (forceEmptyMemory) {
231 printf(
"Valgrind detected, emptying GPU output memory to avoid false positive undefined reads");
236 if (forceEmptyMemory) {
258 printf(
"No GPU backend / device found, running on CPU is disabled due to runGPUforce\n");
270 printf(
"Config Dump after ReadConfiguration\n");
286 printf(
"Error reading event config file\n");
303 GPUSettingsProcessing procSet;
319 printf(
"ERROR: requested to overlay continuous data - not supported\n");
323 printf(
"Continuous mode forced\n");
334 printf(
"Standalone Test Framework for CA Tracker - Using CPU\n");
336 printf(
"Standalone Test Framework for CA Tracker - Using GPU\n");
343 throw std::runtime_error(
"Requested display not available");
345 printf(
"Enabling event display (%s backend)\n",
eventDisplay->frontendName());
348 procSet.runMC =
true;
353 procSet.runMC =
true;
356 steps.
steps = GPUDataTypes::RecoStep::AllRecoSteps;
360 steps.
steps.
setBits(GPUDataTypes::RecoStep::TRDTracking,
false);
373 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCMerging,
false);
374 steps.
steps.
setBits(GPUDataTypes::RecoStep::TRDTracking,
false);
375 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCdEdx,
false);
376 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCCompression,
false);
377 steps.
steps.
setBits(GPUDataTypes::RecoStep::Refit,
false);
381 steps.
steps.
setBits(GPUDataTypes::RecoStep::TRDTracking,
false);
383 steps.
inputs.
set(GPUDataTypes::InOutType::TPCClusters, GPUDataTypes::InOutType::TRDTracklets);
384 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCDecompression,
false);
385 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
false);
387 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
true);
388 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCClusters,
false);
389 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCCompression,
false);
390 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCClusterFinding,
false);
391 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCDecompression,
true);
392 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
false);
395 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCClusters,
false);
397 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCClusterFinding,
false);
408 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCMergedTracks, steps.
steps.
isSet(GPUDataTypes::RecoStep::TPCMerging));
409 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters, steps.
steps.
isSet(GPUDataTypes::RecoStep::TPCCompression));
411 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCClusters, steps.
steps.
isSet(GPUDataTypes::RecoStep::TPCClusterFinding));
413 if (steps.
steps.
isSet(GPUDataTypes::RecoStep::TRDTracking)) {
414 if (recSet.tpc.nWays > 1) {
415 recSet.tpc.nWaysOuter = 1;
417 if (procSet.createO2Output && !procSet.trdTrackModelO2) {
418 procSet.createO2Output = 1;
425 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCdEdx, 0);
427 recSet.useMatLUT =
false;
429 procSet.eventDisplay =
nullptr;
442 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCDecompression,
true);
443 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCdEdx,
true);
444 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCCompression,
false);
445 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCClusterFinding,
false);
446 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCRaw,
false);
447 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCClusters,
false);
448 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
true);
449 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
false);
450 procSet.runMC =
false;
451 procSet.runQA =
false;
453 procSet.runCompressionStatistics = 0;
454 procSet.rtc.optSpecialCode = 0;
456 procSet.tpcInputWithClusterRejection = 1;
458 recSet.tpc.disableRefitAttachment = 0xFF;
459 recSet.tpc.looperInterpolationInExtraPass = 0;
460 recSet.maxTrackQPtB5 = CAMath::Min(recSet.maxTrackQPtB5, recSet.tpc.rejectQPtB5);
461 recSet.useMatLUT =
true;
484 procSet.o2PropagatorUseGPUField =
true;
487 printf(
"Error initializing GPUReconstruction!\n");
492 printf(
"ERROR registering memory for the GPU!!!\n");
498 printf(
"ERROR registering input memory for the GPU!!!\n");
519#if defined(GPUCA_TPC_GEOMETRY_O2) && defined(GPUCA_BUILD_QA) && !defined(GPUCA_O2_LIB)
527 throw std::runtime_error(
"Error reading O2 MC dump");
534 printf(
"Converting Native to Legacy ClusterData for overlaying - WARNING: No raw clusters produced - Compression etc will not run!!!\n");
544 if (
tf->LoadCreateTimeFrame(iEvent)) {
548 if (
tf->LoadMergedEvents(iEvent)) {
558 if (encodeZS || zsFilter) {
560 printf(
"Need digit input to run ZS\n");
576 printf(
"Converting Legacy Raw Cluster to Native\n");
591 printf(
"Need cluster native data for on-the-fly TPC transform\n");
613 if (nTracksTotal && nClustersTotal) {
614 *nTracksTotal += nTracks;
621 int32_t iRun = 0, iteration = 0;
622 while ((iteration =
nIteration.fetch_add(1)) < runs) {
624 printf(
"Run %d (thread %d)\n", iteration + 1, threadId);
632 printf(
"Running synchronous phase\n");
635 chainTrackingUse->
mIOPtrs = ioPtrs;
638 timerPipeline->Start();
648 timerPipeline->Stop();
655 if (tmpRetVal == 0 || tmpRetVal == 2) {
656 OutputStat(chainTrackingUse, iRun == 0 ? nTracksTotal :
nullptr, iRun == 0 ? nClustersTotal :
nullptr);
666 printf(
"Running asynchronous phase\n");
691 if (tmpRetVal == 0 || tmpRetVal == 2) {
703 if (tmpRetVal == 2) {
708 printf(
"Non-FATAL GPU error occured, ignoring\n");
710 if (tmpRetVal != 2) {
711 printf(
"Error occured\n");
724int32_t
main(
int argc,
char** argv)
726 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;
795 in.open(
filename, std::ifstream::binary);
829 printf(
"Preloading events%s",
configStandalone.proc.debugLevel >= 2 ?
"\n" :
"");
834 printf(
"Loading event %d\n",
i);
843 for (int32_t iRunOuter = 0; iRunOuter <
configStandalone.runs2; iRunOuter++) {
849 printf(
"RUN2: %d\n", iRunOuter);
851 int64_t nTracksTotal = 0;
852 int64_t nClustersTotal = 0;
853 int32_t nEventsProcessed = 0;
873 snprintf(fname, 1024,
"event.%d.dump", nEventsProcessed);
875 if (nEventsProcessed == 0) {
883 printf(
"Cannot override max time bin for non-continuous data!\n");
898 printf(
"Processing Event %d\n", iEvent);
902 double pipelineWalltime = 1.;
905 if (
RunBenchmark(
rec,
chainTracking, 1, iEvent, &nTracksTotal, &nClustersTotal) ||
RunBenchmark(
recPipeline,
chainTrackingPipeline, 2, iEvent, &nTracksTotal, &nClustersTotal)) {
910 if (pipeline1.get() || pipeline2.get()) {
925 const int32_t nOrbits = 32;
926 const double colRate = 50000;
927 const double orbitRate = 11245;
928 const double nClsPerTF = 755851. * nOrbits * colRate / orbitRate;
930 const double nGPUsReq = timePerTF * orbitRate / nOrbits;
932 snprintf(stat, 1024,
"Sync phase: %.2f sec per %d orbit TF, %.1f GPUs required", timePerTF, nOrbits, nGPUsReq);
935 snprintf(stat + strlen(stat), 1024 - strlen(stat),
" - Async phase: %f sec per TF", timePerTF);
937 printf(
"%s (Measured %s time - Extrapolated from %d clusters to %d)\n", stat,
configStandalone.proc.debugLevel ?
"kernel" :
"wall", (int32_t)
nClusters, (int32_t)nClsPerTF);
945 if (nEventsProcessed > 1) {
946 printf(
"Total: %ld clusters, %ld tracks\n", nClustersTotal, nTracksTotal);
957 fedisableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
963 pipelineThread->join();
969 printf(
"Error unregistering memory\n");
975 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
void DumpData(const char *filename)
const o2::base::MatLayerCylSet * GetMatLUT() const
void ConvertRun2RawToNative()
const GPUSettingsDisplay * mConfigDisplay
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)
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLenum GLenum GLsizei len
GPUSettingsStandalone configStandalone
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