3 /**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * for The ALICE Off-line Project. *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
18 /** @file AliHLTSystem.cxx
19 @author Matthias Richter
21 @brief Implementation of HLT module management.
28 #include "AliHLTStdIncludes.h"
29 #include "AliHLTSystem.h"
30 #include "AliHLTComponentHandler.h"
31 #include "AliHLTComponent.h"
32 #include "AliHLTConfiguration.h"
33 #include "AliHLTConfigurationHandler.h"
34 #include "AliHLTTask.h"
35 #include "AliHLTModuleAgent.h"
36 #include "AliHLTOfflineInterface.h"
37 #include <TObjArray.h>
38 #include <TObjString.h>
40 #include <TStopwatch.h>
42 /** ROOT macro for the implementation of ROOT specific class methods */
43 ClassImp(AliHLTSystem)
45 AliHLTSystem::AliHLTSystem()
47 fpComponentHandler(new AliHLTComponentHandler()),
48 fpConfigurationHandler(new AliHLTConfigurationHandler()),
52 // see header file for class documentation
54 // refer to README to build package
56 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
58 if (fgNofInstances++>0)
59 HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
61 SetGlobalLoggingLevel(kHLTLogDefault);
62 if (fpComponentHandler) {
63 AliHLTComponentEnvironment env;
64 memset(&env, 0, sizeof(AliHLTComponentEnvironment));
65 env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
66 env.fLoggingFunc=NULL;
67 AliHLTComponentLogSeverity loglevel=fpComponentHandler->GetLocalLoggingLevel();
68 fpComponentHandler->SetLocalLoggingLevel(kHLTLogError);
69 fpComponentHandler->SetEnvironment(&env);
70 fpComponentHandler->LoadLibrary("libAliHLTUtil.so");
71 fgAliLoggingFunc=(AliHLTLogging::AliHLTDynamicMessage)fpComponentHandler->FindSymbol("libAliHLTUtil.so", "AliDynamicMessage");
72 fpComponentHandler->SetLocalLoggingLevel(loglevel);
73 if (fgAliLoggingFunc==NULL) {
74 HLTError("symbol lookp failure: can not find AliDynamicMessage, switching to HLT logging system");
76 fpComponentHandler->AnnounceVersion();
78 HLTFatal("can not create Component Handler");
80 if (fpConfigurationHandler) {
81 AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
83 HLTFatal("can not create Configuration Handler");
87 AliHLTSystem::AliHLTSystem(const AliHLTSystem&)
90 fpComponentHandler(NULL),
91 fpConfigurationHandler(NULL),
95 // see header file for class documentation
96 if (fgNofInstances++>0)
97 HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
99 HLTFatal("copy constructor untested");
102 AliHLTSystem& AliHLTSystem::operator=(const AliHLTSystem&)
104 // see header file for class documentation
105 HLTFatal("assignment operator untested");
109 AliHLTSystem::~AliHLTSystem()
111 // see header file for class documentation
114 AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
115 if (fpConfigurationHandler) {
116 delete fpConfigurationHandler;
118 fpConfigurationHandler=NULL;
120 if (fpComponentHandler) {
121 delete fpComponentHandler;
123 fpComponentHandler=NULL;
126 int AliHLTSystem::fgNofInstances=0;
128 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
130 // see header file for class documentation
139 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
141 // see header file for class documentation
153 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
155 // see header file for class documentation
164 int AliHLTSystem::BuildTaskList(const char* id)
166 // see header file for class documentation
169 if (fpConfigurationHandler) {
170 AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(id);
172 iResult=BuildTaskList(pConf);
174 HLTError("unknown configuration \"%s\"", id);
186 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
188 // see header file for class documentation
191 AliHLTTask* pTask=NULL;
192 if ((pTask=FindTask(pConf->GetName()))!=NULL) {
193 if (pTask->GetConf()!=pConf) {
194 HLTError("configuration missmatch, there is already a task with configuration name \"%s\", but it is different. Most likely configuration %p is not registered properly", pConf->GetName(), pConf);
198 } else if (pConf->SourcesResolved(1)!=1) {
199 HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
202 pTask=new AliHLTTask(pConf);
208 // check for circular dependencies
209 if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
210 HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
211 pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
212 HLTError("aborted ...");
216 // check whether all dependencies are already in the task list
217 // create the missing ones
218 // this step is an iterative process which calls this function again for the missing
219 // configurations, in order to avoid the currently processed task to be created
220 // again it is added to the list temporarily and removed afterwards
221 // This is of high importance to preserve the order of the tasks. Furthermore, the
222 // InsertTask method has to be used in order to set all the cross links right
223 fTaskList.Add(pTask);
224 AliHLTConfiguration* pDep=pConf->GetFirstSource();
225 while (pDep!=NULL && iResult>=0) {
226 if (FindTask(pDep->GetName())==NULL) {
227 iResult=BuildTaskList(pDep);
229 pDep=pConf->GetNextSource();
231 // remove the temporarily added task
232 fTaskList.Remove(pTask);
234 // insert the task and set the cross-links
236 iResult=InsertTask(pTask);
249 int AliHLTSystem::CleanTaskList()
251 // see header file for class documentation
254 while ((lnk=fTaskList.LastLink())!=NULL) {
255 delete (lnk->GetObject());
256 fTaskList.Remove(lnk);
261 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
263 // see header file for class documentation
265 TObjLink *lnk = NULL;
266 if ((iResult=pTask->CheckDependencies())>0)
267 lnk=fTaskList.FirstLink();
268 while (lnk && iResult>0) {
269 AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
270 //HLTDebug("checking \"%s\"", pCurr->GetName());
271 iResult=pTask->Depends(pCurr);
273 iResult=pTask->SetDependency(pCurr);
274 pCurr->SetTarget(pTask);
275 HLTDebug("set dependency \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
277 if (pCurr->Depends(pTask)) {
278 // circular dependency
279 HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
281 } else if ((iResult=pTask->CheckDependencies())>0) {
287 fTaskList.AddAfter(lnk, pTask);
289 fTaskList.AddFirst(pTask);
291 HLTDebug("task \"%s\" (%p) inserted (size %d)", pTask->GetName(), pTask, sizeof(AliHLTTask));
292 } else if (iResult>0) {
293 HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
299 AliHLTTask* AliHLTSystem::FindTask(const char* id)
301 // see header file for class documentation
302 AliHLTTask* pTask=NULL;
304 pTask=(AliHLTTask*)fTaskList.FindObject(id);
309 void AliHLTSystem::PrintTaskList()
311 // see header file for class documentation
312 HLTLogKeyword("task list");
313 TObjLink *lnk = NULL;
314 HLTMessage("Task List");
315 lnk=fTaskList.FirstLink();
317 TObject* obj=lnk->GetObject();
319 HLTMessage(" %s - status:", obj->GetName());
320 AliHLTTask* pTask=(AliHLTTask*)obj;
321 pTask->PrintStatus();
328 int AliHLTSystem::Run(Int_t iNofEvents)
330 // see header file for class documentation
333 SetStatusFlags(kRunning);
334 TStopwatch StopwatchBase; StopwatchBase.Reset();
335 TStopwatch StopwatchDA; StopwatchDA.Reset();
336 TStopwatch StopwatchInput; StopwatchInput.Reset();
337 TStopwatch StopwatchOutput; StopwatchOutput.Reset();
338 TObjArray Stopwatches;
339 Stopwatches.AddAt(&StopwatchBase, (int)AliHLTComponent::kSWBase);
340 Stopwatches.AddAt(&StopwatchDA, (int)AliHLTComponent::kSWDA);
341 Stopwatches.AddAt(&StopwatchInput, (int)AliHLTComponent::kSWInput);
342 Stopwatches.AddAt(&StopwatchOutput, (int)AliHLTComponent::kSWOutput);
343 if ((iResult=InitTasks())>=0 && (iResult=InitBenchmarking(&Stopwatches))>=0) {
344 if ((iResult=StartTasks())>=0) {
345 for (int i=0; i<iNofEvents && iResult>=0; i++) {
346 iResult=ProcessTasks(i);
348 HLTInfo("Event %d successfully finished (%d)", i, iResult);
352 HLTError("Processing of event %d failed (%d)", i, iResult);
353 // TODO: define different running modes to either ignore errors in
354 // event processing or not
361 HLTError("can not start task list");
364 } else if (iResult!=-ENOENT) {
365 HLTError("can not initialize task list");
369 HLTInfo("HLT statistics:\n"
370 " base: R:%.3fs C:%.3fs\n"
371 " input: R:%.3fs C:%.3fs\n"
372 " output: R:%.3fs C:%.3fs\n"
373 " event processing : R:%.3fs C:%.3fs"
374 , StopwatchBase.RealTime(),StopwatchBase.CpuTime()
375 , StopwatchInput.RealTime(),StopwatchInput.CpuTime()
376 , StopwatchOutput.RealTime(),StopwatchOutput.CpuTime()
377 , StopwatchDA.RealTime(),StopwatchDA.CpuTime());
379 ClearStatusFlags(kRunning);
383 int AliHLTSystem::InitTasks()
385 // see header file for class documentation
387 TObjLink *lnk=fTaskList.FirstLink();
389 HLTWarning("Task list is empty, aborting ...");
392 while (lnk && iResult>=0) {
393 TObject* obj=lnk->GetObject();
395 AliHLTTask* pTask=(AliHLTTask*)obj;
396 iResult=pTask->Init(NULL, fpComponentHandler);
406 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
408 // see header file for class documentation
409 if (pStopwatches==NULL) return -EINVAL;
412 TObjLink *lnk=fTaskList.FirstLink();
413 while (lnk && iResult>=0) {
414 TObject* obj=lnk->GetObject();
416 AliHLTTask* pTask=(AliHLTTask*)obj;
417 AliHLTComponent* pComp=NULL;
418 if (iResult>=0 && (pComp=pTask->GetComponent())!=NULL) {
419 switch (pComp->GetComponentType()) {
420 case AliHLTComponent::kProcessor:
421 pComp->SetStopwatches(pStopwatches);
423 case AliHLTComponent::kSource:
425 // this switch determines whether the time consumption of the
426 // AliHLTComponent base methods should be counted to the input
427 // stopwatch or base stopwatch.
428 //int inputBase=(int)AliHLTComponent::kSWBase;
429 int inputBase=(int)AliHLTComponent::kSWInput;
430 pComp->SetStopwatch(pStopwatches->At(inputBase), AliHLTComponent::kSWBase);
431 pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWInput), AliHLTComponent::kSWDA);
434 case AliHLTComponent::kSink:
436 // this switch determines whether the time consumption of the
437 // AliHLTComponent base methods should be counted to the output
438 // stopwatch or base stopwatch.
439 //int outputBase=(int)AliHLTComponent::kSWBase;
440 int outputBase=(int)AliHLTComponent::kSWOutput;
441 pComp->SetStopwatch(pStopwatches->At(outputBase), AliHLTComponent::kSWBase);
442 pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWOutput), AliHLTComponent::kSWDA);
446 HLTWarning("unknown component type %d", (int)pComp->GetComponentType());
456 int AliHLTSystem::StartTasks()
458 // see header file for class documentation
460 TObjLink *lnk=fTaskList.FirstLink();
461 while (lnk && iResult>=0) {
462 TObject* obj=lnk->GetObject();
464 AliHLTTask* pTask=(AliHLTTask*)obj;
465 iResult=pTask->StartRun();
475 int AliHLTSystem::ProcessTasks(Int_t eventNo)
477 // see header file for class documentation
479 HLTDebug("processing event no %d", eventNo);
480 TObjLink *lnk=fTaskList.FirstLink();
481 while (lnk && iResult>=0) {
482 TObject* obj=lnk->GetObject();
484 AliHLTTask* pTask=(AliHLTTask*)obj;
485 iResult=pTask->ProcessTask(eventNo);
486 HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
494 int AliHLTSystem::StopTasks()
496 // see header file for class documentation
498 TObjLink *lnk=fTaskList.FirstLink();
499 while (lnk && iResult>=0) {
500 TObject* obj=lnk->GetObject();
502 AliHLTTask* pTask=(AliHLTTask*)obj;
503 iResult=pTask->EndRun();
511 int AliHLTSystem::DeinitTasks()
513 // see header file for class documentation
515 TObjLink *lnk=fTaskList.FirstLink();
516 while (lnk && iResult>=0) {
517 TObject* obj=lnk->GetObject();
519 AliHLTTask* pTask=(AliHLTTask*)obj;
520 iResult=pTask->Deinit();
528 void* AliHLTSystem::AllocMemory( void* param, unsigned long size )
530 // see header file for class documentation
532 // get rid of 'unused parameter' warning
534 return (void*)new char[size];
537 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader,
538 AliRawReader* rawReader)
540 // see header file for class documentation
543 HLTInfo("Run Loader %p, Raw Reader %p , %d events", runLoader, rawReader, nofEvents);
544 if (CheckStatus(kReady)) {
545 if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
546 iResult=Run(nofEvents);
549 HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
552 HLTError("missing run loader instance");
558 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESD* esd)
560 // see header file for class documentation
563 HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
564 iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
566 HLTError("missing run loader/ESD instance(s)");
572 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
574 // see header file for class documentation
577 if (fpComponentHandler) {
578 TString libs(libraries);
579 TObjArray* pTokens=libs.Tokenize(" ");
581 int iEntries=pTokens->GetEntries();
582 for (int i=0; i<iEntries && iResult>=0; i++) {
583 iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
588 SetStatusFlags(kLibrariesLoaded);
590 // lets see if we need this, probably not
591 //fpComponentHandler->UnloadLibraries();
592 ClearStatusFlags(kLibrariesLoaded);
596 HLTFatal("no component handler available");
604 int AliHLTSystem::Configure(AliRunLoader* runloader)
606 // see header file for class documentation
608 if (CheckStatus(kRunning)) {
609 HLTError("HLT system in running state, can not configure");
612 if (CheckFilter(kHLTLogDebug))
613 AliHLTModuleAgent::PrintStatus();
614 ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
615 iResult=LoadConfigurations(runloader);
617 SetStatusFlags(kConfigurationLoaded);
618 iResult=BuildTaskListsFromTopConfigurations(runloader);
620 SetStatusFlags(kTaskListCreated);
623 if (iResult<0) SetStatusFlags(kError);
628 int AliHLTSystem::Reset(int bForce)
630 // see header file for class documentation
632 if (!bForce && CheckStatus(kRunning)) {
633 HLTError("HLT system in running state, can not configure");
637 ClearStatusFlags(~kUninitialized);
641 int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
643 // see header file for class documentation
644 if (CheckStatus(kRunning)) {
645 HLTError("HLT system in running state, can not configure");
649 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
650 while (pAgent && iResult>=0) {
651 const char* deplibs=pAgent->GetRequiredComponentLibraries();
653 HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
654 iResult=LoadComponentLibraries(deplibs);
657 HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
658 pAgent->CreateConfigurations(fpConfigurationHandler, runloader);
659 pAgent=AliHLTModuleAgent::GetNextAgent();
665 int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
667 // see header file for class documentation
668 if (CheckStatus(kRunning)) {
669 HLTError("HLT system in running state, can not configure");
672 if (!CheckStatus(kConfigurationLoaded)) {
673 HLTWarning("configurations not yet loaded");
678 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
679 while (pAgent && iResult>=0) {
680 TString tops=pAgent->GetLocalRecConfigurations(runloader);
681 HLTDebug("top configurations for agent %s (%p): %s", pAgent->GetName(), pAgent, tops.Data());
682 TObjArray* pTokens=tops.Tokenize(" ");
684 int iEntries=pTokens->GetEntries();
685 for (int i=0; i<iEntries && iResult>=0; i++) {
686 const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
687 AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
689 iResult=BuildTaskList(pConf);
691 HLTWarning("can not find top configuration %s", pCID);
697 pAgent=AliHLTModuleAgent::GetNextAgent();
699 if (iResult>=0) SetStatusFlags(kTaskListCreated);
704 int AliHLTSystem::CheckStatus(int flag)
706 // see header file for class documentation
707 if (flag==kUninitialized && flag==fState) return 1;
708 if ((fState&flag)==flag) return 1;
712 int AliHLTSystem::GetStatusFlags()
714 // see header file for class documentation
718 int AliHLTSystem::SetStatusFlags(int flags)
720 // see header file for class documentation
725 int AliHLTSystem::ClearStatusFlags(int flags)
727 // see header file for class documentation
732 void* AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
734 if (fpComponentHandler==NULL) return NULL;
735 return fpComponentHandler->FindSymbol(library, symbol);