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 fpComponentHandler->SetEnvironment(&env);
69 HLTFatal("can not create Component Handler");
71 if (fpConfigurationHandler) {
72 AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
74 HLTFatal("can not create Configuration Handler");
78 AliHLTSystem::AliHLTSystem(const AliHLTSystem&)
81 fpComponentHandler(NULL),
82 fpConfigurationHandler(NULL),
86 // see header file for class documentation
87 if (fgNofInstances++>0)
88 HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
90 HLTFatal("copy constructor untested");
93 AliHLTSystem& AliHLTSystem::operator=(const AliHLTSystem&)
95 // see header file for class documentation
96 HLTFatal("assignment operator untested");
100 AliHLTSystem::~AliHLTSystem()
102 // see header file for class documentation
105 AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
106 if (fpConfigurationHandler) {
107 delete fpConfigurationHandler;
109 fpConfigurationHandler=NULL;
111 if (fpComponentHandler) {
112 delete fpComponentHandler;
114 fpComponentHandler=NULL;
117 int AliHLTSystem::fgNofInstances=0;
119 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
121 // see header file for class documentation
130 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
132 // see header file for class documentation
144 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
146 // see header file for class documentation
155 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
157 // see header file for class documentation
160 AliHLTTask* pTask=NULL;
161 if ((pTask=FindTask(pConf->GetName()))!=NULL) {
162 if (pTask->GetConf()!=pConf) {
163 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);
167 } else if (pConf->SourcesResolved(1)!=1) {
168 HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
171 pTask=new AliHLTTask(pConf);
177 // check for circular dependencies
178 if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
179 HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
180 pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
181 HLTError("aborted ...");
185 // check whether all dependencies are already in the task list
186 // create the missing ones
187 // this step is an iterative process which calls this function again for the missing
188 // configurations, in order to avoid the currently processed task to be created
189 // again it is added to the list temporarily and removed afterwards
190 // This is of high importance to preserve the order of the tasks. Furthermore, the
191 // InsertTask method has to be used in order to set all the cross links right
192 fTaskList.Add(pTask);
193 AliHLTConfiguration* pDep=pConf->GetFirstSource();
194 while (pDep!=NULL && iResult>=0) {
195 if (FindTask(pDep->GetName())==NULL) {
196 iResult=BuildTaskList(pDep);
198 pDep=pConf->GetNextSource();
200 // remove the temporarily added task
201 fTaskList.Remove(pTask);
203 // insert the task and set the cross-links
205 iResult=InsertTask(pTask);
218 int AliHLTSystem::CleanTaskList()
220 // see header file for class documentation
223 while ((lnk=fTaskList.FirstLink())!=NULL) {
224 fTaskList.Remove(lnk);
225 delete (lnk->GetObject());
230 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
232 // see header file for class documentation
234 TObjLink *lnk = NULL;
235 if ((iResult=pTask->CheckDependencies())>0)
236 lnk=fTaskList.FirstLink();
237 while (lnk && iResult>0) {
238 AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
239 //HLTDebug("checking \"%s\"", pCurr->GetName());
240 iResult=pTask->Depends(pCurr);
242 iResult=pTask->SetDependency(pCurr);
243 pCurr->SetTarget(pTask);
244 HLTDebug("set dependency \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
246 if (pCurr->Depends(pTask)) {
247 // circular dependency
248 HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
250 } else if ((iResult=pTask->CheckDependencies())>0) {
256 fTaskList.AddAfter(lnk, pTask);
258 fTaskList.AddFirst(pTask);
260 HLTDebug("task \"%s\" inserted", pTask->GetName());
261 } else if (iResult>0) {
262 HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
268 AliHLTTask* AliHLTSystem::FindTask(const char* id)
270 // see header file for class documentation
271 AliHLTTask* pTask=NULL;
273 pTask=(AliHLTTask*)fTaskList.FindObject(id);
278 void AliHLTSystem::PrintTaskList()
280 // see header file for class documentation
281 HLTLogKeyword("task list");
282 TObjLink *lnk = NULL;
283 HLTMessage("Task List");
284 lnk=fTaskList.FirstLink();
286 TObject* obj=lnk->GetObject();
288 HLTMessage(" %s - status:", obj->GetName());
289 AliHLTTask* pTask=(AliHLTTask*)obj;
290 pTask->PrintStatus();
297 int AliHLTSystem::Run(Int_t iNofEvents)
299 // see header file for class documentation
302 SetStatusFlags(kRunning);
303 TStopwatch StopwatchBase; StopwatchBase.Reset();
304 TStopwatch StopwatchDA; StopwatchDA.Reset();
305 TStopwatch StopwatchInput; StopwatchInput.Reset();
306 TStopwatch StopwatchOutput; StopwatchOutput.Reset();
307 TObjArray Stopwatches;
308 Stopwatches.AddAt(&StopwatchBase, (int)AliHLTComponent::kSWBase);
309 Stopwatches.AddAt(&StopwatchDA, (int)AliHLTComponent::kSWDA);
310 Stopwatches.AddAt(&StopwatchInput, (int)AliHLTComponent::kSWInput);
311 Stopwatches.AddAt(&StopwatchOutput, (int)AliHLTComponent::kSWOutput);
312 if ((iResult=InitTasks())>=0 && (iResult=InitBenchmarking(&Stopwatches))>=0) {
313 if ((iResult=StartTasks())>=0) {
314 for (int i=0; i<iNofEvents && iResult>=0; i++) {
315 iResult=ProcessTasks(i);
317 HLTInfo("Event %d successfully finished (%d)", i, iResult);
321 HLTError("Processing of event %d failed (%d)", i, iResult);
322 // TODO: define different running modes to either ignore errors in
323 // event processing or not
330 HLTError("can not start task list");
333 } else if (iResult!=-ENOENT) {
334 HLTError("can not initialize task list");
338 HLTInfo("HLT statistics:\n"
339 " base: R:%.3fs C:%.3fs\n"
340 " input: R:%.3fs C:%.3fs\n"
341 " output: R:%.3fs C:%.3fs\n"
342 " event processing : R:%.3fs C:%.3fs"
343 , StopwatchBase.RealTime(),StopwatchBase.CpuTime()
344 , StopwatchInput.RealTime(),StopwatchInput.CpuTime()
345 , StopwatchOutput.RealTime(),StopwatchOutput.CpuTime()
346 , StopwatchDA.RealTime(),StopwatchDA.CpuTime());
348 ClearStatusFlags(kRunning);
352 int AliHLTSystem::InitTasks()
354 // see header file for class documentation
356 TObjLink *lnk=fTaskList.FirstLink();
358 HLTWarning("Task list is empty, aborting ...");
361 while (lnk && iResult>=0) {
362 TObject* obj=lnk->GetObject();
364 AliHLTTask* pTask=(AliHLTTask*)obj;
365 iResult=pTask->Init(NULL, fpComponentHandler);
375 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
377 // see header file for class documentation
378 if (pStopwatches==NULL) return -EINVAL;
381 TObjLink *lnk=fTaskList.FirstLink();
382 while (lnk && iResult>=0) {
383 TObject* obj=lnk->GetObject();
385 AliHLTTask* pTask=(AliHLTTask*)obj;
386 AliHLTComponent* pComp=NULL;
387 if (iResult>=0 && (pComp=pTask->GetComponent())!=NULL) {
388 switch (pComp->GetComponentType()) {
389 case AliHLTComponent::kProcessor:
390 pComp->SetStopwatches(pStopwatches);
392 case AliHLTComponent::kSource:
394 // this switch determines whether the time consumption of the
395 // AliHLTComponent base methods should be counted to the input
396 // stopwatch or base stopwatch.
397 //int inputBase=(int)AliHLTComponent::kSWBase;
398 int inputBase=(int)AliHLTComponent::kSWInput;
399 pComp->SetStopwatch(pStopwatches->At(inputBase), AliHLTComponent::kSWBase);
400 pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWInput), AliHLTComponent::kSWDA);
403 case AliHLTComponent::kSink:
405 // this switch determines whether the time consumption of the
406 // AliHLTComponent base methods should be counted to the output
407 // stopwatch or base stopwatch.
408 //int outputBase=(int)AliHLTComponent::kSWBase;
409 int outputBase=(int)AliHLTComponent::kSWOutput;
410 pComp->SetStopwatch(pStopwatches->At(outputBase), AliHLTComponent::kSWBase);
411 pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWOutput), AliHLTComponent::kSWDA);
423 int AliHLTSystem::StartTasks()
425 // see header file for class documentation
427 TObjLink *lnk=fTaskList.FirstLink();
428 while (lnk && iResult>=0) {
429 TObject* obj=lnk->GetObject();
431 AliHLTTask* pTask=(AliHLTTask*)obj;
432 iResult=pTask->StartRun();
442 int AliHLTSystem::ProcessTasks(Int_t eventNo)
444 // see header file for class documentation
446 HLTDebug("processing event no %d", eventNo);
447 TObjLink *lnk=fTaskList.FirstLink();
448 while (lnk && iResult>=0) {
449 TObject* obj=lnk->GetObject();
451 AliHLTTask* pTask=(AliHLTTask*)obj;
452 iResult=pTask->ProcessTask(eventNo);
453 HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
461 int AliHLTSystem::StopTasks()
463 // see header file for class documentation
465 TObjLink *lnk=fTaskList.FirstLink();
466 while (lnk && iResult>=0) {
467 TObject* obj=lnk->GetObject();
469 AliHLTTask* pTask=(AliHLTTask*)obj;
470 iResult=pTask->EndRun();
478 int AliHLTSystem::DeinitTasks()
480 // see header file for class documentation
482 TObjLink *lnk=fTaskList.FirstLink();
483 while (lnk && iResult>=0) {
484 TObject* obj=lnk->GetObject();
486 AliHLTTask* pTask=(AliHLTTask*)obj;
487 iResult=pTask->Deinit();
495 void* AliHLTSystem::AllocMemory( void* param, unsigned long size )
497 // see header file for class documentation
499 // get rid of 'unused parameter' warning
501 return (void*)new char[size];
504 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader,
505 AliRawReader* rawReader)
507 // see header file for class documentation
510 HLTInfo("Run Loader %p, Raw Reader %p , %d events", runLoader, rawReader, nofEvents);
511 if (CheckStatus(kReady)) {
512 if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
513 iResult=Run(nofEvents);
516 HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
519 HLTError("missing run loader instance");
525 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESD* esd)
527 // see header file for class documentation
530 HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
531 iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
533 HLTError("missing run loader/ESD instance(s)");
539 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
541 // see header file for class documentation
544 if (fpComponentHandler) {
545 TString libs(libraries);
546 TObjArray* pTokens=libs.Tokenize(" ");
548 int iEntries=pTokens->GetEntries();
549 for (int i=0; i<iEntries && iResult>=0; i++) {
550 iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
555 SetStatusFlags(kLibrariesLoaded);
557 // lets see if we need this, probably not
558 //fpComponentHandler->UnloadLibraries();
559 ClearStatusFlags(kLibrariesLoaded);
563 HLTFatal("no component handler available");
571 int AliHLTSystem::Configure(AliRunLoader* runloader)
573 // see header file for class documentation
575 if (CheckStatus(kRunning)) {
576 HLTError("HLT system in running state, can not configure");
579 if (CheckFilter(kHLTLogDebug))
580 AliHLTModuleAgent::PrintStatus();
581 ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
582 iResult=LoadConfigurations(runloader);
584 SetStatusFlags(kConfigurationLoaded);
585 iResult=BuildTaskListsFromTopConfigurations(runloader);
587 SetStatusFlags(kTaskListCreated);
590 if (iResult<0) SetStatusFlags(kError);
595 int AliHLTSystem::Reset(int bForce)
597 // see header file for class documentation
599 if (!bForce && CheckStatus(kRunning)) {
600 HLTError("HLT system in running state, can not configure");
604 ClearStatusFlags(~kUninitialized);
608 int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
610 // see header file for class documentation
611 if (CheckStatus(kRunning)) {
612 HLTError("HLT system in running state, can not configure");
616 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
617 while (pAgent && iResult>=0) {
618 const char* deplibs=pAgent->GetRequiredComponentLibraries();
620 HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
621 iResult=LoadComponentLibraries(deplibs);
624 HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
625 pAgent->CreateConfigurations(fpConfigurationHandler, runloader);
626 pAgent=AliHLTModuleAgent::GetNextAgent();
632 int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
634 // see header file for class documentation
635 if (CheckStatus(kRunning)) {
636 HLTError("HLT system in running state, can not configure");
639 if (!CheckStatus(kConfigurationLoaded)) {
640 HLTWarning("configurations not yet loaded");
645 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
646 while (pAgent && iResult>=0) {
647 TString tops=pAgent->GetLocalRecConfigurations(runloader);
648 HLTDebug("top configurations for agent %s (%p): %s", pAgent->GetName(), pAgent, tops.Data());
649 TObjArray* pTokens=tops.Tokenize(" ");
651 int iEntries=pTokens->GetEntries();
652 for (int i=0; i<iEntries && iResult>=0; i++) {
653 const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
654 AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
656 iResult=BuildTaskList(pConf);
658 HLTWarning("can not find top configuration %s", pCID);
664 pAgent=AliHLTModuleAgent::GetNextAgent();
666 if (iResult>=0) SetStatusFlags(kTaskListCreated);
671 int AliHLTSystem::CheckStatus(int flag)
673 // see header file for class documentation
674 if (flag==kUninitialized && flag==fState) return 1;
675 if ((fState&flag)==flag) return 1;
679 int AliHLTSystem::GetStatusFlags()
681 // see header file for class documentation
685 int AliHLTSystem::SetStatusFlags(int flags)
687 // see header file for class documentation
692 int AliHLTSystem::ClearStatusFlags(int flags)
694 // see header file for class documentation