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 #include "TStopwatch.h"
36 * @class AliHLTTPCCATracker
38 * Slice tracker for ALICE HLT.
39 * The class reconstructs tracks in one slice of TPC.
40 * The reconstruction algorithm is based on the Cellular Automaton method
42 * The CA tracker is designed stand-alone.
43 * It is integrated to the HLT framework via AliHLTTPCCATrackerComponent interface.
44 * The class is under construction.
48 class AliHLTTPCCAClusterData;
50 MEM_CLASS_PRE() class AliHLTTPCCATracker
56 #ifdef HLTCA_STANDALONE
58 fLinkTmpMemory( NULL ),
64 fIsGPUTracker( false ),
67 fRowStartHitCountOffset( NULL ),
68 fTrackletTmpStartHits( NULL ),
69 fGPUTrackletTemp( NULL ),
70 fRowBlockTracklets( NULL ),
72 fBlockStartingTracklet( NULL ),
73 fGPUParametersConst(),
78 fTrackletMemorySize( 0 ),
80 fTrackMemorySize( 0 ),
81 fTrackletStartHits( 0 ),
83 fTrackletRowHits( NULL ),
89 for( int i=0; i<10; i++ ) fTimers[i] = 0;
90 for( int i=0; i<16; i++ ) fPerfTimers[i] = 0;
92 ~AliHLTTPCCATracker();
94 struct StructGPUParameters
96 StructGPUParameters() : fNextTracklet(0), fScheduleFirstDynamicTracklet( 0 ), fGPUError( 0 ) {}
97 int fNextTracklet; //Next Tracklet to process
98 int fScheduleFirstDynamicTracklet; //Last Tracklet with fixed position in sheduling
99 int fGPUError; //Signalizes error on GPU during GPU Reconstruction, kind of return value
102 MEM_CLASS_PRE2() struct StructGPUParametersConst
104 StructGPUParametersConst() : fGPUFixedBlockCount( 0 ), fGPUiSlice( 0 ), fGPUnSlices( 0 ), fGPUMem( NULL ) {}
105 int fGPUFixedBlockCount; //Count of blocks that is used for this tracker in fixed schedule situations
106 int fGPUiSlice; // slice number processed by running GPU MP
107 int fGPUnSlices; // n of slices to be processed in parallel
108 GPUglobalref() char* fGPUMem; //Base pointer to GPU memory (Needed for OpenCL for verification)
111 struct commonMemoryStruct
113 commonMemoryStruct() : fNTracklets( 0 ), fNTracks( 0 ), fNLocalTracks( 0 ), fNTrackHits( 0 ), fNLocalTrackHits( 0 ), fGPUParameters() {}
114 int fNTracklets; // number of tracklets
115 int fNTracks; // number of reconstructed tracks
116 int fNLocalTracks; //number of reconstructed tracks before global tracking
117 int fNTrackHits; // number of track hits
118 int fNLocalTrackHits; //see above
119 StructGPUParameters fGPUParameters; // GPU parameters
122 MEM_CLASS_PRE2() void Initialize( const MEM_LG2(AliHLTTPCCAParam) ¶m );
126 int CheckEmptySlice() const;
127 void WriteOutputPrepare();
130 #if !defined(HLTCA_GPUCODE)
132 void ReconstructOutput();
133 #endif //!HLTCA_GPUCODE
136 //Make Reconstruction steps directly callable (Used for GPU debugging)
137 void RunNeighboursFinder();
138 void RunNeighboursCleaner();
139 void RunStartHitsFinder();
140 void RunTrackletConstructor();
141 void RunTrackletSelector();
143 //GPU Tracker Interface
144 void SetGPUTracker();
145 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
146 void SetGPUDebugLevel(int Level, std::ostream *NewDebugOut = NULL) {fGPUDebugLevel = Level;if (NewDebugOut) fGPUDebugOut = NewDebugOut;}
147 char* SetGPUTrackerCommonMemory(char* const pGPUMemory);
148 char* SetGPUTrackerHitsMemory(char* pGPUMemory, int MaxNHits);
149 char* SetGPUTrackerTrackletsMemory(char* pGPUMemory, int MaxNTracklets, int constructorBlockCount);
150 char* SetGPUTrackerTracksMemory(char* pGPUMemory, int MaxNTracks, int MaxNHits );
153 void DumpSliceData(std::ostream &out); //Dump Input Slice Data
154 void DumpLinks(std::ostream &out); //Dump all links to file (for comparison after NeighboursFinder/Cleaner)
155 void DumpStartHits(std::ostream &out); //Same for Start Hits
156 void DumpHitWeights(std::ostream &out); //....
157 void DumpTrackHits(std::ostream &out); //Same for Track Hits
158 void DumpTrackletHits(std::ostream &out); //Same for Track Hits
159 void DumpOutput(FILE* out); //Similar for output
161 void SetOutput( AliHLTTPCCASliceOutput** out ) { fOutput = out; }
162 void ReadEvent( AliHLTTPCCAClusterData *clusterData );
164 GPUhd() const AliHLTTPCCASliceOutput::outputControlStruct* OutputControl() const { return fOutputControl; }
165 GPUh() void SetOutputControl( AliHLTTPCCASliceOutput::outputControlStruct* const val) { fOutputControl = val; }
167 GPUhd() AliHLTTPCCAClusterData *ClusterData() const { return fClusterData; }
169 GPUh() void ClearSliceDataHitWeights() {fData.ClearHitWeights();}
170 GPUh() MakeType(const MEM_LG(AliHLTTPCCARow)&) Row( const AliHLTTPCCAHitId &HitId ) const { return fData.Row( HitId.RowIndex() ); }
172 GPUhd() AliHLTTPCCASliceOutput** Output() const { return fOutput; }
174 GPUh() GPUglobalref() commonMemoryStruct *CommonMemory() const {return(fCommonMem); }
175 GPUh() static size_t CommonMemorySize() { return(sizeof(AliHLTTPCCATracker::commonMemoryStruct)); }
176 GPUh() GPUglobalref() char* HitMemory() const {return(fHitMemory); }
177 GPUh() size_t HitMemorySize() const {return(fHitMemorySize); }
178 GPUh() char* TrackletMemory() {return(fTrackletMemory); }
179 GPUh() size_t TrackletMemorySize() const {return(fTrackletMemorySize); }
180 GPUh() char* TrackMemory() {return(fTrackMemory); }
181 GPUh() size_t TrackMemorySize() const {return(fTrackMemorySize); }
183 GPUh() void SetGPUSliceDataMemory(void* const pSliceMemory, void* const pRowMemory) { fData.SetGPUSliceDataMemory(pSliceMemory, pRowMemory); }
184 GPUh() unsigned long long int* PerfTimer(unsigned int i) {return &fPerfTimers[i]; }
186 GPUh() static int SortComparison(const void* a, const void* b);
189 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 );}
190 GPUd() void GetErrors2( int iRow, float z, float sinPhi, float cosPhi, float DzDs, float &Err2Y, float &Err2Z ) const
192 fParam.GetClusterErrors2( iRow, z, sinPhi, cosPhi, DzDs, Err2Y, Err2Z );
193 Err2Y*=fParam.ClusterError2CorrectionY();
194 Err2Z*=fParam.ClusterError2CorrectionZ();
197 MEM_CLASS_PRE2() void FitTrack( const MEM_LG2(AliHLTTPCCATrack) &track, float *t0 = 0 ) const;
198 MEM_CLASS_PRE2() void FitTrackFull( const MEM_LG2(AliHLTTPCCATrack) &track, float *t0 = 0 ) const;
200 void SetupCommonMemory();
201 void SetPointersHits( int MaxNHits );
202 void SetPointersTracklets ( int MaxNTracklets );
203 void SetPointersTracks( int MaxNTracks, int MaxNHits );
204 size_t SetPointersSliceData(const AliHLTTPCCAClusterData *data, bool allocate = false) { return(fData.SetPointers(data, allocate)); }
206 #if !defined(HLTCA_GPUCODE)
207 GPUh() void WriteEvent( std::ostream &out );
208 GPUh() void WriteTracks( std::ostream &out ) ;
209 GPUh() void ReadTracks( std::istream &in );
210 #endif //!HLTCA_GPUCODE
212 GPUhd() MakeType(const MEM_LG(AliHLTTPCCAParam)&) Param() const { return fParam; }
213 GPUhd() MakeType(const MEM_LG(AliHLTTPCCAParam)*) pParam() const { return &fParam; }
214 MEM_CLASS_PRE2() GPUhd() void SetParam( const MEM_LG2(AliHLTTPCCAParam) &v ) { fParam = v; }
216 GPUhd() MakeType(const MEM_LG(AliHLTTPCCASliceData)&) Data() const { return fData; }
218 GPUhd() GPUglobalref() const MEM_GLOBAL(AliHLTTPCCARow)& Row( int rowIndex ) const { return fData.Row( rowIndex ); }
220 GPUhd() double Timer( int i ) const { return fTimers[i]; }
221 GPUhd() void SetTimer( int i, double v ) { fTimers[i] = v; }
223 GPUhd() int NHitsTotal() const { return fData.NumberOfHits(); }
225 MEM_TEMPLATE() GPUd() void SetHitLinkUpData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, short v ) { fData.SetHitLinkUpData( row, hitIndex, v ); }
226 MEM_TEMPLATE() GPUd() void SetHitLinkDownData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, short v ) { fData.SetHitLinkDownData( row, hitIndex, v ); }
227 MEM_TEMPLATE() GPUd() short HitLinkUpData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const { return fData.HitLinkUpData( row, hitIndex ); }
228 MEM_TEMPLATE() GPUd() short HitLinkDownData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const { return fData.HitLinkDownData( row, hitIndex ); }
230 //MEM_CLASS_PRE2() GPUd() GPUglobalref() const ushort2 *HitData( const MEM_TYPE( AliHLTTPCCARow)&row ) const { return fData.HitData(row); }
231 MEM_TEMPLATE() GPUd() GPUglobalref() const ushort2 *HitData( const MEM_TYPE( AliHLTTPCCARow)& row ) const { return fData.HitData(row); }
232 MEM_TEMPLATE() GPUd() GPUglobalref() const short_v *HitLinkUpData ( const MEM_TYPE( AliHLTTPCCARow)&row ) const { return fData.HitLinkUpData(row); }
233 MEM_TEMPLATE() GPUd() GPUglobalref() const short_v *HitLinkDownData( const MEM_TYPE( AliHLTTPCCARow)&row ) const { return fData.HitLinkDownData(row); }
234 MEM_TEMPLATE() GPUd() GPUglobalref() const ushort_v *FirstHitInBin( const MEM_TYPE( AliHLTTPCCARow)&row ) const { return fData.FirstHitInBin(row); }
236 MEM_TEMPLATE() GPUd() int FirstHitInBin( const MEM_TYPE( AliHLTTPCCARow)&row, int binIndex ) const { return fData.FirstHitInBin( row, binIndex ); }
238 MEM_TEMPLATE() GPUd() unsigned short HitDataY( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
239 return fData.HitDataY( row, hitIndex );
241 MEM_TEMPLATE() GPUd() unsigned short HitDataZ( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
242 return fData.HitDataZ( row, hitIndex );
244 MEM_TEMPLATE() GPUd() ushort2 HitData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
245 return fData.HitData( row, hitIndex );
248 MEM_TEMPLATE() GPUhd() int HitInputID( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const { return fData.ClusterDataIndex( row, hitIndex ); }
251 * The hit weight is used to determine whether a hit belongs to a certain tracklet or another one
252 * competing for the same hit. The tracklet that has a higher weight wins. Comparison is done
253 * using the the number of hits in the tracklet (the more hits it has the more it keeps). If
254 * tracklets have the same number of hits then it doesn't matter who gets it, but it should be
255 * only one. So a unique number (row index is good) is added in the least significant part of
258 GPUd() static int CalculateHitWeight( int NHits, float chi2, int ) {
259 const float chi2_suppress = 6.f;
260 float weight = (((float) NHits * (chi2_suppress - chi2 / 500.f)) * (1e9 / chi2_suppress / 160.));
261 if (weight < 0 || weight > 2e9) weight = 0;
262 return ( (int) weight );
263 //return( (NHits << 16) + num);
265 MEM_TEMPLATE() GPUd() void MaximizeHitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, int weight ) {
266 fData.MaximizeHitWeight( row, hitIndex, weight );
268 MEM_TEMPLATE() GPUd() void SetHitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, int weight ) {
269 fData.SetHitWeight( row, hitIndex, weight );
271 MEM_TEMPLATE() GPUd() int HitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
272 return fData.HitWeight( row, hitIndex );
275 GPUhd() GPUglobalref() int *NTracklets() const { return &fCommonMem->fNTracklets; }
277 GPUhd() const AliHLTTPCCAHitId &TrackletStartHit( int i ) const { return fTrackletStartHits[i]; }
278 GPUhd() GPUglobalref() AliHLTTPCCAHitId *TrackletStartHits() const { return fTrackletStartHits; }
279 GPUhd() GPUglobalref() AliHLTTPCCAHitId *TrackletTmpStartHits() const { return fTrackletTmpStartHits; }
280 MEM_CLASS_PRE2() GPUhd() const MEM_LG2(AliHLTTPCCATracklet) &Tracklet( int i ) const { return fTracklets[i]; }
281 GPUhd() GPUglobalref() MEM_GLOBAL(AliHLTTPCCATracklet) *Tracklets() const { return fTracklets;}
282 GPUhd() GPUglobalref()int* TrackletRowHits() const { return fTrackletRowHits; }
284 GPUhd() GPUglobalref() int *NTracks() const { return &fCommonMem->fNTracks; }
285 GPUhd() GPUglobalref() MEM_GLOBAL(AliHLTTPCCATrack) *Tracks() const { return fTracks; }
286 GPUhd() GPUglobalref() int *NTrackHits() const { return &fCommonMem->fNTrackHits; }
287 GPUhd() GPUglobalref() AliHLTTPCCAHitId *TrackHits() const { return fTrackHits; }
290 GPUhd() GPUglobalref() MEM_GLOBAL(AliHLTTPCCARow)* SliceDataRows() const {return(fData.Rows()); }
292 GPUhd() GPUglobalref() uint3* RowStartHitCountOffset() const {return(fRowStartHitCountOffset);}
294 MEM_CLASS_PRE2() GPUhd() AliHLTTPCCATrackletConstructor::MEM_LG2(AliHLTTPCCAGPUTempMemory)* GPUTrackletTemp() const {return(fGPUTrackletTemp);}
296 GPUhd() GPUglobalref() int* RowBlockTracklets(int reverse, int iRowBlock) const {return(&fRowBlockTracklets[(reverse * ((fParam.NRows() / HLTCA_GPU_SCHED_ROW_STEP) + 1) + iRowBlock) * fCommonMem->fNTracklets]);}
297 GPUhd() GPUglobalref() int* RowBlockTracklets() const {return(fRowBlockTracklets);}
298 GPUhd() GPUglobalref() int4* RowBlockPos(int reverse, int iRowBlock) const {return(&fRowBlockPos[reverse * ((fParam.NRows() / HLTCA_GPU_SCHED_ROW_STEP) + 1) + iRowBlock]);}
299 GPUhd() GPUglobalref() int4* RowBlockPos() const {return(fRowBlockPos);}
300 GPUhd() GPUglobalref() uint2* BlockStartingTracklet() const {return(fBlockStartingTracklet);}
301 GPUhd() GPUglobalref() StructGPUParameters* GPUParameters() const {return(&fCommonMem->fGPUParameters);}
302 GPUhd() MakeType(MEM_LG(StructGPUParametersConst)*) GPUParametersConst() {return(&fGPUParametersConst);}
303 GPUhd() void SetGPUTextureBase(char* val) { fData.SetGPUTextureBase(val); }
305 #ifdef HLTCA_STANDALONE
306 GPUhd() char* StageAtSync() {return(fStageAtSync);}
307 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
308 GPUh() const char* LinkTmpMemory() const {return(fLinkTmpMemory);}
312 #ifdef HLTCA_STANDALONE
313 static inline void StandaloneQueryTime(ULong64_t *i);
314 static inline void StandaloneQueryFreq(ULong64_t *i);
315 #endif //HLTCA_STANDALONE
316 void StandalonePerfTime(int i);
320 int fTtrack; //Track ID
321 float fSortVal; //Value to sort for
324 void PerformGlobalTracking(AliHLTTPCCATracker& sliceLeft, AliHLTTPCCATracker& sliceRight, int MaxTracks);
327 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
328 GPUh() int PerformGlobalTrackingRun(AliHLTTPCCATracker& sliceNeighbour, int iTrack, int rowIndex, float angle, int direction);
331 //Temporary Variables for Standalone measurements
332 #ifdef HLTCA_STANDALONE
334 char* fStageAtSync; //Pointer to array storing current stage for every thread at every sync point
335 char *fLinkTmpMemory; //tmp memory for hits after neighbours finder
339 MEM_LG(AliHLTTPCCAParam) fParam; // parameters
340 double fTimers[10]; // timers
341 ULong64_t fPerfTimers[16]; // running CPU time for different parts of the algorithm
343 AliHLTTPCCASliceOutput::outputControlStruct* fOutputControl; // output control
345 /** A pointer to the ClusterData object that the SliceData was created from. This can be used to
346 * merge clusters from inside the SliceTracker code and recreate the SliceData. */
347 GPUglobalref() AliHLTTPCCAClusterData *fClusterData; // ^
348 MEM_LG(AliHLTTPCCASliceData) fData; // The SliceData object. It is used to encapsulate the storage in memory from the access
350 bool fIsGPUTracker; // is it GPU tracker object
351 int fGPUDebugLevel; // debug level
353 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
354 std::ostream *fGPUDebugOut; // debug stream
356 void* fGPUDebugOut; //No this is a hack, but I have no better idea.
360 GPUglobalref() uint3* fRowStartHitCountOffset; //Offset, length and new offset of start hits in row
361 GPUglobalref() AliHLTTPCCAHitId *fTrackletTmpStartHits; //Unsorted start hits
362 GPUglobalref() MEM_GLOBAL(AliHLTTPCCATrackletConstructor::AliHLTTPCCAGPUTempMemory)* fGPUTrackletTemp; //Temp Memory for GPU Tracklet Constructor
363 GPUglobalref() int* fRowBlockTracklets; //Reference which tracklet is processed in which rowblock next
364 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
365 GPUglobalref() uint2* fBlockStartingTracklet; // First Tracklet that is to be processed by current GPU MP
367 MEM_LG(StructGPUParametersConst) fGPUParametersConst; // Parameters for GPU if this is a GPU tracker
371 GPUglobalref() commonMemoryStruct *fCommonMem; // common event memory
373 GPUglobalref() char *fHitMemory; // event memory for hits
374 size_t fHitMemorySize; // size of the event memory for hits [bytes]
376 GPUglobalref() char *fTrackletMemory; //event memory for tracklets
377 size_t fTrackletMemorySize; //size of the event memory for tracklets
379 GPUglobalref() char *fTrackMemory; // event memory for tracks
380 size_t fTrackMemorySize; // size of the event memory for tracks [bytes]
382 GPUglobalref() AliHLTTPCCAHitId *fTrackletStartHits; // start hits for the tracklets
383 GPUglobalref() MEM_GLOBAL(AliHLTTPCCATracklet) *fTracklets; // tracklets
384 GPUglobalref() int *fTrackletRowHits; //Hits for each Tracklet in each row
387 GPUglobalref() MEM_GLOBAL(AliHLTTPCCATrack) *fTracks; // reconstructed tracks
388 GPUglobalref() AliHLTTPCCAHitId *fTrackHits; // array of track hit numbers
392 GPUglobalref() AliHLTTPCCASliceOutput **fOutput; //address of pointer pointing to SliceOutput Object
395 AliHLTTPCCATracker( const AliHLTTPCCATracker& );
396 AliHLTTPCCATracker &operator=( const AliHLTTPCCATracker& );
398 static int StarthitSortComparison(const void*a, const void* b);
401 #if defined(HLTCA_STANDALONE) && (!defined(__OPENCL__) || defined(HLTCA_HOSTCODE))
402 void AliHLTTPCCATracker::StandaloneQueryTime(unsigned long long int *i)
405 QueryPerformanceCounter((LARGE_INTEGER*) i);
408 clock_gettime(CLOCK_REALTIME, &t);
409 *i = (unsigned long long int) t.tv_sec * (unsigned long long int) 1000000000 + (unsigned long long int) t.tv_nsec;
413 void AliHLTTPCCATracker::StandaloneQueryFreq(unsigned long long int *i)
416 QueryPerformanceFrequency((LARGE_INTEGER*) i);
421 #endif //HLTCA_STANDALONE
423 #endif //ALIHLTTPCCATRACKER_H