e00c47c1e9e1c80c1758e97baab83babfebbf492
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCATrackerFramework.cxx
1 // @(#) $Id: AliHLTTPCCATracker.cxx 34611 2009-09-04 00:22:05Z sgorbuno $
2 // **************************************************************************
3 // This file is property of and copyright by the ALICE HLT Project          *
4 // ALICE Experiment at CERN, All rights reserved.                           *
5 //                                                                          *
6 // Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
7 //                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
8 //                  for The ALICE HLT Project.                              *
9 //                                                                          *
10 // Permission to use, copy, modify and distribute this software and its     *
11 // documentation strictly for non-commercial purposes is hereby granted     *
12 // without fee, provided that the above copyright notice appears in all     *
13 // copies and that both the copyright notice and this permission notice     *
14 // appear in the supporting documentation. The authors make no claims       *
15 // about the suitability of this software for any purpose. It is            *
16 // provided "as is" without express or implied warranty.                    *
17 //                                                                          *
18 //***************************************************************************
19
20 #include "AliHLTTPCCADef.h"
21 #include "AliHLTTPCCAGPUConfig.h"
22 #include "AliHLTTPCCATrackerFramework.h"
23 #include "AliHLTTPCCAGPUTracker.h"
24 #include "AliHLTTPCCATracker.h"
25 #include "AliHLTTPCCAMath.h"
26 #include "AliHLTTPCCAClusterData.h"
27
28 #ifdef R__WIN32
29 #include <windows.h>
30 #include <winbase.h>
31 #else
32 #include <dlfcn.h>
33 #endif
34
35 #ifdef HLTCA_STANDALONE
36 #include <omp.h>
37 #endif
38
39 ClassImp( AliHLTTPCCATrackerFramework )
40
41 int AliHLTTPCCATrackerFramework::InitGPU(int sliceCount, int forceDeviceID)
42 {
43         //Initialize GPU Tracker and determine if GPU available
44         int retVal;
45         if (!fGPULibAvailable)
46         {
47                 HLTError("GPU Library not loaded\n");
48                 return(1);
49         }
50         if (fGPUTrackerAvailable && (retVal = ExitGPU())) return(retVal);
51         retVal = fGPUTracker->InitGPU(sliceCount, forceDeviceID);
52         fUseGPUTracker = fGPUTrackerAvailable = retVal == 0;
53         return(retVal);
54 }
55
56 int AliHLTTPCCATrackerFramework::ExitGPU()
57 {
58         //Uninitialize GPU Tracker
59         if (!fGPUTrackerAvailable) return(0);
60         fUseGPUTracker = false;
61         fGPUTrackerAvailable = false;
62         return(fGPUTracker->ExitGPU());
63 }
64
65 void AliHLTTPCCATrackerFramework::SetGPUDebugLevel(int Level, std::ostream *OutFile, std::ostream *GPUOutFile)
66 {
67         //Set Debug Level for GPU Tracker and also for CPU Tracker for comparison reasons
68         fGPUTracker->SetDebugLevel(Level, GPUOutFile);
69         fGPUDebugLevel = Level;
70         for (int i = 0;i < fgkNSlices;i++)
71         {
72                 fCPUTrackers[i].SetGPUDebugLevel(Level, OutFile);
73         }
74 }
75
76 int AliHLTTPCCATrackerFramework::SetGPUTracker(bool enable)
77 {
78         //Enable / disable GPU Tracker
79         if (enable && !fGPUTrackerAvailable)
80         {
81                 fUseGPUTracker = false;
82                 return(1);
83         }
84         fUseGPUTracker = enable;
85         return(0);
86 }
87
88 GPUhd() void AliHLTTPCCATrackerFramework::SetOutputControl( AliHLTTPCCASliceOutput::outputControlStruct* val)
89 {
90         //Set Output Control Pointers
91         fOutputControl = val;
92         fGPUTracker->SetOutputControl(val);
93         for (int i = 0;i < fgkNSlices;i++)
94         {
95                 fCPUTrackers[i].SetOutputControl(val);
96         }
97 }
98
99 int AliHLTTPCCATrackerFramework::ProcessSlices(int firstSlice, int sliceCount, AliHLTTPCCAClusterData* pClusterData, AliHLTTPCCASliceOutput** pOutput)
100 {
101         int useGlobalTracking = fGlobalTracking;
102         if (fGlobalTracking && (firstSlice || sliceCount != fgkNSlices))
103         {
104                 HLTWarning("Global Tracking only available if all slices are processed!");
105                 useGlobalTracking = 0;
106         }
107
108         //Process sliceCount slices starting from firstslice, in is pClusterData array, out pOutput array
109         if (fUseGPUTracker)
110         {
111                 if (fGPUTracker->Reconstruct(pOutput, pClusterData, firstSlice, CAMath::Min(sliceCount, fgkNSlices - firstSlice))) return(1);
112         }
113         else
114         {
115 #ifdef HLTCA_STANDALONE
116                 if (fOutputControl->fOutputPtr && omp_get_max_threads() > 1)
117                 {
118                         HLTError("fOutputPtr must not be used with OpenMP\n");
119                         return(1);
120                 }
121                 int nLocalTracks = 0, nGlobalTracks = 0, nOutputTracks = 0, nLocalHits = 0, nGlobalHits = 0;
122
123 #pragma omp parallel for
124 #endif
125                 for (int iSlice = 0;iSlice < CAMath::Min(sliceCount, fgkNSlices - firstSlice);iSlice++)
126                 {
127 #ifdef HLTCA_STANDALONE
128                         fCPUTrackers[firstSlice + iSlice].StandalonePerfTime(0);
129 #endif
130                         fCPUTrackers[firstSlice + iSlice].ReadEvent(&pClusterData[iSlice]);
131                         fCPUTrackers[firstSlice + iSlice].SetOutput(&pOutput[iSlice]);
132                         fCPUTrackers[firstSlice + iSlice].Reconstruct();
133                         fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNLocalTracks = fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNTracks;
134                         fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNLocalTrackHits = fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNTrackHits;
135                         if (!useGlobalTracking)
136                         {
137                                 fCPUTrackers[firstSlice + iSlice].ReconstructOutput();
138 #ifdef HLTCA_STANDALONE
139                                 nOutputTracks += (*fCPUTrackers[firstSlice + iSlice].Output())->NTracks();
140                                 nLocalTracks += fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNTracks;
141 #endif
142                                 if (!fKeepData)
143                                 {
144                                         fCPUTrackers[firstSlice + iSlice].SetupCommonMemory();
145                                 }
146                         }
147                 }
148
149                 if (useGlobalTracking)
150                 {
151                         for (int iSlice = 0;iSlice < CAMath::Min(sliceCount, fgkNSlices - firstSlice);iSlice++)
152                         {
153                                 int sliceLeft = (iSlice + (fgkNSlices / 2 - 1)) % (fgkNSlices / 2);
154                                 int sliceRight = (iSlice + 1) % (fgkNSlices / 2);
155                                 if (iSlice >= fgkNSlices / 2)
156                                 {
157                                         sliceLeft += fgkNSlices / 2;
158                                         sliceRight += fgkNSlices / 2;
159                                 }
160                                 fCPUTrackers[iSlice].PerformGlobalTracking(fCPUTrackers[sliceLeft], fCPUTrackers[sliceRight], CAMath::Min(fCPUTrackers[sliceLeft].CommonMemory()->fNTracklets, fCPUTrackers[sliceRight].CommonMemory()->fNTracklets) * 2);
161                         }
162                         for (int iSlice = 0;iSlice < CAMath::Min(sliceCount, fgkNSlices - firstSlice);iSlice++)
163                         {
164                                 fCPUTrackers[firstSlice + iSlice].ReconstructOutput();
165 #ifdef HLTCA_STANDALONE
166                                 //printf("Slice %d - Tracks: Local %d Global %d - Hits: Local %d Global %d\n", iSlice, fCPUTrackers[iSlice].CommonMemory()->fNLocalTracks, fCPUTrackers[iSlice].CommonMemory()->fNTracks, fCPUTrackers[iSlice].CommonMemory()->fNLocalTrackHits, fCPUTrackers[iSlice].CommonMemory()->fNTrackHits);
167                                 nLocalTracks += fCPUTrackers[iSlice].CommonMemory()->fNLocalTracks;
168                                 nGlobalTracks += fCPUTrackers[iSlice].CommonMemory()->fNTracks;
169                                 nLocalHits += fCPUTrackers[iSlice].CommonMemory()->fNLocalTrackHits;
170                                 nGlobalHits += fCPUTrackers[iSlice].CommonMemory()->fNTrackHits;
171                                 nOutputTracks += (*fCPUTrackers[iSlice].Output())->NTracks();
172 #endif
173                                 if (!fKeepData)
174                                 {
175                                         fCPUTrackers[firstSlice + iSlice].SetupCommonMemory();
176                                 }
177                         }
178                 }
179 #ifdef HLTCA_STANDALONE
180                 //printf("Slice Tracks Output %d: - Tracks: %d local, %d global -  Hits: %d local, %d global\n", nOutputTracks, nLocalTracks, nGlobalTracks, nLocalHits, nGlobalHits);
181                 /*for (int i = firstSlice;i < firstSlice + sliceCount;i++)
182                 {
183                         fCPUTrackers[i].DumpOutput(stdout);
184                 }*/
185 #endif
186         }
187         
188         if (fGPUDebugLevel >= 6 && fUseGPUTracker)
189         {
190             fUseGPUTracker = 0;
191             ProcessSlices(firstSlice, sliceCount, pClusterData, pOutput);
192             fUseGPUTracker = 1;
193         }
194
195         return(0);
196 }
197
198 unsigned long long int* AliHLTTPCCATrackerFramework::PerfTimer(int GPU, int iSlice, int iTimer)
199 {
200         //Performance information for slice trackers
201         return(GPU ? fGPUTracker->PerfTimer(iSlice, iTimer) : fCPUTrackers[iSlice].PerfTimer(iTimer));
202 }
203
204 int AliHLTTPCCATrackerFramework::InitializeSliceParam(int iSlice, AliHLTTPCCAParam &param)
205 {
206         //Initialize Tracker Parameters for a slice
207         if (fGPUTrackerAvailable && fGPUTracker->InitializeSliceParam(iSlice, param)) return(1);
208         fCPUTrackers[iSlice].Initialize(param);
209         return(0);
210 }
211
212 #ifdef HLTCA_STANDALONE
213 #define GPULIBNAME "libAliHLTTPCCAGPUSA"
214 #else
215 #define GPULIBNAME "libAliHLTTPCCAGPU"
216 #endif
217
218 AliHLTTPCCATrackerFramework::AliHLTTPCCATrackerFramework(int allowGPU, char* GPU_Library) : fGPULibAvailable(false), fGPUTrackerAvailable(false), fUseGPUTracker(false), fGPUDebugLevel(0), fGPUTracker(NULL), fGPULib(NULL), fOutputControl( NULL ), fKeepData(false), fGlobalTracking(false)
219 {
220         //Constructor
221         if (GPU_Library && !GPU_Library[0]) GPU_Library = NULL;
222 #ifdef R__WIN32
223         HMODULE hGPULib = LoadLibraryEx(GPU_Library == NULL ? (GPULIBNAME ".dll") : GPU_Library, NULL, NULL);
224 #else
225         void* hGPULib = dlopen(GPU_Library == NULL ? (GPULIBNAME ".so") : GPU_Library, RTLD_NOW);
226 #endif
227         if (hGPULib == NULL)
228         {
229                 if (allowGPU)
230                 {
231                         #ifndef R__WIN32
232                                 HLTInfo("The following error occured during dlopen: %s", dlerror());
233                         #endif
234                         HLTError("Error Opening cagpu library for GPU Tracker, will fallback to CPU");
235                 }
236                 else
237                 {
238                         HLTDebug("Cagpu library was not found, Tracking on GPU will not be available");
239                 }
240                 fGPUTracker = new AliHLTTPCCAGPUTracker;
241         }
242         else
243         {
244 #ifdef R__WIN32
245                 FARPROC createFunc = GetProcAddress(hGPULib, "AliHLTTPCCAGPUTrackerNVCCCreate");
246 #else
247                 void* createFunc = (void*) dlsym(hGPULib, "AliHLTTPCCAGPUTrackerNVCCCreate");
248 #endif
249                 if (createFunc == NULL)
250                 {
251                         HLTError("Error Creating GPU Tracker\n");
252 #ifdef R__WIN32
253                         FreeLibrary(hGPULib);
254 #else
255                         dlclose(hGPULib);
256 #endif
257                         fGPUTracker = new AliHLTTPCCAGPUTracker;
258                 }
259                 else
260                 {
261                         AliHLTTPCCAGPUTracker* (*tmp)() = (AliHLTTPCCAGPUTracker* (*)()) createFunc;
262                         fGPUTracker = tmp();
263                         fGPULibAvailable = true;
264                         fGPULib = (void*) (size_t) hGPULib;
265                         HLTImportant("GPU Tracker library loaded and GPU tracker object created sucessfully (%sactive)", allowGPU ? "" : "in");
266                 }
267         }
268
269         if (allowGPU && fGPULibAvailable)
270         {
271                 fUseGPUTracker = (fGPUTrackerAvailable = (fGPUTracker->InitGPU() == 0));
272                 HLTInfo("GPU Tracker Initialized and available in framework");
273         }
274 }
275
276 AliHLTTPCCATrackerFramework::~AliHLTTPCCATrackerFramework()
277 {
278 #ifdef R__WIN32
279         HMODULE hGPULib = (HMODULE) (size_t) fGPULib;
280 #else
281         void* hGPULib = fGPULib;
282 #endif
283         if (fGPULib)
284         {
285                 if (fGPUTracker)
286                 {
287                         ExitGPU();
288 #ifdef R__WIN32
289                         FARPROC destroyFunc = GetProcAddress(hGPULib, "AliHLTTPCCAGPUTrackerNVCCDestroy");
290 #else
291                         void* destroyFunc = (void*) dlsym(hGPULib, "AliHLTTPCCAGPUTrackerNVCCDestroy");
292 #endif
293                         if (destroyFunc == NULL)
294                         {
295                                 HLTError("Error Freeing GPU Tracker\n");
296                         }
297                         else
298                         {
299                                 void (*tmp)(AliHLTTPCCAGPUTracker*) =  (void (*)(AliHLTTPCCAGPUTracker*)) destroyFunc;
300                                 tmp(fGPUTracker);
301                         }
302                 }
303
304 #ifdef R__WIN32
305                 FreeLibrary(hGPULib);
306 #else
307                 dlclose(hGPULib);
308 #endif
309         }
310         else if (fGPUTracker)
311         {
312                 delete fGPUTracker;
313         }
314         fGPULib = NULL;
315         fGPUTracker = NULL;
316 }