DPC++ Runtime
Runtime libraries for oneAPI DPC++
aligned_allocator.hpp
Go to the documentation of this file.
1 //==------------ aligned_allocator.hpp - SYCL standard header file ---------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
11 #include <sycl/detail/os_util.hpp> // for OSUtil
12 
13 #include <limits> // for numeric_limits
14 #include <memory> // for pointer_traits, allocator_traits
15 #include <new> // for bad_alloc, operator new
16 #include <stddef.h> // for size_t
17 #include <type_traits> // for false_type, is_empty, make_unsign...
18 
19 namespace sycl {
20 inline namespace _V1 {
21 namespace detail {
22 template <typename T> class aligned_allocator {
23 public:
24  using value_type = T;
25  using pointer = T *;
26  using const_pointer = const T *;
27  using reference = T &;
28  using const_reference = const T &;
29 
30 public:
31  template <typename U> struct rebind {
33  };
34 
35  aligned_allocator() = default;
36  ~aligned_allocator() = default;
37 
38  explicit aligned_allocator(size_t Alignment) : MAlignment(Alignment) {}
39 
40  // Construct an object
42  new (Ptr) value_type(Val);
43  }
44 
45  // Destroy an object
46  void destroy(pointer Ptr) { Ptr->~value_type(); }
47 
48  pointer address(reference Val) const { return &Val; }
49  const_pointer address(const_reference Val) { return &Val; }
50 
51  // Allocate memory aligned to Alignment
52  pointer allocate(size_t Size) {
53  size_t NumBytes = Size * sizeof(value_type);
54  NumBytes = ((NumBytes - 1) | (MAlignment - 1)) + 1;
55  if (Size > NumBytes)
56  throw std::bad_alloc();
57 
58  pointer Result = reinterpret_cast<pointer>(
59  detail::OSUtil::alignedAlloc(MAlignment, NumBytes));
60  if (!Result)
61  throw std::bad_alloc();
62  return Result;
63  }
64 
65  // Release allocated memory
66  void deallocate(pointer Ptr, size_t) {
67  if (Ptr)
69  }
70 
71  bool operator==(const aligned_allocator &) { return true; }
72  bool operator!=(const aligned_allocator &) { return false; }
73 
74  void setAlignment(size_t Alignment) { MAlignment = Alignment; }
75 
76 private:
77  // By default assume the "worst" case
78  size_t MAlignment = 128;
79 };
80 } // namespace detail
81 } // namespace _V1
82 } // namespace sycl
83 
84 namespace std {
85 template <typename T>
86 struct allocator_traits<sycl::detail::aligned_allocator<T>> {
87  using allocator_type = typename sycl::detail::aligned_allocator<T>;
89  using pointer = typename allocator_type::pointer;
90  using const_pointer = typename allocator_type::const_pointer;
91  using void_pointer =
92  typename std::pointer_traits<pointer>::template rebind<void>;
94  typename std::pointer_traits<pointer>::template rebind<const void>;
97  using size_type = std::make_unsigned_t<difference_type>;
98  using propagate_on_container_copy_assignment = std::false_type;
99  using propagate_on_container_move_assignment = std::false_type;
100  using propagate_on_container_swap = std::false_type;
101  using is_always_equal = typename std::is_empty<allocator_type>::type;
102 
103  template <typename U>
104  using rebind_alloc =
105  typename sycl::detail::aligned_allocator<T>::template rebind<U>::other;
106  template <typename U> using rebind_traits = allocator_traits<rebind_alloc<U>>;
107 
108  static pointer allocate(allocator_type &Allocator, size_type NumElems) {
109  return Allocator.allocate(NumElems);
110  }
111 
112  static pointer allocate(allocator_type &Allocator, size_type NumElems,
114  // TODO: Utilize the locality hint argument.
115  return Allocator.allocate(NumElems);
116  }
117 
118  static void deallocate(allocator_type &Allocator, pointer Ptr,
119  size_type NumElems) {
120  Allocator.deallocate(Ptr, NumElems);
121  }
122 
123  template <class U, class... ArgsT>
124  static void construct(allocator_type &Allocator, U *Ptr, ArgsT &&...Args) {
125  return Allocator.construct(Ptr, Args...);
126  }
127 
128  template <class U> static void destroy(allocator_type &Allocator, U *Ptr) {
129  Allocator.destroy(Ptr);
130  }
131 
133  // max is a macro on Windows...
134  return (std::numeric_limits<size_type>::max)() / sizeof(value_type);
135  }
136 
137  static allocator_type
139  return Allocator;
140  }
141 };
142 } // namespace std
static void * alignedAlloc(size_t Alignment, size_t NumBytes)
Allocates NumBytes bytes of uninitialized storage whose alignment is specified by Alignment.
Definition: os_util.cpp:220
static void alignedFree(void *Ptr)
Deallocates the memory referenced by Ptr.
Definition: os_util.cpp:233
pointer address(reference Val) const
void construct(pointer Ptr, const_reference Val)
bool operator!=(const aligned_allocator &)
bool operator==(const aligned_allocator &)
void deallocate(pointer Ptr, size_t)
const_pointer address(const_reference Val)
std::ptrdiff_t difference_type
Definition: multi_ptr.hpp:460
std::conditional_t< is_decorated, decorated_type *, std::add_pointer_t< value_type > > pointer
Definition: multi_ptr.hpp:459
const void value_type
Definition: multi_ptr.hpp:457
Definition: access.hpp:18
_Abi const simd< _Tp, _Abi > & noexcept
Definition: simd.hpp:1324
typename std::is_empty< allocator_type >::type is_always_equal
static pointer allocate(allocator_type &Allocator, size_type NumElems, const_void_pointer)
static void construct(allocator_type &Allocator, U *Ptr, ArgsT &&...Args)
static allocator_type select_on_container_copy_construction(const allocator_type &Allocator)
typename std::pointer_traits< pointer >::template rebind< const void > const_void_pointer
static pointer allocate(allocator_type &Allocator, size_type NumElems)
typename sycl::detail::aligned_allocator< T >::template rebind< U >::other rebind_alloc
static void deallocate(allocator_type &Allocator, pointer Ptr, size_type NumElems)
typename std::pointer_traits< pointer >::difference_type difference_type
static void destroy(allocator_type &Allocator, U *Ptr)
typename sycl::detail::aligned_allocator< T > allocator_type
static size_type max_size(const allocator_type &) noexcept
typename std::pointer_traits< pointer >::template rebind< void > void_pointer