]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/util/AliHLTCompStatCollector.cxx
correcting coding violations
[u/mrichter/AliRoot.git] / HLT / BASE / util / AliHLTCompStatCollector.cxx
CommitLineData
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
19/** @file AliHLTCompStatCollector.cxx
20 @author Matthias Richter
21 @date
22 @brief Collector component for the component statistics information.
23*/
24
25#include "AliHLTCompStatCollector.h"
26#include "TStopwatch.h"
27#include "TH1F.h"
28#include "TH2F.h"
29#include "TH2C.h"
30#include "TTree.h"
abb52c8f 31#include "TFolder.h"
32#include "TNamed.h"
b765ad15 33#include "TString.h"
abb52c8f 34#include <cassert>
35
36#define HLTSTAT_FOLDER_NAME "HLTstat"
37#define HLTSTAT_FOLDER_DESC "ALICE HLT component statistics"
38#define HLTSTAT_ENTRY_PARENT_FOLDER_NAME "parents"
39#define HLTSTAT_ENTRY_PARENT_FOLDER_DESC "parent components"
40#define HLTSTAT_ENTRY_PROPS_FOLDER_NAME "props"
41#define HLTSTAT_ENTRY_PROPS_FOLDER_DESC "component properties"
42#define HLTSTAT_ENTRY_PROPS_IDOBJ_NAME "id"
43#define HLTSTAT_ENTRY_PROPS_IDOBJ_DESC "numerical id calculated from chain id"
b765ad15 44
45/** ROOT macro for the implementation of ROOT specific class methods */
46ClassImp(AliHLTCompStatCollector)
47
48AliHLTCompStatCollector::AliHLTCompStatCollector()
49 :
50 AliHLTProcessor(),
51 fpTimer(NULL),
abb52c8f 52 fpFolder(NULL),
b765ad15 53 fpStatTree(NULL),
54 fCycleTime(0),
55 fNofSets(0),
56 fArraySize(1000),
57 fPosition(0),
58 fpLevelArray(NULL),
59 fpSpecArray(NULL),
60 fpBlockNoArray(NULL),
61 fpIdArray(NULL),
62 fpTimeArray(NULL),
63 fpCTimeArray(NULL),
64 fpInputBlockCountArray(NULL),
65 fpTotalInputSizeArray(NULL),
66 fpOutputBlockCountArray(NULL),
67 fpTotalOutputSizeArray(NULL)
63410eb4 68 , fSizeEstimator(1000)
b765ad15 69{
70 // see header file for class documentation
71 // or
72 // refer to README to build package
73 // or
74 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
75}
76
77AliHLTCompStatCollector::~AliHLTCompStatCollector()
78{
79 // see header file for class documentation
80 ClearAll();
81}
82
83void AliHLTCompStatCollector::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
84{
85 // see header file for class documentation
86 list.push_back(kAliHLTDataTypeComponentStatistics);
87}
88
89AliHLTComponentDataType AliHLTCompStatCollector::GetOutputDataType()
90{
91 // see header file for class documentation
92 return kAliHLTMultipleDataType;
93}
94
95int AliHLTCompStatCollector::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
96{
97 // see header file for class documentation
98 tgtList.clear();
99 tgtList.push_back(kAliHLTDataTypeHistogram);
100 tgtList.push_back(kAliHLTDataTypeTTree);
101 return tgtList.size();
102}
103
104void AliHLTCompStatCollector::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
105{
106 // see header file for class documentation
63410eb4 107 constBase=fSizeEstimator;
b765ad15 108 inputMultiplier=100.0;
109}
110
111int AliHLTCompStatCollector::DoInit( int argc, const char** argv )
112{
113 // see header file for class documentation
114 int iResult=0;
115 TString argument="";
116 int bMissingParam=0;
117 for (int i=0; i<argc && iResult>=0; i++) {
118 argument=argv[i];
119 if (argument.IsNull()) continue;
120
121 // -array-size
122 if (argument.CompareTo("-array-size")==0) {
123 if ((bMissingParam=(++i>=argc))) break;
124 TString param=argv[argc];
125 if (param.IsDigit()) {
126 fArraySize=param.Atoi();
127 } else {
128 HLTError("expecting number as parameter for option '-array-size'");
129 iResult=-EINVAL;
130 }
131
132 } else {
133 iResult=-EINVAL;
134 }
135 }
136 if (bMissingParam) {
137 HLTError("missing parameter for argument %s", argument.Data());
138 iResult=-EINVAL;
139 }
140
141 if (iResult>=0) {
142 fpLevelArray=new UInt_t[fArraySize];
143 fpSpecArray=new UInt_t[fArraySize];
144 fpBlockNoArray=new UInt_t[fArraySize];
145 fpIdArray=new UInt_t[fArraySize];
146 fpTimeArray=new UInt_t[fArraySize];
147 fpCTimeArray=new UInt_t[fArraySize];
148 fpInputBlockCountArray=new UInt_t[fArraySize];
149 fpTotalInputSizeArray=new UInt_t[fArraySize];
150 fpOutputBlockCountArray=new UInt_t[fArraySize];
151 fpTotalOutputSizeArray=new UInt_t[fArraySize];
152
153 fpStatTree=new TTree("CompStat", "HLT component statistics");
154 if (fpStatTree) {
155 fpStatTree->SetDirectory(0);
156 fpStatTree->Branch("cycleTime", &fCycleTime, "cycleTime/F");
157 fpStatTree->Branch("nofSets", &fNofSets, "nofSets/I");
158 fpStatTree->Branch("Level", fpLevelArray, "Level[nofSets]/i");
159 fpStatTree->Branch("Specification", fpSpecArray, "Specification[nofSets]/i");
160 fpStatTree->Branch("BlockNo", fpBlockNoArray, "BlockNo[nofSets]/i");
161 fpStatTree->Branch("Id", fpIdArray, "Id[nofSets]/i");
162 fpStatTree->Branch("Time", fpTimeArray, "Time[nofSets]/i");
163 fpStatTree->Branch("CTime", fpCTimeArray, "CTime[nofSets]/i");
164 fpStatTree->Branch("InputBlockCount", fpInputBlockCountArray, "InputBlockCount[nofSets]/i");
165 fpStatTree->Branch("TotalInputSize", fpTotalInputSizeArray, "TotalInputSize[nofSets]/i");
166 fpStatTree->Branch("OutputBlockCount", fpOutputBlockCountArray, "OutputBlockCount[nofSets]/i");
167 fpStatTree->Branch("TotalOutputSize", fpTotalOutputSizeArray, "TotalOutputSize[nofSets]/i");
168 }
169 }
170 return iResult;
171}
172
173int AliHLTCompStatCollector::DoDeinit( )
174{
175 // see header file for class documentation
176 ClearAll();
177
178 return 0;
179}
180
181int AliHLTCompStatCollector::DoEvent( const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/)
182{
183 // see header file for class documentation
184 int iResult=0;
185
abb52c8f 186 AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
187 IsDataEvent(&eventType);
188
b765ad15 189 ResetFillingVariables();
190 if (fpTimer) {
191 fCycleTime=fpTimer->RealTime()*1000000;
192 }
193
abb52c8f 194 bool bEmbeddedTree=false;
195 bool bFolderCreated=false;
9d5f00ad 196 if ((bFolderCreated=(fpFolder==NULL))) {
abb52c8f 197 fpFolder=new TFolder(HLTSTAT_FOLDER_NAME, HLTSTAT_FOLDER_DESC);
198 if (bEmbeddedTree) fpFolder->Add(fpStatTree);
199 }
200 if (!fpFolder) return -ENOMEM;
201 vector<TFolder*> newFolders;
202
203 for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeComponentTable);
204 pBlock && iResult>=0;
205 pBlock=GetNextInputBlock()) {
206 string chainId, compId, compArgs;
207 vector<AliHLTUInt32_t> parents;
208 iResult=ExtractComponentTableEntry((const AliHLTUInt8_t*)pBlock->fPtr, pBlock->fSize,
209 chainId, compId, compArgs,
210 parents);
211 if (iResult>0) {
212 HLTDebug("%s(%s) 0x%08x", chainId.c_str(), compId.c_str(), pBlock->fSpecification);
213 TObject* pObj=NULL;
214 TFolder* pEntry=NULL;
215 if ((pObj=fpFolder->FindObjectAny(chainId.c_str()))!=NULL &&
216 (pEntry=dynamic_cast<TFolder*>(pObj))!=NULL ) {
217
218 } else if (pObj) {
219 HLTError("entry %s exists in folder, but is not a sub-folder", chainId.c_str());
220 } else if (chainId.size()>0) {
221 pEntry=new TFolder(chainId.c_str(), chainId.c_str());
222 if (pEntry) {
223 pEntry->SetOwner();
224 TFolder* pProps=pEntry->AddFolder(HLTSTAT_ENTRY_PROPS_FOLDER_NAME, HLTSTAT_ENTRY_PROPS_FOLDER_DESC);
225 if (pProps) {
226 pProps->Add(new TObjString(compId.c_str()));
227 if (!compArgs.empty())
228 pProps->Add(new TObjString(compArgs.c_str()));
229 TNamed* pCRC=new TNamed(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME, HLTSTAT_ENTRY_PROPS_IDOBJ_DESC);
230 if (pCRC) {
231 pCRC->SetUniqueID(pBlock->fSpecification);
232 pProps->Add(pCRC);
233 }
234 }
235 TFolder* pParents=pEntry->AddFolder(HLTSTAT_ENTRY_PARENT_FOLDER_NAME, HLTSTAT_ENTRY_PARENT_FOLDER_DESC);
236 if (pParents) {
237 for (vector<AliHLTUInt32_t>::iterator parent=parents.begin();
238 parent!=parents.end(); parent++) {
239 TString name; name.Form("0x%08x", *parent);
240 pParents->Add(new TObjString(name));
241 }
242 }
243 if (parents.size()==0) {
244 newFolders.push_back(pEntry);
245 } else {
246 vector<TFolder*>::iterator iter=newFolders.begin();
247 vector<AliHLTUInt32_t>::iterator parent=parents.begin();
248 while (iter!=newFolders.end() && parent!=parents.end()) {
249 TObject* idobj=(*iter)->FindObjectAny(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME);
250 AliHLTUInt32_t crcid=0;
251 if (idobj) crcid=idobj->GetUniqueID();
252 HLTDebug("check: %s 0x%08x", (*iter)->GetName(), crcid);
253 if (idobj && crcid==*parent) break;
254 if ((++parent!=parents.end())) continue;
255 parent=parents.begin();
256 iter++;
257 }
258 newFolders.insert(iter,pEntry);
259 }
260 }
261 } else {
262 HLTError("missing chain id for table entry 0x%08x (%p %d), skipping ...", pBlock->fSpecification, pBlock->fPtr, pBlock->fSize);
263 }
264 } else if (iResult!=0) {
265 HLTError("extraction of table entry 0x%08x (%p %d) failed with %d", pBlock->fSpecification, pBlock->fPtr, pBlock->fSize, iResult);
266 }
267 iResult=0;
268 }
269
270 if (newFolders.size()>0) {
271 vector<TFolder*> revert;
272 vector<TFolder*>::iterator iter=newFolders.begin();
273 while (iter!=newFolders.end()) {
274 revert.insert(revert.begin(), *iter);
275 HLTDebug("%s", (*iter)->GetName());
276 iter++;
277 }
278 newFolders.empty();
279 newFolders.assign(revert.begin(), revert.end());
280
281 vector<TFolder*>::iterator publisher=newFolders.begin();
282 while (publisher!=newFolders.end()) {
283 bool bRemove=false;
284 HLTDebug("checking %s for parents", (*publisher)->GetName());
285 TFolder* propsFolder=dynamic_cast<TFolder*>((*publisher)->FindObject(HLTSTAT_ENTRY_PROPS_FOLDER_NAME));
286 assert(propsFolder);
287 TObject* idobj=NULL;
288 if (propsFolder) idobj=propsFolder->FindObject(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME);
289 assert(idobj);
290 AliHLTUInt32_t crcid=idobj->GetUniqueID();
291 TString idstr; idstr.Form("0x%08x", crcid);
292 if (idobj) {
293 for (vector<TFolder*>::iterator consumer=publisher+1;
294 consumer!=newFolders.end(); consumer++) {
295 HLTDebug(" checking %s", (*consumer)->GetName());
296 TFolder* parentFolder=dynamic_cast<TFolder*>((*consumer)->FindObject(HLTSTAT_ENTRY_PARENT_FOLDER_NAME));
297 assert(parentFolder);
298 if (parentFolder) {
299 TIter entries(parentFolder->GetListOfFolders());
300 while (TObject* entry=entries.Next())
460c4045 301 if (entry) {
302 Bool_t foo; foo=kTRUE;// only to avoid warning in non-debug compile
303 HLTDebug(" searching %s in %s: %s", idstr.Data(), (*consumer)->GetName(), entry->GetName());
304 }
abb52c8f 305 TObject* parent=parentFolder->FindObjectAny(idstr);
306 if (parent) {
307 parentFolder->Add(*publisher);
308 parentFolder->Remove(parent);
309 bRemove=true;
310 }
311 }
312 }
313 }
314 if (bRemove) publisher=newFolders.erase(publisher);
315 else publisher++;
316 }
317
318 for (publisher=newFolders.begin();
319 publisher!=newFolders.end(); publisher++) {
320 RemoveRecurrence(*publisher);
321 fpFolder->Add(*publisher);
322 }
323 }
324
b765ad15 325 int blockNo=0;
326 for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeComponentStatistics);
327 pBlock && iResult>=0;
328 pBlock=GetNextInputBlock(), blockNo++) {
329 unsigned int current=fPosition;
330 iResult=FillVariablesSorted(pBlock->fPtr, pBlock->fSize);
331 for (; current<fPosition; current++) {
332 fpSpecArray[current]=pBlock->fSpecification;
333 fpBlockNoArray[current]=blockNo;
334 }
587c9cf9 335 // indicate availability of component statistic block
336 iResult=1;
b765ad15 337 }
338
587c9cf9 339 if (iResult>0) {
b765ad15 340 fNofSets=fPosition;
341 fpStatTree->Fill();
63410eb4 342 if (!bEmbeddedTree && ((iResult=PushBack(fpStatTree, kAliHLTDataTypeTTree|kAliHLTDataOriginOut))==-ENOSPC)) {
343 fSizeEstimator+=GetLastObjectSize();
344 }
b765ad15 345
587c9cf9 346 // init the timer for the next cycle
347 if (!fpTimer) fpTimer=new TStopwatch;
348 if (fpTimer) {
349 fpTimer->Reset();
350 fpTimer->Start();
351 }
b765ad15 352 }
353
abb52c8f 354 if (iResult>=0 /*&& eventType==gkAliEventTypeEndOfRun*/) {
63410eb4 355 if ((iResult=PushBack(fpFolder, kAliHLTDataTypeTObject|kAliHLTDataOriginOut))==-ENOSPC) {
356 fSizeEstimator+=GetLastObjectSize();
357 }
abb52c8f 358 }
359
360 if (iResult>0) iResult=0;
b765ad15 361 return iResult;
362}
363
364void AliHLTCompStatCollector::ResetFillingVariables()
365{
366 // see header file for class documentation
367 fCycleTime=0;
368 fNofSets=0;
369 fPosition=0;
370 memset(fpLevelArray, 0, sizeof(UInt_t)*fArraySize);
371 memset(fpSpecArray, 0, sizeof(UInt_t)*fArraySize);
372 memset(fpBlockNoArray, 0, sizeof(UInt_t)*fArraySize);
373 memset(fpIdArray, 0, sizeof(UInt_t)*fArraySize);
374 memset(fpTimeArray, 0, sizeof(UInt_t)*fArraySize);
375 memset(fpCTimeArray, 0, sizeof(UInt_t)*fArraySize);
376 memset(fpInputBlockCountArray, 0, sizeof(UInt_t)*fArraySize);
377 memset(fpTotalInputSizeArray, 0, sizeof(UInt_t)*fArraySize);
378 memset(fpOutputBlockCountArray, 0, sizeof(UInt_t)*fArraySize);
379 memset(fpTotalOutputSizeArray, 0, sizeof(UInt_t)*fArraySize);
380}
381
382int AliHLTCompStatCollector::FillVariablesSorted(void* ptr, int size)
383{
384 // see header file for class documentation
385 int iResult=0;
386 if (size%sizeof(AliHLTComponentStatistics)) {
387 HLTError("data block is not aligned to the size of the AliHLTComponentStatistics struct");
388 return -EINVAL;
389 }
390 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(ptr);
391 UInt_t nofStats=size/sizeof(AliHLTComponentStatistics);
392 vector<int> indexList;
393 UInt_t i=0;
394 for (i=0; i<nofStats; i++) {
395 vector<int>::iterator element=indexList.begin();
396 for (; element!=indexList.end(); element++) {
397 if (pStat[i].fLevel>pStat[*element].fLevel) {
398 break;
399 }
400 }
401 indexList.insert(element, i);
402 }
403
404 i=fPosition;
405 for (vector<int>::iterator element=indexList.begin();
406 element!=indexList.end();
407 element++, i++) {
408 if (i<fArraySize) {
409 fpLevelArray[i]=pStat[*element].fLevel;
410 fpIdArray[i]=pStat[*element].fId;
411 fpTimeArray[i]=pStat[*element].fTime;
412 fpCTimeArray[i]=pStat[*element].fCTime;
413 fpInputBlockCountArray[i]=pStat[*element].fInputBlockCount;
414 fpTotalInputSizeArray[i]=pStat[*element].fTotalInputSize;
415 fpOutputBlockCountArray[i]=pStat[*element].fOutputBlockCount;
416 fpTotalOutputSizeArray[i]=pStat[*element].fTotalOutputSize;
417 }
418 }
419
420 if (i>=fArraySize) {
421 HLTWarning("too little space in branch variables to fill %d statistics blocks, available %d at position %d", i, fArraySize, fPosition);
422 fPosition=fArraySize;
423 } else {
424 fPosition=i;
425 }
426
427 return iResult;
428}
429
430void AliHLTCompStatCollector::ClearAll()
431{
abb52c8f 432 // see header file for class documentation
b765ad15 433 if (fpTimer) delete fpTimer; fpTimer=NULL;
abb52c8f 434 if (fpFolder) delete fpFolder; fpFolder=NULL;
b765ad15 435 if (fpStatTree) delete fpStatTree; fpStatTree=NULL;
436 if (fpLevelArray) delete fpLevelArray; fpLevelArray=NULL;
437 if (fpSpecArray) delete fpSpecArray; fpSpecArray=NULL;
438 if (fpBlockNoArray) delete fpBlockNoArray; fpBlockNoArray=NULL;
439 if (fpIdArray) delete fpIdArray; fpIdArray=NULL;
440 if (fpTimeArray) delete fpTimeArray; fpTimeArray=NULL;
441 if (fpCTimeArray) delete fpCTimeArray; fpCTimeArray=NULL;
442 if (fpInputBlockCountArray) delete fpInputBlockCountArray; fpInputBlockCountArray=NULL;
443 if (fpTotalInputSizeArray) delete fpTotalInputSizeArray; fpTotalInputSizeArray=NULL;
444 if (fpOutputBlockCountArray) delete fpOutputBlockCountArray; fpOutputBlockCountArray=NULL;
445 if (fpTotalOutputSizeArray) delete fpTotalOutputSizeArray; fpTotalOutputSizeArray=NULL;
446}
abb52c8f 447
448int AliHLTCompStatCollector::RemoveRecurrence(TFolder* pRoot) const
449{
450 // see header file for class documentation
451 int iResult=0;
452 if (!pRoot) return -EINVAL;
453 TFolder* parentFolder=dynamic_cast<TFolder*>(pRoot->FindObject(HLTSTAT_ENTRY_PARENT_FOLDER_NAME));
454 assert(parentFolder);
455 vector<TFolder*> listRemove;
456 if (parentFolder) {
457 TIter entries(parentFolder->GetListOfFolders());
458 TFolder* entry=NULL;
459 TObject* obj=NULL;
460 while ((obj=entries.Next())!=NULL && (entry=dynamic_cast<TFolder*>(obj))!=NULL) {
461 TString name=entry->GetName();
462 HLTDebug("checking %s for recurrence", name.Data());
463 TIter tokens(parentFolder->GetListOfFolders());
464 TFolder* token=NULL;
465 while ((obj=tokens.Next())!=NULL && (token=dynamic_cast<TFolder*>(obj))!=NULL) {
466 if (name.CompareTo(token->GetName())==0) continue;
467 if ((obj=token->FindObjectAny(name))!=NULL) {
468 listRemove.push_back(entry);
469 HLTDebug("found recurrence in %s", token->GetName());
470 break;
471 } else {
472 HLTDebug("no recurrence found in %s", token->GetName());
473 }
474 }
475 RemoveRecurrence(entry);
476 }
477 for (vector<TFolder*>::iterator removeElement=listRemove.begin();
478 removeElement!=listRemove.end(); removeElement++) {
479 parentFolder->Remove(*removeElement);
480 }
481 }
482
483 return iResult;
484}