Line data Source code
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 6 : 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 0 : if (!fGPULibAvailable)
46 : {
47 0 : HLTError("GPU Library not loaded\n");
48 0 : return(1);
49 : }
50 0 : if (fGPUTrackerAvailable && (retVal = ExitGPU())) return(retVal);
51 0 : retVal = fGPUTracker->InitGPU(sliceCount, forceDeviceID);
52 0 : fUseGPUTracker = fGPUTrackerAvailable = retVal == 0;
53 0 : return(retVal);
54 0 : }
55 :
56 : int AliHLTTPCCATrackerFramework::ExitGPU()
57 : {
58 : //Uninitialize GPU Tracker
59 0 : if (!fGPUTrackerAvailable) return(0);
60 0 : fUseGPUTracker = false;
61 0 : fGPUTrackerAvailable = false;
62 0 : return(fGPUTracker->ExitGPU());
63 0 : }
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 0 : fGPUTracker->SetDebugLevel(Level, GPUOutFile);
69 0 : fGPUDebugLevel = Level;
70 0 : for (int i = 0;i < fgkNSlices;i++)
71 : {
72 0 : fCPUTrackers[i].SetGPUDebugLevel(Level, OutFile);
73 : }
74 0 : }
75 :
76 : int AliHLTTPCCATrackerFramework::SetGPUTracker(bool enable)
77 : {
78 : //Enable / disable GPU Tracker
79 0 : if (enable && !fGPUTrackerAvailable)
80 : {
81 0 : fUseGPUTracker = false;
82 0 : return(1);
83 : }
84 0 : fUseGPUTracker = enable;
85 0 : return(0);
86 0 : }
87 :
88 : GPUhd() void AliHLTTPCCATrackerFramework::SetOutputControl( AliHLTTPCCASliceOutput::outputControlStruct* val)
89 : {
90 : //Set Output Control Pointers
91 0 : fOutputControl = val;
92 0 : fGPUTracker->SetOutputControl(val);
93 0 : for (int i = 0;i < fgkNSlices;i++)
94 : {
95 0 : fCPUTrackers[i].SetOutputControl(val);
96 : }
97 0 : }
98 :
99 : int AliHLTTPCCATrackerFramework::ProcessSlices(int firstSlice, int sliceCount, AliHLTTPCCAClusterData* pClusterData, AliHLTTPCCASliceOutput** pOutput)
100 : {
101 0 : int useGlobalTracking = fGlobalTracking;
102 0 : if (fGlobalTracking && (firstSlice || sliceCount != fgkNSlices))
103 : {
104 0 : HLTWarning("Global Tracking only available if all slices are processed!");
105 : useGlobalTracking = 0;
106 0 : }
107 :
108 : //Process sliceCount slices starting from firstslice, in is pClusterData array, out pOutput array
109 0 : if (fUseGPUTracker)
110 : {
111 0 : 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 0 : 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 0 : fCPUTrackers[firstSlice + iSlice].ReadEvent(&pClusterData[iSlice]);
131 0 : fCPUTrackers[firstSlice + iSlice].SetOutput(&pOutput[iSlice]);
132 0 : fCPUTrackers[firstSlice + iSlice].Reconstruct();
133 0 : fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNLocalTracks = fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNTracks;
134 0 : fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNLocalTrackHits = fCPUTrackers[firstSlice + iSlice].CommonMemory()->fNTrackHits;
135 0 : if (!useGlobalTracking)
136 : {
137 0 : 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 0 : if (!fKeepData)
143 : {
144 0 : fCPUTrackers[firstSlice + iSlice].SetupCommonMemory();
145 0 : }
146 : }
147 : }
148 :
149 0 : if (useGlobalTracking)
150 : {
151 0 : for (int iSlice = 0;iSlice < CAMath::Min(sliceCount, fgkNSlices - firstSlice);iSlice++)
152 : {
153 0 : int sliceLeft = (iSlice + (fgkNSlices / 2 - 1)) % (fgkNSlices / 2);
154 0 : int sliceRight = (iSlice + 1) % (fgkNSlices / 2);
155 0 : if (iSlice >= fgkNSlices / 2)
156 : {
157 0 : sliceLeft += fgkNSlices / 2;
158 0 : sliceRight += fgkNSlices / 2;
159 0 : }
160 0 : fCPUTrackers[iSlice].PerformGlobalTracking(fCPUTrackers[sliceLeft], fCPUTrackers[sliceRight], CAMath::Min(fCPUTrackers[sliceLeft].CommonMemory()->fNTracklets, fCPUTrackers[sliceRight].CommonMemory()->fNTracklets) * 2);
161 : }
162 0 : for (int iSlice = 0;iSlice < CAMath::Min(sliceCount, fgkNSlices - firstSlice);iSlice++)
163 : {
164 0 : 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 0 : if (!fKeepData)
174 : {
175 0 : fCPUTrackers[firstSlice + iSlice].SetupCommonMemory();
176 0 : }
177 : }
178 0 : }
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 0 : if (fGPUDebugLevel >= 6 && fUseGPUTracker)
189 : {
190 0 : fUseGPUTracker = 0;
191 0 : ProcessSlices(firstSlice, sliceCount, pClusterData, pOutput);
192 0 : fUseGPUTracker = 1;
193 0 : }
194 :
195 0 : return(0);
196 0 : }
197 :
198 : unsigned long long int* AliHLTTPCCATrackerFramework::PerfTimer(int GPU, int iSlice, int iTimer)
199 : {
200 : //Performance information for slice trackers
201 0 : return(GPU ? fGPUTracker->PerfTimer(iSlice, iTimer) : fCPUTrackers[iSlice].PerfTimer(iTimer));
202 : }
203 :
204 : int AliHLTTPCCATrackerFramework::InitializeSliceParam(int iSlice, AliHLTTPCCAParam ¶m)
205 : {
206 : //Initialize Tracker Parameters for a slice
207 0 : if (fGPUTrackerAvailable && fGPUTracker->InitializeSliceParam(iSlice, param)) return(1);
208 0 : fCPUTrackers[iSlice].Initialize(param);
209 0 : return(0);
210 0 : }
211 :
212 : #ifdef HLTCA_STANDALONE
213 : #define GPULIBNAME "libAliHLTTPCCAGPUSA"
214 : #else
215 : #define GPULIBNAME "libAliHLTTPCCAGPU"
216 : #endif
217 :
218 0 : AliHLTTPCCATrackerFramework::AliHLTTPCCATrackerFramework(int allowGPU, const char* GPU_Library, int GPUDeviceNum) : fGPULibAvailable(false), fGPUTrackerAvailable(false), fUseGPUTracker(false), fGPUDebugLevel(0), fGPUTracker(NULL), fGPULib(NULL), fOutputControl( NULL ), fKeepData(false), fGlobalTracking(false)
219 0 : {
220 : //Constructor
221 0 : 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 0 : void* hGPULib = dlopen(GPU_Library == NULL ? (GPULIBNAME ".so") : GPU_Library, RTLD_NOW);
226 : #endif
227 0 : if (hGPULib == NULL)
228 : {
229 0 : if (allowGPU)
230 : {
231 : #ifndef R__WIN32
232 0 : HLTImportant("The following error occured during dlopen: %s", dlerror());
233 : #endif
234 0 : HLTError("Error Opening cagpu library for GPU Tracker (%s), will fallback to CPU", GPU_Library == NULL ? "default: " GPULIBNAME : GPU_Library);
235 : }
236 : else
237 : {
238 : HLTDebug("Cagpu library was not found, Tracking on GPU will not be available");
239 : }
240 0 : fGPUTracker = new AliHLTTPCCAGPUTracker;
241 0 : }
242 : else
243 : {
244 : #ifdef R__WIN32
245 : FARPROC createFunc = GetProcAddress(hGPULib, "AliHLTTPCCAGPUTrackerNVCCCreate");
246 : #else
247 0 : void* createFunc = (void*) dlsym(hGPULib, "AliHLTTPCCAGPUTrackerNVCCCreate");
248 : #endif
249 0 : if (createFunc == NULL)
250 : {
251 0 : HLTError("Error Creating GPU Tracker\n");
252 : #ifdef R__WIN32
253 : FreeLibrary(hGPULib);
254 : #else
255 0 : dlclose(hGPULib);
256 : #endif
257 0 : fGPUTracker = new AliHLTTPCCAGPUTracker;
258 0 : }
259 : else
260 : {
261 0 : AliHLTTPCCAGPUTracker* (*tmp)() = (AliHLTTPCCAGPUTracker* (*)()) createFunc;
262 0 : fGPUTracker = tmp();
263 0 : fGPULibAvailable = true;
264 0 : fGPULib = (void*) (size_t) hGPULib;
265 0 : HLTInfo("GPU Tracker library loaded and GPU tracker object created sucessfully (%sactive)", allowGPU ? "" : "in");
266 : }
267 : }
268 :
269 0 : if (allowGPU && fGPULibAvailable)
270 : {
271 0 : fUseGPUTracker = (fGPUTrackerAvailable = (fGPUTracker->InitGPU(-1, GPUDeviceNum) == 0));
272 0 : if(fUseGPUTracker)
273 : {
274 0 : HLTInfo("GPU Tracker Initialized and available in framework");
275 : }
276 : else
277 : {
278 0 : HLTError("GPU Tracker NOT Initialized and NOT available in framework");
279 : }
280 : }
281 0 : }
282 :
283 : AliHLTTPCCATrackerFramework::~AliHLTTPCCATrackerFramework()
284 0 : {
285 : #ifdef R__WIN32
286 : HMODULE hGPULib = (HMODULE) (size_t) fGPULib;
287 : #else
288 0 : void* hGPULib = fGPULib;
289 : #endif
290 0 : if (fGPULib)
291 : {
292 0 : if (fGPUTracker)
293 : {
294 0 : ExitGPU();
295 : #ifdef R__WIN32
296 : FARPROC destroyFunc = GetProcAddress(hGPULib, "AliHLTTPCCAGPUTrackerNVCCDestroy");
297 : #else
298 0 : void* destroyFunc = (void*) dlsym(hGPULib, "AliHLTTPCCAGPUTrackerNVCCDestroy");
299 : #endif
300 0 : if (destroyFunc == NULL)
301 : {
302 0 : HLTError("Error Freeing GPU Tracker\n");
303 : }
304 : else
305 : {
306 0 : void (*tmp)(AliHLTTPCCAGPUTracker*) = (void (*)(AliHLTTPCCAGPUTracker*)) destroyFunc;
307 0 : tmp(fGPUTracker);
308 : }
309 0 : }
310 :
311 : #ifdef R__WIN32
312 : FreeLibrary(hGPULib);
313 : #else
314 0 : dlclose(hGPULib);
315 : #endif
316 : }
317 0 : else if (fGPUTracker)
318 : {
319 0 : delete fGPUTracker;
320 : }
321 0 : fGPULib = NULL;
322 0 : fGPUTracker = NULL;
323 0 : }
|