Skip to content

Commit ec5043f

Browse files
committed
Have InputTag cache EDGetToken
Removed direct caching of ProductResolverIndex and related items and replace with EDGetToken.
1 parent 3e42353 commit ec5043f

File tree

7 files changed

+108
-163
lines changed

7 files changed

+108
-163
lines changed

FWCore/Framework/interface/EDConsumerBase.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ namespace edm {
9090
// ---------- const member functions ---------------------
9191
ProductResolverIndexAndSkipBit indexFrom(EDGetToken, BranchType, TypeID const&) const;
9292
ProductResolverIndexAndSkipBit uncheckedIndexFrom(EDGetToken) const;
93+
/**returns edm::ProductResolverIndexInvalid if type and branch do not match the index
94+
this can happen if the same InputTag is used for different products */
95+
ProductResolverIndexAndSkipBit indexFromIfExactMatch(EDGetToken, BranchType, TypeID const&) const;
96+
EDGetToken getRegisteredToken(TypeID const& typeID,
97+
std::string const& label,
98+
std::string const& instance,
99+
std::string const& processName,
100+
BranchType branchType,
101+
bool skipCurrentProcess) const;
93102

94103
void itemsToGet(BranchType, std::vector<ProductResolverIndexAndSkipBit>&) const;
95104
void itemsMayGet(BranchType, std::vector<ProductResolverIndexAndSkipBit>&) const;

FWCore/Framework/src/EDConsumerBase.cc

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,44 @@ ProductResolverIndexAndSkipBit EDConsumerBase::uncheckedIndexFrom(EDGetToken iTo
256256
return m_tokenInfo.get<kLookupInfo>(iToken.index()).m_index;
257257
}
258258

259+
ProductResolverIndexAndSkipBit EDConsumerBase::indexFromIfExactMatch(EDGetToken iToken,
260+
BranchType iBranch,
261+
TypeID const& iType) const {
262+
if (UNLIKELY(iToken.index() >= m_tokenInfo.size())) {
263+
throwBadToken(iType, iToken);
264+
}
265+
const auto& info = m_tokenInfo.get<kLookupInfo>(iToken.index());
266+
if (LIKELY(iBranch == info.m_branchType)) {
267+
if (LIKELY(iType == info.m_type)) {
268+
return info.m_index;
269+
}
270+
}
271+
return ProductResolverIndexAndSkipBit(edm::ProductResolverIndexInvalid, false);
272+
}
273+
274+
EDGetToken EDConsumerBase::getRegisteredToken(TypeID const& typeID,
275+
std::string const& label,
276+
std::string const& instance,
277+
std::string const& processName,
278+
BranchType branchType,
279+
bool skipCurrentProcess) const {
280+
auto const itBegin = m_tokenInfo.begin<kLookupInfo>();
281+
for (auto it = itBegin, itEnd = m_tokenInfo.end<kLookupInfo>(); it != itEnd; ++it) {
282+
if (it->m_type == typeID && it->m_branchType == branchType &&
283+
it->m_index.skipCurrentProcess() == skipCurrentProcess) {
284+
auto index = it - itBegin;
285+
auto const& labels = m_tokenInfo.get<kLabels>(index);
286+
unsigned int labelStart = labels.m_startOfModuleLabel;
287+
const char* moduleLabel = &(m_tokenLabels[labelStart]);
288+
if (label == moduleLabel && instance == (moduleLabel + labels.m_deltaToProductInstance) &&
289+
(skipCurrentProcess or (processName == (moduleLabel + labels.m_deltaToProcessName)))) {
290+
return EDGetToken{static_cast<unsigned int>(index)};
291+
}
292+
}
293+
}
294+
return EDGetToken{EDGetToken::s_uninitializedValue};
295+
}
296+
259297
void EDConsumerBase::itemsToGet(BranchType iBranch, std::vector<ProductResolverIndexAndSkipBit>& oIndices) const {
260298
//how many are we adding?
261299
unsigned int count = 0;
@@ -363,7 +401,8 @@ void EDConsumerBase::throwBadToken(edm::TypeID const& iType, EDGetToken iToken)
363401
throw cms::Exception("BadToken")
364402
<< "A get using a EDGetToken with the C++ type '" << iType.className() << "' was made using a token with a value "
365403
<< iToken.index()
366-
<< " which is beyond the range used by this module.\n Please check that the variable is being initialized from a "
404+
<< " which is beyond the range used by this module.\n Please check that the variable is being initialized from "
405+
"a "
367406
"'consumes' call from this module.\n You can not share EDGetToken values between modules.";
368407
}
369408

FWCore/Framework/src/Principal.cc

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -450,16 +450,34 @@ namespace edm {
450450
ModuleCallingContext const* mcc) const {
451451
bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
452452

453-
ProductResolverIndex index = inputTag.indexFor(typeID, branchType(), &productRegistry());
453+
auto token = inputTag.cachedToken();
454454

455+
if (token.isUninitialized() and consumer) {
456+
std::string const* processName = &inputTag.process();
457+
if (inputTag.process() == InputTag::kCurrentProcess) {
458+
processName = &processConfiguration_->processName();
459+
}
460+
token = consumer->getRegisteredToken(
461+
typeID, inputTag.label(), inputTag.instance(), *processName, branchType(), skipCurrentProcess);
462+
if (token.isUninitialized()) {
463+
failedToRegisterConsumes(kindOfType,
464+
typeID,
465+
inputTag.label(),
466+
inputTag.instance(),
467+
appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
468+
}
469+
inputTag.cacheToken(token);
470+
}
471+
//check that the InputTag is not being used for a different type/Principal than the first call
472+
auto index = consumer ? consumer->indexFromIfExactMatch(token, branchType(), typeID).productResolverIndex()
473+
: ProductResolverIndexInvalid;
455474
if (index == ProductResolverIndexInvalid) {
456475
char const* processName = inputTag.process().c_str();
457476
if (skipCurrentProcess) {
458477
processName = "\0";
459478
} else if (inputTag.process() == InputTag::kCurrentProcess) {
460479
processName = processConfiguration_->processName().c_str();
461480
}
462-
463481
index =
464482
productLookup().index(kindOfType, typeID, inputTag.label().c_str(), inputTag.instance().c_str(), processName);
465483

@@ -490,14 +508,6 @@ namespace edm {
490508
}
491509
return nullptr;
492510
}
493-
inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
494-
}
495-
if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
496-
failedToRegisterConsumes(kindOfType,
497-
typeID,
498-
inputTag.label(),
499-
inputTag.instance(),
500-
appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
501511
}
502512

503513
auto const& productResolver = productResolvers_[index];

FWCore/Utilities/interface/InputTag.h

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55
#include <iosfwd>
66
#include <string>
77

8-
#include "FWCore/Utilities/interface/TypeID.h"
9-
#include "FWCore/Utilities/interface/BranchType.h"
10-
#include "FWCore/Utilities/interface/ProductResolverIndex.h"
11-
#include "FWCore/Utilities/interface/thread_safety_macros.h"
8+
#include "FWCore/Utilities/interface/EDGetToken.h"
129

1310
namespace edm {
1411

@@ -43,12 +40,9 @@ namespace edm {
4340

4441
bool operator==(InputTag const& tag) const;
4542

46-
ProductResolverIndex indexFor(TypeID const& typeID, BranchType branchType, void const* productRegistry) const;
43+
EDGetToken cachedToken() const { return token_; }
4744

48-
void tryToCacheIndex(ProductResolverIndex index,
49-
TypeID const& typeID,
50-
BranchType branchType,
51-
void const* productRegistry) const;
45+
void cacheToken(EDGetToken) const;
5246

5347
static const std::string kSkipCurrentProcess;
5448
static const std::string kCurrentProcess;
@@ -60,12 +54,7 @@ namespace edm {
6054
std::string instance_;
6155
std::string process_;
6256

63-
CMS_THREAD_GUARD(index_) mutable TypeID typeID_;
64-
CMS_THREAD_GUARD(index_) mutable void const* productRegistry_;
65-
66-
mutable std::atomic<unsigned int> index_;
67-
68-
CMS_THREAD_GUARD(index_) mutable char branchType_;
57+
mutable std::atomic<EDGetToken> token_;
6958

7059
bool skipCurrentProcess_;
7160
};

FWCore/Utilities/src/InputTag.cc

Lines changed: 11 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,23 @@ namespace edm {
88
const std::string InputTag::kCurrentProcess("@currentProcess");
99
static std::string const separator(":");
1010

11-
InputTag::InputTag()
12-
: label_(),
13-
instance_(),
14-
process_(),
15-
typeID_(),
16-
productRegistry_(nullptr),
17-
index_(ProductResolverIndexInvalid),
18-
branchType_(NumBranchTypes),
19-
skipCurrentProcess_(false) {}
11+
InputTag::InputTag() : label_(), instance_(), process_(), token_(), skipCurrentProcess_(false) {}
2012

2113
InputTag::InputTag(std::string const& label, std::string const& instance, std::string const& processName)
2214
: label_(label),
2315
instance_(instance),
2416
process_(processName),
25-
typeID_(),
26-
productRegistry_(nullptr),
27-
index_(ProductResolverIndexInvalid),
28-
branchType_(NumBranchTypes),
17+
token_(),
2918
skipCurrentProcess_(calcSkipCurrentProcess()) {}
3019

3120
InputTag::InputTag(char const* label, char const* instance, char const* processName)
3221
: label_(label),
3322
instance_(instance),
3423
process_(processName),
35-
typeID_(),
36-
productRegistry_(nullptr),
37-
index_(ProductResolverIndexInvalid),
38-
branchType_(NumBranchTypes),
24+
token_(),
3925
skipCurrentProcess_(calcSkipCurrentProcess()) {}
4026

41-
InputTag::InputTag(std::string const& s)
42-
: label_(),
43-
instance_(),
44-
process_(),
45-
typeID_(),
46-
productRegistry_(nullptr),
47-
index_(ProductResolverIndexInvalid),
48-
branchType_(NumBranchTypes),
49-
skipCurrentProcess_(false) {
27+
InputTag::InputTag(std::string const& s) : label_(), instance_(), process_(), token_(), skipCurrentProcess_(false) {
5028
// string is delimited by colons
5129
std::vector<std::string> tokens = tokenize(s, separator);
5230
size_t nwords = tokens.size();
@@ -68,57 +46,23 @@ namespace edm {
6846
: label_(other.label()),
6947
instance_(other.instance()),
7048
process_(other.process()),
71-
typeID_(),
72-
productRegistry_(nullptr),
73-
index_(ProductResolverIndexInvalid),
74-
branchType_(NumBranchTypes),
75-
skipCurrentProcess_(other.willSkipCurrentProcess()) {
76-
ProductResolverIndex otherIndex = other.index_.load();
77-
if (otherIndex < ProductResolverIndexInitializing) {
78-
branchType_ = other.branchType_;
79-
typeID_ = other.typeID_;
80-
productRegistry_ = other.productRegistry_;
81-
index_.store(otherIndex);
82-
}
83-
}
49+
token_(other.token_.load()),
50+
skipCurrentProcess_(other.willSkipCurrentProcess()) {}
8451

8552
InputTag::InputTag(InputTag&& other)
8653
: label_(std::move(other.label_)),
8754
instance_(std::move(other.instance_)),
8855
process_(std::move(other.process_)),
89-
typeID_(),
90-
productRegistry_(nullptr),
91-
index_(ProductResolverIndexInvalid),
92-
branchType_(NumBranchTypes),
93-
skipCurrentProcess_(other.willSkipCurrentProcess()) {
94-
ProductResolverIndex otherIndex = other.index_.load();
95-
if (otherIndex < ProductResolverIndexInitializing) {
96-
branchType_ = other.branchType_;
97-
typeID_ = other.typeID_;
98-
productRegistry_ = other.productRegistry_;
99-
index_.store(otherIndex);
100-
}
101-
}
56+
token_(other.token_.load()),
57+
skipCurrentProcess_(other.willSkipCurrentProcess()) {}
10258

10359
InputTag& InputTag::operator=(InputTag const& other) {
10460
if (this != &other) {
10561
label_ = other.label_;
10662
instance_ = other.instance_;
10763
process_ = other.process_;
10864
skipCurrentProcess_ = other.skipCurrentProcess_;
109-
110-
ProductResolverIndex otherIndex = other.index_.load();
111-
if (otherIndex < ProductResolverIndexInitializing) {
112-
branchType_ = other.branchType_;
113-
typeID_ = other.typeID_;
114-
productRegistry_ = other.productRegistry_;
115-
index_.store(otherIndex);
116-
} else {
117-
branchType_ = NumBranchTypes;
118-
typeID_ = TypeID();
119-
productRegistry_ = nullptr;
120-
index_.store(ProductResolverIndexInvalid);
121-
}
65+
token_.store(other.token_.load());
12266
}
12367
return *this;
12468
}
@@ -129,19 +73,7 @@ namespace edm {
12973
instance_ = std::move(other.instance_);
13074
process_ = std::move(other.process_);
13175
skipCurrentProcess_ = other.skipCurrentProcess_;
132-
133-
ProductResolverIndex otherIndex = other.index_.load();
134-
if (otherIndex < ProductResolverIndexInitializing) {
135-
branchType_ = other.branchType_;
136-
typeID_ = other.typeID_;
137-
productRegistry_ = other.productRegistry_;
138-
index_.store(otherIndex);
139-
} else {
140-
branchType_ = NumBranchTypes;
141-
typeID_ = TypeID();
142-
productRegistry_ = nullptr;
143-
index_.store(ProductResolverIndexInvalid);
144-
}
76+
token_.store(other.token_.load());
14577
}
14678
return *this;
14779
}
@@ -174,30 +106,7 @@ namespace edm {
174106
return (label_ == tag.label_) && (instance_ == tag.instance_) && (process_ == tag.process_);
175107
}
176108

177-
ProductResolverIndex InputTag::indexFor(TypeID const& typeID,
178-
BranchType branchType,
179-
void const* productRegistry) const {
180-
ProductResolverIndex index = index_.load();
181-
182-
if (index < ProductResolverIndexInitializing && typeID_ == typeID && branchType_ == branchType &&
183-
productRegistry_ == productRegistry) {
184-
return index;
185-
}
186-
return ProductResolverIndexInvalid;
187-
}
188-
189-
void InputTag::tryToCacheIndex(ProductResolverIndex index,
190-
TypeID const& typeID,
191-
BranchType branchType,
192-
void const* productRegistry) const {
193-
unsigned int invalidValue = static_cast<unsigned int>(ProductResolverIndexInvalid);
194-
if (index_.compare_exchange_strong(invalidValue, static_cast<unsigned int>(ProductResolverIndexInitializing))) {
195-
typeID_ = typeID;
196-
branchType_ = branchType;
197-
productRegistry_ = productRegistry;
198-
index_.store(index);
199-
}
200-
}
109+
void InputTag::cacheToken(EDGetToken token) const { token_.store(token); }
201110

202111
std::ostream& operator<<(std::ostream& ost, InputTag const& tag) {
203112
static std::string const process(", process = ");

FWCore/Utilities/test/InputTag_t.cpp

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,15 @@
1010
#include <string>
1111

1212
namespace edm {
13-
class ProductRegistry;
14-
}
13+
class TestEDGetToken {
14+
public:
15+
static EDGetToken makeEDGetToken(unsigned int iValue) { return EDGetToken(iValue); }
16+
};
17+
18+
} // namespace edm
1519

1620
// This is just for the test. Do not dereference the pointers.
1721
// They points to nothing legal.
18-
edm::ProductRegistry* reg1 = reinterpret_cast<edm::ProductRegistry*>(1);
19-
edm::ProductRegistry* reg2 = reinterpret_cast<edm::ProductRegistry*>(2);
20-
21-
class TypeToTestInputTag1 {};
22-
class TypeToTestInputTag2 {};
23-
TypeToTestInputTag1 typeToTestInputTag1;
24-
TypeToTestInputTag2 typeToTestInputTag2;
25-
26-
edm::TypeID testTypeID1(typeToTestInputTag1);
27-
edm::TypeID testTypeID2(typeToTestInputTag2);
2822

2923
class InputTagModifier {
3024
edm::InputTag* inputTag;
@@ -35,20 +29,20 @@ class InputTagModifier {
3529
void operator()(oneapi::tbb::blocked_range<int> const& r) const {
3630
for (int i = r.begin(); i != r.end(); i++) {
3731
for (unsigned int j = 0; j < 10000; ++j) {
38-
unsigned int index = inputTag->indexFor(testTypeID1, edm::InRun, reg1);
39-
if (index != 5 && index != edm::ProductResolverIndexInvalid)
32+
unsigned int index = inputTag->cachedToken().index();
33+
if (index != 5 && index != edm::EDGetToken().index())
4034
abort();
4135
// std::cout << "a\n";
4236
}
4337
for (unsigned int j = 0; j < 100; ++j) {
44-
inputTag->tryToCacheIndex(5, testTypeID1, edm::InRun, reg1);
38+
inputTag->cacheToken(edm::TestEDGetToken::makeEDGetToken(5));
4539
// std::cout << "b\n";
4640
}
4741
for (unsigned int j = 0; j < 1000; ++j) {
48-
unsigned int index = inputTag->indexFor(testTypeID1, edm::InRun, reg1);
42+
unsigned int index = inputTag->cachedToken().index();
4943
// if (index != 5) abort(); // This can fail!
5044
// std::cout << index << " c\n";
51-
if (index != 5 && index != edm::ProductResolverIndexInvalid)
45+
if (index != 5 && index != edm::EDGetToken().index())
5246
abort();
5347
}
5448
}

0 commit comments

Comments
 (0)