Skip to content

Commit 72ba74e

Browse files
Dan RileyDan Riley
authored andcommitted
simple cache takes ownership of its cache
fix training of simple cache when promptRead is true add NoCache and SimpleWithAuxCache
1 parent 0a10c2f commit 72ba74e

File tree

5 files changed

+106
-51
lines changed

5 files changed

+106
-51
lines changed

IOPool/Input/src/InputFile.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,12 @@ namespace edm {
4848
static void reportReadBranch(InputType inputType, std::string const& branchname);
4949

5050
TObject* Get(char const* name) { return file_->Get(name); }
51-
std::unique_ptr<TTreeCache> createCacheWithSize(TTree& iTree, unsigned int cacheSize) {
52-
iTree.SetCacheSize(static_cast<Long64_t>(cacheSize));
53-
std::unique_ptr<TTreeCache> newCache(dynamic_cast<TTreeCache*>(file_->GetCacheRead(&iTree)));
54-
file_->SetCacheRead(nullptr, &iTree, TFile::kDoNotDisconnect);
51+
std::unique_ptr<TTreeCache> createCacheWithSize(TTree* iTree, unsigned int cacheSize) {
52+
iTree->SetCacheSize(static_cast<Long64_t>(cacheSize));
53+
std::unique_ptr<TTreeCache> newCache(dynamic_cast<TTreeCache*>(file_->GetCacheRead(iTree)));
54+
file_->SetCacheRead(nullptr, iTree, TFile::kDoNotDisconnect);
5555
return newCache;
5656
}
57-
TTreeCache* getCacheRead(TTree* tree) { return dynamic_cast<TTreeCache*>(file_->GetCacheRead(tree)); }
5857

5958
class CacheGuard {
6059
public:

IOPool/Input/src/RootTree.cc

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,17 +270,13 @@ namespace edm {
270270
return retval;
271271
}
272272

273-
void RootTree::resetTraining() { treeCacheManager_->resetTraining(); }
273+
void RootTree::resetTraining() { treeCacheManager_->resetTraining(promptRead_); }
274274

275275
void RootTree::close() {
276276
// The TFile is about to be closed, and destructed.
277277
// Just to play it safe, zero all pointers to quantities that are owned by the TFile.
278278
auxBranch_ = branchEntryInfoBranch_ = nullptr;
279279
tree_ = metaTree_ = infoTree_ = nullptr;
280-
// We own the treeCache_.
281-
// We make sure the treeCache_ is detached from the file,
282-
// so that ROOT does not also delete it.
283-
filePtr_->clearCacheRead(tree_);
284280
// We *must* delete the TTreeCache here because the TFilePrefetch object
285281
// references the TFile. If TFile is closed, before the TTreeCache is
286282
// deleted, the TFilePrefetch may continue to do TFile operations, causing
@@ -324,7 +320,7 @@ namespace edm {
324320
unsigned int cacheSize,
325321
char const* branchNames) {
326322
tree->LoadTree(0);
327-
std::unique_ptr<TTreeCache> treeCache = file.createCacheWithSize(*tree, cacheSize);
323+
std::unique_ptr<TTreeCache> treeCache = file.createCacheWithSize(tree, cacheSize);
328324
if (nullptr != treeCache.get()) {
329325
treeCache->StartLearningPhase();
330326
treeCache->SetEntryRange(0, tree->GetEntries());

IOPool/Input/src/RootTree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ namespace edm {
9999
bool promptReading = false;
100100

101101
Options usingDefaultNonEventOptions() const {
102-
return {roottree::defaultNonEventCacheSize, treeMaxVirtualSize, enablePrefetching, false};
102+
return {roottree::defaultNonEventCacheSize, treeMaxVirtualSize, enablePrefetching, true};
103103
}
104104
};
105105

IOPool/Input/src/RootTreeCacheManager.cc

Lines changed: 94 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ namespace edm {
2020
void CacheManagerBase::getEntry(TBranch* branch, EntryNumber entryNumber) { branch->GetEntry(entryNumber); }
2121
void CacheManagerBase::getAuxEntry(TBranch* branch, EntryNumber entryNumber) { getEntry(branch, entryNumber); }
2222
void CacheManagerBase::getEntryForAllBranches(EntryNumber entryNumber) const { tree_->GetEntry(entryNumber); }
23+
std::shared_ptr<TTreeCache> CacheManagerBase::createCacheWithSize(unsigned int cacheSize) {
24+
return filePtr_->createCacheWithSize(tree_, cacheSize);
25+
}
2326

2427
// policy with no TTreeCache
2528
class NoCache : public CacheManagerBase {
@@ -52,13 +55,12 @@ namespace edm {
5255
void createPrimaryCache(unsigned int cacheSize) override;
5356
void setEntryNumber(EntryNumber nextEntryNumber, EntryNumber entryNumber, EntryNumber entries) override;
5457
void trainCache(char const* branchNames) override;
55-
void resetTraining() override;
58+
void resetTraining(bool promptRead) override;
5659
void getEntry(TBranch* branch, EntryNumber entryNumber) override;
5760
void getEntryForAllBranches(EntryNumber entryNumber) const override;
5861

59-
private:
60-
// SimpleCache does not own the treeCache_
61-
TTreeCache* treeCache_;
62+
protected:
63+
std::shared_ptr<TTreeCache> treeCache_;
6264
BranchType branchType_;
6365
unsigned int learningEntries_;
6466
bool enablePrefetching_;
@@ -77,46 +79,105 @@ namespace edm {
7779
if (cachestats && treeCache_) {
7880
treeCache_->Print("a cachedbranches");
7981
}
82+
// We own the treeCache_.
83+
// We make sure the treeCache_ is detached from the file,
84+
// so that ROOT does not also delete it.
85+
filePtr_->clearCacheRead(tree_);
86+
treeCache_.reset();
8087
}
8188

8289
void SimpleCache::setEntryNumber(EntryNumber nextEntryNumber, EntryNumber entryNumber, EntryNumber entries) {
8390
if (nextEntryNumber != entryNumber) {
84-
oneapi::tbb::this_task_arena::isolate([&]() {
85-
tree_->LoadTree(nextEntryNumber);
86-
treeCache_->FillBuffer();
87-
});
91+
auto guard = filePtr_->setCacheReadTemporarily(treeCache_.get(), tree_);
92+
oneapi::tbb::this_task_arena::isolate([&]() { tree_->LoadTree(nextEntryNumber); });
8893
}
8994
}
9095

9196
void SimpleCache::getEntry(TBranch* branch, EntryNumber entryNumber) {
97+
auto guard = filePtr_->setCacheReadTemporarily(treeCache_.get(), tree_);
9298
oneapi::tbb::this_task_arena::isolate([&]() { branch->GetEntry(entryNumber); });
9399
}
94100

95101
void SimpleCache::getEntryForAllBranches(EntryNumber entryNumber) const {
102+
auto guard = filePtr_->setCacheReadTemporarily(treeCache_.get(), tree_);
96103
oneapi::tbb::this_task_arena::isolate([&]() { tree_->GetEntry(entryNumber); });
97104
}
98105

99106
void SimpleCache::createPrimaryCache(unsigned int cacheSize) {
100-
tree_->SetCacheSize(static_cast<Long64_t>(cacheSize));
101-
treeCache_ = dynamic_cast<TTreeCache*>(filePtr_->getCacheRead(tree_));
107+
treeCache_ = createCacheWithSize(cacheSize);
102108
assert(treeCache_);
103-
104109
treeCache_->SetEnablePrefetching(enablePrefetching_);
105-
treeCache_->SetLearnEntries(learningEntries_);
106110
}
107111

108-
void SimpleCache::resetTraining() {
109-
trainCache(nullptr);
110-
treeCache_->SetLearnEntries(learningEntries_);
112+
void SimpleCache::resetTraining(bool promptRead) {
113+
if (cachestats) {
114+
treeCache_->Print("a cachedbranches");
115+
}
116+
const auto addBranches = promptRead ? "*" : nullptr;
117+
trainCache(addBranches);
111118
}
112119

113120
void SimpleCache::trainCache(char const* branchNames) {
114-
tree_->LoadTree(0);
115121
treeCache_->StartLearningPhase();
116122
treeCache_->SetEntryRange(0, tree_->GetEntries());
117123
if (branchNames) {
124+
treeCache_->SetLearnEntries(0);
118125
treeCache_->AddBranch(branchNames, kTRUE);
126+
treeCache_->StopLearningPhase();
127+
} else {
128+
treeCache_->SetLearnEntries(learningEntries_);
129+
auto guard = filePtr_->setCacheReadTemporarily(treeCache_.get(), tree_);
130+
tree_->LoadTree(0);
131+
}
132+
}
133+
134+
class SimpleWithAuxCache : public SimpleCache {
135+
public:
136+
SimpleWithAuxCache(std::shared_ptr<InputFile> filePtr,
137+
unsigned int learningEntries,
138+
bool enablePrefetching,
139+
BranchType const& branchType);
140+
void getAuxEntry(TBranch* branch, EntryNumber entryNumber) override;
141+
void reset() override;
142+
143+
private:
144+
TTreeCache* getAuxCache(TBranch* auxBranch);
145+
std::shared_ptr<TTreeCache> auxCache_;
146+
};
147+
148+
SimpleWithAuxCache::SimpleWithAuxCache(std::shared_ptr<InputFile> filePtr,
149+
unsigned int learningEntries,
150+
bool enablePrefetching,
151+
BranchType const& branchType)
152+
: SimpleCache(filePtr, learningEntries, enablePrefetching, branchType) {}
153+
154+
TTreeCache* SimpleWithAuxCache::getAuxCache(TBranch* auxBranch) {
155+
if (not auxCache_) {
156+
auxCache_ = createCacheWithSize(1 * 1024 * 1024);
157+
if (auxCache_) {
158+
auxCache_->SetEnablePrefetching(enablePrefetching_);
159+
auxCache_->SetLearnEntries(0);
160+
auxCache_->StartLearningPhase();
161+
auxCache_->SetEntryRange(0, tree_->GetEntries());
162+
auxCache_->AddBranch(auxBranch->GetName(), kTRUE);
163+
auxCache_->StopLearningPhase();
164+
}
165+
}
166+
return auxCache_.get();
167+
}
168+
169+
void SimpleWithAuxCache::reset() {
170+
if constexpr (cachestats) {
171+
if (auxCache_)
172+
auxCache_->Print("a cachedbranches");
119173
}
174+
auxCache_.reset();
175+
SimpleCache::reset();
176+
}
177+
178+
void SimpleWithAuxCache::getAuxEntry(TBranch* branch, EntryNumber entryNumber) {
179+
auto guard = filePtr_->setCacheReadTemporarily(getAuxCache(branch), tree_);
180+
branch->GetEntry(entryNumber);
120181
}
121182

122183
//
@@ -139,7 +200,7 @@ namespace edm {
139200
enableTriggerCache_(branchType_ == InEvent) {}
140201
~SparseReadCache() override { reset(); }
141202
void createPrimaryCache(unsigned int cacheSize) override;
142-
void resetTraining() override;
203+
void resetTraining(bool promptRead) override;
143204
void reset() override;
144205
void setEntryNumber(EntryNumber nextEntryNumber, EntryNumber entryNumber, EntryNumber entries) override;
145206
void trainCache(char const* branchNames) override;
@@ -152,7 +213,6 @@ namespace edm {
152213
private:
153214
void getEntryUsingCache(TBranch* branch, EntryNumber entryNumber, TTreeCache* cache);
154215
TTreeCache* getAuxCache(TBranch* auxBranch);
155-
std::shared_ptr<TTreeCache> createCacheWithSize(unsigned int cacheSize);
156216
TTreeCache* selectCache(TBranch* branch, EntryNumber entryNumber);
157217
TTreeCache* checkTriggerCache(TBranch* branch, EntryNumber entryNumber);
158218
TTreeCache* checkTriggerCacheImpl(TBranch* branch, EntryNumber entryNumber);
@@ -186,10 +246,6 @@ namespace edm {
186246
std::unordered_set<TBranch*> triggerSet_;
187247
};
188248

189-
std::shared_ptr<TTreeCache> SparseReadCache::createCacheWithSize(unsigned int cacheSize) {
190-
return filePtr_->createCacheWithSize(*tree_, cacheSize);
191-
}
192-
193249
void SparseReadCache::createPrimaryCache(unsigned int cacheSize) {
194250
cacheSize_ = cacheSize;
195251
treeCache_ = createCacheWithSize(cacheSize);
@@ -353,10 +409,8 @@ namespace edm {
353409
}
354410

355411
void SparseReadCache::getEntryForAllBranches(EntryNumber entryNumber) const {
356-
oneapi::tbb::this_task_arena::isolate([&]() {
357-
auto guard = filePtr_->setCacheReadTemporarily(treeCache_.get(), tree_);
358-
tree_->GetEntry(entryNumber);
359-
});
412+
auto guard = filePtr_->setCacheReadTemporarily(treeCache_.get(), tree_);
413+
oneapi::tbb::this_task_arena::isolate([&]() { tree_->GetEntry(entryNumber); });
360414
}
361415

362416
void SparseReadCache::startTraining(EntryNumber entryNumber) {
@@ -404,9 +458,13 @@ namespace edm {
404458
rawTreeCache_.reset();
405459
}
406460

407-
void SparseReadCache::resetTraining() { trainNow_ = true; }
461+
void SparseReadCache::resetTraining(bool promptRead) { trainNow_ = true; }
408462

409463
void SparseReadCache::reset() {
464+
// We own the treeCache_.
465+
// We make sure the treeCache_ is detached from the file,
466+
// so that ROOT does not also delete it.
467+
filePtr_->clearCacheRead(tree_);
410468
if constexpr (cachestats) {
411469
if (treeCache_)
412470
treeCache_->Print("a cachedbranches");
@@ -479,10 +537,6 @@ namespace edm {
479537
}
480538

481539
void SparseReadCache::trainCache(char const* branchNames) {
482-
// We own the treeCache_.
483-
// We make sure the treeCache_ is detached from the file,
484-
// so that ROOT does not also delete it.
485-
486540
if (cacheSize_ == 0) {
487541
return;
488542
}
@@ -529,12 +583,15 @@ namespace edm {
529583
unsigned int learningEntries,
530584
bool enablePrefetching,
531585
BranchType const& branchType) {
532-
if (strategy == CacheStrategy::kSimple) {
533-
return std::make_unique<SimpleCache>(filePtr, learningEntries, enablePrefetching, branchType);
534-
} else if (strategy == CacheStrategy::kSparse) {
535-
return std::make_unique<SparseReadCache>(filePtr, learningEntries, enablePrefetching, branchType);
536-
} else if (strategy == CacheStrategy::kNone) {
537-
return std::make_unique<NoCache>(filePtr);
586+
switch (strategy) {
587+
case CacheStrategy::kNone:
588+
return std::make_unique<NoCache>(filePtr);
589+
case CacheStrategy::kSimple:
590+
return std::make_unique<SimpleCache>(filePtr, learningEntries, enablePrefetching, branchType);
591+
case CacheStrategy::kSimpleWithAuxCache:
592+
return std::make_unique<SimpleWithAuxCache>(filePtr, learningEntries, enablePrefetching, branchType);
593+
case CacheStrategy::kSparse:
594+
return std::make_unique<SparseReadCache>(filePtr, learningEntries, enablePrefetching, branchType);
538595
}
539596

540597
throw cms::Exception("BadConfig") << "CacheManagerBase: unknown cache strategy requested";

IOPool/Input/src/RootTreeCacheManager.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#include <memory>
2121

22-
class TFileCacheRead;
22+
class TTreeCache;
2323
class TBranch;
2424
class TTree;
2525

@@ -34,6 +34,7 @@ namespace edm {
3434
enum class CacheStrategy {
3535
kNone,
3636
kSimple,
37+
kSimpleWithAuxCache,
3738
kSparse,
3839
};
3940

@@ -45,7 +46,7 @@ namespace edm {
4546
// non-serial reads, especially skipping backwards in the tree
4647
virtual void setEntryNumber(EntryNumber nextEntryNumber, EntryNumber entryNumber, EntryNumber entries) = 0;
4748

48-
virtual void resetTraining() {}
49+
virtual void resetTraining(bool promptRead = false) {}
4950
virtual void reset() {}
5051
virtual void trainCache(char const* branchNames) {}
5152
virtual void init(TTree* tree, unsigned int treeAutoFlush) { tree_ = tree; }
@@ -61,6 +62,8 @@ namespace edm {
6162
BranchType const& branchType);
6263

6364
protected:
65+
std::shared_ptr<TTreeCache> createCacheWithSize(unsigned int cacheSize);
66+
6467
std::shared_ptr<InputFile> filePtr_;
6568
TTree* tree_ = nullptr;
6669

0 commit comments

Comments
 (0)