Distributed Ranges
Loading...
Searching...
No Matches
allocators.hpp
1// SPDX-FileCopyrightText: Intel Corporation
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#pragma once
6
7#include <type_traits>
8
9#include <sycl/sycl.hpp>
10
11#include <dr/sp/device_ptr.hpp>
12
13namespace dr::sp {
14
15template <typename T>
16using shared_allocator = sycl::usm_allocator<T, sycl::usm::alloc::shared>;
17
18template <typename T, std::size_t Alignment = 0>
19 requires(std::is_trivially_copyable_v<T>)
21public:
22 using value_type = T;
23 using pointer = device_ptr<T>;
27 using size_type = std::size_t;
28 using difference_type = std::ptrdiff_t;
29
30 template <typename U>
32 : device_(other.get_device()), context_(other.get_context()) {}
33
34 device_allocator(const sycl::queue &q) noexcept
35 : device_(q.get_device()), context_(q.get_context()) {}
36 device_allocator(const sycl::context &ctxt, const sycl::device &dev) noexcept
37 : device_(dev), context_(ctxt) {}
38
39 device_allocator(const device_allocator &) = default;
40 device_allocator &operator=(const device_allocator &) = default;
41 ~device_allocator() = default;
42
43 using is_always_equal = std::false_type;
44
45 pointer allocate(std::size_t size) {
46 if constexpr (Alignment == 0) {
47 return pointer(sycl::malloc_device<T>(size, device_, context_));
48 } else {
49 return pointer(
50 sycl::aligned_alloc_device<T>(Alignment, size, device_, context_));
51 }
52 }
53
54 void deallocate(pointer ptr, std::size_t n) {
55 sycl::free(ptr.get_raw_pointer(), context_);
56 }
57
58 bool operator==(const device_allocator &) const = default;
59 bool operator!=(const device_allocator &) const = default;
60
61 template <typename U> struct rebind {
63 };
64
65 sycl::device get_device() const noexcept { return device_; }
66
67 sycl::context get_context() const noexcept { return context_; }
68
69private:
70 sycl::device device_;
71 sycl::context context_;
72};
73
74template <typename Allocator> class buffered_allocator {
75public:
76 using value_type = typename std::allocator_traits<Allocator>::value_type;
77 using pointer = typename std::allocator_traits<Allocator>::pointer;
78 using const_pointer =
79 typename std::allocator_traits<Allocator>::const_pointer;
80 using size_type = typename std::allocator_traits<Allocator>::size_type;
81 using difference_type =
82 typename std::allocator_traits<Allocator>::difference_type;
83
84 buffered_allocator(const Allocator &alloc, std::size_t buffer_size,
85 std::size_t n_buffers)
86 : alloc_(alloc), buffer_size_(buffer_size),
87 free_buffers_(new std::vector<pointer>()),
88 buffers_(new std::vector<pointer>()) {
89 for (std::size_t i = 0; i < n_buffers; i++) {
90 buffers_->push_back(alloc_.allocate(buffer_size_));
91 }
92 free_buffers_->assign(buffers_->begin(), buffers_->end());
93 }
94
96 if (buffers_.use_count() == 1) {
97 for (auto &&buffer : *buffers_) {
98 alloc_.deallocate(buffer, buffer_size_);
99 }
100 }
101 }
102
103 using is_always_equal = std::false_type;
104
105 pointer allocate(std::size_t size) {
106 if (size > buffer_size_ || free_buffers_->empty()) {
107 throw std::bad_alloc();
108 } else {
109 pointer buffer = free_buffers_->back();
110 free_buffers_->pop_back();
111 return buffer;
112 }
113 }
114
115 void deallocate(pointer ptr, std::size_t n) { free_buffers_->push_back(ptr); }
116
117 bool operator==(const buffered_allocator &) const = default;
118 bool operator!=(const buffered_allocator &) const = default;
119
120private:
121 Allocator alloc_;
122 std::size_t buffer_size_;
123 std::shared_ptr<std::vector<pointer>> free_buffers_;
124 std::shared_ptr<std::vector<pointer>> buffers_;
125};
126
127} // namespace dr::sp
Definition: allocators.hpp:74
Definition: allocators.hpp:20
Definition: device_ptr.hpp:17
Definition: device_ref.hpp:15
Definition: allocators.hpp:61