15base_class(name, pSvcLocator),
44 ATH_MSG_WARNING(
"numConcurrentEvents() == 0. This is a misconfiguration, probably coming from running from pickle. "
45 "Setting local m_eventSlots to a 'large' number until this is fixed to allow the job to proceed.");
60 return StatusCode::SUCCESS;
69 ATH_MSG_INFO(
"Calling hashes2file, saving dump of job's HLT hashing dictionary to disk.");
71 return StatusCode::SUCCESS;
84 std::unique_lock lockUnique(
m_slotMutex[ context.slot() ] );
100 return StatusCode::SUCCESS;
113 std::shared_lock lockShared(
m_slotMutex[ context.slot() ] );
121 << (
type == AuditType::Before ?
"BEGAN" :
"ENDED") <<
" at " << now.microsecondsSinceEpoch());
135 return StatusCode::SUCCESS;
142 if (
type == AuditType::Before) {
146 std::this_thread::get_id(),
148 static_cast<uint32_t
>(context.slot())
154 tbb::concurrent_hash_map<std::thread::id, AlgorithmIdentifier, ThreadHashCompare>::accessor acc;
159 }
else if (
type == AuditType::After) {
165 ATH_MSG_ERROR(
"Only expecting AuditType::Before or AuditType::After");
166 return StatusCode::FAILURE;
170 return StatusCode::SUCCESS;
183 tbb::concurrent_hash_map<std::thread::id, AlgorithmIdentifier, ThreadHashCompare>::const_accessor acc;
186 ATH_MSG_WARNING(
"Cannot find algorithm on this thread (id=" << std::this_thread::get_id() <<
"). Request "<< payload <<
" won't be monitored");
187 return StatusCode::SUCCESS;
190 theAlg = acc->second;
196 std::shared_lock lockShared(
m_slotMutex[ context.slot() ] );
200 return StatusCode::SUCCESS;
211 return StatusCode::SUCCESS;
226 std::unique_lock lockUnique(
m_slotMutex[ context.slot() ] );
231 uint64_t eventStopTime = 0;
235 tbb::concurrent_hash_map<AlgorithmIdentifier, TrigTimeStamp, AlgorithmIdentifierHashCompare>::const_accessor stopTimeAcessor;
239 eventStopTime = stopTimeAcessor->second.microsecondsSinceEpoch();
244 uint64_t eventStartTime = 0;
248 tbb::concurrent_hash_map<AlgorithmIdentifier, AlgorithmPayload, AlgorithmIdentifierHashCompare>::const_accessor startAcessor;
252 eventStartTime = startAcessor->second.m_algStartTime.microsecondsSinceEpoch();
257 tbb::concurrent_hash_map< AlgorithmIdentifier, AlgorithmPayload, AlgorithmIdentifierHashCompare>::const_iterator beginIt;
258 tbb::concurrent_hash_map< AlgorithmIdentifier, AlgorithmPayload, AlgorithmIdentifierHashCompare>::const_iterator endIt;
259 tbb::concurrent_hash_map< AlgorithmIdentifier, AlgorithmPayload, AlgorithmIdentifierHashCompare>::const_iterator it;
262 ATH_MSG_DEBUG(
"Monitored event with " << std::distance(beginIt, endIt) <<
" AlgorithmPayload objects.");
264 std::map<size_t, size_t> aiToHandleIndex;
265 for (it = beginIt; it != endIt; ++it) {
268 uint64_t startTime = ap.m_algStartTime.microsecondsSinceEpoch();
271 uint64_t stopTime = eventStopTime;
273 tbb::concurrent_hash_map<AlgorithmIdentifier, TrigTimeStamp, AlgorithmIdentifierHashCompare>::const_accessor stopTimeAcessor;
277 stopTime = stopTimeAcessor->second.microsecondsSinceEpoch();
285 if (startTime > stopTime) {
286 ATH_MSG_VERBOSE(
"Disregard start-time:" << startTime <<
" > stop-time:" << stopTime
296 if (startTime > eventStopTime) {
300 if (stopTime > eventStopTime) {
302 <<
" truncating its ending time stamp from " << stopTime <<
" to " << eventStopTime);
303 stopTime = eventStopTime;
309 if (stopTime < eventStartTime) {
313 if (startTime < eventStartTime) {
315 <<
" truncating its starting time stamp from " << startTime <<
" to " << eventStartTime);
316 startTime = eventStartTime;
321 costOutputHandle->push_back(
tc );
324 const uint32_t threadID =
static_cast<uint32_t
>( std::hash< std::thread::id >()(ap.m_algThreadID) );
325 uint32_t threadEnumerator = 0;
329 const std::unordered_map<uint32_t, uint32_t>::const_iterator mapIt =
m_threadToCounterMap.find(threadID);
334 threadEnumerator = mapIt->second;
342 result &=
tc->setDetail(
"thread", threadEnumerator);
343 result &=
tc->setDetail(
"thash", threadID);
344 result &=
tc->setDetail(
"slot", ap.m_slot);
345 result &=
tc->setDetail(
"roi", ap.m_algROIID);
346 result &=
tc->setDetail(
"start", startTime);
347 result &=
tc->setDetail(
"stop", stopTime);
350 aiToHandleIndex[ai.
m_hash] = costOutputHandle->size() - 1;
359 for (ROBConstIt it = beginRob; it != endRob; ++it) {
360 size_t aiHash = it->first.m_hash;
362 if (aiToHandleIndex.count(aiHash) == 0) {
369 rosOutputHandle->push_back(
tc);
372 std::vector<uint32_t> robs_id;
373 std::vector<uint32_t> robs_size;
374 std::vector<unsigned> robs_history;
375 std::vector<unsigned short> robs_status;
383 robs_id.push_back(rob.second.rob_id);
384 robs_size.push_back(rob.second.rob_size);
385 robs_history.push_back(rob.second.rob_history);
386 robs_status.push_back(rob.second.isStatusOk());
390 result &=
tc->setDetail(
"alg_idx", aiToHandleIndex[aiHash]);
392 result &=
tc->setDetail<std::vector<uint32_t>>(
"robs_id", robs_id);
393 result &=
tc->setDetail<std::vector<uint32_t>>(
"robs_size", robs_size);
394 result &=
tc->setDetail<std::vector<unsigned>>(
"robs_history", robs_history);
395 result &=
tc->setDetail<std::vector<unsigned short>>(
"robs_status", robs_status);
403 if (
msg().level() <= MSG::VERBOSE) {
418 return StatusCode::SUCCESS;
429 return StatusCode::SUCCESS;
432 std::unique_lock lockUnique(
m_slotMutex[context.slot()]);
434 tbb::concurrent_hash_map< AlgorithmIdentifier, AlgorithmPayload, AlgorithmIdentifierHashCompare>::const_iterator beginIt;
435 tbb::concurrent_hash_map< AlgorithmIdentifier, AlgorithmPayload, AlgorithmIdentifierHashCompare>::const_iterator endIt;
436 tbb::concurrent_hash_map< AlgorithmIdentifier, AlgorithmPayload, AlgorithmIdentifierHashCompare>::const_iterator it;
440 std::map<uint64_t, std::string, std::greater<uint64_t>> timeToAlgMap;
442 for (it = beginIt; it != endIt; ++it) {
447 if (ai.
m_realSlot != context.slot())
continue;
449 uint64_t startTime = ap.m_algStartTime.microsecondsSinceEpoch();
450 uint64_t stopTime = 0;
452 tbb::concurrent_hash_map<AlgorithmIdentifier, TrigTimeStamp, AlgorithmIdentifierHashCompare>::const_accessor stopTimeAcessor;
456 stopTime = stopTimeAcessor->second.microsecondsSinceEpoch();
461 if (stopTime == 0)
continue;
463 timeToAlgMap[stopTime-startTime] = ai.
m_caller;
467 report =
"Timeout detected with the following algorithms consuming the most time: ";
469 for(
const std::pair<const uint64_t, std::string>& p : timeToAlgMap){
471 report += p.second +
" (" + std::to_string(std::lround(p.first/1e3)) +
" ms)";
473 if (algCounter >= 5){
479 return StatusCode::SUCCESS;
487 ATH_MSG_DEBUG(
"All events are monitored - event will not be discarded");
488 return StatusCode::SUCCESS;
494 std::unique_lock lockUnique(
m_slotMutex[ context.slot() ] );
501 return StatusCode::SUCCESS;
509 return StatusCode::FAILURE;
511 return StatusCode::SUCCESS;
519 if (roi)
return static_cast<int32_t
>(roi->
roiId());
539 return static_cast<size_t>( std::hash< std::thread::id >()(thread) );
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Maintain a set of objects, one per slot.
const TrigRoiDescriptor * roiDescriptor() const
Get cached pointer to View's Region of Interest Descriptor or nullptr if not describing a View.
static const std::string hash2string(HLTHash, const std::string &category="TE")
hash function translating identifiers into names (via internal dictionary)
static void hashes2file(const std::string &fileName="hashes2string.txt")
debugging output of internal dictionary
virtual StatusCode processAlg(const EventContext &context, const std::string &caller, const AuditType type) override
Implementation of ITrigCostSvc::processAlg.
Gaudi::Property< bool > m_monitorAllEvents
Gaudi::Property< bool > m_saveHashes
Gaudi::Property< std::string > m_costFinalizeAlgName
std::mutex m_globalMutex
Used to protect all-slot modifications.
TrigCostDataStore< AlgorithmPayload > m_algStartInfo
Thread-safe store of algorithm start payload.
StatusCode checkSlot(const EventContext &context) const
Sanity check that the job is respecting the number of slots which were declared at config time.
TrigCostDataStore< TrigTimeStamp > m_algStopTime
Thread-safe store of algorithm stop times.
Gaudi::Property< bool > m_enableMultiSlot
virtual StatusCode initialize() override
Initialise, create enough storage to store m_eventSlots.
size_t m_eventSlots
Number of concurrent processing slots.
virtual ~TrigCostSvc()
Destructor.
std::unique_ptr< std::shared_mutex[] > m_slotMutex
Used to control and protect whole-table operations.
virtual StatusCode monitorROS(const EventContext &context, robmonitor::ROBDataMonitorStruct payload) override
Implementation of ITrigCostSvc::monitorROS.
virtual bool isMonitoredEvent(const EventContext &context, const bool includeMultiSlot=true) const override
std::unique_ptr< std::atomic< bool >[] > m_eventMonitored
Used to cache if the event in a given slot is being monitored.
virtual StatusCode endEvent(const EventContext &context, SG::WriteHandle< xAOD::TrigCompositeContainer > &costOutputHandle, SG::WriteHandle< xAOD::TrigCompositeContainer > &rosOutputHandle) override
Implementation of ITrigCostSvc::endEvent.
int32_t getROIID(const EventContext &context)
@breif Internal function to return a RoI from an extended event context context
virtual StatusCode discardEvent(const EventContext &context) override
Discard a cost monitored event.
Gaudi::Property< std::string > m_costSupervisorAlgName
TrigCostDataStore< std::vector< robmonitor::ROBDataMonitorStruct > > m_rosData
Thread-safe store of ROS data.
TrigCostSvc(const std::string &name, ISvcLocator *pSvcLocator)
Standard ATLAS Service constructor.
Gaudi::Property< size_t > m_masterSlot
virtual StatusCode finalize() override
Finalize, act on m_saveHashes.
virtual StatusCode generateTimeoutReport(const EventContext &context, std::string &report) override
StatusCode monitor(const EventContext &context, const AlgorithmIdentifier &ai, const TrigTimeStamp &now, const AuditType type)
Internal call to save monitoring data for a given AlgorithmIdentifier.
size_t m_threadCounter
Count how many unique thread ID we have seen.
tbb::concurrent_hash_map< std::thread::id, AlgorithmIdentifier, ThreadHashCompare > m_threadToAlgMap
Keeps track of what is running right now in each thread.
std::unordered_map< uint32_t, uint32_t > m_threadToCounterMap
Map thread's hash ID to a counting numeral.
virtual StatusCode startEvent(const EventContext &context, const bool enableMonitoring=true) override
Implementation of ITrigCostSvc::startEvent.
nope - should be used for standalone also, perhaps need to protect the class def bits ifndef XAOD_ANA...
virtual unsigned int roiId() const override final
these quantities probably don't need to be used any more
utility class to measure time duration in AthenaMT The pattern when it is useful: AlgA tags the begin...
The structure which is used to monitor the ROB data request in L2 It is created for every addROBData ...
uint64_t start_time
map of ROBs requested
std::map< const uint32_t, robmonitor::ROBDataStruct > requested_ROBs
name of requesting algorithm
uint64_t end_time
start time of ROB request (microsec since epoch)
const ExtendedEventContext & getExtendedEventContext(const EventContext &ctx)
Retrieve an extended context from a context object.
bool hasExtendedEventContext(const EventContext &ctx)
Test whether a context object has an extended context installed.
size_t getNSlots()
Return the number of event slots.
TrigComposite_v1 TrigComposite
Declare the latest version of the class.
Static hash and equal members as required by tbb::concurrent_hash_map.
static AlgorithmIdentifier make(const EventContext &context, const std::string &caller, MsgStream &msg, const int16_t slotOverride=-1)
Construct an AlgorithmIdentifier.
Small structure to hold an algorithm's name and store, plus some details on its EventView.
std::string m_caller
Name of the algorithm.
std::string m_store
Name of the algorithm's store.
TrigConf::HLTHash callerHash(MsgStream &msg) const
size_t m_slotToSaveInto
The slot which is used for the purposes of recording data on this algorithm's execution.
static constexpr int16_t s_noView
Constant value used to express an Algorithm which is not running in a View.
TrigConf::HLTHash storeHash(MsgStream &msg) const
size_t m_realSlot
The actual slot of the algorithm.
size_t m_hash
Hash of algorithm + store + realSlot.
StatusCode isValid() const
int16_t m_viewID
If not within an event view, then the m_iewID = s_noView = -1.
Small structure wrap the various values stored for an algorithm just before it starts to execute.
static bool equal(const std::thread::id &x, const std::thread::id &y)
static size_t hash(const std::thread::id &thread)