34constexpr char const *kNTupleFileName =
"ntpl013_staged.root";
37constexpr int kNWriterThreads = 4;
40constexpr int kNEventsPerThread = 25000;
43constexpr int kNEventsPerBlock = 10000;
50 static std::mutex g_Mutex;
53 using generator = std::mt19937;
57 auto fillContext =
writer->CreateFillContext();
58 fillContext->EnableStagedClusterCommitting();
59 auto entry = fillContext->CreateEntry();
61 auto eventId = entry->GetPtr<std::uint32_t>(
"eventId");
62 auto eventIdStart =
id * kNEventsPerThread;
63 auto rndm = entry->GetPtr<
float>(
"rndm");
65 for (
int i = 0; i < kNEventsPerThread; i++) {
67 *eventId = eventIdStart + i;
68 auto d =
static_cast<double>(gen()) / generator::max();
69 *rndm =
static_cast<float>(
d);
72 fillContext->Fill(*entry);
76 fillContext->FlushCluster();
78 std::lock_guard
g(g_Mutex);
79 fillContext->CommitStagedClusters();
80 std::cout <<
"Thread #" <<
id <<
" wrote events #" << eventIdStart <<
" - #"
81 << (eventIdStart + kNEventsPerThread - 1) <<
" as entries #" << g_WrittenEntries <<
" - #"
82 << (g_WrittenEntries + kNEventsPerThread - 1) << std::endl;
83 g_WrittenEntries += kNEventsPerThread;
90 std::cout <<
" === Writing with staged cluster committing ===" << std::endl;
93 auto model = RNTupleModel::CreateBare();
94 model->MakeField<std::uint32_t>(
"eventId");
95 model->MakeField<
float>(
"rndm");
101 RNTupleWriteOptions options;
102 options.SetApproxZippedClusterSize(32'000);
105 auto writer = RNTupleParallelWriter::Recreate(std::move(model),
"NTuple", kNTupleFileName, options);
107 std::vector<std::thread> threads;
108 for (
int i = 0; i < kNWriterThreads; ++i)
109 threads.emplace_back(FillData, i,
writer.get());
110 for (
int i = 0; i < kNWriterThreads; ++i)
117void FillDataInBlocks(
int id, RNTupleParallelWriter *
writer)
121 static std::mutex g_Mutex;
124 using generator = std::mt19937;
128 auto fillContext =
writer->CreateFillContext();
129 fillContext->EnableStagedClusterCommitting();
130 auto entry = fillContext->CreateEntry();
132 auto eventId = entry->GetPtr<std::uint32_t>(
"eventId");
133 auto eventIdStart =
id * kNEventsPerThread;
134 int startOfBlock = 0;
135 auto rndm = entry->GetPtr<
float>(
"rndm");
137 for (
int i = 0; i < kNEventsPerThread; i++) {
139 *eventId = eventIdStart + i;
140 auto d =
static_cast<double>(gen()) / generator::max();
141 *rndm =
static_cast<float>(
d);
144 fillContext->Fill(*entry);
146 if ((i + 1) % kNEventsPerBlock == 0) {
148 fillContext->FlushCluster();
150 std::lock_guard
g(g_Mutex);
151 fillContext->CommitStagedClusters();
152 auto firstEvent = eventIdStart + startOfBlock;
153 auto lastEvent = eventIdStart + i;
154 std::cout <<
"Thread #" <<
id <<
" wrote events #" <<
firstEvent <<
" - #" << lastEvent <<
" as entries #"
155 << g_WrittenEntries <<
" - #" << (g_WrittenEntries + kNEventsPerBlock - 1) << std::endl;
156 g_WrittenEntries += kNEventsPerBlock;
157 startOfBlock += kNEventsPerBlock;
163 fillContext->FlushCluster();
165 std::lock_guard
g(g_Mutex);
166 fillContext->CommitStagedClusters();
167 auto firstEvent = eventIdStart + startOfBlock;
168 auto lastEvent = eventIdStart + kNEventsPerThread - 1;
169 auto numEvents = kNEventsPerThread - startOfBlock;
170 std::cout <<
"Thread #" <<
id <<
" wrote events #" <<
firstEvent <<
" - #" << lastEvent <<
" as entries #"
171 << g_WrittenEntries <<
" - #" << (g_WrittenEntries + numEvents - 1) << std::endl;
172 g_WrittenEntries += numEvents;
179 std::cout <<
"\n === ... with sequencing in blocks of " << kNEventsPerBlock <<
" events ===" << std::endl;
182 auto model = RNTupleModel::CreateBare();
183 model->MakeField<std::uint32_t>(
"eventId");
184 model->MakeField<
float>(
"rndm");
191 RNTupleWriteOptions options;
192 options.SetApproxZippedClusterSize(32'000);
195 auto writer = RNTupleParallelWriter::Recreate(std::move(model),
"NTuple", kNTupleFileName, options);
197 std::vector<std::thread> threads;
198 for (
int i = 0; i < kNWriterThreads; ++i)
199 threads.emplace_back(FillDataInBlocks, i,
writer.get());
200 for (
int i = 0; i < kNWriterThreads; ++i)
The RNTupleModel encapulates the schema of an ntuple.
A writer to fill an RNTuple from multiple contexts.
Common user-tunable settings for storing ntuples.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.