sparrow 1.4.0
C++20 idiomatic APIs for the Apache Arrow Columnar Format
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
27namespace 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>
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 {
66 };
67
70
71 template <class U>
72 XSIMD_INLINE aligned_allocator(const aligned_allocator<U, Align>& rhs) noexcept;
73
75
78
79 XSIMD_INLINE pointer allocate(size_type n, const void* hint = 0);
81
84
85 template <class U, class... Args>
86 XSIMD_INLINE void construct(U* p, Args&&... args);
87
88 template <class U>
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>
115 {
116 }
117
121 template <class T, size_t A>
125
129 template <class T, size_t A>
130 template <class U>
134
138 template <class T, size_t A>
142
148 template <class T, size_t A>
149 XSIMD_INLINE auto
151 {
152 return &r;
153 }
154
160 template <class T, size_t A>
161 XSIMD_INLINE auto
163 {
164 return &r;
165 }
166
175 template <class T, size_t A>
176 XSIMD_INLINE auto
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>
199
205 template <class T, size_t A>
206 XSIMD_INLINE auto
208 {
209 return size_type(-1) / sizeof(T);
210 }
211
215 template <class T, size_t A>
216 XSIMD_INLINE auto
218 {
219 return size_type(-1) / sizeof(T);
220 }
221
228 template <class T, size_t A>
229 template <class U, class... 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>
242 {
243 p->~U();
244 }
245
249
258 template <class T1, size_t A1, class T2, size_t A2>
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>
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
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 {
315 }
316
318 {
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
Allocator for aligned memory.
XSIMD_INLINE ~aligned_allocator()
Destructor.
XSIMD_INLINE void construct(U *p, Args &&... args)
XSIMD_INLINE void deallocate(pointer p, size_type n)
XSIMD_INLINE size_type max_size() const noexcept
XSIMD_INLINE pointer allocate(size_type n, const void *hint=0)
XSIMD_INLINE void destroy(U *p)
XSIMD_INLINE aligned_allocator() noexcept
Default constructor.
XSIMD_INLINE size_type size_max() const noexcept
XSIMD_INLINE pointer address(reference) noexcept
XSIMD_INLINE void xaligned_free(void *ptr)
XSIMD_INLINE void * xaligned_malloc(size_t size, size_t alignment)
XSIMD_INLINE bool operator==(const aligned_allocator< T1, Align1 > &lhs, const aligned_allocator< T2, Align2 > &rhs) noexcept
XSIMD_INLINE bool operator!=(const aligned_allocator< T1, Align1 > &lhs, const aligned_allocator< T2, Align2 > &rhs) noexcept
XSIMD_INLINE void aligned_free(void *ptr)
XSIMD_INLINE size_t get_alignment_offset(const T *p, size_t size, size_t block_size)
XSIMD_INLINE void * aligned_malloc(size_t size, size_t alignment)
aligned_allocator< U, Align > other
#define XSIMD_INLINE