13 Reference optionfile which shows in a simple way how to take advantage of the 
   14 Gaudi components desicated to concurrency. 
   16  o HiveWhiteBoard: a convenient way to collect several TES (one per "processing 
   17  slot"), accessible in a thread safe way, keeps a catalogue of the products 
   18  written on each processing slot. The number of slots in the whiteboard 
   19  determines also the number of events processed simultaneously by the scheduler. 
   20  o AvalancheSchedulerSvc: state machine of the algorithms interfaced with the 
   21  TBB runtime. It is responsible for the submission of the algorithms. An 
   22  algorithm is marked ready for submission when its needed input is available. 
   23  It deals the asynchronous termination of algorithms with a "receiver" thread 
   24  and a thread safe queue. 
   25  o HiveSlimEventLoopMgr: an event factory. Pushes new events and pops finished 
   26  events to/from the scheduler. It does not manage algorithms/streams. 
   27  o AlgResourcePool: Service managing the creation of algorithms (through the 
   28  algorithm manager), including clones. It also manages the algorithms according 
   29  to the resources they need (parameter NeededResources - vector of strings - of 
   31  o InertMessageSvc: as the TBBMsgSvc, it manages the printing of the messages in 
   32  a multithreaded environment. 
   34 The CPUCruncher is not a component dealing with concurrency, but a useful 
   35 entity to test it. It's an algorithm that simply wastes cpu. 
   39 from Configurables 
import (
 
   41     AvalancheSchedulerSvc,
 
   42     ContextEventCounterData,
 
   43     ContextEventCounterPtr,
 
   65 whiteboard = HiveWhiteBoard(
"EventDataSvc", EventSlots=evtslots)
 
   73 slimeventloopmgr = HiveSlimEventLoopMgr(
 
   74     SchedulerName=
"AvalancheSchedulerSvc", OutputLevel=WARNING
 
   84 scheduler = AvalancheSchedulerSvc(
 
   85     ThreadPoolSize=threads, NumOffloadThreads=gpuThreads, OutputLevel=WARNING
 
   92 AlgResourcePool(OutputLevel=WARNING)
 
   94 CPUCrunchSvc(shortCalib=
True)
 
  100 a1 = CPUCruncher(
"A1")
 
  101 a1.outKeys = [
"/Event/a1"]
 
  103 a2 = CPUCruncher(
"A2")
 
  104 a2.inpKeys = [
"/Event/a1"]
 
  105 a2.outKeys = [
"/Event/a2"]
 
  107 a3 = CPUCruncher(
"A3")
 
  108 a3.inpKeys = [
"/Event/a1"]
 
  109 a3.outKeys = [
"/Event/a3"]
 
  111 ga1 = GPUCruncher(
"GA1")
 
  112 ga1.inpKeys = [
"/Event/a1"]
 
  113 ga1.outKeys = [
"/Event/ga1"]
 
  115 ga2 = GPUCruncher(
"GA2")
 
  116 ga2.inpKeys = [
"/Event/ga1"]
 
  117 ga2.outKeys = [
"/Event/ga2"]
 
  119 a4 = CPUCruncher(
"A4")
 
  120 a4.inpKeys = [
"/Event/a2", 
"/Event/a3", 
"/Event/ga2"]
 
  122 a4.outKeys = [
"/Event/a4"]
 
  124 for algo 
in [a1, a2, a3, a4, ga1, ga2]:
 
  125     algo.Cardinality = cardinality
 
  126     algo.OutputLevel = INFO
 
  127     algo.varRuntime = 0.001
 
  128     algo.avgRuntime = 0.001
 
  130 for algo 
in [ga1, ga2]:
 
  131     algo.avgRuntime = 10.0
 
  132     algo.varRuntime = 1.00
 
  135 ctrp = ContextEventCounterPtr(
"CNT*", Cardinality=1, OutputLevel=INFO)
 
  136 ctrd = ContextEventCounterData(
"CNT&", Cardinality=1, OutputLevel=INFO)
 
  145     EventLoop=slimeventloopmgr,
 
  146     TopAlg=[a1, a2, a3, a4, ga1, ga2, ctrp, ctrd],
 
  148     MessageSvcType=
"InertMessageSvc",