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");
218 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 (procSet.createO2Output && !procSet.trdTrackModelO2) {
419 procSet.createO2Output = 1;
426 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCdEdx, 0);
428 recSet.useMatLUT =
false;
430 procSet.eventDisplay =
nullptr;
443 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCDecompression,
true);
444 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCdEdx,
true);
445 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCCompression,
false);
446 steps.
steps.
setBits(GPUDataTypes::RecoStep::TPCClusterFinding,
false);
447 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCRaw,
false);
448 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCClusters,
false);
449 steps.
inputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
true);
450 steps.
outputs.
setBits(GPUDataTypes::InOutType::TPCCompressedClusters,
false);
451 procSet.runMC =
false;
452 procSet.runQA =
false;
454 procSet.runCompressionStatistics = 0;
455 procSet.rtc.optSpecialCode = 0;
457 procSet.tpcInputWithClusterRejection = 1;
459 recSet.tpc.disableRefitAttachment = 0xFF;
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");
517#if defined(GPUCA_TPC_GEOMETRY_O2) && defined(GPUCA_BUILD_QA) && !defined(GPUCA_O2_LIB)
523 throw std::runtime_error(
"Error reading O2 MC dump");
529 printf(
"Converting Native to Legacy ClusterData for overlaying - WARNING: No raw clusters produced - Compression etc will not run!!!\n");
539 if (
tf->LoadCreateTimeFrame(iEvent)) {
543 if (
tf->LoadMergedEvents(iEvent)) {
553 if (encodeZS || zsFilter) {
555 printf(
"Need digit input to run ZS\n");
571 printf(
"Converting Legacy Raw Cluster to Native\n");
586 printf(
"Need cluster native data for on-the-fly TPC transform\n");
608 if (nTracksTotal && nClustersTotal) {
609 *nTracksTotal += nTracks;
616 int32_t iRun = 0, iteration = 0;
617 while ((iteration =
nIteration.fetch_add(1)) < runs) {
619 printf(
"Run %d (thread %d)\n", iteration + 1, threadId);
627 printf(
"Running synchronous phase\n");
630 chainTrackingUse->
mIOPtrs = ioPtrs;
633 timerPipeline->Start();
643 timerPipeline->Stop();
650 if (tmpRetVal == 0 || tmpRetVal == 2) {
651 OutputStat(chainTrackingUse, iRun == 0 ? nTracksTotal :
nullptr, iRun == 0 ? nClustersTotal :
nullptr);
661 printf(
"Running asynchronous phase\n");
686 if (tmpRetVal == 0 || tmpRetVal == 2) {
698 if (tmpRetVal == 2) {
703 printf(
"GPU Standalone Benchmark: Non-FATAL GPU error occured, ignoring\n");
705 if (tmpRetVal != 2) {
706 printf(
"GPU Standalone Benchmark: Error occured\n");
719int32_t
main(
int argc,
char** argv)
721 std::unique_ptr<GPUReconstruction> recUnique, recUniqueAsync, recUniquePipeline;
731 deviceSet.
master =
nullptr;
733 rec = recUnique.get();
744 printf(
"Error initializing GPUReconstruction\n");
774 std::unique_ptr<std::thread> pipelineThread;
780 std::random_device
rd;
816 printf(
"No event data found in event folder\n");
826 printf(
"Preloading events%s",
configStandalone.proc.debugLevel >= 2 ?
"\n" :
"");
831 printf(
"Loading event %d\n",
i);
840 for (int32_t iRunOuter = 0; iRunOuter <
configStandalone.runs2; iRunOuter++) {
846 printf(
"\nRUN2: %d\n", iRunOuter);
848 int64_t nTracksTotal = 0;
849 int64_t nClustersTotal = 0;
850 int32_t nEventsProcessed = 0;
870 snprintf(fname, 1024,
"event.%d.dump", nEventsProcessed);
872 if (nEventsProcessed == 0) {
880 printf(
"Cannot override max time bin for non-continuous data!\n");
895 printf(
"Processing Event %d\n", iEvent);
899 double pipelineWalltime = 1.;
902 if (
configStandalone.proc.debugLevel < 2 && (
RunBenchmark(
rec,
chainTracking, 1, iEvent, &nTracksTotal, &nClustersTotal) ||
RunBenchmark(
recPipeline,
chainTrackingPipeline, 2, iEvent, &nTracksTotal, &nClustersTotal))) {
907 if (pipeline1.get() || pipeline2.get()) {
922 const int32_t nOrbits = 32;
923 const double colRate = 50000;
924 const double orbitRate = 11245;
925 const double nClsPerTF = 755851. * nOrbits * colRate / orbitRate;
927 const double nGPUsReq = timePerTF * orbitRate / nOrbits;
929 snprintf(stat, 1024,
"Sync phase: %.2f sec per %d orbit TF, %.1f GPUs required", timePerTF, nOrbits, nGPUsReq);
932 snprintf(stat + strlen(stat), 1024 - strlen(stat),
" - Async phase: %f sec per TF", timePerTF);
934 printf(
"%s (Measured %s time - Extrapolated from %d clusters to %d)\n", stat,
configStandalone.proc.debugLevel ?
"kernel" :
"wall", (int32_t)
nClusters, (int32_t)nClsPerTF);
942 if (nEventsProcessed > 1) {
943 printf(
"Total: %ld clusters, %ld tracks\n", nClustersTotal, nTracksTotal);
954 fedisableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
960 pipelineThread->join();
966 printf(
"Error unregistering memory\n");
972 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