]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/tracking-ca/AliHLTTPCCATracker.h
Update NVIDIA GPU Tracking library to be compatible to AliRoot patch 64473, add preli...
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCATracker.h
1 //-*- Mode: C++ -*-
2 // @(#) $Id$
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                               *
7 //                                                                        *
8 //*************************************************************************
9
10 #ifndef ALIHLTTPCCATRACKER_H
11 #define ALIHLTTPCCATRACKER_H
12
13
14 #include "AliHLTTPCCADef.h"
15 #include "AliHLTTPCCAGPUConfig.h"
16
17 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
18 #include <iostream>
19 #endif
20
21 #include "AliHLTTPCCAParam.h"
22 #include "AliHLTTPCCAHitId.h"
23 #include "AliHLTTPCCASliceData.h"
24 #include "AliHLTTPCCASliceOutput.h"
25 #include "AliHLTTPCCATrackletConstructor.h"
26 #include "AliHLTTPCCATracklet.h"
27
28 MEM_CLASS_PRE() class AliHLTTPCCATrack;
29 MEM_CLASS_PRE() class AliHLTTPCCATrackParam;
30 class AliHLTTPCCAClusterData;
31 MEM_CLASS_PRE() class AliHLTTPCCARow;
32
33 #if !(defined(HLTCA_GPUCODE) && defined(__OPENCL__) && !defined(HLTCA_HOSTCODE))
34 #include "TStopwatch.h"
35 #endif
36
37 /**
38  * @class AliHLTTPCCATracker
39  *
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
43  *
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.
47  *
48  */
49
50 class AliHLTTPCCAClusterData;
51
52 MEM_CLASS_PRE() class AliHLTTPCCATracker
53 {
54   public:
55
56   AliHLTTPCCATracker()
57     :
58 #ifdef HLTCA_STANDALONE
59       fStageAtSync( NULL ),
60           fLinkTmpMemory( NULL ),
61 #endif
62           fParam(),
63       fOutputControl(),
64       fClusterData( 0 ),
65       fData(),
66       fIsGPUTracker( false ),
67       fGPUDebugLevel( 0 ),
68       fGPUDebugOut( 0 ),
69       fRowStartHitCountOffset( NULL ),
70       fTrackletTmpStartHits( NULL ),
71       fGPUTrackletTemp( NULL ),
72       fRowBlockTracklets( NULL ),
73       fRowBlockPos( NULL ),
74       fBlockStartingTracklet( NULL ),
75       fGPUParametersConst(),
76       fCommonMem( 0 ),
77       fHitMemory( 0 ),
78       fHitMemorySize( 0 ),
79       fTrackletMemory( 0 ),
80       fTrackletMemorySize( 0 ),
81       fTrackMemory( 0 ),
82       fTrackMemorySize( 0 ),
83       fTrackletStartHits( 0 ),
84       fTracklets( 0 ),
85       fTrackletRowHits( NULL ),
86       fTracks( 0 ),
87       fTrackHits( 0 ),
88       fOutput( 0 )
89   {
90     // constructor
91     for( int i=0; i<10; i++ ) fTimers[i] = 0;
92     for( int i=0; i<16; i++ ) fPerfTimers[i] = 0;
93   }
94   ~AliHLTTPCCATracker();
95   
96   struct StructGPUParameters
97   {
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
102   };
103   
104   MEM_CLASS_PRE2() struct StructGPUParametersConst
105   {
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)
111   };
112   
113   struct commonMemoryStruct
114   {
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
122   };
123   
124   MEM_CLASS_PRE2() void Initialize( const MEM_LG2(AliHLTTPCCAParam) &param );
125   
126   void StartEvent();
127   
128   int CheckEmptySlice() const;
129   void WriteOutputPrepare();
130   void WriteOutput();
131   
132 #if !defined(HLTCA_GPUCODE)
133   void Reconstruct();
134   void ReconstructOutput();
135 #endif //!HLTCA_GPUCODE
136   void DoTracking();
137   
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();
144   
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 );
153   
154   //Debugging Stuff
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
162
163   void SetOutput( AliHLTTPCCASliceOutput** out ) { fOutput = out; }
164   void ReadEvent( AliHLTTPCCAClusterData *clusterData );
165
166   GPUhd() const AliHLTTPCCASliceOutput::outputControlStruct* OutputControl() const { return fOutputControl; }  
167   GPUh() void SetOutputControl( AliHLTTPCCASliceOutput::outputControlStruct* const val) { fOutputControl = val; }
168
169   GPUhd() AliHLTTPCCAClusterData *ClusterData() const { return fClusterData; }
170
171   GPUh() void ClearSliceDataHitWeights() {fData.ClearHitWeights();}
172   GPUh() MakeType(const MEM_LG(AliHLTTPCCARow)&) Row( const AliHLTTPCCAHitId &HitId ) const { return fData.Row( HitId.RowIndex() ); }
173
174   GPUhd() AliHLTTPCCASliceOutput** Output() const { return fOutput; }
175
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); }
184
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]; }
187
188   GPUh() static int SortComparison(const void* a, const void* b);
189 #endif  
190   
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
193   {
194         fParam.GetClusterErrors2( iRow, z, sinPhi, cosPhi, DzDs, Err2Y, Err2Z );
195         Err2Y*=fParam.ClusterError2CorrectionY();
196         Err2Z*=fParam.ClusterError2CorrectionZ();
197   }
198   
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;
201   
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)); }
207  
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
213   
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; }
217   
218   GPUhd() MakeType(const MEM_LG(AliHLTTPCCASliceData)&) Data() const { return fData; }
219   
220   GPUhd() GPUglobalref() const MEM_GLOBAL(AliHLTTPCCARow)& Row( int rowIndex ) const { return fData.Row( rowIndex ); }
221   
222   GPUhd() double Timer( int i ) const { return fTimers[i]; }
223   GPUhd() void SetTimer( int i, double v ) { fTimers[i] = v; }
224   
225   GPUhd() int NHitsTotal() const { return fData.NumberOfHits(); }
226   
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 ); }
231   
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); }
237   
238   MEM_TEMPLATE() GPUd() int FirstHitInBin( const MEM_TYPE( AliHLTTPCCARow)&row, int binIndex ) const { return fData.FirstHitInBin( row, binIndex ); }
239   
240   MEM_TEMPLATE() GPUd() unsigned short HitDataY( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
241     return fData.HitDataY( row, hitIndex );
242   }
243   MEM_TEMPLATE() GPUd() unsigned short HitDataZ( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
244     return fData.HitDataZ( row, hitIndex );
245   }
246   MEM_TEMPLATE() GPUd() ushort2 HitData( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
247     return fData.HitData( row, hitIndex );
248   }
249   
250   MEM_TEMPLATE() GPUhd() int HitInputID( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const { return fData.ClusterDataIndex( row, hitIndex ); }
251   
252   /**
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
258    * the weight
259    */
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);
266   }
267   MEM_TEMPLATE() GPUd() void MaximizeHitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, int weight ) {
268     fData.MaximizeHitWeight( row, hitIndex, weight );
269   }
270   MEM_TEMPLATE() GPUd() void SetHitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex, int weight ) {
271         fData.SetHitWeight( row, hitIndex, weight );
272   }
273   MEM_TEMPLATE() GPUd() int HitWeight( const MEM_TYPE( AliHLTTPCCARow)&row, int hitIndex ) const {
274     return fData.HitWeight( row, hitIndex );
275   }
276   
277   GPUhd() GPUglobalref() int *NTracklets() const { return &fCommonMem->fNTracklets; }
278   
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; }
285
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; }
290   
291  
292   GPUhd() GPUglobalref() MEM_GLOBAL(AliHLTTPCCARow)* SliceDataRows() const {return(fData.Rows()); }
293   
294   GPUhd() GPUglobalref() uint3* RowStartHitCountOffset() const {return(fRowStartHitCountOffset);}
295 #ifdef HLTCA_GPUCODE
296   MEM_CLASS_PRE2() GPUhd() AliHLTTPCCATrackletConstructor::MEM_LG2(AliHLTTPCCAGPUTempMemory)* GPUTrackletTemp() const {return(fGPUTrackletTemp);}
297 #endif
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); }
306
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);}
311 #endif
312 #endif
313
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);
319
320   struct trackSortData
321   {
322         int fTtrack;            //Track ID
323         float fSortVal;         //Value to sort for
324   };
325
326   void PerformGlobalTracking(AliHLTTPCCATracker& sliceLeft, AliHLTTPCCATracker& sliceRight, int MaxTracks);
327
328 private:
329 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
330   GPUh() int PerformGlobalTrackingRun(AliHLTTPCCATracker& sliceNeighbour, int iTrack, int rowIndex, float angle, int direction);
331 #endif
332
333         //Temporary Variables for Standalone measurements
334 #ifdef HLTCA_STANDALONE
335 public:
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
338 private:
339 #endif
340   
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
344   
345   AliHLTTPCCASliceOutput::outputControlStruct* fOutputControl; // output control
346   
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
351   
352   bool fIsGPUTracker; // is it GPU tracker object
353   int fGPUDebugLevel; // debug level
354
355 #if !defined(__OPENCL__) || defined(HLTCA_HOSTCODE)
356   std::ostream *fGPUDebugOut; // debug stream
357 #else
358   void* fGPUDebugOut; //No this is a hack, but I have no better idea.
359 #endif
360   
361   //GPU Temp Arrays
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
368
369   MEM_LG(StructGPUParametersConst) fGPUParametersConst; // Parameters for GPU if this is a GPU tracker
370
371   // event
372   
373   GPUglobalref() commonMemoryStruct *fCommonMem; // common event memory
374   
375   GPUglobalref() char *fHitMemory; // event memory for hits
376   size_t   fHitMemorySize; // size of the event memory for hits [bytes]
377
378   GPUglobalref() char *fTrackletMemory; //event memory for tracklets
379   size_t fTrackletMemorySize; //size of the event memory for tracklets
380
381   GPUglobalref() char *fTrackMemory; // event memory for tracks
382   size_t   fTrackMemorySize; // size of the event memory for tracks [bytes]
383
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
387
388   //
389   GPUglobalref() MEM_GLOBAL(AliHLTTPCCATrack) *fTracks;  // reconstructed tracks
390   GPUglobalref() AliHLTTPCCAHitId *fTrackHits;          // array of track hit numbers
391   
392   // output
393   
394   GPUglobalref() AliHLTTPCCASliceOutput **fOutput;              //address of pointer pointing to SliceOutput Object
395   
396   // disable copy
397   AliHLTTPCCATracker( const AliHLTTPCCATracker& );
398   AliHLTTPCCATracker &operator=( const AliHLTTPCCATracker& );
399   
400   static int StarthitSortComparison(const void*a, const void* b);
401 };
402
403 #if defined(HLTCA_STANDALONE) && (!defined(__OPENCL__) || defined(HLTCA_HOSTCODE))
404         void AliHLTTPCCATracker::StandaloneQueryTime(unsigned long long int *i)
405         {
406         #ifdef R__WIN32
407                   QueryPerformanceCounter((LARGE_INTEGER*) i);
408         #else
409                   timespec t;
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;
412         #endif //R__WIN32
413         }
414
415         void AliHLTTPCCATracker::StandaloneQueryFreq(unsigned long long int *i)
416         {
417         #ifdef R__WIN32
418                   QueryPerformanceFrequency((LARGE_INTEGER*) i);
419         #else
420                 *i = 1000000000;
421         #endif //R__WIN32
422         }
423 #endif //HLTCA_STANDALONE
424
425 #endif //ALIHLTTPCCATRACKER_H