3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * for The ALICE HLT Project. *
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 **************************************************************************/
19 /** @file AliHLTSystem.cxx
20 @author Matthias Richter
22 @brief Implementation of HLT module management.
29 #include "AliHLTStdIncludes.h"
30 #include "AliHLTSystem.h"
31 #include "AliHLTComponentHandler.h"
32 #include "AliHLTComponent.h"
33 #include "AliHLTConfiguration.h"
34 #include "AliHLTConfigurationHandler.h"
35 #include "AliHLTTask.h"
36 #include "AliHLTModuleAgent.h"
37 #include "AliHLTOfflineInterface.h"
38 #include <TObjArray.h>
39 #include <TObjString.h>
40 #include <TStopwatch.h>
42 #include <TInterpreter.h>
44 /** ROOT macro for the implementation of ROOT specific class methods */
45 ClassImp(AliHLTSystem)
47 AliHLTSystem::AliHLTSystem()
49 fpComponentHandler(new AliHLTComponentHandler()),
50 fpConfigurationHandler(new AliHLTConfigurationHandler()),
55 // see header file for class documentation
57 // refer to README to build package
59 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
61 if (fgNofInstances++>0)
62 HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
64 SetGlobalLoggingLevel(kHLTLogDefault);
65 if (fpComponentHandler) {
66 AliHLTComponentEnvironment env;
67 memset(&env, 0, sizeof(AliHLTComponentEnvironment));
68 env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
69 env.fLoggingFunc=NULL;
70 AliHLTComponentLogSeverity loglevel=fpComponentHandler->GetLocalLoggingLevel();
71 fpComponentHandler->SetLocalLoggingLevel(kHLTLogError);
72 fpComponentHandler->SetEnvironment(&env);
73 fpComponentHandler->LoadLibrary("libAliHLTUtil.so");
74 fgAliLoggingFunc=(AliHLTLogging::AliHLTDynamicMessage)fpComponentHandler->FindSymbol("libAliHLTUtil.so", "AliDynamicMessage");
75 fpComponentHandler->SetLocalLoggingLevel(loglevel);
76 if (fgAliLoggingFunc==NULL) {
77 HLTError("symbol lookp failure: can not find AliDynamicMessage, switching to HLT logging system");
79 fpComponentHandler->AnnounceVersion();
81 HLTFatal("can not create Component Handler");
83 if (fpConfigurationHandler) {
84 AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
86 HLTFatal("can not create Configuration Handler");
90 AliHLTSystem::~AliHLTSystem()
92 // see header file for class documentation
95 AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
96 if (fpConfigurationHandler) {
97 delete fpConfigurationHandler;
99 fpConfigurationHandler=NULL;
101 if (fpComponentHandler) {
102 delete fpComponentHandler;
104 fpComponentHandler=NULL;
107 int AliHLTSystem::fgNofInstances=0;
109 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
111 // see header file for class documentation
120 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
122 // see header file for class documentation
134 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
136 // see header file for class documentation
145 int AliHLTSystem::BuildTaskList(const char* id)
147 // see header file for class documentation
150 if (fpConfigurationHandler) {
151 AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(id);
153 iResult=BuildTaskList(pConf);
155 HLTError("unknown configuration \"%s\"", id);
167 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
169 // see header file for class documentation
172 AliHLTTask* pTask=NULL;
173 if ((pTask=FindTask(pConf->GetName()))!=NULL) {
174 if (pTask->GetConf()!=pConf) {
175 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);
178 // task for this configuration exists, terminate
180 } else if (pConf->SourcesResolved(1)!=1) {
181 HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
184 pTask=new AliHLTTask(pConf);
189 static int iterationLevel=0;
190 if (pTask && iResult>=0) {
191 // check for circular dependencies
192 if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
193 HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
194 pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
195 HLTError("aborted ...");
199 // check whether all dependencies are already in the task list
200 // create the missing ones
201 // this step is an iterative process which calls this function again for the missing
202 // configurations, in order to avoid the currently processed task to be created
203 // again it is added to the list temporarily and removed afterwards
204 // This is of high importance to preserve the order of the tasks. Furthermore, the
205 // InsertTask method has to be used in order to set all the cross links right
206 fTaskList.Add(pTask);
207 AliHLTConfiguration* pDep=pConf->GetFirstSource();
208 while (pDep!=NULL && iResult>=0) {
209 HLTDebug("iteration %d: checking dependency %s (%p)", iterationLevel, pDep->GetName(), pDep);
210 if (FindTask(pDep->GetName())==NULL) {
211 HLTDebug("iteration %d: building task list for configuration %s (%p)", iterationLevel, pDep->GetName(), pDep);
213 iResult=BuildTaskList(pDep);
216 pDep=pConf->GetNextSource();
218 // remove the temporarily added task
219 fTaskList.Remove(pTask);
221 // insert the task and set the cross-links
223 HLTDebug("iteration %d: inserting task %s (%p)", iterationLevel, pTask->GetName(), pTask);
224 iResult=InsertTask(pTask);
237 int AliHLTSystem::CleanTaskList()
239 // see header file for class documentation
242 while ((lnk=fTaskList.LastLink())!=NULL) {
243 delete (lnk->GetObject());
244 fTaskList.Remove(lnk);
249 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
251 // see header file for class documentation
253 TObjLink *lnk = NULL;
254 if ((iResult=pTask->CheckDependencies())>0)
255 lnk=fTaskList.FirstLink();
256 while (lnk && iResult>0) {
257 AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
258 //HLTDebug("checking \"%s\"", pCurr->GetName());
259 iResult=pTask->Depends(pCurr);
261 iResult=pTask->SetDependency(pCurr);
262 pCurr->SetTarget(pTask);
263 HLTDebug("set dependency \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
265 if (pCurr->Depends(pTask)) {
266 // circular dependency
267 HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
269 } else if ((iResult=pTask->CheckDependencies())>0) {
275 fTaskList.AddAfter(lnk, pTask);
277 fTaskList.AddFirst(pTask);
279 HLTDebug("task \"%s\" (%p) inserted (size %d)", pTask->GetName(), pTask, sizeof(AliHLTTask));
280 } else if (iResult>0) {
281 HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
287 AliHLTTask* AliHLTSystem::FindTask(const char* id)
289 // see header file for class documentation
290 AliHLTTask* pTask=NULL;
292 pTask=(AliHLTTask*)fTaskList.FindObject(id);
297 void AliHLTSystem::PrintTaskList()
299 // see header file for class documentation
300 HLTLogKeyword("task list");
301 TObjLink *lnk = NULL;
302 HLTMessage("Task List");
303 lnk=fTaskList.FirstLink();
305 TObject* obj=lnk->GetObject();
307 HLTMessage(" %s - status:", obj->GetName());
308 AliHLTTask* pTask=(AliHLTTask*)obj;
309 pTask->PrintStatus();
316 int AliHLTSystem::Run(Int_t iNofEvents)
318 // see header file for class documentation
321 SetStatusFlags(kRunning);
322 TStopwatch StopwatchBase; StopwatchBase.Reset();
323 TStopwatch StopwatchDA; StopwatchDA.Reset();
324 TStopwatch StopwatchInput; StopwatchInput.Reset();
325 TStopwatch StopwatchOutput; StopwatchOutput.Reset();
326 TObjArray Stopwatches;
327 Stopwatches.AddAt(&StopwatchBase, (int)AliHLTComponent::kSWBase);
328 Stopwatches.AddAt(&StopwatchDA, (int)AliHLTComponent::kSWDA);
329 Stopwatches.AddAt(&StopwatchInput, (int)AliHLTComponent::kSWInput);
330 Stopwatches.AddAt(&StopwatchOutput, (int)AliHLTComponent::kSWOutput);
331 if ((iResult=InitTasks())>=0 && (iResult=InitBenchmarking(&Stopwatches))>=0) {
332 if ((iResult=StartTasks())>=0) {
333 for (int i=0; i<iNofEvents && iResult>=0; i++) {
334 iResult=ProcessTasks(i);
336 HLTInfo("Event %d successfully finished (%d)", i, iResult);
340 HLTError("Processing of event %d failed (%d)", i, iResult);
341 // TODO: define different running modes to either ignore errors in
342 // event processing or not
349 HLTError("can not start task list");
352 } else if (iResult!=-ENOENT) {
353 HLTError("can not initialize task list");
357 HLTInfo("HLT statistics:\n"
358 " base: R:%.3fs C:%.3fs\n"
359 " input: R:%.3fs C:%.3fs\n"
360 " output: R:%.3fs C:%.3fs\n"
361 " event processing : R:%.3fs C:%.3fs"
362 , StopwatchBase.RealTime(),StopwatchBase.CpuTime()
363 , StopwatchInput.RealTime(),StopwatchInput.CpuTime()
364 , StopwatchOutput.RealTime(),StopwatchOutput.CpuTime()
365 , StopwatchDA.RealTime(),StopwatchDA.CpuTime());
367 ClearStatusFlags(kRunning);
371 int AliHLTSystem::InitTasks()
373 // see header file for class documentation
375 TObjLink *lnk=fTaskList.FirstLink();
377 HLTWarning("Task list is empty, aborting ...");
380 while (lnk && iResult>=0) {
381 TObject* obj=lnk->GetObject();
383 AliHLTTask* pTask=(AliHLTTask*)obj;
384 iResult=pTask->Init(NULL, fpComponentHandler);
394 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
396 // see header file for class documentation
397 if (pStopwatches==NULL) return -EINVAL;
400 TObjLink *lnk=fTaskList.FirstLink();
401 while (lnk && iResult>=0) {
402 TObject* obj=lnk->GetObject();
404 AliHLTTask* pTask=(AliHLTTask*)obj;
405 AliHLTComponent* pComp=NULL;
406 if (iResult>=0 && (pComp=pTask->GetComponent())!=NULL) {
407 switch (pComp->GetComponentType()) {
408 case AliHLTComponent::kProcessor:
409 pComp->SetStopwatches(pStopwatches);
411 case AliHLTComponent::kSource:
413 // this switch determines whether the time consumption of the
414 // AliHLTComponent base methods should be counted to the input
415 // stopwatch or base stopwatch.
416 //int inputBase=(int)AliHLTComponent::kSWBase;
417 int inputBase=(int)AliHLTComponent::kSWInput;
418 pComp->SetStopwatch(pStopwatches->At(inputBase), AliHLTComponent::kSWBase);
419 pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWInput), AliHLTComponent::kSWDA);
422 case AliHLTComponent::kSink:
424 // this switch determines whether the time consumption of the
425 // AliHLTComponent base methods should be counted to the output
426 // stopwatch or base stopwatch.
427 //int outputBase=(int)AliHLTComponent::kSWBase;
428 int outputBase=(int)AliHLTComponent::kSWOutput;
429 pComp->SetStopwatch(pStopwatches->At(outputBase), AliHLTComponent::kSWBase);
430 pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWOutput), AliHLTComponent::kSWDA);
434 HLTWarning("unknown component type %d", (int)pComp->GetComponentType());
444 int AliHLTSystem::StartTasks()
446 // see header file for class documentation
448 TObjLink *lnk=fTaskList.FirstLink();
449 while (lnk && iResult>=0) {
450 TObject* obj=lnk->GetObject();
452 AliHLTTask* pTask=(AliHLTTask*)obj;
453 iResult=pTask->StartRun();
463 int AliHLTSystem::ProcessTasks(Int_t eventNo)
465 // see header file for class documentation
467 HLTDebug("processing event no %d", eventNo);
468 TObjLink *lnk=fTaskList.FirstLink();
469 while (lnk && iResult>=0) {
470 TObject* obj=lnk->GetObject();
472 AliHLTTask* pTask=(AliHLTTask*)obj;
473 iResult=pTask->ProcessTask(eventNo);
474 HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
482 int AliHLTSystem::StopTasks()
484 // see header file for class documentation
486 TObjLink *lnk=fTaskList.FirstLink();
487 while (lnk && iResult>=0) {
488 TObject* obj=lnk->GetObject();
490 AliHLTTask* pTask=(AliHLTTask*)obj;
491 iResult=pTask->EndRun();
499 int AliHLTSystem::DeinitTasks()
501 // see header file for class documentation
503 TObjLink *lnk=fTaskList.FirstLink();
504 while (lnk && iResult>=0) {
505 TObject* obj=lnk->GetObject();
507 AliHLTTask* pTask=(AliHLTTask*)obj;
508 iResult=pTask->Deinit();
516 void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
518 // see header file for class documentation
521 p=(void*)new char[size];
525 log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
530 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader,
531 AliRawReader* rawReader)
533 // see header file for class documentation
536 HLTInfo("Run Loader %p, Raw Reader %p , %d events", runLoader, rawReader, nofEvents);
537 if (CheckStatus(kReady)) {
538 if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
539 iResult=Run(nofEvents);
542 HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
545 HLTError("missing run loader instance");
551 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
553 // see header file for class documentation
556 HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
557 iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
559 HLTError("missing run loader/ESD instance(s)");
565 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
567 // see header file for class documentation
570 if (fpComponentHandler) {
571 TString libs(libraries);
572 TObjArray* pTokens=libs.Tokenize(" ");
574 int iEntries=pTokens->GetEntries();
575 for (int i=0; i<iEntries && iResult>=0; i++) {
576 iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
581 SetStatusFlags(kLibrariesLoaded);
583 // lets see if we need this, probably not
584 //fpComponentHandler->UnloadLibraries();
585 ClearStatusFlags(kLibrariesLoaded);
589 HLTFatal("no component handler available");
597 int AliHLTSystem::Configure(AliRunLoader* runloader)
599 // see header file for class documentation
601 if (CheckStatus(kRunning)) {
602 HLTError("HLT system in running state, can not configure");
605 ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
606 if (CheckFilter(kHLTLogDebug))
607 AliHLTModuleAgent::PrintStatus();
608 if (CheckStatus(kConfigurationLoaded)==0) {
609 iResult=LoadConfigurations(runloader);
611 if (fLocalRec.Length()==0) {
612 HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'localrec=<conf>\' option");
617 SetStatusFlags(kConfigurationLoaded);
618 if (CheckFilter(kHLTLogDebug))
619 fpConfigurationHandler->PrintConfigurations();
620 iResult=BuildTaskListsFromTopConfigurations(runloader);
622 SetStatusFlags(kTaskListCreated);
625 if (iResult<0) SetStatusFlags(kError);
630 int AliHLTSystem::ScanOptions(const char* options)
632 // see header file for class documentation
635 TString alloptions(options);
636 TObjArray* pTokens=alloptions.Tokenize(" ");
638 int iEntries=pTokens->GetEntries();
639 for (int i=0; i<iEntries; i++) {
640 TString token=(((TObjString*)pTokens->At(i))->GetString());
641 if (token.Contains("loglevel=")) {
642 TString param=token.ReplaceAll("loglevel=", "");
643 if (param.IsDigit()) {
644 SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
645 } else if (param.BeginsWith("0x") &&
646 param.Replace(0,2,"",0).IsHex()) {
648 sscanf(param.Data(),"%x", &severity);
649 SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
651 HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
653 } else if (token.Contains("alilog=off")) {
655 } else if (token.Contains("config=")) {
656 TString param=token.ReplaceAll("config=", "");
658 gROOT->Macro(param.Data(), &error);
660 SetStatusFlags(kConfigurationLoaded);
662 HLTError("can not execute macro \'%s\'", param.Data());
665 } else if (token.Contains("localrec=")) {
666 TString param=token.ReplaceAll("localrec=", "");
667 fLocalRec=param.ReplaceAll(",", " ");
669 HLTWarning("unknown option \'%s\'", token.Data());
678 int AliHLTSystem::Reset(int bForce)
680 // see header file for class documentation
682 if (!bForce && CheckStatus(kRunning)) {
683 HLTError("HLT system in running state, can not configure");
687 ClearStatusFlags(~kUninitialized);
691 int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
693 // see header file for class documentation
694 if (CheckStatus(kRunning)) {
695 HLTError("HLT system in running state, can not configure");
699 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
700 while (pAgent && iResult>=0) {
701 const char* deplibs=pAgent->GetRequiredComponentLibraries();
703 HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
704 iResult=LoadComponentLibraries(deplibs);
707 HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
708 pAgent->CreateConfigurations(fpConfigurationHandler, runloader);
709 pAgent=AliHLTModuleAgent::GetNextAgent();
715 int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
717 // see header file for class documentation
718 if (CheckStatus(kRunning)) {
719 HLTError("HLT system in running state, can not configure");
722 if (!CheckStatus(kConfigurationLoaded)) {
723 HLTWarning("configurations not yet loaded");
728 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
729 while ((pAgent || fLocalRec.Length()>0) && iResult>=0) {
731 if (fLocalRec.Length()>0) {
733 HLTInfo("custom local reconstruction configurations: %s", tops.Data());
735 tops=pAgent->GetLocalRecConfigurations(runloader);
736 HLTInfo("local reconstruction configurations for agent %s (%p): %s", pAgent->GetName(), pAgent, tops.Data());
738 TObjArray* pTokens=tops.Tokenize(" ");
740 int iEntries=pTokens->GetEntries();
741 for (int i=0; i<iEntries && iResult>=0; i++) {
742 const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
743 AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
745 iResult=BuildTaskList(pConf);
747 HLTWarning("can not find top configuration %s", pCID);
753 if (fLocalRec.Length()>0) {
754 break; // ignore the agents
756 pAgent=AliHLTModuleAgent::GetNextAgent();
758 if (iResult>=0) SetStatusFlags(kTaskListCreated);
763 int AliHLTSystem::CheckStatus(int flag)
765 // see header file for class documentation
766 if (flag==kUninitialized && flag==fState) return 1;
767 if ((fState&flag)==flag) return 1;
771 int AliHLTSystem::GetStatusFlags()
773 // see header file for class documentation
777 int AliHLTSystem::SetStatusFlags(int flags)
779 // see header file for class documentation
784 int AliHLTSystem::ClearStatusFlags(int flags)
786 // see header file for class documentation
791 void* AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
793 // see header file for class documentation
794 if (fpComponentHandler==NULL) return NULL;
795 return fpComponentHandler->FindSymbol(library, symbol);