DPC++ Runtime
Runtime libraries for oneAPI DPC++
usm_allocator.hpp
Go to the documentation of this file.
1 //==------ usm_allocator.hpp - SYCL USM Allocator ------*- C++ -*-----------==//
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 #pragma once
9 
10 #include <sycl/builtins.hpp> // for max
11 #include <sycl/context.hpp> // for context
12 #include <sycl/detail/common.hpp> // for code_location
13 #include <sycl/device.hpp> // for device
14 #include <sycl/exception.hpp> // for memory_allocation_error
15 #include <sycl/property_list.hpp> // for property_list
16 #include <sycl/queue.hpp> // for queue
17 #include <sycl/usm/usm_enums.hpp> // for alloc
18 
19 #include <cstdlib> // for size_t, aligned_alloc, free
20 #include <type_traits> // for true_type
21 
22 namespace sycl {
23 inline namespace _V1 {
24 template <typename T, usm::alloc AllocKind, size_t Alignment = 0>
26 public:
27  using value_type = T;
30  using propagate_on_container_swap = std::true_type;
31 
32 public:
33  template <typename U> struct rebind {
35  };
36 
37  static_assert(
38  AllocKind != usm::alloc::device,
39  "usm_allocator does not support AllocKind == usm::alloc::device");
40 
41  usm_allocator() = delete;
42  usm_allocator(const context &Ctxt, const device &Dev,
43  const property_list &PropList = {})
44  : MContext(Ctxt), MDevice(Dev), MPropList(PropList) {}
45  usm_allocator(const queue &Q, const property_list &PropList = {})
46  : MContext(Q.get_context()), MDevice(Q.get_device()),
47  MPropList(PropList) {}
48  usm_allocator(const usm_allocator &) = default;
50  usm_allocator &operator=(const usm_allocator &Other) {
51  MContext = Other.MContext;
52  MDevice = Other.MDevice;
53  MPropList = Other.MPropList;
54  return *this;
55  }
57  MContext = std::move(Other.MContext);
58  MDevice = std::move(Other.MDevice);
59  MPropList = std::move(Other.MPropList);
60  return *this;
61  }
62 
63  template <class U>
65  : MContext(Other.MContext), MDevice(Other.MDevice),
66  MPropList(Other.MPropList) {}
67 
71  T *allocate(size_t NumberOfElements, const detail::code_location CodeLoc =
73 
74  if (!NumberOfElements)
75  return nullptr;
76 
77  auto Result = reinterpret_cast<T *>(
78  aligned_alloc(getAlignment(), NumberOfElements * sizeof(value_type),
79  MDevice, MContext, AllocKind, MPropList, CodeLoc));
80  if (!Result) {
81  throw memory_allocation_error();
82  }
83  return Result;
84  }
85 
90  void deallocate(
91  T *Ptr, size_t,
93  if (Ptr) {
94  free(Ptr, MContext, CodeLoc);
95  }
96  }
97 
98  template <class U, usm::alloc AllocKindU, size_t AlignmentU>
101  return ((AllocKind == AllocKindU) && (One.MContext == Two.MContext) &&
102  (One.MDevice == Two.MDevice));
103  }
104 
105  template <class U, usm::alloc AllocKindU, size_t AlignmentU>
108  return !((AllocKind == AllocKindU) && (One.MContext == Two.MContext) &&
109  (One.MDevice == Two.MDevice));
110  }
111 
112  template <typename Property> bool has_property() const noexcept {
113  return MPropList.has_property<Property>();
114  }
115 
116  template <typename Property> Property get_property() const {
117  return MPropList.get_property<Property>();
118  }
119 
120 private:
121  constexpr size_t getAlignment() const { return max(alignof(T), Alignment); }
122 
123  template <class U, usm::alloc AllocKindU, size_t AlignmentU>
124  friend class usm_allocator;
125 
126  context MContext;
127  device MDevice;
128  property_list MPropList;
129 };
130 
131 } // namespace _V1
132 } // namespace sycl
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:50
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:64
Objects of the property_list class are containers for the SYCL properties.
bool has_property() const noexcept
Encapsulates a single SYCL queue which schedules kernels on a SYCL device.
Definition: queue.hpp:105
device get_device() const
Definition: queue.cpp:76
context get_context() const
Definition: queue.cpp:74
std::true_type propagate_on_container_swap
friend bool operator==(const usm_allocator< T, AllocKind, Alignment > &One, const usm_allocator< U, AllocKindU, AlignmentU > &Two)
usm_allocator(const usm_allocator &)=default
usm_allocator(usm_allocator &&) noexcept=default
usm_allocator & operator=(usm_allocator &&Other)
bool has_property() const noexcept
friend bool operator!=(const usm_allocator< T, AllocKind, Alignment > &One, const usm_allocator< U, AllocKindU, AlignmentU > &Two)
std::true_type propagate_on_container_copy_assignment
T * allocate(size_t NumberOfElements, const detail::code_location CodeLoc=detail::code_location::current())
Allocates memory.
Property get_property() const
usm_allocator(const queue &Q, const property_list &PropList={})
usm_allocator(const usm_allocator< U, AllocKind, Alignment > &Other) noexcept
std::true_type propagate_on_container_move_assignment
void deallocate(T *Ptr, size_t, const detail::code_location CodeLoc=detail::code_location::current())
Deallocates memory.
usm_allocator(const context &Ctxt, const device &Dev, const property_list &PropList={})
void * aligned_alloc(size_t alignment, size_t size, const device &dev, const context &ctxt, usm::alloc kind, const detail::code_location &CodeLoc=detail::code_location::current())
void free(void *ptr, const context &ctxt, const detail::code_location &CodeLoc=detail::code_location::current())
Definition: usm_impl.cpp:374
Definition: access.hpp:18
_Abi const simd< _Tp, _Abi > & noexcept
Definition: simd.hpp:1324
static constexpr code_location current(const char *fileName=__CODELOC_FILE_NAME, const char *funcName=__CODELOC_FUNCTION, unsigned long lineNo=__CODELOC_LINE, unsigned long columnNo=__CODELOC_COLUMN) noexcept
Definition: common.hpp:68
usm_allocator< U, AllocKind, Alignment > other