]>
Commit | Line | Data |
---|---|---|
b765ad15 | 1 | // $Id$ |
2 | ||
3 | //************************************************************************** | |
4 | //* This file is property of and copyright by the ALICE HLT Project * | |
5 | //* ALICE Experiment at CERN, All rights reserved. * | |
6 | //* * | |
7 | //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
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 | ||
11010adb | 19 | /// @file AliHLTCompStatCollector.cxx |
20 | /// @author Matthias Richter | |
21 | /// @date | |
22 | /// @brief Collector component for the component statistics information. | |
23 | /// | |
b765ad15 | 24 | |
25 | #include "AliHLTCompStatCollector.h" | |
c7b299f1 | 26 | #include "TFile.h" |
b765ad15 | 27 | #include "TStopwatch.h" |
28 | #include "TH1F.h" | |
29 | #include "TH2F.h" | |
30 | #include "TH2C.h" | |
31 | #include "TTree.h" | |
abb52c8f | 32 | #include "TFolder.h" |
33 | #include "TNamed.h" | |
b765ad15 | 34 | #include "TString.h" |
abb52c8f | 35 | #include <cassert> |
11010adb | 36 | #include <algorithm> |
37 | using std::sort; | |
abb52c8f | 38 | |
39 | #define HLTSTAT_FOLDER_NAME "HLTstat" | |
40 | #define HLTSTAT_FOLDER_DESC "ALICE HLT component statistics" | |
41 | #define HLTSTAT_ENTRY_PARENT_FOLDER_NAME "parents" | |
42 | #define HLTSTAT_ENTRY_PARENT_FOLDER_DESC "parent components" | |
43 | #define HLTSTAT_ENTRY_PROPS_FOLDER_NAME "props" | |
44 | #define HLTSTAT_ENTRY_PROPS_FOLDER_DESC "component properties" | |
45 | #define HLTSTAT_ENTRY_PROPS_IDOBJ_NAME "id" | |
46 | #define HLTSTAT_ENTRY_PROPS_IDOBJ_DESC "numerical id calculated from chain id" | |
b765ad15 | 47 | |
48 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
49 | ClassImp(AliHLTCompStatCollector) | |
50 | ||
51 | AliHLTCompStatCollector::AliHLTCompStatCollector() | |
52 | : | |
53 | AliHLTProcessor(), | |
54 | fpTimer(NULL), | |
abb52c8f | 55 | fpFolder(NULL), |
11010adb | 56 | fInstances(), |
b765ad15 | 57 | fpStatTree(NULL), |
58 | fCycleTime(0), | |
59 | fNofSets(0), | |
11010adb | 60 | fArraySize(0), |
b765ad15 | 61 | fPosition(0), |
62 | fpLevelArray(NULL), | |
63 | fpSpecArray(NULL), | |
64 | fpBlockNoArray(NULL), | |
65 | fpIdArray(NULL), | |
66 | fpTimeArray(NULL), | |
67 | fpCTimeArray(NULL), | |
68 | fpInputBlockCountArray(NULL), | |
69 | fpTotalInputSizeArray(NULL), | |
fce51f62 | 70 | fpNormalizedInputSizeArray(NULL), |
b765ad15 | 71 | fpOutputBlockCountArray(NULL), |
72 | fpTotalOutputSizeArray(NULL) | |
fce51f62 | 73 | , fpInputOutputRatioArray(NULL) |
74 | , fpNormalizedInputOutputRatioArray(NULL) | |
2e3fd14f | 75 | , fpComponentCycleTimeArray(NULL) |
76 | , fpEventTypeArray(NULL) | |
77 | , fpEventCountArray(NULL) | |
63410eb4 | 78 | , fSizeEstimator(1000) |
c7b299f1 | 79 | , fMode(kPublishObjects) |
80 | , fFileName() | |
81 | , fFile(NULL) | |
82 | , fLastTime(time(NULL)) | |
83 | , fPeriod(0) | |
84 | , fEventModulo(0) | |
b765ad15 | 85 | { |
86 | // see header file for class documentation | |
87 | // or | |
88 | // refer to README to build package | |
89 | // or | |
90 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
91 | } | |
92 | ||
93 | AliHLTCompStatCollector::~AliHLTCompStatCollector() | |
94 | { | |
95 | // see header file for class documentation | |
96 | ClearAll(); | |
97 | } | |
98 | ||
99 | void AliHLTCompStatCollector::GetInputDataTypes( vector<AliHLTComponentDataType>& list) | |
100 | { | |
101 | // see header file for class documentation | |
102 | list.push_back(kAliHLTDataTypeComponentStatistics); | |
103 | } | |
104 | ||
105 | AliHLTComponentDataType AliHLTCompStatCollector::GetOutputDataType() | |
106 | { | |
107 | // see header file for class documentation | |
108 | return kAliHLTMultipleDataType; | |
109 | } | |
110 | ||
111 | int AliHLTCompStatCollector::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) | |
112 | { | |
113 | // see header file for class documentation | |
114 | tgtList.clear(); | |
115 | tgtList.push_back(kAliHLTDataTypeHistogram); | |
116 | tgtList.push_back(kAliHLTDataTypeTTree); | |
117 | return tgtList.size(); | |
118 | } | |
119 | ||
120 | void AliHLTCompStatCollector::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) | |
121 | { | |
122 | // see header file for class documentation | |
63410eb4 | 123 | constBase=fSizeEstimator; |
b765ad15 | 124 | inputMultiplier=100.0; |
125 | } | |
126 | ||
127 | int AliHLTCompStatCollector::DoInit( int argc, const char** argv ) | |
128 | { | |
129 | // see header file for class documentation | |
130 | int iResult=0; | |
131 | TString argument=""; | |
132 | int bMissingParam=0; | |
133 | for (int i=0; i<argc && iResult>=0; i++) { | |
134 | argument=argv[i]; | |
135 | if (argument.IsNull()) continue; | |
136 | ||
c7b299f1 | 137 | // -file |
138 | if (argument.CompareTo("-file")==0) { | |
b765ad15 | 139 | if ((bMissingParam=(++i>=argc))) break; |
c7b299f1 | 140 | fFileName=argv[i]; |
141 | fMode|=kSaveObjects; | |
142 | ||
143 | // -modulo | |
144 | } else if (argument.CompareTo("-modulo")==0) { | |
145 | if ((bMissingParam=(++i>=argc))) break; | |
146 | TString param=argv[i]; | |
b765ad15 | 147 | if (param.IsDigit()) { |
c7b299f1 | 148 | fEventModulo=param.Atoi(); |
b765ad15 | 149 | } else { |
c7b299f1 | 150 | HLTError("expecting number as parameter for option %s", argument.Data()); |
b765ad15 | 151 | iResult=-EINVAL; |
152 | } | |
153 | ||
c7b299f1 | 154 | // -period |
155 | } else if (argument.CompareTo("-period")==0) { | |
156 | if ((bMissingParam=(++i>=argc))) break; | |
157 | TString param=argv[i]; | |
158 | if (param.IsDigit()) { | |
159 | fPeriod=param.Atoi(); | |
160 | } else { | |
161 | HLTError("expecting number as parameter for option %s", argument.Data()); | |
162 | iResult=-EINVAL; | |
163 | } | |
164 | ||
165 | // -publish | |
166 | } else if (argument.CompareTo("-publish")==0) { | |
167 | if ((bMissingParam=(++i>=argc))) break; | |
168 | TString param=argv[i]; | |
169 | if (param.IsDigit()) { | |
170 | if (param.Atoi()==1) fMode|=kPublishObjects; | |
171 | else if (param.Atoi()==0) fMode&=~kPublishObjects; | |
172 | else { | |
173 | HLTError("expecting 0 or 1 as parameter for option %s", argument.Data()); | |
174 | iResult=-EINVAL; | |
175 | } | |
176 | } else { | |
177 | HLTError("expecting number as parameter for option %s", argument.Data()); | |
178 | iResult=-EINVAL; | |
179 | } | |
fce51f62 | 180 | |
181 | // -arraysize | |
182 | } else if (argument.CompareTo("-arraysize")==0) { | |
183 | if ((bMissingParam=(++i>=argc))) break; | |
184 | TString param=argv[i]; | |
185 | if (param.IsDigit()) { | |
11010adb | 186 | //fArraySize=param.Atoi(); |
187 | HLTWarning("argument -arraysize is deprecated, array size adjusted dynamically"); | |
fce51f62 | 188 | } else { |
189 | HLTError("expecting number as parameter for option %s", argument.Data()); | |
190 | iResult=-EINVAL; | |
191 | } | |
192 | ||
b765ad15 | 193 | } else { |
c7b299f1 | 194 | HLTError("unknown argument %s", argument.Data()); |
b765ad15 | 195 | iResult=-EINVAL; |
196 | } | |
197 | } | |
198 | if (bMissingParam) { | |
199 | HLTError("missing parameter for argument %s", argument.Data()); | |
200 | iResult=-EINVAL; | |
201 | } | |
202 | ||
c7b299f1 | 203 | if (!fFileName.empty()) { |
204 | fFile=new TFile(fFileName.c_str(), "RECREATE"); | |
205 | } | |
b765ad15 | 206 | return iResult; |
207 | } | |
208 | ||
209 | int AliHLTCompStatCollector::DoDeinit( ) | |
210 | { | |
211 | // see header file for class documentation | |
212 | ClearAll(); | |
213 | ||
c7b299f1 | 214 | if (fFile) { |
215 | fFile->Close(); | |
216 | delete fFile; | |
217 | fFile=NULL; | |
218 | } | |
b765ad15 | 219 | return 0; |
220 | } | |
221 | ||
222 | int AliHLTCompStatCollector::DoEvent( const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/) | |
223 | { | |
224 | // see header file for class documentation | |
225 | int iResult=0; | |
226 | ||
abb52c8f | 227 | AliHLTUInt32_t eventType=gkAliEventTypeUnknown; |
228 | IsDataEvent(&eventType); | |
229 | ||
b765ad15 | 230 | ResetFillingVariables(); |
231 | if (fpTimer) { | |
232 | fCycleTime=fpTimer->RealTime()*1000000; | |
233 | } | |
234 | ||
11010adb | 235 | // only if the map of instances is empty it can be initialized from the |
236 | // component table entries | |
237 | // the logical check fo eventType==gkAliEventTypeStartOfRun does not work | |
238 | // for simulated data where the blocks of the SOR are stored inside the | |
239 | // first event | |
240 | bool bMapInitialization=fInstances.empty(); | |
241 | vector<AliHLTCompStatCollector::AliHLTCompStatInstance> sortedInstances; | |
242 | ||
abb52c8f | 243 | bool bEmbeddedTree=false; |
244 | bool bFolderCreated=false; | |
9d5f00ad | 245 | if ((bFolderCreated=(fpFolder==NULL))) { |
abb52c8f | 246 | fpFolder=new TFolder(HLTSTAT_FOLDER_NAME, HLTSTAT_FOLDER_DESC); |
247 | if (bEmbeddedTree) fpFolder->Add(fpStatTree); | |
248 | } | |
249 | if (!fpFolder) return -ENOMEM; | |
250 | vector<TFolder*> newFolders; | |
251 | ||
252 | for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeComponentTable); | |
253 | pBlock && iResult>=0; | |
254 | pBlock=GetNextInputBlock()) { | |
255 | string chainId, compId, compArgs; | |
256 | vector<AliHLTUInt32_t> parents; | |
11010adb | 257 | int level=0; |
abb52c8f | 258 | iResult=ExtractComponentTableEntry((const AliHLTUInt8_t*)pBlock->fPtr, pBlock->fSize, |
259 | chainId, compId, compArgs, | |
11010adb | 260 | parents, level); |
abb52c8f | 261 | if (iResult>0) { |
262 | HLTDebug("%s(%s) 0x%08x", chainId.c_str(), compId.c_str(), pBlock->fSpecification); | |
11010adb | 263 | if (bMapInitialization) { |
264 | map<AliHLTUInt32_t, AliHLTCompStatInstance>::const_iterator element=fInstances.find(pBlock->fSpecification); | |
265 | AliHLTCompStatInstance newInstance(pBlock->fSpecification, chainId, compId, compArgs, parents, level); | |
266 | if (element==fInstances.end()) { | |
267 | // new instance | |
268 | fInstances[pBlock->fSpecification]=newInstance; | |
269 | sortedInstances.push_back(newInstance); | |
270 | } else { | |
271 | // check existing instance | |
272 | if (element->second!=newInstance) { | |
273 | HLTWarning("component table entries have identical CRC ids but different content\n in list: %s\n skipping: %s", | |
274 | element->second.Description().c_str(), newInstance.Description().c_str()); | |
275 | } | |
276 | } | |
277 | } | |
278 | ||
abb52c8f | 279 | TObject* pObj=NULL; |
280 | TFolder* pEntry=NULL; | |
281 | if ((pObj=fpFolder->FindObjectAny(chainId.c_str()))!=NULL && | |
282 | (pEntry=dynamic_cast<TFolder*>(pObj))!=NULL ) { | |
283 | ||
284 | } else if (pObj) { | |
285 | HLTError("entry %s exists in folder, but is not a sub-folder", chainId.c_str()); | |
286 | } else if (chainId.size()>0) { | |
287 | pEntry=new TFolder(chainId.c_str(), chainId.c_str()); | |
288 | if (pEntry) { | |
289 | pEntry->SetOwner(); | |
290 | TFolder* pProps=pEntry->AddFolder(HLTSTAT_ENTRY_PROPS_FOLDER_NAME, HLTSTAT_ENTRY_PROPS_FOLDER_DESC); | |
291 | if (pProps) { | |
292 | pProps->Add(new TObjString(compId.c_str())); | |
293 | if (!compArgs.empty()) | |
294 | pProps->Add(new TObjString(compArgs.c_str())); | |
295 | TNamed* pCRC=new TNamed(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME, HLTSTAT_ENTRY_PROPS_IDOBJ_DESC); | |
296 | if (pCRC) { | |
297 | pCRC->SetUniqueID(pBlock->fSpecification); | |
298 | pProps->Add(pCRC); | |
299 | } | |
300 | } | |
301 | TFolder* pParents=pEntry->AddFolder(HLTSTAT_ENTRY_PARENT_FOLDER_NAME, HLTSTAT_ENTRY_PARENT_FOLDER_DESC); | |
302 | if (pParents) { | |
303 | for (vector<AliHLTUInt32_t>::iterator parent=parents.begin(); | |
304 | parent!=parents.end(); parent++) { | |
305 | TString name; name.Form("0x%08x", *parent); | |
306 | pParents->Add(new TObjString(name)); | |
307 | } | |
308 | } | |
309 | if (parents.size()==0) { | |
310 | newFolders.push_back(pEntry); | |
311 | } else { | |
312 | vector<TFolder*>::iterator iter=newFolders.begin(); | |
313 | vector<AliHLTUInt32_t>::iterator parent=parents.begin(); | |
314 | while (iter!=newFolders.end() && parent!=parents.end()) { | |
315 | TObject* idobj=(*iter)->FindObjectAny(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME); | |
316 | AliHLTUInt32_t crcid=0; | |
317 | if (idobj) crcid=idobj->GetUniqueID(); | |
318 | HLTDebug("check: %s 0x%08x", (*iter)->GetName(), crcid); | |
319 | if (idobj && crcid==*parent) break; | |
320 | if ((++parent!=parents.end())) continue; | |
321 | parent=parents.begin(); | |
322 | iter++; | |
323 | } | |
324 | newFolders.insert(iter,pEntry); | |
325 | } | |
326 | } | |
327 | } else { | |
328 | HLTError("missing chain id for table entry 0x%08x (%p %d), skipping ...", pBlock->fSpecification, pBlock->fPtr, pBlock->fSize); | |
329 | } | |
330 | } else if (iResult!=0) { | |
331 | HLTError("extraction of table entry 0x%08x (%p %d) failed with %d", pBlock->fSpecification, pBlock->fPtr, pBlock->fSize, iResult); | |
332 | } | |
333 | iResult=0; | |
334 | } | |
335 | ||
11010adb | 336 | if (bMapInitialization) { |
337 | // assign tags to all instances in the map | |
338 | int level=-1; | |
339 | int tag=-1; | |
340 | TString componentId; | |
341 | TObjArray* taglist=NULL; | |
342 | sort(sortedInstances.begin(), sortedInstances.end(), AliHLTCompStatInstance::SortByLevelAndComponentId); | |
343 | for (vector< AliHLTCompStatInstance>::const_iterator element=sortedInstances.begin(); | |
344 | element!=sortedInstances.end(); | |
345 | element++) { | |
346 | if (level!=element->GetLevel() || | |
347 | componentId.CompareTo(element->GetComponentId().c_str())!=0) { | |
348 | tag++; | |
349 | level=element->GetLevel(); | |
350 | componentId=element->GetComponentId().c_str(); | |
351 | if (fpFolder) { | |
352 | if (!taglist) { | |
353 | taglist=new TObjArray; | |
354 | taglist->SetName("CompStatMap"); | |
355 | fpFolder->Add(taglist); | |
356 | } | |
357 | if (taglist) { | |
358 | TString entry; | |
359 | entry.Form("%02d ", tag); entry+=componentId; | |
360 | taglist->Add(new TObjString(entry)); | |
361 | } | |
362 | } | |
363 | } | |
364 | fInstances[element->GetCRCId()].SetTag(tag); | |
365 | } | |
366 | ||
367 | if (fpStatTree==NULL && !fInstances.empty()) { | |
368 | iResult=AllocateStatTree(fInstances.size()); | |
369 | } | |
370 | } | |
371 | ||
abb52c8f | 372 | if (newFolders.size()>0) { |
373 | vector<TFolder*> revert; | |
374 | vector<TFolder*>::iterator iter=newFolders.begin(); | |
375 | while (iter!=newFolders.end()) { | |
376 | revert.insert(revert.begin(), *iter); | |
377 | HLTDebug("%s", (*iter)->GetName()); | |
378 | iter++; | |
379 | } | |
380 | newFolders.empty(); | |
381 | newFolders.assign(revert.begin(), revert.end()); | |
382 | ||
383 | vector<TFolder*>::iterator publisher=newFolders.begin(); | |
384 | while (publisher!=newFolders.end()) { | |
385 | bool bRemove=false; | |
386 | HLTDebug("checking %s for parents", (*publisher)->GetName()); | |
387 | TFolder* propsFolder=dynamic_cast<TFolder*>((*publisher)->FindObject(HLTSTAT_ENTRY_PROPS_FOLDER_NAME)); | |
388 | assert(propsFolder); | |
389 | TObject* idobj=NULL; | |
390 | if (propsFolder) idobj=propsFolder->FindObject(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME); | |
391 | assert(idobj); | |
abb52c8f | 392 | if (idobj) { |
0b8c418e | 393 | AliHLTUInt32_t crcid=idobj->GetUniqueID(); |
394 | TString idstr; idstr.Form("0x%08x", crcid); | |
abb52c8f | 395 | for (vector<TFolder*>::iterator consumer=publisher+1; |
396 | consumer!=newFolders.end(); consumer++) { | |
397 | HLTDebug(" checking %s", (*consumer)->GetName()); | |
398 | TFolder* parentFolder=dynamic_cast<TFolder*>((*consumer)->FindObject(HLTSTAT_ENTRY_PARENT_FOLDER_NAME)); | |
399 | assert(parentFolder); | |
400 | if (parentFolder) { | |
74dbd6a4 | 401 | #ifdef __DEBUG |
abb52c8f | 402 | TIter entries(parentFolder->GetListOfFolders()); |
403 | while (TObject* entry=entries.Next()) | |
460c4045 | 404 | if (entry) { |
460c4045 | 405 | HLTDebug(" searching %s in %s: %s", idstr.Data(), (*consumer)->GetName(), entry->GetName()); |
406 | } | |
e56b78b4 | 407 | #endif |
abb52c8f | 408 | TObject* parent=parentFolder->FindObjectAny(idstr); |
409 | if (parent) { | |
410 | parentFolder->Add(*publisher); | |
411 | parentFolder->Remove(parent); | |
412 | bRemove=true; | |
413 | } | |
414 | } | |
415 | } | |
416 | } | |
417 | if (bRemove) publisher=newFolders.erase(publisher); | |
418 | else publisher++; | |
419 | } | |
420 | ||
421 | for (publisher=newFolders.begin(); | |
422 | publisher!=newFolders.end(); publisher++) { | |
423 | RemoveRecurrence(*publisher); | |
424 | fpFolder->Add(*publisher); | |
425 | } | |
426 | } | |
427 | ||
b765ad15 | 428 | int blockNo=0; |
429 | for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeComponentStatistics); | |
430 | pBlock && iResult>=0; | |
431 | pBlock=GetNextInputBlock(), blockNo++) { | |
432 | unsigned int current=fPosition; | |
2e3fd14f | 433 | iResult=FillVariablesSorted(pBlock->fPtr, pBlock->fSize, eventType); |
b765ad15 | 434 | for (; current<fPosition; current++) { |
435 | fpSpecArray[current]=pBlock->fSpecification; | |
436 | fpBlockNoArray[current]=blockNo; | |
437 | } | |
587c9cf9 | 438 | // indicate availability of component statistic block |
439 | iResult=1; | |
b765ad15 | 440 | } |
441 | ||
4e5a2a53 | 442 | int totalOutputSize=0; |
2e3fd14f | 443 | if (iResult>0 && eventType) { |
b765ad15 | 444 | fNofSets=fPosition; |
445 | fpStatTree->Fill(); | |
b765ad15 | 446 | |
587c9cf9 | 447 | // init the timer for the next cycle |
448 | if (!fpTimer) fpTimer=new TStopwatch; | |
449 | if (fpTimer) { | |
450 | fpTimer->Reset(); | |
451 | fpTimer->Start(); | |
452 | } | |
b765ad15 | 453 | } |
454 | ||
c7b299f1 | 455 | if (eventType==gkAliEventTypeEndOfRun || |
456 | (iResult>=0 && CheckPeriod())) { | |
457 | ||
458 | // publish objects to component output | |
459 | if ((fMode&kPublishObjects)!=0) { | |
460 | if (!bEmbeddedTree) { | |
461 | iResult=PushBack(fpStatTree, kAliHLTDataTypeTTree|kAliHLTDataOriginOut); | |
462 | totalOutputSize+=GetLastObjectSize(); | |
463 | } | |
464 | iResult=PushBack(fpFolder, kAliHLTDataTypeTObject|kAliHLTDataOriginOut); | |
465 | totalOutputSize+=GetLastObjectSize(); | |
466 | } | |
467 | ||
468 | // save objects to file | |
469 | if ((fMode&kSaveObjects)!=0 && fFile!=NULL) { | |
470 | HLTDebug("saving objects to file %s", fFileName.c_str()); | |
471 | fFile->cd(); | |
472 | if (!bEmbeddedTree) { | |
473 | fpStatTree->Write("", TObject::kOverwrite); | |
474 | } | |
475 | fpFolder->Write("", TObject::kOverwrite); | |
476 | } | |
4e5a2a53 | 477 | } |
c7b299f1 | 478 | |
4e5a2a53 | 479 | if (iResult==-ENOSPC) { |
480 | fSizeEstimator+=totalOutputSize; | |
abb52c8f | 481 | } |
482 | ||
483 | if (iResult>0) iResult=0; | |
b765ad15 | 484 | return iResult; |
485 | } | |
486 | ||
487 | void AliHLTCompStatCollector::ResetFillingVariables() | |
488 | { | |
489 | // see header file for class documentation | |
11010adb | 490 | |
491 | for (map<AliHLTUInt32_t, AliHLTCompStatInstance>::iterator element=fInstances.begin(); | |
492 | element!=fInstances.end(); | |
493 | element++) { | |
494 | element->second.ResetProcessed(); | |
495 | } | |
496 | ||
b765ad15 | 497 | fCycleTime=0; |
498 | fNofSets=0; | |
499 | fPosition=0; | |
11010adb | 500 | if (fArraySize==0) return; |
b765ad15 | 501 | memset(fpLevelArray, 0, sizeof(UInt_t)*fArraySize); |
502 | memset(fpSpecArray, 0, sizeof(UInt_t)*fArraySize); | |
503 | memset(fpBlockNoArray, 0, sizeof(UInt_t)*fArraySize); | |
504 | memset(fpIdArray, 0, sizeof(UInt_t)*fArraySize); | |
505 | memset(fpTimeArray, 0, sizeof(UInt_t)*fArraySize); | |
506 | memset(fpCTimeArray, 0, sizeof(UInt_t)*fArraySize); | |
507 | memset(fpInputBlockCountArray, 0, sizeof(UInt_t)*fArraySize); | |
508 | memset(fpTotalInputSizeArray, 0, sizeof(UInt_t)*fArraySize); | |
fce51f62 | 509 | memset(fpNormalizedInputSizeArray, 0, sizeof(UInt_t)*fArraySize); |
b765ad15 | 510 | memset(fpOutputBlockCountArray, 0, sizeof(UInt_t)*fArraySize); |
511 | memset(fpTotalOutputSizeArray, 0, sizeof(UInt_t)*fArraySize); | |
fce51f62 | 512 | memset(fpInputOutputRatioArray, 0, sizeof(UInt_t)*fArraySize); |
513 | memset(fpNormalizedInputOutputRatioArray, 0, sizeof(UInt_t)*fArraySize); | |
2e3fd14f | 514 | memset(fpComponentCycleTimeArray, 0, sizeof(UInt_t)*fArraySize); |
515 | memset(fpEventTypeArray, 0, sizeof(UInt_t)*fArraySize); | |
516 | memset(fpEventCountArray, 0, sizeof(UInt_t)*fArraySize); | |
b765ad15 | 517 | } |
518 | ||
2e3fd14f | 519 | int AliHLTCompStatCollector::FillVariablesSorted(void* ptr, int size, AliHLTUInt32_t eventType) |
b765ad15 | 520 | { |
521 | // see header file for class documentation | |
522 | int iResult=0; | |
523 | if (size%sizeof(AliHLTComponentStatistics)) { | |
2e3fd14f | 524 | // older or invalid structure |
b765ad15 | 525 | HLTError("data block is not aligned to the size of the AliHLTComponentStatistics struct"); |
526 | return -EINVAL; | |
527 | } | |
2e3fd14f | 528 | |
b765ad15 | 529 | AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(ptr); |
530 | UInt_t nofStats=size/sizeof(AliHLTComponentStatistics); | |
531 | vector<int> indexList; | |
532 | UInt_t i=0; | |
533 | for (i=0; i<nofStats; i++) { | |
534 | vector<int>::iterator element=indexList.begin(); | |
535 | for (; element!=indexList.end(); element++) { | |
536 | if (pStat[i].fLevel>pStat[*element].fLevel) { | |
537 | break; | |
538 | } | |
539 | } | |
540 | indexList.insert(element, i); | |
541 | } | |
542 | ||
543 | i=fPosition; | |
544 | for (vector<int>::iterator element=indexList.begin(); | |
545 | element!=indexList.end(); | |
11010adb | 546 | element++) { |
547 | map<AliHLTUInt32_t, AliHLTCompStatInstance>::iterator instance=fInstances.find(pStat[*element].fId); | |
548 | if (i<fArraySize && instance!=fInstances.end()) { | |
549 | if (instance->second.IsProcessed()) { | |
550 | //HLTWarning("already processed instance %s, skip", instance->second.Description().c_str()); | |
551 | continue; | |
552 | } | |
553 | instance->second.MarkProcessed(); | |
554 | if ((int)pStat[*element].fLevel!=instance->second.GetLevel()) { | |
555 | // TODO: there is currently a mismatch of the level set in the statistics entry and | |
556 | // the one in the component table entries. However this does not matter for | |
557 | // archiving because the CRC id is related to a tag/level | |
558 | //HLTWarning("level does not match for instance %s, expected %d", instance->second.Description().c_str(), pStat[*element].fLevel); | |
559 | } | |
560 | fpLevelArray[i]=instance->second.GetTag(); | |
b765ad15 | 561 | fpIdArray[i]=pStat[*element].fId; |
562 | fpTimeArray[i]=pStat[*element].fTime; | |
563 | fpCTimeArray[i]=pStat[*element].fCTime; | |
564 | fpInputBlockCountArray[i]=pStat[*element].fInputBlockCount; | |
565 | fpTotalInputSizeArray[i]=pStat[*element].fTotalInputSize; | |
fce51f62 | 566 | fpNormalizedInputSizeArray[i]=pStat[*element].fTotalInputSize; |
567 | if (pStat[*element].fInputBlockCount>0) | |
568 | fpNormalizedInputSizeArray[i]/=pStat[*element].fInputBlockCount; | |
b765ad15 | 569 | fpOutputBlockCountArray[i]=pStat[*element].fOutputBlockCount; |
570 | fpTotalOutputSizeArray[i]=pStat[*element].fTotalOutputSize; | |
fce51f62 | 571 | if (pStat[*element].fTotalOutputSize>0) |
572 | fpInputOutputRatioArray[i]=pStat[*element].fTotalInputSize/pStat[*element].fTotalOutputSize; | |
573 | if (pStat[*element].fInputBlockCount>0) | |
574 | fpNormalizedInputOutputRatioArray[i]=fpInputOutputRatioArray[i]*pStat[*element].fOutputBlockCount/pStat[*element].fInputBlockCount; | |
2e3fd14f | 575 | fpComponentCycleTimeArray[i]=pStat[*element].fComponentCycleTime; |
576 | fpEventTypeArray[i]=eventType; | |
577 | fpEventCountArray[i]=GetEventCount(); | |
11010adb | 578 | i++; |
579 | } else if (instance==fInstances.end()) { | |
580 | HLTWarning("can not find instance of CRC id 0x%08x", pStat[*element].fId); | |
b765ad15 | 581 | } |
582 | } | |
583 | ||
11010adb | 584 | if (i>fArraySize) { |
585 | HLTWarning("too little space in branch variables to fill %d statistics blocks, total available %d, current position %d", i, fArraySize, fPosition); | |
b765ad15 | 586 | fPosition=fArraySize; |
587 | } else { | |
588 | fPosition=i; | |
589 | } | |
590 | ||
591 | return iResult; | |
592 | } | |
593 | ||
11010adb | 594 | int AliHLTCompStatCollector::AllocateStatTree(AliHLTUInt32_t size) |
595 | { | |
596 | // allocate the statistics tree and the branch arrays | |
597 | if (fArraySize>0) { | |
598 | ClearStatTree(); | |
599 | } | |
600 | fArraySize=size; | |
601 | if (fArraySize==0) return 0; | |
602 | ||
603 | fpLevelArray=new UInt_t[fArraySize]; | |
604 | fpSpecArray=new UInt_t[fArraySize]; | |
605 | fpBlockNoArray=new UInt_t[fArraySize]; | |
606 | fpIdArray=new UInt_t[fArraySize]; | |
607 | fpTimeArray=new UInt_t[fArraySize]; | |
608 | fpCTimeArray=new UInt_t[fArraySize]; | |
609 | fpInputBlockCountArray=new UInt_t[fArraySize]; | |
610 | fpTotalInputSizeArray=new UInt_t[fArraySize]; | |
611 | fpNormalizedInputSizeArray=new UInt_t[fArraySize]; | |
612 | fpOutputBlockCountArray=new UInt_t[fArraySize]; | |
613 | fpTotalOutputSizeArray=new UInt_t[fArraySize]; | |
614 | fpInputOutputRatioArray=new UInt_t[fArraySize]; | |
615 | fpNormalizedInputOutputRatioArray=new UInt_t[fArraySize]; | |
616 | fpComponentCycleTimeArray=new UInt_t[fArraySize]; | |
617 | fpEventTypeArray=new UInt_t[fArraySize]; | |
618 | fpEventCountArray=new UInt_t[fArraySize]; | |
619 | ||
620 | fpStatTree=new TTree("CompStat", "HLT component statistics"); | |
621 | if (fpStatTree) { | |
622 | fpStatTree->SetDirectory(0); | |
623 | fpStatTree->Branch("cycleTime", &fCycleTime, "cycleTime/F"); | |
624 | fpStatTree->Branch("nofSets", &fNofSets, "nofSets/I"); | |
625 | fpStatTree->Branch("Level", fpLevelArray, "Level[nofSets]/i"); | |
626 | fpStatTree->Branch("Specification", fpSpecArray, "Specification[nofSets]/i"); | |
627 | fpStatTree->Branch("BlockNo", fpBlockNoArray, "BlockNo[nofSets]/i"); | |
628 | fpStatTree->Branch("Id", fpIdArray, "Id[nofSets]/i"); | |
629 | fpStatTree->Branch("Time", fpTimeArray, "Time[nofSets]/i"); | |
630 | fpStatTree->Branch("CTime", fpCTimeArray, "CTime[nofSets]/i"); | |
631 | fpStatTree->Branch("InputBlockCount", fpInputBlockCountArray, "InputBlockCount[nofSets]/i"); | |
632 | fpStatTree->Branch("TotalInputSize", fpTotalInputSizeArray, "TotalInputSize[nofSets]/i"); | |
633 | fpStatTree->Branch("NormalizedInputSize", fpNormalizedInputSizeArray, "NormalizedInputSize[nofSets]/i"); | |
634 | fpStatTree->Branch("OutputBlockCount", fpOutputBlockCountArray, "OutputBlockCount[nofSets]/i"); | |
635 | fpStatTree->Branch("TotalOutputSize", fpTotalOutputSizeArray, "TotalOutputSize[nofSets]/i"); | |
636 | fpStatTree->Branch("InputOutputRatio", fpInputOutputRatioArray, "InputOutputRatio[nofSets]/i"); | |
637 | fpStatTree->Branch("NormalizedInputOutputRatio", fpNormalizedInputOutputRatioArray, "NormalizedInputOutputRatio[nofSets]/i"); | |
638 | fpStatTree->Branch("ComponentCycleTime",fpComponentCycleTimeArray, "ComponentCycleTime[nofSets]/i"); | |
639 | fpStatTree->Branch("EventType",fpEventTypeArray, "EventType[nofSets]/i"); | |
640 | fpStatTree->Branch("EventCount",fpEventCountArray, "EventCount[nofSets]/i"); | |
641 | } | |
642 | ||
643 | return 0; | |
644 | } | |
645 | ||
b765ad15 | 646 | void AliHLTCompStatCollector::ClearAll() |
647 | { | |
abb52c8f | 648 | // see header file for class documentation |
b765ad15 | 649 | if (fpTimer) delete fpTimer; fpTimer=NULL; |
abb52c8f | 650 | if (fpFolder) delete fpFolder; fpFolder=NULL; |
11010adb | 651 | ClearStatTree(); |
652 | } | |
653 | ||
654 | void AliHLTCompStatCollector::ClearStatTree() | |
655 | { | |
656 | // clear the statistics tree and the branch arrays | |
b765ad15 | 657 | if (fpStatTree) delete fpStatTree; fpStatTree=NULL; |
658 | if (fpLevelArray) delete fpLevelArray; fpLevelArray=NULL; | |
659 | if (fpSpecArray) delete fpSpecArray; fpSpecArray=NULL; | |
660 | if (fpBlockNoArray) delete fpBlockNoArray; fpBlockNoArray=NULL; | |
661 | if (fpIdArray) delete fpIdArray; fpIdArray=NULL; | |
662 | if (fpTimeArray) delete fpTimeArray; fpTimeArray=NULL; | |
663 | if (fpCTimeArray) delete fpCTimeArray; fpCTimeArray=NULL; | |
664 | if (fpInputBlockCountArray) delete fpInputBlockCountArray; fpInputBlockCountArray=NULL; | |
665 | if (fpTotalInputSizeArray) delete fpTotalInputSizeArray; fpTotalInputSizeArray=NULL; | |
fce51f62 | 666 | if (fpNormalizedInputSizeArray) delete fpNormalizedInputSizeArray; fpNormalizedInputSizeArray=NULL; |
b765ad15 | 667 | if (fpOutputBlockCountArray) delete fpOutputBlockCountArray; fpOutputBlockCountArray=NULL; |
668 | if (fpTotalOutputSizeArray) delete fpTotalOutputSizeArray; fpTotalOutputSizeArray=NULL; | |
fce51f62 | 669 | if (fpInputOutputRatioArray) delete fpInputOutputRatioArray; fpInputOutputRatioArray=NULL; |
670 | if (fpNormalizedInputOutputRatioArray) delete fpNormalizedInputOutputRatioArray; fpNormalizedInputOutputRatioArray=NULL; | |
2e3fd14f | 671 | if (fpComponentCycleTimeArray) delete fpComponentCycleTimeArray; fpComponentCycleTimeArray=NULL; |
672 | if (fpEventTypeArray) delete fpEventTypeArray; fpEventTypeArray=NULL; | |
673 | if (fpEventCountArray) delete fpEventCountArray; fpEventCountArray=NULL; | |
11010adb | 674 | fArraySize=0; |
b765ad15 | 675 | } |
abb52c8f | 676 | |
677 | int AliHLTCompStatCollector::RemoveRecurrence(TFolder* pRoot) const | |
678 | { | |
679 | // see header file for class documentation | |
680 | int iResult=0; | |
681 | if (!pRoot) return -EINVAL; | |
682 | TFolder* parentFolder=dynamic_cast<TFolder*>(pRoot->FindObject(HLTSTAT_ENTRY_PARENT_FOLDER_NAME)); | |
683 | assert(parentFolder); | |
684 | vector<TFolder*> listRemove; | |
685 | if (parentFolder) { | |
686 | TIter entries(parentFolder->GetListOfFolders()); | |
687 | TFolder* entry=NULL; | |
688 | TObject* obj=NULL; | |
689 | while ((obj=entries.Next())!=NULL && (entry=dynamic_cast<TFolder*>(obj))!=NULL) { | |
690 | TString name=entry->GetName(); | |
691 | HLTDebug("checking %s for recurrence", name.Data()); | |
692 | TIter tokens(parentFolder->GetListOfFolders()); | |
693 | TFolder* token=NULL; | |
694 | while ((obj=tokens.Next())!=NULL && (token=dynamic_cast<TFolder*>(obj))!=NULL) { | |
695 | if (name.CompareTo(token->GetName())==0) continue; | |
0b8c418e | 696 | if (token->FindObjectAny(name)!=NULL) { |
abb52c8f | 697 | listRemove.push_back(entry); |
698 | HLTDebug("found recurrence in %s", token->GetName()); | |
699 | break; | |
700 | } else { | |
701 | HLTDebug("no recurrence found in %s", token->GetName()); | |
702 | } | |
703 | } | |
704 | RemoveRecurrence(entry); | |
705 | } | |
706 | for (vector<TFolder*>::iterator removeElement=listRemove.begin(); | |
707 | removeElement!=listRemove.end(); removeElement++) { | |
708 | parentFolder->Remove(*removeElement); | |
709 | } | |
710 | } | |
711 | ||
712 | return iResult; | |
713 | } | |
c7b299f1 | 714 | |
715 | bool AliHLTCompStatCollector::CheckPeriod(bool bUpdate) | |
716 | { | |
717 | // see header file for class documentation | |
718 | bool result=true; | |
719 | if (fEventModulo>0) { | |
720 | if ((result=((GetEventCount()+1)%fEventModulo)==0)) { | |
721 | return true; | |
722 | } | |
723 | } | |
724 | if (fPeriod>0) { | |
725 | if ((result=((difftime(time(NULL), fLastTime)>(double)fPeriod))) && | |
726 | bUpdate) { | |
727 | fLastTime=time(NULL); | |
728 | } | |
729 | } | |
730 | return result; | |
731 | } | |
11010adb | 732 | |
733 | void AliHLTCompStatCollector::Print(const char* option) const | |
734 | { | |
735 | // print information | |
736 | if (strcmp(option, "instances")==0) { | |
737 | vector<AliHLTCompStatInstance> sortedInstances; | |
738 | for (map<AliHLTUInt32_t, AliHLTCompStatInstance>::const_iterator element=fInstances.begin(); | |
739 | element!=fInstances.end(); | |
740 | element++) { | |
741 | sortedInstances.push_back(element->second); | |
742 | } | |
743 | sort(sortedInstances.begin(), sortedInstances.end(), AliHLTCompStatInstance::SortByLevelAndComponentId); | |
744 | for (vector<AliHLTCompStatInstance>::const_iterator element=sortedInstances.begin(); | |
745 | element!=sortedInstances.end(); | |
746 | element++) { | |
747 | element->Print(""); | |
748 | } | |
749 | } | |
750 | } | |
751 | ||
752 | AliHLTCompStatCollector::AliHLTCompStatInstance::AliHLTCompStatInstance() | |
753 | : fCRCId(0) | |
754 | , fChainId() | |
755 | , fComponentId() | |
756 | , fComponentParam() | |
757 | , fParents() | |
758 | , fLevel(-1) | |
759 | , fTag(-1) | |
760 | , fProcessed(false) | |
761 | { | |
762 | /// default constructor | |
763 | } | |
764 | ||
765 | AliHLTCompStatCollector::AliHLTCompStatInstance::AliHLTCompStatInstance(AliHLTUInt32_t CRCId, | |
766 | const char* chainId, | |
767 | const char* componentId, | |
768 | const char* componentParam, | |
769 | const vector<AliHLTUInt32_t>& parents, | |
770 | int level, | |
771 | int tag) | |
772 | : fCRCId(CRCId) | |
773 | , fChainId(chainId) | |
774 | , fComponentId(componentId) | |
775 | , fComponentParam(componentParam) | |
776 | , fParents(parents) | |
777 | , fLevel(level) | |
778 | , fTag(tag) | |
779 | , fProcessed(false) | |
780 | { | |
781 | } | |
782 | ||
783 | AliHLTCompStatCollector::AliHLTCompStatInstance::AliHLTCompStatInstance(AliHLTUInt32_t CRCId, | |
784 | const string& chainId, | |
785 | const string& componentId, | |
786 | const string& componentParam, | |
787 | const vector<AliHLTUInt32_t>& parents, | |
788 | int level, | |
789 | int tag) | |
790 | : fCRCId(CRCId) | |
791 | , fChainId(chainId) | |
792 | , fComponentId(componentId) | |
793 | , fComponentParam(componentParam) | |
794 | , fParents(parents) | |
795 | , fLevel(level) | |
796 | , fTag(tag) | |
797 | , fProcessed(false) | |
798 | { | |
799 | } | |
800 | ||
801 | AliHLTCompStatCollector::AliHLTCompStatInstance::AliHLTCompStatInstance(const AliHLTCompStatCollector::AliHLTCompStatInstance& src) | |
802 | : fCRCId(src.fCRCId) | |
803 | , fChainId(src.fChainId) | |
804 | , fComponentId(src.fComponentId) | |
805 | , fComponentParam(src.fComponentParam) | |
806 | , fParents(src.fParents) | |
807 | , fLevel(src.fLevel) | |
808 | , fTag(src.fTag) | |
809 | , fProcessed(src.fProcessed) | |
810 | { | |
811 | /// copy constructor | |
812 | } | |
813 | ||
814 | AliHLTCompStatCollector::AliHLTCompStatInstance& AliHLTCompStatCollector::AliHLTCompStatInstance::operator=(const AliHLTCompStatCollector::AliHLTCompStatInstance& src) | |
815 | { | |
816 | /// assignment operator | |
817 | if (&src==this) return *this; | |
818 | ||
819 | fCRCId=src.fCRCId; | |
820 | fChainId=src.fChainId; | |
821 | fComponentId=src.fComponentId; | |
822 | fComponentParam=src.fComponentParam; | |
823 | fParents.assign(src.fParents.begin(), src.fParents.end()); | |
824 | fLevel=src.fLevel; | |
825 | fTag=src.fTag; | |
826 | ||
827 | return *this; | |
828 | } | |
829 | ||
830 | AliHLTCompStatCollector::AliHLTCompStatInstance::~AliHLTCompStatInstance() | |
831 | { | |
832 | /// destructor | |
833 | } | |
834 | ||
835 | string AliHLTCompStatCollector::AliHLTCompStatInstance::Description(const char* /*option*/) const | |
836 | { | |
837 | // get a description string | |
838 | TString description; | |
839 | description.Form("0x%08x level %d tag %d: %s (%s) %s", | |
840 | fCRCId, fLevel, fTag, fChainId.c_str(), fComponentId.c_str(), fComponentParam.c_str()); | |
841 | string ret=description.Data(); | |
842 | return ret; | |
843 | } | |
844 | ||
845 | void AliHLTCompStatCollector::AliHLTCompStatInstance::Print(const char* /*option*/) const | |
846 | { | |
847 | // print info to cout | |
848 | cout << Description() << endl; | |
849 | } | |
850 | ||
851 | bool AliHLTCompStatCollector::AliHLTCompStatInstance::operator==(const AliHLTCompStatInstance &b) const | |
852 | { | |
853 | // check if two instances are equal | |
854 | if (fChainId !=b.fChainId) return false; | |
855 | if (fComponentId !=b.fComponentId) return false; | |
856 | if (fComponentParam!=b.fComponentParam) return false; | |
857 | if (fCRCId !=b.fCRCId) return false; | |
858 | if (fLevel !=b.fLevel) return false; | |
859 | if (fTag>=0 && fTag!=b.fTag && b.fTag>=0) return false; | |
860 | ||
861 | return true; | |
862 | } | |
863 | ||
864 | bool AliHLTCompStatCollector::AliHLTCompStatInstance::SortByLevelAndComponentId(const AliHLTCompStatInstance &a, | |
865 | const AliHLTCompStatInstance &b) | |
866 | { | |
867 | // helper function for std::sort | |
868 | if ( a.fLevel != b.fLevel ) return ( a.fLevel < b.fLevel ); | |
869 | if ( a.fComponentId != b.fComponentId ) return ( a.fComponentId < b.fComponentId ); | |
870 | if ( a.fChainId != b.fChainId ) return ( a.fChainId < b.fChainId ); | |
871 | return 0; | |
872 | } |