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