]>
Commit | Line | Data |
---|---|---|
b22af1bf | 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 | ||
31649d4b | 28 | #ifdef R__WIN32 |
29 | #include <windows.h> | |
30 | #include <winbase.h> | |
31 | #else | |
32 | #include <dlfcn.h> | |
33 | #endif | |
34 | ||
b22af1bf | 35 | #ifdef HLTCA_STANDALONE |
36 | #include <omp.h> | |
37 | #endif | |
38 | ||
31649d4b | 39 | ClassImp( AliHLTTPCCATrackerFramework ) |
40 | ||
b22af1bf | 41 | int AliHLTTPCCATrackerFramework::InitGPU(int sliceCount, int forceDeviceID) |
42 | { | |
43 | //Initialize GPU Tracker and determine if GPU available | |
44 | int retVal; | |
31649d4b | 45 | if (!fGPULibAvailable) |
46 | { | |
47 | HLTError("GPU Library not loaded\n"); | |
48 | return(1); | |
49 | } | |
b22af1bf | 50 | if (fGPUTrackerAvailable && (retVal = ExitGPU())) return(retVal); |
31649d4b | 51 | retVal = fGPUTracker->InitGPU(sliceCount, forceDeviceID); |
b22af1bf | 52 | fUseGPUTracker = fGPUTrackerAvailable = retVal == 0; |
b22af1bf | 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; | |
31649d4b | 62 | return(fGPUTracker->ExitGPU()); |
b22af1bf | 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 | |
31649d4b | 68 | fGPUTracker->SetDebugLevel(Level, GPUOutFile); |
b22af1bf | 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 | ||
d4594e7d | 88 | GPUhd() void AliHLTTPCCATrackerFramework::SetOutputControl( AliHLTTPCCASliceOutput::outputControlStruct* val) |
89 | { | |
444e5682 | 90 | //Set Output Control Pointers |
d4594e7d | 91 | fOutputControl = val; |
31649d4b | 92 | fGPUTracker->SetOutputControl(val); |
d4594e7d | 93 | for (int i = 0;i < fgkNSlices;i++) |
94 | { | |
95 | fCPUTrackers[i].SetOutputControl(val); | |
96 | } | |
97 | } | |
98 | ||
98512261 | 99 | int AliHLTTPCCATrackerFramework::ProcessSlices(int firstSlice, int sliceCount, AliHLTTPCCAClusterData* pClusterData, AliHLTTPCCASliceOutput** pOutput) |
b22af1bf | 100 | { |
e4818148 | 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 | ||
b22af1bf | 108 | //Process sliceCount slices starting from firstslice, in is pClusterData array, out pOutput array |
109 | if (fUseGPUTracker) | |
110 | { | |
31649d4b | 111 | if (fGPUTracker->Reconstruct(pOutput, pClusterData, firstSlice, CAMath::Min(sliceCount, fgkNSlices - firstSlice))) return(1); |
b22af1bf | 112 | } |
113 | else | |
114 | { | |
115 | #ifdef HLTCA_STANDALONE | |
d4594e7d | 116 | if (fOutputControl->fOutputPtr && omp_get_max_threads() > 1) |
117 | { | |
31649d4b | 118 | HLTError("fOutputPtr must not be used with OpenMP\n"); |
d4594e7d | 119 | return(1); |
120 | } | |
e4818148 | 121 | int nLocalTracks = 0, nGlobalTracks = 0, nOutputTracks = 0, nLocalHits = 0, nGlobalHits = 0; |
d4594e7d | 122 | |
b22af1bf | 123 | #pragma omp parallel for |
124 | #endif | |
125 | for (int iSlice = 0;iSlice < CAMath::Min(sliceCount, fgkNSlices - firstSlice);iSlice++) | |
126 | { | |
e4818148 | 127 | #ifdef HLTCA_STANDALONE |
128 | fCPUTrackers[firstSlice + iSlice].StandalonePerfTime(0); | |
129 | #endif | |
b22af1bf | 130 | fCPUTrackers[firstSlice + iSlice].ReadEvent(&pClusterData[iSlice]); |
131 | fCPUTrackers[firstSlice + iSlice].SetOutput(&pOutput[iSlice]); | |
132 | fCPUTrackers[firstSlice + iSlice].Reconstruct(); | |
e4818148 | 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) | |
f0bada7f | 136 | { |
e4818148 | 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 | } | |
f0bada7f | 146 | } |
b22af1bf | 147 | } |
e4818148 | 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 | |
b22af1bf | 186 | } |
187 | ||
188 | if (fGPUDebugLevel >= 6 && fUseGPUTracker) | |
189 | { | |
190 | fUseGPUTracker = 0; | |
191 | ProcessSlices(firstSlice, sliceCount, pClusterData, pOutput); | |
192 | fUseGPUTracker = 1; | |
193 | } | |
194 | ||
b22af1bf | 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 | |
31649d4b | 201 | return(GPU ? fGPUTracker->PerfTimer(iSlice, iTimer) : fCPUTrackers[iSlice].PerfTimer(iTimer)); |
b22af1bf | 202 | } |
203 | ||
204 | int AliHLTTPCCATrackerFramework::InitializeSliceParam(int iSlice, AliHLTTPCCAParam ¶m) | |
205 | { | |
206 | //Initialize Tracker Parameters for a slice | |
31649d4b | 207 | if (fGPUTrackerAvailable && fGPUTracker->InitializeSliceParam(iSlice, param)) return(1); |
b22af1bf | 208 | fCPUTrackers[iSlice].Initialize(param); |
209 | return(0); | |
a59a784e | 210 | } |
31649d4b | 211 | |
f0bada7f | 212 | #ifdef HLTCA_STANDALONE |
213 | #define GPULIBNAME "libAliHLTTPCCAGPUSA" | |
214 | #else | |
31649d4b | 215 | #define GPULIBNAME "libAliHLTTPCCAGPU" |
f0bada7f | 216 | #endif |
31649d4b | 217 | |
10dd8017 | 218 | 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) |
31649d4b | 219 | { |
220 | //Constructor | |
43422963 | 221 | if (GPU_Library && !GPU_Library[0]) GPU_Library = NULL; |
31649d4b | 222 | #ifdef R__WIN32 |
43422963 | 223 | HMODULE hGPULib = LoadLibraryEx(GPU_Library == NULL ? (GPULIBNAME ".dll") : GPU_Library, NULL, NULL); |
31649d4b | 224 | #else |
43422963 | 225 | void* hGPULib = dlopen(GPU_Library == NULL ? (GPULIBNAME ".so") : GPU_Library, RTLD_NOW); |
31649d4b | 226 | #endif |
227 | if (hGPULib == NULL) | |
228 | { | |
31649d4b | 229 | if (allowGPU) |
230 | { | |
7dd6188c | 231 | #ifndef R__WIN32 |
d3821846 | 232 | HLTImportant("The following error occured during dlopen: %s", dlerror()); |
7dd6188c | 233 | #endif |
d3821846 | 234 | HLTError("Error Opening cagpu library for GPU Tracker (%s), will fallback to CPU", GPU_Library == NULL ? "default: " GPULIBNAME : GPU_Library); |
31649d4b | 235 | } |
236 | else | |
237 | { | |
7dd6188c | 238 | HLTDebug("Cagpu library was not found, Tracking on GPU will not be available"); |
31649d4b | 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; | |
1e63725a | 265 | HLTImportant("GPU Tracker library loaded and GPU tracker object created sucessfully (%sactive)", allowGPU ? "" : "in"); |
31649d4b | 266 | } |
267 | } | |
268 | ||
269 | if (allowGPU && fGPULibAvailable) | |
270 | { | |
10dd8017 | 271 | fUseGPUTracker = (fGPUTrackerAvailable = (fGPUTracker->InitGPU(-1, GPUDeviceNum) == 0)); |
75ac9be6 | 272 | if(fUseGPUTracker) |
273 | HLTInfo("GPU Tracker Initialized and available in framework"); | |
274 | else | |
275 | HLTError("GPU Tracker NOT Initialized and NOT available in framework"); | |
31649d4b | 276 | } |
277 | } | |
278 | ||
279 | AliHLTTPCCATrackerFramework::~AliHLTTPCCATrackerFramework() | |
280 | { | |
281 | #ifdef R__WIN32 | |
282 | HMODULE hGPULib = (HMODULE) (size_t) fGPULib; | |
283 | #else | |
284 | void* hGPULib = fGPULib; | |
285 | #endif | |
286 | if (fGPULib) | |
287 | { | |
288 | if (fGPUTracker) | |
289 | { | |
9a3194d4 | 290 | ExitGPU(); |
31649d4b | 291 | #ifdef R__WIN32 |
292 | FARPROC destroyFunc = GetProcAddress(hGPULib, "AliHLTTPCCAGPUTrackerNVCCDestroy"); | |
293 | #else | |
294 | void* destroyFunc = (void*) dlsym(hGPULib, "AliHLTTPCCAGPUTrackerNVCCDestroy"); | |
295 | #endif | |
296 | if (destroyFunc == NULL) | |
297 | { | |
298 | HLTError("Error Freeing GPU Tracker\n"); | |
299 | } | |
300 | else | |
301 | { | |
302 | void (*tmp)(AliHLTTPCCAGPUTracker*) = (void (*)(AliHLTTPCCAGPUTracker*)) destroyFunc; | |
303 | tmp(fGPUTracker); | |
304 | } | |
305 | } | |
306 | ||
307 | #ifdef R__WIN32 | |
308 | FreeLibrary(hGPULib); | |
309 | #else | |
310 | dlclose(hGPULib); | |
311 | #endif | |
312 | } | |
313 | else if (fGPUTracker) | |
314 | { | |
315 | delete fGPUTracker; | |
316 | } | |
317 | fGPULib = NULL; | |
318 | fGPUTracker = NULL; | |
319 | } |