@@ -26,112 +26,45 @@ __SYCL_EXPORT void *aligned_alloc(size_t alignment, size_t size,
2626 usm::alloc kind);
2727__SYCL_EXPORT void free (void *ptr, const context &ctxt);
2828
29- template <typename T, usm::alloc AllocKind, size_t Alignment = 0 >
29+ template <typename T, usm::alloc AllocKind, size_t Alignment = alignof (T) >
3030class usm_allocator {
3131public:
3232 using value_type = T;
33- using pointer = T *;
34- using const_pointer = const T *;
35- using reference = T &;
36- using const_reference = const T &;
33+ using propagate_on_container_copy_assignment = std::true_type;
34+ using propagate_on_container_move_assignment = std::true_type;
35+ using propagate_on_container_swap = std::true_type;
3736
3837public:
3938 template <typename U> struct rebind {
4039 typedef usm_allocator<U, AllocKind, Alignment> other;
4140 };
4241
43- usm_allocator () = delete ;
44- usm_allocator (const context &Ctxt, const device &Dev)
42+ static_assert (
43+ AllocKind != usm::alloc::device,
44+ " usm_allocator does not support AllocKind == usm::alloc::device" );
45+
46+ usm_allocator () noexcept = delete ;
47+ usm_allocator (const context &Ctxt, const device &Dev) noexcept
4548 : MContext(Ctxt), MDevice(Dev) {}
46- usm_allocator (const queue &Q)
49+ usm_allocator (const queue &Q) noexcept
4750 : MContext(Q.get_context()), MDevice(Q.get_device()) {}
48- usm_allocator (const usm_allocator &Other)
49- : MContext(Other.MContext), MDevice(Other.MDevice) {}
50-
51- // / Constructs an object on memory pointed by Ptr.
52- // /
53- // / Note: AllocKind == alloc::device is not allowed.
54- // /
55- // / \param Ptr is a pointer to memory that will be used to construct the
56- // / object.
57- // / \param Val is a value to initialize the newly constructed object.
58- template <
59- usm::alloc AllocT = AllocKind,
60- typename std::enable_if<AllocT != usm::alloc::device, int >::type = 0 >
61- void construct (pointer Ptr, const_reference Val) {
62- new (Ptr) value_type (Val);
63- }
64-
65- template <
66- usm::alloc AllocT = AllocKind,
67- typename std::enable_if<AllocT == usm::alloc::device, int >::type = 0 >
68- void construct (pointer, const_reference) {
69- throw feature_not_supported (
70- " Device pointers do not support construct on host" ,
71- PI_INVALID_OPERATION);
72- }
51+ usm_allocator (const usm_allocator &) noexcept = default ;
52+ usm_allocator (usm_allocator &&) noexcept = default ;
53+ usm_allocator &operator =(const usm_allocator &) = delete ;
54+ usm_allocator &operator =(usm_allocator &&) = default ;
7355
74- // / Destroys an object.
75- // /
76- // / Note:: AllocKind == alloc::device is not allowed
77- // /
78- // / \param Ptr is a pointer to memory where the object resides.
79- template <
80- usm::alloc AllocT = AllocKind,
81- typename std::enable_if<AllocT != usm::alloc::device, int >::type = 0 >
82- void destroy (pointer Ptr) {
83- Ptr->~value_type ();
84- }
85-
86- template <
87- usm::alloc AllocT = AllocKind,
88- typename std::enable_if<AllocT == usm::alloc::device, int >::type = 0 >
89- void destroy (pointer) {
90- // This method must be a NOP for device pointers.
91- }
92-
93- // / Note:: AllocKind == alloc::device is not allowed.
94- // /
95- // / \param Val is a reference to object.
96- // / \return an address of the object referenced by Val.
97- template <
98- usm::alloc AllocT = AllocKind,
99- typename std::enable_if<AllocT != usm::alloc::device, int >::type = 0 >
100- pointer address (reference Val) const {
101- return &Val;
102- }
103-
104- template <
105- usm::alloc AllocT = AllocKind,
106- typename std::enable_if<AllocT == usm::alloc::device, int >::type = 0 >
107- pointer address (reference) const {
108- throw feature_not_supported (
109- " Device pointers do not support address on host" , PI_INVALID_OPERATION);
110- }
111-
112- template <
113- usm::alloc AllocT = AllocKind,
114- typename std::enable_if<AllocT != usm::alloc::device, int >::type = 0 >
115- const_pointer address (const_reference Val) const {
116- return &Val;
117- }
118-
119- template <
120- usm::alloc AllocT = AllocKind,
121- typename std::enable_if<AllocT == usm::alloc::device, int >::type = 0 >
122- const_pointer address (const_reference) const {
123- throw feature_not_supported (
124- " Device pointers do not support address on host" , PI_INVALID_OPERATION);
125- }
56+ template <class U >
57+ usm_allocator (const usm_allocator<U, AllocKind, Alignment> &Other) noexcept
58+ : MContext(Other.MContext), MDevice(Other.MDevice) {}
12659
12760 // / Allocates memory.
12861 // /
12962 // / \param NumberOfElements is a count of elements to allocate memory for.
130- pointer allocate (size_t NumberOfElements) {
63+ T * allocate (size_t NumberOfElements) {
13164
132- auto Result = reinterpret_cast <pointer >(
65+ auto Result = reinterpret_cast <T * >(
13366 aligned_alloc (getAlignment (), NumberOfElements * sizeof (value_type),
134- MDevice, MContext, AllocKind));
67+ MDevice, MContext, AllocKind));
13568 if (!Result) {
13669 throw memory_allocation_error ();
13770 }
@@ -142,24 +75,32 @@ class usm_allocator {
14275 // /
14376 // / \param Ptr is a pointer to memory being deallocated.
14477 // / \param Size is a number of elements previously passed to allocate.
145- void deallocate (pointer Ptr, size_t ) {
78+ void deallocate (T * Ptr, size_t ) {
14679 if (Ptr) {
14780 free (Ptr, MContext);
14881 }
14982 }
15083
151- private:
152- constexpr size_t getAlignment () const {
153- /*
154- // This form might be preferable if the underlying implementation
155- // doesn't do the right thing when given 0 for alignment
156- return ((Alignment == 0)
157- ? alignof(value_type)
158- : Alignment);
159- */
160- return Alignment;
84+ template <class U , usm::alloc AllocKindU, size_t AlignmentU>
85+ friend bool operator ==(const usm_allocator<T, AllocKind, Alignment> &One,
86+ const usm_allocator<U, AllocKindU, AlignmentU> &Two) {
87+ return ((AllocKind == AllocKindU) && (One.MContext == Two.MContext ) &&
88+ (One.MDevice == Two.MDevice ));
89+ }
90+
91+ template <class U , usm::alloc AllocKindU, size_t AlignmentU>
92+ friend bool operator !=(const usm_allocator<T, AllocKind, Alignment> &One,
93+ const usm_allocator<U, AllocKindU, AlignmentU> &Two) {
94+ return !((AllocKind == AllocKindU) && (One.MContext == Two.MContext ) &&
95+ (One.MDevice == Two.MDevice ));
16196 }
16297
98+ private:
99+ constexpr size_t getAlignment () const { return Alignment; }
100+
101+ template <class U , usm::alloc AllocKindU, size_t AlignmentU>
102+ friend class usm_allocator ;
103+
163104 const context MContext;
164105 const device MDevice;
165106};
0 commit comments