Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleWriteOptions.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleWriteOptions.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2024-02-22
4
5/*************************************************************************
6 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_RNTupleWriteOptions
14#define ROOT_RNTupleWriteOptions
15
16#include <Compression.h>
17
18#include <cstdint>
19#include <cstddef>
20#include <memory>
21
22namespace ROOT {
23
24class RNTupleWriteOptions;
25
26namespace Internal {
27
29public:
30 static void SetMaxKeySize(RNTupleWriteOptions &options, std::uint64_t maxKeySize);
31};
32
33} // namespace Internal
34
35// clang-format off
36/**
37\class ROOT::RNTupleWriteOptions
38\ingroup NTuple
39\brief Common user-tunable settings for storing RNTuples
40
41All page sink classes need to support the common options.
42
43<table>
44<tr>
45<th>Option name</th>
46<th>Type</th>
47<th>Default</th>
48<th>Description</th>
49</tr>
50
51<tr>
52<td>`Compression`</td>
53<td>`std::uint32_t`</td>
54<td>RCompressionSetting::EDefaults::kUseGeneralPurpose</td>
55<td>
56The compression settings for this RNTuple
57</td>
58</tr>
59
60<tr>
61<td>`fClusterGroupPageThreshold`</td>
62<td>`std::size_t`</td>
63<td>500'000</td>
64<td>
65Commit a new cluster group when the number of pages in the current cluster group surpasses the given limit.
66Reading and writing will typically pin page locations of one to two cluster groups in memory concurrently.
67This limit typically does not need to be adjusted except, perhaps, for very wide data models (>100k columns)
68or very tight memory budgets.
69Set to zero to disable automatic cluster group creation.
70</td>
71</tr>
72
73<tr>
74<td>`ApproxZippedClusterSize`</td>
75<td>`std::size_t`</td>
76<td>128 MiB</td>
77<td>
78Approximation of the target compressed cluster size
79</td>
80</tr>
81
82<tr>
83<td>`MaxUnzippedClusterSize`</td>
84<td>`std::size_t`</td>
85<td>1280 MiB</td>
86<td>
87Memory limit for committing a cluster: with very high compression ratio, we need a limit
88on how large the I/O buffer can grow during writing.
89</td>
90</tr>
91
92<tr>
93<td>`InitialUnzippedPageSize`</td>
94<td>`std::size_t`</td>
95<td>16</td>
96<td>
97Initially, columns start with a page of this size. The default value is chosen for low memory footprint
98(two 64bit values). If more elements are needed, pages are increased up until the byte limit
99given by the option `MaxUnzippedPageSize` or until the total page buffer limit is reached (as a sum of all page buffers).
100The total write buffer limit needs to be large enough to hold the initial pages of all columns.
101</td>
102</tr>
103
104<tr>
105<td>`MaxUnzippedPageSize`</td>
106<td>`std::size_t`</td>
107<td>1 MiB</td>
108<td>
109Pages can grow only to the given limit in bytes.
110</td>
111</tr>
112
113<tr>
114<td>`PageBufferBudget`</td>
115<td>`std::size_t`</td>
116<td>0 / auto</td>
117<td>
118The maximum size that the sum of all page buffers used for writing into a persistent sink are allowed to use.
119If set to zero, RNTuple will auto-adjust the budget based on the value of `ApproxZippedClusterSize`.
120If set manually, the size needs to be large enough to hold all initial page buffers.
121The total amount of memory for writing is larger, e.g. for the additional compressed buffers etc.
122Use RNTupleModel::EstimateWriteMemoryUsage() for the total estimated memory use for writing.
123The default values are tuned for a total write memory of around 400 MiB per fill context.
124</td>
125</tr>
126
127<tr>
128<td>`UseBufferedWrite`</td>
129<td>`bool`</td>
130<td>`true`</td>
131<td>
132Whether to use buffered writing (with RPageSinkBuf). This buffers compressed pages in memory, reorders them
133to keep pages of the same column adjacent, and coalesces the writes when committing a cluster.
134</td>
135</tr>
136
137<tr>
138<td>`UseDirectIO`</td>
139<td>`bool`</td>
140<td>`false`</td>
141<td>
142Whether to use Direct I/O for writing. Note that this introduces alignment requirements that may very between
143filesystems and platforms.
144</td>
145</tr>
146
147<tr>
148<td>`WriteBufferSize`</td>
149<td>`std::size_t`</td>
150<td>4 MiB</td>
151<td>
152Buffer size to use for writing to files, must be a multiple of 4096 bytes. Testing suggests that 4MiB gives best
153performance (with Direct I/O) at a reasonable memory consumption.
154</td>
155</tr>
156
157<tr>
158<td>`UseImplicitMT`</td>
159<td>EImplicitMT</td>
160<td>EImplicitMT::kDefault</td>
161<td>
162Whether to use implicit multi-threading to compress pages. Only has an effect if buffered writing is turned on.
163The meaning of EImplicitMT::kDefault depends on the used writer: For the (sequential) RNTupleWriter, it translates
164to EImplicitMT::kOn and the user has to manually disable the use of implicit multi-threading if it is not wanted.
165For the RNTupleParalellWriter, the implementation defaults to EImplicitMT::kOff in order to avoid interference with
166explicit parallelism that might create one RNTupleFillContext per thread. If implicit multi-threading is wanted on
167top of this, the user has to explicitly request EImplicitMT::kOn.
168</td>
169</tr>
170
171<tr>
172<td>`EnablePageChecksums`</td>
173<td>`bool`</td>
174<td>`true`</td>
175<td>
176If set, checksums will be calculated and written for every page.
177If turned off, will also turn off `EnableSamePageMerging`.
178</td>
179</tr>
180
181<tr>
182<td>`EnableSamePageMerging`</td>
183<td>`bool`</td>
184<td>`true`</td>
185<td>
186If set, identical pages are deduplicated and aliased on disk.
187Requires `EnablePageChecksums` and will throw if previously disabled.
188</td>
189</tr>
190
191</table>
192*/
193// clang-format on
195public:
196 enum class EImplicitMT {
197 kOff,
198 kOn,
199 kDefault,
200 };
201
202 // clang-format off
203 static constexpr std::uint64_t kDefaultMaxKeySize = 0x4000'0000; // 1 GiB
204 // clang-format on
205
207
208protected:
210 std::size_t fClusterGroupPageThreshold = 500'000;
211 std::size_t fApproxZippedClusterSize = 128 * 1024 * 1024;
213 std::size_t fInitialUnzippedPageSize = 16;
214 std::size_t fMaxUnzippedPageSize = 1024 * 1024;
215 std::size_t fPageBufferBudget = 0;
216 bool fUseBufferedWrite = true;
217 bool fUseDirectIO = false;
218 std::size_t fWriteBufferSize = 4 * 1024 * 1024;
222 /// Specifies the max size of a payload storeable into a single TKey. When writing an RNTuple to a ROOT file,
223 /// any payload whose size exceeds this will be split into multiple keys.
225
226public:
227
228 virtual ~RNTupleWriteOptions() = default;
229 virtual std::unique_ptr<RNTupleWriteOptions> Clone() const;
230
231 std::uint32_t GetCompression() const { return fCompression; }
232 void SetCompression(std::uint32_t val) { fCompression = val; }
233 void SetCompression(RCompressionSetting::EAlgorithm::EValues algorithm, int compressionLevel)
234 {
235 fCompression = CompressionSettings(algorithm, compressionLevel);
236 }
237
240
242 void SetApproxZippedClusterSize(std::size_t val);
243
245 void SetMaxUnzippedClusterSize(std::size_t val);
246
248 void SetInitialUnzippedPageSize(std::size_t val);
249
250 std::size_t GetMaxUnzippedPageSize() const { return fMaxUnzippedPageSize; }
251 void SetMaxUnzippedPageSize(std::size_t val);
252
253 std::size_t GetPageBufferBudget() const;
254 void SetPageBufferBudget(std::size_t val) { fPageBufferBudget = val; }
255
256 bool GetUseBufferedWrite() const { return fUseBufferedWrite; }
257 void SetUseBufferedWrite(bool val) { fUseBufferedWrite = val; }
258
259 bool GetUseDirectIO() const { return fUseDirectIO; }
260 void SetUseDirectIO(bool val) { fUseDirectIO = val; }
261
262 std::size_t GetWriteBufferSize() const { return fWriteBufferSize; }
263 void SetWriteBufferSize(std::size_t val) { fWriteBufferSize = val; }
264
267
269 /// Note that turning off page checksums will also turn off the same page merging optimization (see tuning.md)
271 {
275 }
276 }
277
279 void SetEnableSamePageMerging(bool val);
280
281 std::uint64_t GetMaxKeySize() const { return fMaxKeySize; }
282
294
295 friend bool operator!=(const RNTupleWriteOptions &lhs, const RNTupleWriteOptions &rhs) { return !(lhs == rhs); }
296};
297
298namespace Internal {
299inline void RNTupleWriteOptionsManip::SetMaxKeySize(RNTupleWriteOptions &options, std::uint64_t maxKeySize)
300{
301 options.fMaxKeySize = maxKeySize;
302}
303
304} // namespace Internal
305} // namespace ROOT
306
307#endif // ROOT_RNTupleWriteOptions
static void SetMaxKeySize(RNTupleWriteOptions &options, std::uint64_t maxKeySize)
Common user-tunable settings for storing RNTuples.
void SetEnablePageChecksums(bool val)
Note that turning off page checksums will also turn off the same page merging optimization (see tunin...
friend bool operator==(const RNTupleWriteOptions &lhs, const RNTupleWriteOptions &rhs)
void SetClusterGroupPageThreshold(std::size_t val)
std::size_t GetPageBufferBudget() const
void SetMaxUnzippedClusterSize(std::size_t val)
void SetWriteBufferSize(std::size_t val)
std::size_t GetWriteBufferSize() const
std::size_t GetApproxZippedClusterSize() const
std::size_t GetMaxUnzippedClusterSize() const
std::size_t GetClusterGroupPageThreshold() const
std::uint64_t fMaxKeySize
Specifies the max size of a payload storeable into a single TKey.
void SetUseImplicitMT(EImplicitMT val)
static constexpr std::uint64_t kDefaultMaxKeySize
std::uint64_t GetMaxKeySize() const
friend bool operator!=(const RNTupleWriteOptions &lhs, const RNTupleWriteOptions &rhs)
void SetMaxUnzippedPageSize(std::size_t val)
void SetInitialUnzippedPageSize(std::size_t val)
virtual std::unique_ptr< RNTupleWriteOptions > Clone() const
virtual ~RNTupleWriteOptions()=default
void SetPageBufferBudget(std::size_t val)
void SetApproxZippedClusterSize(std::size_t val)
std::size_t GetMaxUnzippedPageSize() const
std::uint32_t GetCompression() const
void SetCompression(std::uint32_t val)
void SetCompression(RCompressionSetting::EAlgorithm::EValues algorithm, int compressionLevel)
EImplicitMT GetUseImplicitMT() const
std::size_t GetInitialUnzippedPageSize() const
int CompressionSettings(RCompressionSetting::EAlgorithm::EValues algorithm, int compressionLevel)
EValues
Note: this is only temporarily a struct and will become a enum class hence the name convention used.
Definition Compression.h:88
@ kUseGeneralPurpose
Use the new recommended general-purpose setting; it is a best trade-off between compression ratio/dec...
Definition Compression.h:58