1 /**
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef RUNTIME_MEM_ALLOCATOR_ADAPTER_H
16 #define RUNTIME_MEM_ALLOCATOR_ADAPTER_H
17
18 #include "runtime/include/mem/allocator.h"
19
20 namespace ark::mem {
21
22 template <typename T, AllocScope ALLOC_SCOPE_T>
23 class AllocatorAdapter;
24
25 template <AllocScope ALLOC_SCOPE_T>
26 class AllocatorAdapter<void, ALLOC_SCOPE_T> {
27 public:
28 // Naming is not by code style because we need to have allocator traits compatibility. Don't change it.
29 using value_type = void; // NOLINT(readability-identifier-naming)
30 using pointer = void *; // NOLINT(readability-identifier-naming)
31 using const_pointer = const void *; // NOLINT(readability-identifier-naming)
32
33 using propagate_on_container_move_assignment = std::true_type; // NOLINT(readability-identifier-naming)
34
35 template <typename U>
36 struct Rebind {
37 // NOLINTNEXTLINE(readability-identifier-naming)
38 using other = AllocatorAdapter<U, ALLOC_SCOPE_T>;
39 };
40
41 template <typename U>
42 using rebind = Rebind<U>; // NOLINT(readability-identifier-naming)
43
44 explicit AllocatorAdapter(Allocator *allocator = InternalAllocator<>::GetInternalAllocatorFromRuntime())
allocator_(allocator)45 : allocator_(allocator)
46 {
47 ASSERT(allocator_ != nullptr);
48 }
49 template <typename U>
50 // NOLINTNEXTLINE(google-explicit-constructor)
AllocatorAdapter(const AllocatorAdapter<U,ALLOC_SCOPE_T> & other)51 AllocatorAdapter(const AllocatorAdapter<U, ALLOC_SCOPE_T> &other) : allocator_(other.allocator_)
52 {
53 }
54 AllocatorAdapter(const AllocatorAdapter &) noexcept = default;
55 AllocatorAdapter &operator=(const AllocatorAdapter &) noexcept = default;
56
57 AllocatorAdapter(AllocatorAdapter &&other) noexcept = default;
58 AllocatorAdapter &operator=(AllocatorAdapter &&other) noexcept = default;
59
60 ~AllocatorAdapter() = default;
61
62 private:
63 Allocator *allocator_;
64
65 template <typename U, AllocScope TYPE_T>
66 friend class AllocatorAdapter;
67 };
68
69 template <typename T, AllocScope ALLOC_SCOPE_T = AllocScope::GLOBAL>
70 class AllocatorAdapter {
71 public:
72 // Naming is not by code style because we need to have allocator traits compatibility. Don't change it.
73 using value_type = T; // NOLINT(readability-identifier-naming)
74 using pointer = T *; // NOLINT(readability-identifier-naming)
75 using reference = T &; // NOLINT(readability-identifier-naming)
76 using const_pointer = const T *; // NOLINT(readability-identifier-naming)
77 using const_reference = const T &; // NOLINT(readability-identifier-naming)
78 using size_type = size_t; // NOLINT(readability-identifier-naming)
79 using difference_type = ptrdiff_t; // NOLINT(readability-identifier-naming)
80
81 using propagate_on_container_move_assignment = std::true_type; // NOLINT(readability-identifier-naming)
82
83 template <typename U>
84 struct Rebind {
85 // NOLINTNEXTLINE(readability-identifier-naming)
86 using other = AllocatorAdapter<U, ALLOC_SCOPE_T>;
87 };
88
89 template <typename U>
90 using rebind = Rebind<U>; // NOLINT(readability-identifier-naming)
91
92 explicit AllocatorAdapter(Allocator *allocator = InternalAllocator<>::GetInternalAllocatorFromRuntime())
allocator_(allocator)93 : allocator_(allocator)
94 {
95 }
96 template <typename U>
97 // NOLINTNEXTLINE(google-explicit-constructor)
AllocatorAdapter(const AllocatorAdapter<U,ALLOC_SCOPE_T> & other)98 AllocatorAdapter(const AllocatorAdapter<U, ALLOC_SCOPE_T> &other) : allocator_(other.allocator_)
99 {
100 }
101 AllocatorAdapter(const AllocatorAdapter &) noexcept = default;
102 AllocatorAdapter &operator=(const AllocatorAdapter &) noexcept = default;
103
104 AllocatorAdapter(AllocatorAdapter &&other) noexcept = default;
105 AllocatorAdapter &operator=(AllocatorAdapter &&other) noexcept = default;
106
107 ~AllocatorAdapter() = default;
108
109 // NOLINTNEXTLINE(readability-identifier-naming)
110 pointer allocate(size_type size, [[maybe_unused]] const void *hint = nullptr)
111 {
112 // NOLINTNEXTLINE(bugprone-suspicious-semicolon, readability-braces-around-statements)
113 if constexpr (ALLOC_SCOPE_T == AllocScope::GLOBAL) {
114 return allocator_->AllocArray<T>(size);
115 // NOLINTNEXTLINE(readability-misleading-indentation)
116 } else {
117 return allocator_->AllocArrayLocal<T>(size);
118 }
119 }
120
121 // NOLINTNEXTLINE(readability-identifier-naming)
deallocate(pointer ptr,size_type size)122 void deallocate(pointer ptr, [[maybe_unused]] size_type size)
123 {
124 allocator_->Free(ptr);
125 }
126
127 template <typename U, typename... Args>
construct(U * ptr,Args &&...args)128 void construct(U *ptr, Args &&...args) // NOLINT(readability-identifier-naming)
129 {
130 ::new (static_cast<void *>(ptr)) U(std::forward<Args>(args)...);
131 }
132
133 template <typename U>
destroy(U * ptr)134 void destroy(U *ptr) // NOLINT(readability-identifier-naming)
135 {
136 ptr->~U();
137 }
138
139 template <typename U>
140 bool operator==(const AllocatorAdapter<U> &other) const
141 {
142 return this->allocator_ == other.allocator_;
143 }
144
145 template <typename U>
146 bool operator!=(const AllocatorAdapter<U> &other) const
147 {
148 return this->allocator_ != other.allocator_;
149 }
150
151 private:
152 Allocator *allocator_;
153
154 template <typename U, AllocScope TYPE_T>
155 friend class AllocatorAdapter;
156 };
157
158 template <AllocScope ALLOC_SCOPE_T>
Adapter()159 inline AllocatorAdapter<void, ALLOC_SCOPE_T> Allocator::Adapter()
160 {
161 return AllocatorAdapter<void, ALLOC_SCOPE_T>(this);
162 }
163
164 } // namespace ark::mem
165
166 #endif // RUNTIME_MEM_ALLOCATOR_ADAPTER_H
167