3 // ************************************************************************
4 // This file is property of and copyright by the ALICE HLT Project *
5 // ALICE Experiment at CERN, All rights reserved. *
6 // See cxx source for full Copyright notice *
8 //*************************************************************************
10 #ifndef ALIHLTTPCCATRACKER_H
11 #define ALIHLTTPCCATRACKER_H
14 #include "AliHLTTPCCADef.h"
15 #include "AliHLTTPCCAGPUConfig.h"
17 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
21 #include "AliHLTTPCCAParam.h"
22 #include "AliHLTTPCCAHitId.h"
23 #include "AliHLTTPCCASliceData.h"
24 #include "AliHLTTPCCASliceOutput.h"
25 #include "AliHLTTPCCATrackletConstructor.h"
26 #include "AliHLTTPCCATracklet.h"
28 MEM_CLASS_PRE() class AliHLTTPCCATrack;
29 MEM_CLASS_PRE() class AliHLTTPCCATrackParam;
30 class AliHLTTPCCAClusterData;
31 MEM_CLASS_PRE() class AliHLTTPCCARow;
33 #if !(defined(HLTCA_GPUCODE) && defined(__OPENCL__) && !defined(HLTCA_HOSTCODE))
34 #include "TStopwatch.h"
38 * @class AliHLTTPCCATracker
40 * Slice tracker for ALICE HLT.
41 * The class reconstructs tracks in one slice of TPC.
42 * The reconstruction algorithm is based on the Cellular Automaton method
44 * The CA tracker is designed stand-alone.
45 * It is integrated to the HLT framework via AliHLTTPCCATrackerComponent interface.
46 * The class is under construction.
50 class AliHLTTPCCAClusterData;
52 MEM_CLASS_PRE() class AliHLTTPCCATracker
58 #ifdef HLTCA_STANDALONE
60 fLinkTmpMemory( NULL ),
66 fIsGPUTracker( false ),
69 fRowStartHitCountOffset( NULL ),
70 fTrackletTmpStartHits( NULL ),
71 fGPUTrackletTemp( NULL ),
72 fRowBlockTracklets( NULL ),
74 fBlockStartingTracklet( NULL ),
75 fGPUParametersConst(),
80 fTrackletMemorySize( 0 ),
82 fTrackMemorySize( 0 ),
83 fTrackletStartHits( 0 ),
85 fTrackletRowHits( NULL ),
91 for( int i=0; i<10; i++ ) fTimers[i] = 0;
92 for( int i=0; i<16; i++ ) fPerfTimers[i] = 0;
94 ~AliHLTTPCCATracker();
96 struct StructGPUParameters
98 StructGPUParameters() : fNextTracklet(0), fScheduleFirstDynamicTracklet( 0 ), fGPUError( 0 ) {}
99 int fNextTracklet; //Next Tracklet to process
100 int fScheduleFirstDynamicTracklet; //Last Tracklet with fixed position in sheduling
101 int fGPUError; //Signalizes error on GPU during GPU Reconstruction, kind of return value
104 MEM_CLASS_PRE2() struct StructGPUParametersConst
106 StructGPUParametersConst() : fGPUFixedBlockCount( 0 ), fGPUiSlice( 0 ), fGPUnSlices( 0 ), fGPUMem( NULL ) {}
107 int fGPUFixedBlockCount; //Count of blocks that is used for this tracker in fixed schedule situations
108 int fGPUiSlice; // slice number processed by running GPU MP
109 int fGPUnSlices; // n of slices to be processed in parallel
110 GPUglobalref() char* fGPUMem; //Base pointer to GPU memory (Needed for OpenCL for verification)
113 struct commonMemoryStruct
115 commonMemoryStruct() : fNTracklets( 0 ), fNTracks( 0 ), fNLocalTracks( 0 ), fNTrackHits( 0 ), fNLocalTrackHits( 0 ), fGPUParameters() {}
116 int fNTracklets; // number of tracklets
117 int fNTracks; // number of reconstructed tracks
118 int fNLocalTracks; //number of reconstructed tracks before global tracking
119 int fNTrackHits; // number of track hits
120 int fNLocalTrackHits; //see above
121 StructGPUParameters fGPUParameters; // GPU parameters
124 MEM_CLASS_PRE2() void Initialize( const MEM_LG2(AliHLTTPCCAParam) ¶m );
128 int CheckEmptySlice() const;
129 void WriteOutputPrepare();
132 #if !defined(HLTCA_GPUCODE)
134 void ReconstructOutput();
135 #endif //!HLTCA_GPUCODE
138 //Make Reconstruction steps directly callable (Used for GPU debugging)
139 void RunNeighboursFinder();
140 void RunNeighboursCleaner();
141 void RunStartHitsFinder();
142 void RunTrackletConstructor();
143 void RunTrackletSelector();
145 //GPU Tracker Interface
146 void SetGPUTracker();
147 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
148 void SetGPUDebugLevel(int Level, std::ostream *NewDebugOut = NULL) {fGPUDebugLevel = Level;if (NewDebugOut) fGPUDebugOut = NewDebugOut;}
149 char* SetGPUTrackerCommonMemory(char* const pGPUMemory);
150 char* SetGPUTrackerHitsMemory(char* pGPUMemory, int MaxNHits);
151 char* SetGPUTrackerTrackletsMemory(char* pGPUMemory, int MaxNTracklets, int constructorBlockCount);
152 char* SetGPUTrackerTracksMemory(char* pGPUMemory, int MaxNTracks, int MaxNHits );
155 void DumpSliceData(std::ostream &out); //Dump Input Slice Data
156 void DumpLinks(std::ostream &out); //Dump all links to file (for comparison after NeighboursFinder/Cleaner)
157 void DumpStartHits(std::ostream &out); //Same for Start Hits
158 void DumpHitWeights(std::ostream &out); //....
159 void DumpTrackHits(std::ostream &out); //Same for Track Hits
160 void DumpTrackletHits(std::ostream &out); //Same for Track Hits
161 void DumpOutput(FILE* out); //Similar for output
163 void SetOutput( AliHLTTPCCASliceOutput** out ) { fOutput = out; }
164 void ReadEvent( AliHLTTPCCAClusterData *clusterData );
166 GPUhd() const AliHLTTPCCASliceOutput::outputControlStruct* OutputControl() const { return fOutputControl; }
167 GPUh() void SetOutputControl( AliHLTTPCCASliceOutput::outputControlStruct* const val) { fOutputControl = val; }
169 GPUhd() AliHLTTPCCAClusterData *ClusterData() const { return fClusterData; }
171 GPUh() void ClearSliceDataHitWeights() {fData.ClearHitWeights();}
172 GPUh() MakeType(const MEM_LG(AliHLTTPCCARow)&) Row( const AliHLTTPCCAHitId &HitId ) const { return fData.Row( HitId.RowIndex() ); }
174 GPUhd() AliHLTTPCCASliceOutput** Output() const { return fOutput; }
176 GPUh() GPUglobalref() commonMemoryStruct *CommonMemory() const {return(fCommonMem); }
177 GPUh() static size_t CommonMemorySize() { return(sizeof(AliHLTTPCCATracker::commonMemoryStruct)); }
178 GPUh() GPUglobalref() char* HitMemory() const {return(fHitMemory); }
179 GPUh() size_t HitMemorySize() const {return(fHitMemorySize); }
180 GPUh() char* TrackletMemory() {return(fTrackletMemory); }
181 GPUh() size_t TrackletMemorySize() const {return(fTrackletMemorySize); }
182 GPUh() char* TrackMemory() {return(fTrackMemory); }
183 GPUh() size_t TrackMemorySize() const {return(fTrackMemorySize); }
185 GPUh() void SetGPUSliceDataMemory(void* const pSliceMemory, void* const pRowMemory) { fData.SetGPUSliceDataMemory(pSliceMemory, pRowMemory); }
186 GPUh() unsigned long long int* PerfTimer(unsigned int i) {return &fPerfTimers[i]; }
188 GPUh() static int SortComparison(const void* a, const void* b);
191 MEM_CLASS_PRE2() GPUd() void GetErrors2( int iRow, const MEM_LG2(AliHLTTPCCATrackParam) &t, float &Err2Y, float &Err2Z ) const {fParam.GetClusterErrors2( iRow, t.GetZ(), t.SinPhi(), t.GetCosPhi(), t.DzDs(), Err2Y, Err2Z );}
192 GPUd() void GetErrors2( int iRow, float z, float sinPhi, float cosPhi, float DzDs, float &Err2Y, float &Err2Z ) const
194 fParam.GetClusterErrors2( iRow, z, sinPhi, cosPhi, DzDs, Err2Y, Err2Z );
195 Err2Y*=fParam.ClusterError2CorrectionY();
196 Err2Z*=fParam.ClusterError2CorrectionZ();
199 MEM_CLASS_PRE2() void FitTrack( const MEM_LG2(AliHLTTPCCATrack) &track, float *t0 = 0 ) const;
200 MEM_CLASS_PRE2() void FitTrackFull( const MEM_LG2(AliHLTTPCCATrack) &track, float *t0 = 0 ) const;
202 void SetupCommonMemory();
203 void SetPointersHits( int MaxNHits );
204 void SetPointersTracklets ( int MaxNTracklets );
205 void SetPointersTracks( int MaxNTracks, int MaxNHits );
206 size_t SetPointersSliceData(const AliHLTTPCCAClusterData *data, bool allocate = false) { return(fData.SetPointers(data, allocate)); }
208 #if !defined(HLTCA_GPUCODE)
209 GPUh() void WriteEvent( std::ostream &out );
210 GPUh() void WriteTracks( std::ostream &out ) ;
211 GPUh() void ReadTracks( std::istream &in );
212 #endif //!HLTCA_GPUCODE
214 GPUhd() MakeType(const MEM_LG(AliHLTTPCCAParam)&) Param() const { return fParam; }
215 GPUhd() MakeType(const MEM_LG(AliHLTTPCCAParam)*) pParam() const { return &fParam; }
216 MEM_CLASS_PRE2() GPUhd() void SetParam( const MEM_LG2(AliHLTTPCCAParam) &v ) { fParam = v; }
218 GPUhd() MakeType(const MEM_LG(AliHLTTPCCASliceData)&) Data() const { return fData; }
220 GPUhd() GPUglobalref() const MEM_GLOBAL(AliHLTTPCCARow)& Row( int rowIndex ) const { return fData.Row( rowIndex ); }
222 GPUhd() double Timer( int i ) const { return fTimers[i]; }
223 GPUhd() void SetTimer( int i, double v ) { fTimers[i] = v; }
225 GPUhd() int NHitsTotal() const { return fData.NumberOfHits(); }
227 MEM_TEMPLATE() GPUd() void SetHitLinkUpData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, short v ) { fData.SetHitLinkUpData( row, hitIndex, v ); }
228 MEM_TEMPLATE() GPUd() void SetHitLinkDownData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, short v ) { fData.SetHitLinkDownData( row, hitIndex, v ); }
229 MEM_TEMPLATE() GPUd() short HitLinkUpData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const { return fData.HitLinkUpData( row, hitIndex ); }
230 MEM_TEMPLATE() GPUd() short HitLinkDownData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const { return fData.HitLinkDownData( row, hitIndex ); }
232 //MEM_CLASS_PRE2() GPUd() GPUglobalref() const ushort2 *HitData( const MEM_TYPE( AliHLTTPCCARow)&row ) const { return fData.HitData(row); }
233 MEM_TEMPLATE() GPUd() GPUglobalref() const ushort2 *HitData( const MEM_TYPE( AliHLTTPCCARow)& row ) const { return fData.HitData(row); }
234 MEM_TEMPLATE() GPUd() GPUglobalref() const short_v *HitLinkUpData ( const MEM_TYPE( AliHLTTPCCARow)&row ) const { return fData.HitLinkUpData(row); }
235 MEM_TEMPLATE() GPUd() GPUglobalref() const short_v *HitLinkDownData( const MEM_TYPE( AliHLTTPCCARow)&row ) const { return fData.HitLinkDownData(row); }
236 MEM_TEMPLATE() GPUd() GPUglobalref() const ushort_v *FirstHitInBin( const MEM_TYPE( AliHLTTPCCARow)&row ) const { return fData.FirstHitInBin(row); }
238 MEM_TEMPLATE() GPUd() int FirstHitInBin( const MEM_TYPE( AliHLTTPCCARow)&row, int binIndex ) const { return fData.FirstHitInBin( row, binIndex ); }
240 MEM_TEMPLATE() GPUd() unsigned short HitDataY( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
241 return fData.HitDataY( row, hitIndex );
243 MEM_TEMPLATE() GPUd() unsigned short HitDataZ( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
244 return fData.HitDataZ( row, hitIndex );
246 MEM_TEMPLATE() GPUd() ushort2 HitData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
247 return fData.HitData( row, hitIndex );
250 MEM_TEMPLATE() GPUhd() int HitInputID( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const { return fData.ClusterDataIndex( row, hitIndex ); }
253 * The hit weight is used to determine whether a hit belongs to a certain tracklet or another one
254 * competing for the same hit. The tracklet that has a higher weight wins. Comparison is done
255 * using the the number of hits in the tracklet (the more hits it has the more it keeps). If
256 * tracklets have the same number of hits then it doesn't matter who gets it, but it should be
257 * only one. So a unique number (row index is good) is added in the least significant part of
260 GPUd() static int CalculateHitWeight( int NHits, float chi2, int ) {
261 const float chi2_suppress = 6.f;
262 float weight = (((float) NHits * (chi2_suppress - chi2 / 500.f)) * (1e9 / chi2_suppress / 160.));
263 if (weight < 0 || weight > 2e9) weight = 0;
264 return ( (int) weight );
265 //return( (NHits << 16) + num);
267 MEM_TEMPLATE() GPUd() void MaximizeHitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, int weight ) {
268 fData.MaximizeHitWeight( row, hitIndex, weight );
270 MEM_TEMPLATE() GPUd() void SetHitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, int weight ) {
271 fData.SetHitWeight( row, hitIndex, weight );
273 MEM_TEMPLATE() GPUd() int HitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
274 return fData.HitWeight( row, hitIndex );
277 GPUhd() GPUglobalref() int *NTracklets() const { return &fCommonMem->fNTracklets; }
279 GPUhd() const AliHLTTPCCAHitId &TrackletStartHit( int i ) const { return fTrackletStartHits[i]; }
280 GPUhd() GPUglobalref() AliHLTTPCCAHitId *TrackletStartHits() const { return fTrackletStartHits; }
281 GPUhd() GPUglobalref() AliHLTTPCCAHitId *TrackletTmpStartHits() const { return fTrackletTmpStartHits; }
282 MEM_CLASS_PRE2() GPUhd() const MEM_LG2(AliHLTTPCCATracklet) &Tracklet( int i ) const { return fTracklets[i]; }
283 GPUhd() GPUglobalref() MEM_GLOBAL(AliHLTTPCCATracklet) *Tracklets() const { return fTracklets;}
284 GPUhd() GPUglobalref()int* TrackletRowHits() const { return fTrackletRowHits; }
286 GPUhd() GPUglobalref() int *NTracks() const { return &fCommonMem->fNTracks; }
287 GPUhd() GPUglobalref() MEM_GLOBAL(AliHLTTPCCATrack) *Tracks() const { return fTracks; }
288 GPUhd() GPUglobalref() int *NTrackHits() const { return &fCommonMem->fNTrackHits; }
289 GPUhd() GPUglobalref() AliHLTTPCCAHitId *TrackHits() const { return fTrackHits; }
292 GPUhd() GPUglobalref() MEM_GLOBAL(AliHLTTPCCARow)* SliceDataRows() const {return(fData.Rows()); }
294 GPUhd() GPUglobalref() uint3* RowStartHitCountOffset() const {return(fRowStartHitCountOffset);}
296 MEM_CLASS_PRE2() GPUhd() AliHLTTPCCATrackletConstructor::MEM_LG2(AliHLTTPCCAGPUTempMemory)* GPUTrackletTemp() const {return(fGPUTrackletTemp);}
298 GPUhd() GPUglobalref() int* RowBlockTracklets(int reverse, int iRowBlock) const {return(&fRowBlockTracklets[(reverse * ((fParam.NRows() / HLTCA_GPU_SCHED_ROW_STEP) + 1) + iRowBlock) * fCommonMem->fNTracklets]);}
299 GPUhd() GPUglobalref() int* RowBlockTracklets() const {return(fRowBlockTracklets);}
300 GPUhd() GPUglobalref() int4* RowBlockPos(int reverse, int iRowBlock) const {return(&fRowBlockPos[reverse * ((fParam.NRows() / HLTCA_GPU_SCHED_ROW_STEP) + 1) + iRowBlock]);}
301 GPUhd() GPUglobalref() int4* RowBlockPos() const {return(fRowBlockPos);}
302 GPUhd() GPUglobalref() uint2* BlockStartingTracklet() const {return(fBlockStartingTracklet);}
303 GPUhd() GPUglobalref() StructGPUParameters* GPUParameters() const {return(&fCommonMem->fGPUParameters);}
304 GPUhd() MakeType(MEM_LG(StructGPUParametersConst)*) GPUParametersConst() {return(&fGPUParametersConst);}
305 GPUhd() void SetGPUTextureBase(char* val) { fData.SetGPUTextureBase(val); }
307 #ifdef HLTCA_STANDALONE
308 GPUhd() char* StageAtSync() {return(fStageAtSync);}
309 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
310 GPUh() const char* LinkTmpMemory() const {return(fLinkTmpMemory);}
314 #ifdef HLTCA_STANDALONE
315 static inline void StandaloneQueryTime(ULong64_t *i);
316 static inline void StandaloneQueryFreq(ULong64_t *i);
317 #endif //HLTCA_STANDALONE
318 void StandalonePerfTime(int i);
322 int fTtrack; //Track ID
323 float fSortVal; //Value to sort for
326 void PerformGlobalTracking(AliHLTTPCCATracker& sliceLeft, AliHLTTPCCATracker& sliceRight, int MaxTracks);
329 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
330 GPUh() int PerformGlobalTrackingRun(AliHLTTPCCATracker& sliceNeighbour, int iTrack, int rowIndex, float angle, int direction);
333 //Temporary Variables for Standalone measurements
334 #ifdef HLTCA_STANDALONE
336 char* fStageAtSync; //Pointer to array storing current stage for every thread at every sync point
337 char *fLinkTmpMemory; //tmp memory for hits after neighbours finder
341 MEM_LG(AliHLTTPCCAParam) fParam; // parameters
342 double fTimers[10]; // timers
343 ULong64_t fPerfTimers[16]; // running CPU time for different parts of the algorithm
345 AliHLTTPCCASliceOutput::outputControlStruct* fOutputControl; // output control
347 /** A pointer to the ClusterData object that the SliceData was created from. This can be used to
348 * merge clusters from inside the SliceTracker code and recreate the SliceData. */
349 GPUglobalref() AliHLTTPCCAClusterData *fClusterData; // ^
350 MEM_LG(AliHLTTPCCASliceData) fData; // The SliceData object. It is used to encapsulate the storage in memory from the access
352 bool fIsGPUTracker; // is it GPU tracker object
353 int fGPUDebugLevel; // debug level
355 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
356 std::ostream *fGPUDebugOut; // debug stream
358 void* fGPUDebugOut; //No this is a hack, but I have no better idea.
362 GPUglobalref() uint3* fRowStartHitCountOffset; //Offset, length and new offset of start hits in row
363 GPUglobalref() AliHLTTPCCAHitId *fTrackletTmpStartHits; //Unsorted start hits
364 GPUglobalref() MEM_GLOBAL(AliHLTTPCCATrackletConstructor::AliHLTTPCCAGPUTempMemory)* fGPUTrackletTemp; //Temp Memory for GPU Tracklet Constructor
365 GPUglobalref() int* fRowBlockTracklets; //Reference which tracklet is processed in which rowblock next
366 GPUglobalref() int4* fRowBlockPos; //x is last tracklet to be processed, y is last tracklet already processed, z is last tracklet to be processed in next iteration, w is initial x value to check if tracklet must be initialized
367 GPUglobalref() uint2* fBlockStartingTracklet; // First Tracklet that is to be processed by current GPU MP
369 MEM_LG(StructGPUParametersConst) fGPUParametersConst; // Parameters for GPU if this is a GPU tracker
373 GPUglobalref() commonMemoryStruct *fCommonMem; // common event memory
375 GPUglobalref() char *fHitMemory; // event memory for hits
376 size_t fHitMemorySize; // size of the event memory for hits [bytes]
378 GPUglobalref() char *fTrackletMemory; //event memory for tracklets
379 size_t fTrackletMemorySize; //size of the event memory for tracklets
381 GPUglobalref() char *fTrackMemory; // event memory for tracks
382 size_t fTrackMemorySize; // size of the event memory for tracks [bytes]
384 GPUglobalref() AliHLTTPCCAHitId *fTrackletStartHits; // start hits for the tracklets
385 GPUglobalref() MEM_GLOBAL(AliHLTTPCCATracklet) *fTracklets; // tracklets
386 GPUglobalref() int *fTrackletRowHits; //Hits for each Tracklet in each row
389 GPUglobalref() MEM_GLOBAL(AliHLTTPCCATrack) *fTracks; // reconstructed tracks
390 GPUglobalref() AliHLTTPCCAHitId *fTrackHits; // array of track hit numbers
394 GPUglobalref() AliHLTTPCCASliceOutput **fOutput; //address of pointer pointing to SliceOutput Object
397 AliHLTTPCCATracker( const AliHLTTPCCATracker& );
398 AliHLTTPCCATracker &operator=( const AliHLTTPCCATracker& );
400 static int StarthitSortComparison(const void*a, const void* b);
403 #if defined(HLTCA_STANDALONE) && (!defined(__OPENCL__) || defined(HLTCA_HOSTCODE))
404 void AliHLTTPCCATracker::StandaloneQueryTime(unsigned long long int *i)
407 QueryPerformanceCounter((LARGE_INTEGER*) i);
410 clock_gettime(CLOCK_REALTIME, &t);
411 *i = (unsigned long long int) t.tv_sec * (unsigned long long int) 1000000000 + (unsigned long long int) t.tv_nsec;
415 void AliHLTTPCCATracker::StandaloneQueryFreq(unsigned long long int *i)
418 QueryPerformanceFrequency((LARGE_INTEGER*) i);
423 #endif //HLTCA_STANDALONE
425 #endif //ALIHLTTPCCATRACKER_H