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/common.hpp>
12 #include <sycl/detail/os_util.hpp>
13 
14 #include <cstdlib>
15 #include <cstring>
16 #include <memory>
17 #include <type_traits>
18 #include <vector>
19 
20 namespace sycl {
22 namespace detail {
23 template <typename T> class aligned_allocator {
24 public:
25  using value_type = T;
26  using pointer = T *;
27  using const_pointer = const T *;
28  using reference = T &;
29  using const_reference = const T &;
30 
31 public:
32  template <typename U> struct rebind {
34  };
35 
36  aligned_allocator() = default;
37  ~aligned_allocator() = default;
38 
39  explicit aligned_allocator(size_t Alignment) : MAlignment(Alignment) {}
40 
41  // Construct an object
43  new (Ptr) value_type(Val);
44  }
45 
46  // Destroy an object
47  void destroy(pointer Ptr) { Ptr->~value_type(); }
48 
49  pointer address(reference Val) const { return &Val; }
50  const_pointer address(const_reference Val) { return &Val; }
51 
52  // Allocate memory aligned to Alignment
53  pointer allocate(size_t Size) {
54  size_t NumBytes = Size * sizeof(value_type);
55  NumBytes = ((NumBytes - 1) | (MAlignment - 1)) + 1;
56  if (Size > NumBytes)
57  throw std::bad_alloc();
58 
59  pointer Result = reinterpret_cast<pointer>(
60  detail::OSUtil::alignedAlloc(MAlignment, NumBytes));
61  if (!Result)
62  throw std::bad_alloc();
63  return Result;
64  }
65 
66  // Release allocated memory
67  void deallocate(pointer Ptr, size_t) {
68  if (Ptr)
69  detail::OSUtil::alignedFree(Ptr);
70  }
71 
72  bool operator==(const aligned_allocator &) { return true; }
73  bool operator!=(const aligned_allocator &) { return false; }
74 
75  void setAlignment(size_t Alignment) { MAlignment = Alignment; }
76 
77 private:
78  // By default assume the "worst" case
79  size_t MAlignment = 128;
80 };
81 } // namespace detail
82 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
83 } // namespace sycl
84 
85 namespace std {
86 template <typename T>
87 struct allocator_traits<sycl::detail::aligned_allocator<T>> {
88  using allocator_type = typename sycl::detail::aligned_allocator<T>;
89  using value_type = typename allocator_type::value_type;
90  using pointer = typename allocator_type::pointer;
91  using const_pointer = typename allocator_type::const_pointer;
92  using void_pointer =
93  typename std::pointer_traits<pointer>::template rebind<void>;
95  typename std::pointer_traits<pointer>::template rebind<const void>;
97  typename std::pointer_traits<pointer>::difference_type;
98  using size_type = typename std::make_unsigned<difference_type>::type;
99  using propagate_on_container_copy_assignment = std::false_type;
100  using propagate_on_container_move_assignment = std::false_type;
101  using propagate_on_container_swap = std::false_type;
102  using is_always_equal = typename std::is_empty<allocator_type>::type;
103 
104  template <typename U>
105  using rebind_alloc =
106  typename sycl::detail::aligned_allocator<T>::template rebind<U>::other;
107  template <typename U> using rebind_traits = allocator_traits<rebind_alloc<U>>;
108 
109  static pointer allocate(allocator_type &Allocator, size_type NumElems) {
110  return Allocator.allocate(NumElems);
111  }
112 
113  static pointer allocate(allocator_type &Allocator, size_type NumElems,
115  // TODO: Utilize the locality hint argument.
116  return Allocator.allocate(NumElems);
117  }
118 
119  static void deallocate(allocator_type &Allocator, pointer Ptr,
120  size_type NumElems) {
121  Allocator.deallocate(Ptr, NumElems);
122  }
123 
124  template <class U, class... ArgsT>
125  static void construct(allocator_type &Allocator, U *Ptr, ArgsT &&...Args) {
126  return Allocator.construct(Ptr, Args...);
127  }
128 
129  template <class U> static void destroy(allocator_type &Allocator, U *Ptr) {
130  Allocator.destroy(Ptr);
131  }
132 
133  static size_type max_size(const allocator_type &) noexcept {
134  // max is a macro on Windows...
135  return (std::numeric_limits<size_type>::max)() / sizeof(value_type);
136  }
137 
138  static allocator_type
140  return Allocator;
141  }
142 };
143 } // namespace std
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)
#define __SYCL_INLINE_VER_NAMESPACE(X)
void * alignedAlloc(size_t Alignment, size_t Bytes, const context &Ctxt, const device &Dev, sycl::usm::alloc Kind, const code_location &CL)
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
simd< _Tp, _Abi > max(const simd< _Tp, _Abi > &, const simd< _Tp, _Abi > &) noexcept
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::make_unsigned< difference_type >::type size_type
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