Loading...
Searching...
No Matches
ListPolicy.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2019-2025 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26Namespace
27 Foam::ListPolicy
28
29Description
30 Additional compile-time controls of List behaviour
31
32\*---------------------------------------------------------------------------*/
33
34#ifndef Foam_ListPolicy_H
35#define Foam_ListPolicy_H
36
37#include "MemoryPool.H" // Also includes <cstdint>
38#include "contiguous.H" // Also includes <type_traits>
39
40// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41
42namespace Foam
43{
44
45// Forward Declarations
46class keyType;
47class word;
48class wordRe;
49
50namespace ListPolicy
51{
52
53// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54
55//- Number of items before requiring line-breaks in the list output.
56//
57// Default definition: 10
58template<class T>
59struct short_length : std::integral_constant<int,10> {};
60
61// Can override on a per-type basis
62// Eg,
63// template<> struct short_length<label> : std::integral_constant<int,20> {};
64
65
66// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
67
68//- Can suppress additional line breaks separate ASCII data content
69//- when the data elements are primitives, or contiguous
70//
71// Default definition: (integral | floating-point) are contiguous and thus
72// never need any line breaks
73template<class T>
74struct no_linebreak : std::is_arithmetic<std::remove_cv_t<T>> {};
75
76// Specialization for word-like classes
77// These elements are normally fairly short, so ok to output a few (eg, 10)
78// of them on a single line.
79
80//- Suppress line-breaks for keyType
81template<> struct no_linebreak<keyType> : std::true_type {};
82
83//- Suppress line-breaks for word
84template<> struct no_linebreak<word> : std::true_type {};
85
86//- Suppress line-breaks for wordRe
87template<> struct no_linebreak<wordRe> : std::true_type {};
89
90// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
91//
92// Memory allocation/deallocation handling - primarily used by List and Matrix
93//
94// - is_aligned_type() :
95// Defines which types may be aligned
96//
97// - use_alignment(n) :
98// Lower threshold for using memory alignment
99//
100// - use_memory_pool(n) :
101// Lower threshold for using a memory pool.
102// Must be larger than use_alignment() value.
103//
104// - use_offload(n) :
105// Lower threshold for switching to device offloading
106//
107//
108// Use of the memory-pool is controlled by the 'is_aligned_type()' test
109// and the minimum field size, controlled by the 'use_memory_pool()' test.
110//
111// If the memory-pool is not enabled or not required according to the two
112// above tests, the allocation falls back to either an aligned or unaligned
113// allocation.
114//
115// The decision about when to choose aligned vs unaligned allocation
116// is still a compile-time option. Made by direct edit of the
117// appropriate functions.
118//
119// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
120
121//- Consider aligned allocation for the given type?
122// Benefits for field data (floating-point, ints, vectorspace),
123// but avoid for char data, strings, pointers etc
124template<class T>
125inline constexpr bool is_aligned_type() noexcept
126{
127 return
128 (
129 !std::is_enum_v<T>
130 && !std::is_pointer_v<T>
131 && !std::is_union_v<T>
132 && (sizeof(T) >= 4) // skip small data (eg, char)
134 );
135}
136
137
138//- True if size exceeds the min-size for using memory alignment
139template<class IntType>
140inline constexpr bool use_alignment(IntType n) noexcept
141{
142 return (n >= IntType(200));
143}
144
145
146//- True if size exceeds the min-size for using the memory pool
147template<class IntType>
148inline constexpr bool use_memory_pool(IntType n) noexcept
149{
150 return (n >= IntType(3000));
152
153
154//- True if size exceeds the min-size for offloading
155template<class IntType>
156inline constexpr bool use_offload(IntType n) noexcept
157{
158 return (n >= IntType(1000));
159}
160
162//- Default alignment for larger fields
163inline constexpr std::align_val_t default_alignment() noexcept
164{
165 return std::align_val_t(256);
166}
167
168
169//- Allocate from memory pool (if active), or aligned, or normal
170template<class T, class IntType>
171inline T* allocate(IntType n)
172{
173 if constexpr (ListPolicy::is_aligned_type<T>())
174 {
175 // Note: threshold for use_memory_pool() >= use_alignment()
176
178 {
179 if
181 void *pool_ptr
182 (
183 // Consider memory pool for large amounts of data
186 : nullptr
187 );
188 pool_ptr
189 )
191 // Placement new
192 return new (pool_ptr) T[n];
193 }
194 else
195 {
196 return new (ListPolicy::default_alignment()) T[n];
197 }
198 }
199 else
200 {
201 // Plain new
202 return new T[n];
203 }
204 }
205 else
206 {
207 // Plain new
208 return new T[n];
209 }
210}
211
212
213//- Deallocate from memory pool, or normal
214template<class T, class IntType>
215inline void deallocate(T* ptr)
216{
217 if constexpr (ListPolicy::is_aligned_type<T>())
218 {
219 if (ptr && !Foam::MemoryPool::try_deallocate(ptr))
220 {
221 // Plain new
222 delete[] ptr;
223 }
224 }
225 else
226 {
227 // Plain new
228 delete[] ptr;
229 }
230}
231
232
233//- Deallocate from memory pool, or aligned, or normal
234template<class T, class IntType>
235inline void deallocate(T* ptr, [[maybe_unused]] IntType n)
237 if constexpr (ListPolicy::is_aligned_type<T>())
238 {
239 // Note: threshold for use_memory_pool() >= use_alignment()
240
242 {
243 if (ptr && !Foam::MemoryPool::try_deallocate(ptr))
244 {
245 // Alignment depends on the number of elements
246 ::operator delete[](ptr, ListPolicy::default_alignment());
247 }
248 }
249 else
250 {
251 // Plain new
252 delete[] ptr;
253 }
254 }
255 else
256 {
257 // Plain new
258 delete[] ptr;
259 }
260}
261
262
263// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
264
265//- Calculate a reserve size (eg, doubling) based on the requested length
266//- and the current capacity
267template<int SizeMin, int Numerator, class IntType>
268inline IntType reserve_size(IntType requested, IntType capacity) noexcept
269{
270 static_assert(Numerator > 1, "Invalid numerator");
271
272 // The caller already checks this:
273 // if (requested < capacity) { return capacity; }
274
275 IntType size(capacity*Numerator);
276 if (size < requested)
277 {
278 size = requested;
279 }
280 if constexpr (SizeMin > 0) // The min size is optional
281 {
282 if (size < SizeMin)
283 {
284 size = SizeMin;
285 }
286 }
287 return size;
288}
289
290
291//- Calculate a reserve size based on the requested length
292//- and the current capacity
293template<int SizeMin, int Numerator, int Denominator, class IntType>
294inline IntType reserve_size(IntType requested, IntType capacity) noexcept
295{
296 static_assert(Numerator > Denominator, "Invalid numerator");
297 static_assert(Denominator > 0, "Invalid denominator");
298
299 // The caller already checks this:
300 // if (requested < capacity) { return capacity; }
301
302 // Very unlikely that capacity is less than Denominator,
303 // so divide before multiply to avoid overflow
304 IntType size((capacity/Denominator)*Numerator);
305 if (size < requested)
306 {
307 size = requested;
308 }
309 if constexpr (SizeMin > 0) // The min size is optional
310 {
311 if (size < SizeMin)
312 {
313 size = SizeMin;
314 }
315 }
316 return size;
317}
318
319
320// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
322//- Classification of list/container uniformity.
323//- The values can be used with bit-wise \c or reduction
324enum uniformity : unsigned char
325{
326 EMPTY = 0,
327 UNIFORM = 0x1,
328 NONUNIFORM = 0x2,
329 MIXED = 0x3
330};
331
332//- Algorithm to determine list/container uniformity
333template<class InputIt>
334enum uniformity check_uniformity(InputIt first, InputIt last)
335{
336 if (first == last) return uniformity::EMPTY;
337
338 // Like std::all_of() with checking against element 0,
339 // but without using a lambda with auto type (pre C++14) etc.
340
341 const auto& elem0 = *first;
342
343 for ((void)++first; (first != last); (void)++first)
344 {
345 if (elem0 != *first)
346 {
348 }
349 }
350
351 return uniformity::UNIFORM;
352}
354
355// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
357} // End namespace ListPolicy
358} // End namespace Foam
359
360// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
361
362#endif
363
364// ************************************************************************* //
label n
static void * try_allocate(std::size_t nbytes)
Allocate from pool (if active).
static bool try_deallocate(void *ptr)
Deallocate a pointer managed by the pool.
A class for handling keywords in dictionaries.
Definition keyType.H:69
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition wordRe.H:81
A class for handling words, derived from Foam::string.
Definition word.H:66
const volScalarField & T
Additional compile-time controls of List behaviour.
constexpr bool is_aligned_type() noexcept
Consider aligned allocation for the given type?
Definition ListPolicy.H:134
T * allocate(IntType n)
Allocate from memory pool (if active), or aligned, or normal.
Definition ListPolicy.H:190
constexpr bool use_memory_pool(IntType n) noexcept
True if size exceeds the min-size for using the memory pool.
Definition ListPolicy.H:161
constexpr bool use_offload(IntType n) noexcept
True if size exceeds the min-size for offloading.
Definition ListPolicy.H:171
IntType reserve_size(IntType requested, IntType capacity) noexcept
Calculate a reserve size (eg, doubling) based on the requested length and the current capacity.
Definition ListPolicy.H:293
void deallocate(T *ptr)
Deallocate from memory pool, or normal.
Definition ListPolicy.H:236
uniformity
Classification of list/container uniformity. The values can be used with bit-wise or reduction.
Definition ListPolicy.H:354
@ EMPTY
An empty container.
Definition ListPolicy.H:355
@ MIXED
Mixed uniform/non-uniform (eg, after reduction).
Definition ListPolicy.H:358
@ UNIFORM
Container (non-empty) with identical values.
Definition ListPolicy.H:356
@ NONUNIFORM
Container (non-empty) with different values.
Definition ListPolicy.H:357
enum uniformity check_uniformity(InputIt first, InputIt last)
Algorithm to determine list/container uniformity.
Definition ListPolicy.H:365
constexpr bool use_alignment(IntType n) noexcept
True if size exceeds the min-size for using memory alignment.
Definition ListPolicy.H:151
constexpr std::align_val_t default_alignment() noexcept
Default alignment for larger fields.
Definition ListPolicy.H:180
Namespace for OpenFOAM.
const direction noexcept
Definition scalarImpl.H:265
constexpr bool is_contiguous_v
The is_contiguous value of Type (after stripping of qualifiers).
Definition contiguous.H:77
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Can suppress additional line breaks separate ASCII data content when the data elements are primitives...
Definition ListPolicy.H:74
Number of items before requiring line-breaks in the list output.
Definition ListPolicy.H:56