Skip to content
Snippets Groups Projects
Commit ee6d1b64 authored by scott snyder's avatar scott snyder Committed by scott snyder
Browse files

AthenaKernel: Extend ThinningCache to hold additional data.

ThinningCache holds a map of object keys to a set of thinned entries,
and is used during output.

Extend ThinningCache so that it now olds a ThinningInfo structure,
rather than just the set of thinned entries.
This allows us to extend ThinningCache to hold additional information.
Here, we're adding the set of vetoed variables per object.
parent bc6f20e4
No related branches found
No related tags found
No related merge requests found
Showing with 248 additions and 27 deletions
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ATHENAKERNEL_EXTENDEDEVENTCONTEXT_H
......@@ -50,10 +50,10 @@ namespace Atlas {
/**
* @brief Thread-local thinning cache.
* Set when we are doing output with thinning' the cache
* Set when we are doing output with thinning; the cache
* provides information about what was thinned.
* This is to allow converters to get thinning information.
* Unfortuneately, we don't have a better way of doing this
* Unfortunately, we don't have a better way of doing this
* without changing Gaudi interfaces.
*/
void setThinningCache (const SG::ThinningCache* cache) { m_thinningCache = cache; }
......
......@@ -15,7 +15,9 @@
#include "AthenaKernel/ThinningDecisionBase.h"
#include "AthenaKernel/ThinningInfo.h"
#include "AthenaKernel/sgkey_t.h"
#include "CxxUtils/ConcurrentBitset.h"
#include <unordered_map>
#include <string>
#include <vector>
......@@ -29,6 +31,7 @@ namespace SG {
class ThinningDecisionBase;
class auxid_set_t;
/**
......@@ -111,19 +114,38 @@ public:
void lockOwned();
/**
* @brief Set vetoed variable information one object.
* @param key SG string key of the object being added.
* @param vetoed Set of vetoed variables for this object.
*/
void setVetoed (const std::string& key,
const CxxUtils::ConcurrentBitset& vetoed);
/**
* @brief Return thinning information for @c key.
* @param key SG key for which to return selected variables.
*
* Return thinning information @c key, or nullptr.
*/
const ThinningInfo* thinningInfo (const std::string& key) const;
/**
* @brief Clear the cache.
*/
void clear();
private:
/// Mapping by string SG key.
typedef std::unordered_map<std::string, const ThinningDecisionBase*> map_t;
typedef std::unordered_map<std::string, ThinningInfo> map_t;
map_t m_map;
/// Mapping by hashed SG key.
typedef std::unordered_map<sgkey_t, const ThinningDecisionBase*> sgmap_t;
typedef std::unordered_map<sgkey_t, ThinningInfo> sgmap_t;
sgmap_t m_sgmap;
/// List of decision objects we've copied in order to handle merges.
......@@ -135,13 +157,13 @@ private:
/**
* @brief Merge a new thinning request into an existing one via AND.
* @param oldThinningIt Iterator in @c m_map of the existing thinning decision.
* @param info @c ThinningInfo with existing decision.
* @param sgkeys SG hashed keys of the object being added.
* @param thinning New thinning decision.
*
* The new thinning decision will be combined with the old one via AND.
*/
void merge (map_t::iterator oldThinningIt,
void merge (ThinningInfo& info,
const std::vector<sgkey_t>& sgkeys,
const ThinningDecisionBase& thinning);
};
......
// This file's extension implies that it's C, but it's really -*- C++ -*-.
/*
* Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration.
*/
/**
* @file AthenaKernel/ThinningInfo.h
* @author scott snyder <snyder@bnl.gov>
* @date Jul, 2020
* @brief Hold thinning/slimming information for a given object.
*/
#ifndef ATHENAKERNEL_THINNINGINFO_H
#define ATHENAKERNEL_THINNINGINFO_H
#include "CxxUtils/ConcurrentBitset.h"
namespace SG {
class ThinningDecisionBase;
/**
* @brief Hold thinning/slimming information for a given object.
*
* Thinning/slimming information for objects in the event store
* can come from several sources. At present, this includes the TrigDecision
* objects recorded in the event store by thinning algorithms
* and the list of suppressed aux variables constructed by AthenaOutputStream.
*
* ThinningCacheTool will assemble them in one place for ease of access
* during output. ThinningCache maps object keys to ThinningInfo objects,
* when then hold the information for single objects.
*/
class ThinningInfo
{
public:
/// Thinning for the object.
const ThinningDecisionBase* m_decision;
/// Set of auxids not to be written for this object.
/// (In principle, we should use SG::auxid_set_t here, but there
/// are dependency issues with that.)
CxxUtils::ConcurrentBitset m_vetoed;
/// Test if a variable has been vetoed.
bool vetoed (size_t id) const
{
return m_vetoed.test (id);
}
};
} // namespace SG
#endif // not ATHENAKERNEL_THINNINGINFO_H
// This file's extension implies that it's C, but it's really -*- C++ -*-.
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file AthenaKernel/getThinningCache.h
......@@ -21,6 +21,7 @@ class EventContext;
namespace SG {
class ThinningCache;
class ThinningInfo;
class ThinningDecisionBase;
......@@ -40,6 +41,26 @@ const SG::ThinningCache* getThinningCache (const EventContext& ctx);
const SG::ThinningCache* getThinningCache();
/**
* @brief Retrieve the current thinning information for @c key.
* @brief ctx Event context.
* @param key SG key to test.
*
* Returns nullptr if there is no thinning for @c key.
*/
const SG::ThinningInfo* getThinningInfo (const EventContext& ctx,
const std::string& key);
/**
* @brief Retrieve the current thinning information for @c key.
* @param key SG key to test.
*
* Returns nullptr if there is no thinning for @c key.
*/
const SG::ThinningInfo* getThinningInfo (const std::string& key);
/**
* @brief Retrieve the current thinning decision for @c key.
* @brief ctx Event context.
......
......@@ -154,10 +154,14 @@ atlas_add_test( ThinningCache_test
SOURCES test/ThinningCache_test.cxx
LINK_LIBRARIES AthenaKernel TestTools )
atlas_add_test( ThinningInfo_test
SOURCES test/ThinningInfo_test.cxx
LINK_LIBRARIES AthenaKernel TestTools )
atlas_add_test( getThinningCache_test
SOURCES test/getThinningCache_test.cxx
LINK_LIBRARIES AthenaKernel TestTools )
atlas_add_test( AlgorithmTimer_test
atlas_add_test( AlgorithmTimer_test
SOURCES test/AlgorithmTimer_test.cxx
LINK_LIBRARIES AthenaKernel )
AthenaKernel/ThinningInfo_test
test1
......@@ -37,7 +37,7 @@ ThinningCache::thinning (const std::string& key) const
{
auto it = m_map.find (key);
if (it != m_map.end()) {
return it->second;
return it->second.m_decision;
}
return nullptr;
}
......@@ -55,7 +55,7 @@ ThinningCache::thinning (const sgkey_t sgkey) const
{
auto it = m_sgmap.find (sgkey);
if (it != m_sgmap.end()) {
return it->second;
return it->second.m_decision;
}
return nullptr;
}
......@@ -81,19 +81,26 @@ void ThinningCache::addThinning (const std::string& key,
{
if (!thinning) return;
auto pos = m_map.try_emplace (key, thinning);
if (!pos.second) {
if (!unique) {
merge (pos.first, sgkeys, *thinning);
return;
{
ThinningInfo& info = m_map[key];
if (info.m_decision) {
if (!unique) {
merge (info, sgkeys, *thinning);
return;
}
throw std::runtime_error ("Duplicated thinning definition");
}
else {
info.m_decision = thinning;
}
throw std::runtime_error ("Duplicated thinning definition");
}
for (sgkey_t sgkey : sgkeys) {
if (!m_sgmap.try_emplace (sgkey, thinning).second) {
ThinningInfo& info = m_sgmap[sgkey];
if (info.m_decision) {
throw std::runtime_error ("Duplicated thinning definition");
}
info.m_decision = thinning;
}
}
......@@ -132,6 +139,36 @@ void ThinningCache::lockOwned()
}
/**
* @brief Set selected variable information one object.
* @param key SG string key of the object being added.
* @param sgkeys SG hashed keys of the object being added.
* @param vetoed Set of vetoed variables for this object.
*/
void ThinningCache::setVetoed (const std::string& key,
const CxxUtils::ConcurrentBitset& vetoed)
{
m_map[key].m_vetoed = vetoed;
}
/**
* @brief Return thinning information for @c key.
* @param key SG key for which to return selected variables.
*
* Return thinning information @c key, or nullptr.
*/
const ThinningInfo*
ThinningCache::thinningInfo (const std::string& key) const
{
auto it = m_map.find (key);
if (it != m_map.end()) {
return &it->second;
}
return nullptr;
}
/**
* @brief Clear the cache.
*/
......@@ -146,13 +183,13 @@ void ThinningCache::clear()
/**
* @brief Merge a new thinning request into an existing one via AND.
* @param oldThinningIt Iterator in @c m_map of the existing thinning decision.
* @param info @c ThinningInfo with existing decision.
* @param sgkeys SG hashed keys of the object being added.
* @param thinning New thinning decision.
*
* The new thinning decision will be combined with the old one via AND.
*/
void ThinningCache::merge (map_t::iterator oldThinningIt,
void ThinningCache::merge (ThinningInfo& info,
const std::vector<sgkey_t>& sgkeys,
const ThinningDecisionBase& thinning)
{
......@@ -165,7 +202,7 @@ void ThinningCache::merge (map_t::iterator oldThinningIt,
// We expect this to be relatively rare and the number of such objects
// to be small, so just use a linear search.
auto ownedIt = std::find_if (m_owned.begin(), m_owned.end(),
[old = oldThinningIt->second]
[old = info.m_decision]
(const std::unique_ptr<SG::ThinningDecisionBase>& p)
{ return p.get() == old; });
......@@ -175,13 +212,13 @@ void ThinningCache::merge (map_t::iterator oldThinningIt,
}
else {
// We need to make a copy of the existing decision and enter it into the maps.
m_owned.push_back (std::make_unique<SG::ThinningDecisionBase> (oldThinningIt->second->size()));
m_owned.push_back (std::make_unique<SG::ThinningDecisionBase> (info.m_decision->size()));
oldThinning = m_owned.back().get();
oldThinning->thin (*oldThinningIt->second);
oldThinningIt->second = oldThinning;
oldThinning->thin (*info.m_decision);
info.m_decision = oldThinning;
for (sgkey_t sgkey : sgkeys) {
m_sgmap[sgkey] = oldThinning;
m_sgmap[sgkey].m_decision = oldThinning;
}
}
......
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file AthenaKernel/src/getThinningCache.h
......@@ -44,6 +44,35 @@ const SG::ThinningCache* getThinningCache()
}
/**
* @brief Retrieve the current thinning information for @c key.
* @brief ctx Event context.
* @param key SG key to test.
*
* Returns nullptr if there is no thinning for @c key.
*/
const SG::ThinningInfo* getThinningInfo (const EventContext& ctx,
const std::string& key)
{
if (const SG::ThinningCache* cache = getThinningCache (ctx)) {
return cache->thinningInfo (key);
}
return nullptr;
}
/**
* @brief Retrieve the current thinning information for @c key.
* @param key SG key to test.
*
* Returns nullptr if there is no thinning for @c key.
*/
const SG::ThinningInfo* getThinningInfo (const std::string& key)
{
return getThinningInfo (Gaudi::Hive::currentContext(), key);
}
/**
* @brief Retrieve the current thinning decision for @c key.
* @brief ctx Event context.
......
......@@ -108,6 +108,14 @@ void test1()
cache.setTrigNavigationThinningSvc (&tt);
assert (cache.trigNavigationThinningSvc() == &tt);
assert (cache.thinningInfo ("foo")->m_vetoed.empty());
CxxUtils::ConcurrentBitset bs (64);
bs.set (13);
cache.setVetoed ("foo", bs);
assert (cache.thinningInfo ("foo")->m_vetoed == bs);
assert (cache.thinningInfo ("foo")->vetoed(13));
assert (!cache.thinningInfo ("foo")->vetoed(14));
cache.clear();
assert (cache.empty());
assert (cache.trigNavigationThinningSvc() == nullptr);
......
/*
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file AthenaKernel/test/ThinningInfo_test.cxx
* @author scott snyder <snyder@bnl.gov>
* @date Jul, 2020
* @brief Regression tests for ThinningInfo.
*/
#undef NDEBUG
#include "AthenaKernel/ThinningInfo.h"
#include <cassert>
#include <iostream>
#include <stdexcept>
void test1()
{
std::cout << "test1\n";
}
int main()
{
std::cout << "AthenaKernel/ThinningInfo_test\n";
test1();
return 0;
}
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file AthenaKernel/test/getThinningCache_test.cxx
......@@ -29,6 +29,8 @@ void test1()
assert (SG::getThinningCache() == nullptr);
assert (SG::getThinningCache(ctx) == nullptr);
assert (SG::getThinningInfo("foo") == nullptr);
assert (SG::getThinningInfo(ctx, "foo") == nullptr);
assert (SG::getThinningDecision("foo") == nullptr);
assert (SG::getThinningDecision(ctx, "foo") == nullptr);
assert (SG::getThinningDecision(101) == nullptr);
......@@ -42,6 +44,8 @@ void test1()
ctx.getExtension<Atlas::ExtendedEventContext>().setThinningCache (&cache);
assert (SG::getThinningCache() == nullptr);
assert (SG::getThinningCache(ctx) == &cache);
assert (SG::getThinningInfo("foo") == nullptr);
assert (SG::getThinningInfo(ctx, "foo") == nullptr);
assert (SG::getThinningDecision("foo") == nullptr);
assert (SG::getThinningDecision(ctx, "foo") == nullptr);
assert (SG::getThinningDecision(101) == nullptr);
......@@ -52,6 +56,8 @@ void test1()
assert (SG::getThinningCache() == nullptr);
assert (SG::getThinningCache(ctx) == &cache);
assert (SG::getThinningInfo("foo") == nullptr);
assert (SG::getThinningInfo(ctx, "foo")->m_decision == &dec);
assert (SG::getThinningDecision("foo") == nullptr);
assert (SG::getThinningDecision(ctx, "foo") == &dec);
assert (SG::getThinningDecision(101) == nullptr);
......@@ -61,6 +67,8 @@ void test1()
assert (SG::getThinningCache() == &cache);
assert (SG::getThinningCache(ctx) == &cache);
assert (SG::getThinningInfo("foo")->m_decision == &dec);
assert (SG::getThinningInfo(ctx, "foo")->m_decision == &dec);
assert (SG::getThinningDecision("foo") == &dec);
assert (SG::getThinningDecision(ctx, "foo") == &dec);
assert (SG::getThinningDecision(101) == &dec);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment