sparrow
2.4.0
C++20 idiomatic APIs for the Apache Arrow Columnar Format
Toggle main menu visibility
Loading...
Searching...
No Matches
xsimd_aligned_allocator.hpp
Go to the documentation of this file.
1
/***************************************************************************
2
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
3
* Martin Renou *
4
* Copyright (c) QuantStack *
5
* Copyright (c) Serge Guelton *
6
* *
7
* Distributed under the terms of the BSD 3-Clause License. *
8
* *
9
* The full license is in the file LICENSE, distributed with this software. *
10
****************************************************************************/
11
12
#ifndef XSIMD_ALIGNED_ALLOCATOR_HPP
13
#define XSIMD_ALIGNED_ALLOCATOR_HPP
14
15
#include <algorithm>
16
#include <cstddef>
17
#include <utility>
18
#ifdef _WIN32
19
#include <malloc.h>
20
#else
21
#include <cstdlib>
22
#endif
23
24
#include <cassert>
25
#include <memory>
26
27
namespace
xsimd
28
{
29
30
#if defined(__GNUC__)
31
#define XSIMD_INLINE inline __attribute__((always_inline))
32
#elif defined(_MSC_VER)
33
#define XSIMD_INLINE inline __forceinline
34
#else
35
#define XSIMD_INLINE inline
36
#endif
37
48
template
<
class
T,
size_t
Align = 64>
49
class
aligned_allocator
50
{
51
public
:
52
using
value_type
= T;
53
using
pointer
= T*;
54
using
const_pointer
=
const
T*;
55
using
reference
= T&;
56
using
const_reference
=
const
T&;
57
using
size_type
= size_t;
58
using
difference_type
=
ptrdiff_t
;
59
60
static
constexpr
size_t
alignment
= Align;
61
62
template
<
class
U>
63
struct
rebind
64
{
65
using
other
=
aligned_allocator<U, Align>
;
66
};
67
68
XSIMD_INLINE
aligned_allocator
() noexcept;
69
XSIMD_INLINE
aligned_allocator
(const
aligned_allocator
& rhs) noexcept;
70
71
template <class U>
72
XSIMD_INLINE
aligned_allocator
(const
aligned_allocator
<U, Align>& rhs) noexcept;
73
74
XSIMD_INLINE
~
aligned_allocator
();
75
76
XSIMD_INLINE
pointer
address
(
reference
) noexcept;
77
XSIMD_INLINE
const_pointer
address
(
const_reference
) const noexcept;
78
79
XSIMD_INLINE
pointer
allocate
(
size_type
n, const
void
* hint = 0);
80
XSIMD_INLINE
void
deallocate
(
pointer
p,
size_type
n);
81
82
XSIMD_INLINE
size_type
max_size
() const noexcept;
83
XSIMD_INLINE
size_type
size_max
() const noexcept;
84
85
template <class U, class... Args>
86
XSIMD_INLINE
void
construct
(U* p, Args&&... args);
87
88
template <class U>
89
XSIMD_INLINE
void
destroy
(U* p);
90
};
91
92
template <class T1,
size_t
Align1, class T2,
size_t
Align2>
93
XSIMD_INLINE
bool
operator==(const
aligned_allocator
<T1, Align1>& lhs,
94
const
aligned_allocator
<T2, Align2>& rhs) noexcept;
95
96
template <class T1,
size_t
Align1, class T2,
size_t
Align2>
97
XSIMD_INLINE
bool
operator!=(const
aligned_allocator
<T1, Align1>& lhs,
98
const
aligned_allocator
<T2, Align2>& rhs) noexcept;
99
100
XSIMD_INLINE
void
*
aligned_malloc
(
size_t
size,
size_t
alignment
);
101
XSIMD_INLINE
void
aligned_free
(
void
* ptr);
102
103
template <class T>
104
XSIMD_INLINE
size_t
get_alignment_offset
(const T* p,
size_t
size,
size_t
block_size);
105
106
/************************************
107
* aligned_allocator implementation *
108
************************************/
109
113
template <class T,
size_t
A>
114
XSIMD_INLINE
aligned_allocator
<T, A>::
aligned_allocator
() noexcept
115
{
116
}
117
121
template
<
class
T,
size_t
A>
122
XSIMD_INLINE
aligned_allocator<T, A>::aligned_allocator
(
const
aligned_allocator
&)
noexcept
123
{
124
}
125
129
template
<
class
T,
size_t
A>
130
template
<
class
U>
131
XSIMD_INLINE
aligned_allocator<T, A>::aligned_allocator
(
const
aligned_allocator<U, A>
&)
noexcept
132
{
133
}
134
138
template
<
class
T,
size_t
A>
139
XSIMD_INLINE
aligned_allocator<T, A>::~aligned_allocator
()
140
{
141
}
142
148
template
<
class
T,
size_t
A>
149
XSIMD_INLINE
auto
150
aligned_allocator<T, A>::address
(
reference
r)
noexcept
->
pointer
151
{
152
return
&r;
153
}
154
160
template
<
class
T,
size_t
A>
161
XSIMD_INLINE
auto
162
aligned_allocator<T, A>::address
(
const_reference
r)
const
noexcept
->
const_pointer
163
{
164
return
&r;
165
}
166
175
template
<
class
T,
size_t
A>
176
XSIMD_INLINE
auto
177
aligned_allocator<T, A>::allocate
(
size_type
n,
const
void
*) ->
pointer
178
{
179
pointer
res =
reinterpret_cast<
pointer
>
(
aligned_malloc
(
sizeof
(T) * n, A));
180
#if defined(_CPPUNWIND) || defined(__cpp_exceptions)
181
if
(res ==
nullptr
)
182
throw
std::bad_alloc();
183
#endif
184
return
res;
185
}
186
194
template
<
class
T,
size_t
A>
195
XSIMD_INLINE
void
aligned_allocator<T, A>::deallocate
(
pointer
p,
size_type
)
196
{
197
aligned_free
(p);
198
}
199
205
template
<
class
T,
size_t
A>
206
XSIMD_INLINE
auto
207
aligned_allocator<T, A>::max_size
() const noexcept ->
size_type
208
{
209
return
size_type
(-1) /
sizeof
(T);
210
}
211
215
template
<
class
T,
size_t
A>
216
XSIMD_INLINE
auto
217
aligned_allocator<T, A>::size_max
() const noexcept ->
size_type
218
{
219
return
size_type
(-1) /
sizeof
(T);
220
}
221
228
template
<
class
T,
size_t
A>
229
template
<
class
U,
class
... Args>
230
XSIMD_INLINE
void
aligned_allocator<T, A>::construct
(U* p, Args&&... args)
231
{
232
new
(
static_cast<
void
*
>
(p)) U(std::forward<Args>(args)...);
233
}
234
239
template
<
class
T,
size_t
A>
240
template
<
class
U>
241
XSIMD_INLINE
void
aligned_allocator<T, A>::destroy
(U* p)
242
{
243
p->~U();
244
}
245
249
258
template
<
class
T1,
size_t
A1,
class
T2,
size_t
A2>
259
XSIMD_INLINE
bool
operator==
(
const
aligned_allocator<T1, A1>
& lhs,
260
const
aligned_allocator<T2, A2>
& rhs)
noexcept
261
{
262
return
lhs.alignment == rhs.alignment;
263
}
264
273
template
<
class
T1,
size_t
A1,
class
T2,
size_t
A2>
274
XSIMD_INLINE
bool
operator!=
(
const
aligned_allocator<T1, A1>
& lhs,
275
const
aligned_allocator<T2, A2>
& rhs)
noexcept
276
{
277
return
!(lhs == rhs);
278
}
279
280
/****************************************
281
* aligned malloc / free implementation *
282
****************************************/
283
284
namespace
detail
285
{
286
XSIMD_INLINE
void
*
xaligned_malloc
(
size_t
size,
size_t
alignment)
287
{
288
assert(((alignment & (alignment - 1)) == 0) &&
"alignment must be a power of two"
);
289
assert((alignment >=
sizeof
(
void
*)) &&
"alignment must be at least the size of a pointer"
);
290
void
* res =
nullptr
;
291
#ifdef _WIN32
292
res = _aligned_malloc(size, alignment);
293
#else
294
if
(posix_memalign(&res, alignment, size) != 0)
295
{
296
res =
nullptr
;
297
}
298
#endif
299
return
res;
300
}
301
302
XSIMD_INLINE
void
xaligned_free
(
void
* ptr)
303
{
304
#ifdef _WIN32
305
_aligned_free(ptr);
306
#else
307
free(ptr);
308
#endif
309
}
310
}
311
312
XSIMD_INLINE
void
*
aligned_malloc
(
size_t
size,
size_t
alignment
)
313
{
314
return
detail::xaligned_malloc
(size,
alignment
);
315
}
316
317
XSIMD_INLINE
void
aligned_free
(
void
* ptr)
318
{
319
detail::xaligned_free
(ptr);
320
}
321
322
template
<
class
T>
323
XSIMD_INLINE
size_t
get_alignment_offset
(
const
T* p,
size_t
size,
size_t
block_size)
324
{
325
// size_t block_size = simd_traits<T>::size;
326
if
(block_size == 1)
327
{
328
// The simd_block consists of exactly one scalar so that all
329
// elements of the array
330
// are "well" aligned.
331
return
0;
332
}
333
else
if
(
size_t
(p) & (
sizeof
(T) - 1))
334
{
335
// The array is not aligned to the size of a single element, so that
336
// no element
337
// of the array is well aligned
338
return
size;
339
}
340
else
341
{
342
size_t
block_mask = block_size - 1;
343
return
std::min<size_t>(
344
(block_size - ((
size_t
(p) /
sizeof
(T)) & block_mask)) & block_mask,
345
size);
346
}
347
}
348
}
349
350
#endif
ptrdiff_t
xsimd::aligned_allocator
Allocator for aligned memory.
Definition
xsimd_aligned_allocator.hpp:50
xsimd::aligned_allocator::pointer
T * pointer
Definition
xsimd_aligned_allocator.hpp:53
xsimd::aligned_allocator::~aligned_allocator
XSIMD_INLINE ~aligned_allocator()
Destructor.
Definition
xsimd_aligned_allocator.hpp:139
xsimd::aligned_allocator< U, Align >::construct
XSIMD_INLINE void construct(U *p, Args &&... args)
xsimd::aligned_allocator::size_type
size_t size_type
Definition
xsimd_aligned_allocator.hpp:57
xsimd::aligned_allocator< U, Align >::deallocate
XSIMD_INLINE void deallocate(pointer p, size_type n)
xsimd::aligned_allocator< U, Align >::max_size
XSIMD_INLINE size_type max_size() const noexcept
xsimd::aligned_allocator::difference_type
ptrdiff_t difference_type
Definition
xsimd_aligned_allocator.hpp:58
xsimd::aligned_allocator< U, Align >::alignment
static constexpr size_t alignment
Definition
xsimd_aligned_allocator.hpp:60
xsimd::aligned_allocator< U, Align >::allocate
XSIMD_INLINE pointer allocate(size_type n, const void *hint=0)
xsimd::aligned_allocator::const_reference
const T & const_reference
Definition
xsimd_aligned_allocator.hpp:56
xsimd::aligned_allocator< U, Align >::destroy
XSIMD_INLINE void destroy(U *p)
xsimd::aligned_allocator::reference
T & reference
Definition
xsimd_aligned_allocator.hpp:55
xsimd::aligned_allocator::aligned_allocator
XSIMD_INLINE aligned_allocator() noexcept
Default constructor.
Definition
xsimd_aligned_allocator.hpp:114
xsimd::aligned_allocator< U, Align >::size_max
XSIMD_INLINE size_type size_max() const noexcept
xsimd::aligned_allocator< U, Align >::address
XSIMD_INLINE pointer address(reference) noexcept
xsimd::aligned_allocator::const_pointer
const T * const_pointer
Definition
xsimd_aligned_allocator.hpp:54
xsimd::aligned_allocator::value_type
T value_type
Definition
xsimd_aligned_allocator.hpp:52
xsimd::detail
Definition
xsimd_aligned_allocator.hpp:285
xsimd::detail::xaligned_free
XSIMD_INLINE void xaligned_free(void *ptr)
Definition
xsimd_aligned_allocator.hpp:302
xsimd::detail::xaligned_malloc
XSIMD_INLINE void * xaligned_malloc(size_t size, size_t alignment)
Definition
xsimd_aligned_allocator.hpp:286
xsimd
Definition
xsimd_aligned_allocator.hpp:28
xsimd::operator==
XSIMD_INLINE bool operator==(const aligned_allocator< T1, Align1 > &lhs, const aligned_allocator< T2, Align2 > &rhs) noexcept
xsimd::operator!=
XSIMD_INLINE bool operator!=(const aligned_allocator< T1, Align1 > &lhs, const aligned_allocator< T2, Align2 > &rhs) noexcept
xsimd::aligned_free
XSIMD_INLINE void aligned_free(void *ptr)
Definition
xsimd_aligned_allocator.hpp:317
xsimd::get_alignment_offset
XSIMD_INLINE size_t get_alignment_offset(const T *p, size_t size, size_t block_size)
Definition
xsimd_aligned_allocator.hpp:323
xsimd::aligned_malloc
XSIMD_INLINE void * aligned_malloc(size_t size, size_t alignment)
Definition
xsimd_aligned_allocator.hpp:312
xsimd::aligned_allocator::rebind
Definition
xsimd_aligned_allocator.hpp:64
xsimd::aligned_allocator::rebind::other
aligned_allocator< U, Align > other
Definition
xsimd_aligned_allocator.hpp:65
XSIMD_INLINE
#define XSIMD_INLINE
Definition
xsimd_aligned_allocator.hpp:35
sparrow
details
3rdparty
xsimd_aligned_allocator.hpp
Generated by
1.17.0