Commit f967f29d authored by Marco Clemencic's avatar Marco Clemencic

Merge branch 'ConditionsAlgStallDebug' into 'master'

Conditions alg test, with stall debug info

See merge request !1092
parents 347120d7 42dcb057
Pipeline #1730363 passed with stages
in 16 minutes and 59 seconds
/***********************************************************************************\
* (c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations *
* *
* This software is distributed under the terms of the Apache version 2 licence, *
* copied verbatim in the file "LICENSE". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\***********************************************************************************/
#pragma once
#include "GaudiKernel/IAlgResourcePool.h"
#include "GaudiKernel/ICondSvc.h"
#include "GaudiKernel/Property.h"
#include "GaudiKernel/Service.h"
#include "GaudiKernel/SmartIF.h"
namespace Gaudi::Examples::Conditions {
/// Implementation of ICondSvc used for testing
/// Allows declaration of one or more algorithms or data objects
/// as belonging to the "conditions realm"
/// The scheduler will then treat them differently
class CondSvc : public extends<Service, ICondSvc> {
public:
using extends::extends;
StatusCode initialize() override;
StatusCode regHandle( IAlgorithm*, const Gaudi::DataHandle& ) override { return StatusCode::SUCCESS; };
/// check to see if a specific condition object ID is valid for this event
bool isValidID( const EventContext&, const DataObjID& ) const override { return false; };
/// get list of all registered condition Algorithms
const std::set<IAlgorithm*>& condAlgs() const override { return m_condAlgs; };
/// query if a specific Algorithm is a registered condition Algorithm
bool isRegistered( IAlgorithm* alg ) const override { return ( m_condAlgs.find( alg ) != m_condAlgs.end() ); };
/// query if a condition Object ID is registered
bool isRegistered( const DataObjID& id ) const override { return ( m_condData.find( id ) != m_condData.end() ); };
/// get collection of all registered condition Object IDs
const DataObjIDColl& conditionIDs() const override { return m_condData; }
/// dump the condition store
void dump( std::ostream& ) const override{};
/// retrieve all valid ranges for one Object ID
StatusCode validRanges( std::vector<EventIDRange>&, const DataObjID& ) const override {
return StatusCode::SUCCESS;
};
/// Asynchronously setup conditions
ConditionSlotFuture* startConditionSetup( const EventContext& ) override { return nullptr; };
/// register an IConditionIOSvc (alternative to Algorithm processing of
/// Conditions)
StatusCode registerConditionIOSvc( IConditionIOSvc* ) override { return StatusCode::SUCCESS; }
private:
std::set<IAlgorithm*> m_condAlgs;
Gaudi::Property<std::vector<std::string>> m_algNames{this, "Algs", {}, "Names of conditions algorithms"};
DataObjIDColl m_condData;
Gaudi::Property<std::vector<std::string>> m_dataNames{this, "Data", {}, "Names of conditions data"};
SmartIF<IAlgResourcePool> m_algResourcePool;
};
DECLARE_COMPONENT( CondSvc )
} // namespace Gaudi::Examples::Conditions
/***********************************************************************************\
* (c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations *
* *
* This software is distributed under the terms of the Apache version 2 licence, *
* copied verbatim in the file "LICENSE". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\***********************************************************************************/
#include <Gaudi/Examples/Conditions/CondSvc.h>
namespace Gaudi::Examples::Conditions {
StatusCode CondSvc::initialize() {
// Convert alg names vector to a set for easier search
std::set<std::string> algNameSet( m_algNames.begin(), m_algNames.end() );
// Get conditions alg pointers
m_algResourcePool = serviceLocator()->service( "AlgResourcePool" );
for ( auto& alg : m_algResourcePool->getFlatAlgList() ) {
if ( algNameSet.find( alg->name() ) != algNameSet.end() ) { m_condAlgs.insert( alg ); }
}
// Get conditions data ids
for ( auto& name : m_dataNames ) { m_condData.insert( DataObjID( name ) ); }
return StatusCode::SUCCESS;
}
} // namespace Gaudi::Examples::Conditions
#!/usr/bin/env gaudirun.py
#####################################################################################
# (c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations #
# #
# This software is distributed under the terms of the Apache version 2 licence, #
# copied verbatim in the file "LICENSE". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
#####################################################################################
'''
A test to demonstrate stalling for a conditions algorithm
- Control flow requires that Alg C run after Alg B
- Alg B requires conditions data produced by Alg A
- However, Alg A requires the output from Alg C, and thus the job will stall
'''
from Gaudi.Configuration import *
from Configurables import (HiveWhiteBoard, HiveSlimEventLoopMgr,
AvalancheSchedulerSvc, AlgResourcePool,
Test__ViewTester)
# metaconfig -------------------------------------------------------------------
# It's confortable to collect the relevant parameters at the top of the optionfile
evtslots = 1
evtMax = 10
threads = 1
# -------------------------------------------------------------------------------
# The configuration of the whiteboard ------------------------------------------
# It is useful to call it EventDataSvc to replace the usual data service with
# the whiteboard transparently.
whiteboard = HiveWhiteBoard("EventDataSvc", EventSlots=evtslots)
# -------------------------------------------------------------------------------
# Event Loop Manager -----------------------------------------------------------
# It's called slim since it has less functionalities overall than the good-old
# event loop manager. Here we just set its outputlevel to DEBUG.
slimeventloopmgr = HiveSlimEventLoopMgr(
SchedulerName="AvalancheSchedulerSvc", OutputLevel=INFO)
# -------------------------------------------------------------------------------
# ForwardScheduler -------------------------------------------------------------
# We just decide how many algorithms in flight we want to have and how many
# threads in the pool. The default value is -1, which is for TBB equivalent
# to take over the whole machine.
scheduler = AvalancheSchedulerSvc(
ThreadPoolSize=threads,
OutputLevel=INFO,
CheckDependencies=True,
DataLoaderAlg="")
# -------------------------------------------------------------------------------
# Algo Resource Pool -----------------------------------------------------------
# Nothing special here, we just set the debug level.
AlgResourcePool(OutputLevel=INFO)
# -------------------------------------------------------------------------------
# Conditions service -----------------------------------------------------------
# This declares algorithms or data to be part of the "conditions realm"
# They are detached from the regular CF graph
from Configurables import Gaudi__Examples__Conditions__CondSvc as CS
condSvc = CS(name="CondSvc", Algs=["AlgA"], Data=["/Event/A1"])
# -------------------------------------------------------------------------------
# Set up of the crunchers, daily business --------------------------------------
a1 = Test__ViewTester("AlgA", OutputLevel=INFO)
a1.outKeys = ['/Event/A1']
a1.inpKeys = ['/Event/A2']
a2 = Test__ViewTester("AlgB", OutputLevel=INFO)
a2.inpKeys = ['/Event/A1']
a3 = Test__ViewTester("AlgC", OutputLevel=INFO)
a3.outKeys = ['/Event/A2']
algSeq = GaudiSequencer(
"algSeq", Members=[a1, a2, a3], Sequential=True, OutputLevel=INFO)
# Application Manager ----------------------------------------------------------
# We put everything together and change the type of message service
ApplicationMgr(
EvtMax=evtMax,
EvtSel='NONE',
ExtSvc=[whiteboard, condSvc],
EventLoop=slimeventloopmgr,
TopAlg=[algSeq],
MessageSvcType="InertMessageSvc")
# -------------------------------------------------------------------------------
......@@ -255,6 +255,45 @@ namespace concurrency {
return sc;
}
//---------------------------------------------------------------------------
void PrecedenceRulesGraph::printState( std::stringstream& output, EventSlot& slot,
const unsigned int& recursionLevel ) const {
if ( slot.parentSlot ) {
// Start at sub-slot entry point
m_decisionNameToDecisionHubMap.at( slot.entryPoint )->printState( output, slot, recursionLevel );
} else {
// Start at the head node for whole-event slots
m_headNode->printState( output, slot, recursionLevel );
}
// Find detached conditions algs in interesting states
if ( m_conditionsRealmEnabled ) {
bool firstPrint = true;
SmartIF<ICondSvc> condSvc{serviceLocator()->service( "CondSvc", false )};
auto& condAlgs = condSvc->condAlgs();
for ( const auto algo : condAlgs ) {
auto itA = m_algoNameToAlgoNodeMap.find( algo->name() );
if ( itA != m_algoNameToAlgoNodeMap.end() ) {
concurrency::AlgorithmNode* algoNode = itA->second.get();
// Ignore boring states (reduces verbosity)
auto& thisState = slot.algsStates[algoNode->getAlgoIndex()];
if ( thisState == AlgsExecutionStates::State::INITIAL ||
thisState == AlgsExecutionStates::State::EVTACCEPTED )
continue;
// Make output
if ( firstPrint ) {
firstPrint = false;
output << std::endl << "Detached algorithms:" << std::endl;
}
algoNode->printState( output, slot, recursionLevel );
}
}
}
}
//---------------------------------------------------------------------------
void PrecedenceRulesGraph::registerIODataObjects( const Gaudi::Algorithm* algo ) {
......
......@@ -680,15 +680,7 @@ namespace concurrency {
SmartIF<ISvcLocator>& serviceLocator() const override { return m_svcLocator; }
///
/// Print a string representing the control flow state
void printState( std::stringstream& output, EventSlot& slot, const unsigned int& recursionLevel ) const {
if ( slot.parentSlot ) {
// Start at sub-slot entry point
m_decisionNameToDecisionHubMap.at( slot.entryPoint )->printState( output, slot, recursionLevel );
} else {
// Start at the head node for whole-event slots
m_headNode->printState( output, slot, recursionLevel );
}
}
void printState( std::stringstream& output, EventSlot& slot, const unsigned int& recursionLevel ) const;
/// BGL-based facilities
void enableAnalysis() { m_enableAnalysis = true; };
......
<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
<!--
(c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations
This software is distributed under the terms of the Apache version 2 licence,
copied verbatim in the file "LICENSE".
In applying this licence, CERN does not waive the privileges and immunities
granted to it by virtue of its status as an Intergovernmental Organization
or submit itself to any jurisdiction.
-->
<extension class="GaudiTest.GaudiExeTest" kind="test">
<argument name="program"><text>gaudirun.py</text></argument>
<argument name="args"><set><text>../../options/ConditionsStallTest.py</text></set></argument>
<argument name="validator"><text>
expected_string = &quot;AlgA (2), w/ decision: UNDEFINED(-1), in state: CONTROLREADY&quot;
if stdout.find(expected_string) == -1:
causes.append(&apos;missing string: no signature of conditions stall detection found&apos;)
result[&apos;GaudiTest.expected_string&apos;] = result.Quote(expected_string)
</text></argument>
<argument name="timeout"><integer>60</integer></argument>
</extension>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment