DPC++ Runtime
Runtime libraries for oneAPI DPC++
leaves_collection.hpp
Go to the documentation of this file.
1 //==---- leaves_collection.hpp - Container for leaves of execution graph ---==//
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 
13 
14 #include <cstddef>
15 #include <list>
16 #include <unordered_map>
17 #include <utility>
18 
19 namespace sycl {
20 inline namespace _V1 {
21 namespace detail {
22 
23 struct MemObjRecord;
24 
39 public:
41  using HostAccessorCommandsT = std::list<EmptyCommand *>;
42  using EnqueueListT = std::vector<Command *>;
43 
44  // Make first command depend on the second
46  std::function<void(Command *, Command *, MemObjRecord *, EnqueueListT &)>;
47 
48  template <bool IsConst> class IteratorT;
49 
50  using value_type = Command *;
51  using pointer = value_type *;
52  using const_pointer = const value_type *;
53  using reference = value_type &;
54  using const_reference = const value_type &;
55 
58 
59  LeavesCollection(MemObjRecord *Record, std::size_t GenericCommandsCapacity,
60  AllocateDependencyF AllocateDependency)
61  : MRecord{Record}, MGenericCommands{GenericCommandsCapacity},
62  MAllocateDependency{std::move(AllocateDependency)} {}
63 
65  if (MGenericCommands.empty())
66  return iterator{*this, beginHostAccessor()};
67 
68  return iterator{*this, MGenericCommands.begin()};
69  }
70 
71  iterator end() { return iterator{*this, endHostAccessor()}; }
72 
74  if (MGenericCommands.empty())
75  return const_iterator{*this, beginHostAccessor()};
76 
77  return const_iterator{*this, MGenericCommands.begin()};
78  }
79 
80  const_iterator cend() const {
81  return const_iterator{*this, endHostAccessor()};
82  }
83 
85  bool push_back(value_type Cmd, EnqueueListT &ToEnqueue);
86 
90  size_t remove(value_type Cmd);
91 
92  std::vector<value_type> toVector() const;
93 
94  size_t genericCommandsCapacity() const {
95  return MGenericCommands.capacity();
96  };
97 
99  return MGenericCommands;
100  }
101 
103  return MHostAccessorCommands;
104  }
105 
106 private:
107  template <bool IsConst, typename T> struct Iterator;
108 
109  template <typename T> struct Iterator<true, T> {
110  using type = typename T::const_iterator;
111  };
112 
113  template <typename T> struct Iterator<false, T> {
114  using type = typename T::iterator;
115  };
116 
117  using HostAccessorCommandSingleXRefT =
118  typename HostAccessorCommandsT::iterator;
119  using HostAccessorCommandsXRefT =
120  std::unordered_map<EmptyCommand *, HostAccessorCommandSingleXRefT>;
121 
122  MemObjRecord *MRecord;
123  GenericCommandsT MGenericCommands;
124  HostAccessorCommandsT MHostAccessorCommands;
125  HostAccessorCommandsXRefT MHostAccessorCommandsXRef;
126 
127  AllocateDependencyF MAllocateDependency;
128 
129  bool addGenericCommand(value_type Cmd, EnqueueListT &ToEnqueue);
130  bool addHostAccessorCommand(EmptyCommand *Cmd, EnqueueListT &ToEnqueue);
131 
132  // inserts a command to the end of list for its mem object
133  void insertHostAccessorCommand(EmptyCommand *Cmd);
134  // returns number of removed elements
135  size_t eraseHostAccessorCommand(EmptyCommand *Cmd);
136 
137  typename Iterator<false, HostAccessorCommandsT>::type beginHostAccessor() {
138  return MHostAccessorCommands.begin();
139  }
140 
141  typename Iterator<true, HostAccessorCommandsT>::type
142  beginHostAccessor() const {
143  return MHostAccessorCommands.begin();
144  }
145 
146  typename Iterator<false, HostAccessorCommandsT>::type endHostAccessor() {
147  return MHostAccessorCommands.end();
148  }
149 
150  typename Iterator<true, HostAccessorCommandsT>::type endHostAccessor() const {
151  return MHostAccessorCommands.end();
152  }
153 
154  // for access to struct Ref.
155  friend class IteratorT<true>;
156  friend class IteratorT<false>;
157 
158  template <bool IsConst, typename T> struct Ref;
159  template <typename T> struct Ref<true, T> {
160  using type = const T &;
161  };
162  template <typename T> struct Ref<false, T> {
163  using type = T &;
164  };
165 
166  template <bool IsConst, typename T> struct Ptr;
167  template <typename T> struct Ptr<true, T> {
168  using type = const T *;
169  };
170  template <typename T> struct Ptr<false, T> {
171  using type = T *;
172  };
173 
174 public:
175  // iterate over generic commands in the first place and over host accessors
176  // later on
177  template <bool IsConst> class IteratorT {
178  public:
179  using HostT = typename Ref<IsConst, LeavesCollection>::type;
180  using GCItT = typename Iterator<IsConst, GenericCommandsT>::type;
181  using HACItT = typename Iterator<IsConst, HostAccessorCommandsT>::type;
182 
183  private:
184  HostT MHost;
185  GCItT MGCIt;
186  HACItT MHACIt;
187 
188  bool MGenericIsActive;
189 
190  IteratorT(HostT Host, GCItT GCIt, HACItT HACIt, bool GenericIsActive)
191  : MHost(Host), MGCIt(GCIt), MHACIt(HACIt),
192  MGenericIsActive(GenericIsActive) {}
193 
194  public:
195  IteratorT(HostT Host, GCItT GCIt)
196  : IteratorT(Host, std::move(GCIt), Host.beginHostAccessor(), true) {}
197 
198  IteratorT(HostT Host, HACItT HACIt)
199  : IteratorT(Host, Host.MGenericCommands.end(), std::move(HACIt),
200  false) {}
201 
203  : MHost{Other.MHost}, MGCIt(Other.MGCIt), MHACIt(Other.MHACIt),
204  MGenericIsActive(Other.MGenericIsActive) {}
205 
207  : MHost{Other.MHost}, MGCIt(std::move(Other.MGCIt)),
208  MHACIt(std::move(Other.MHACIt)),
209  MGenericIsActive(Other.MGenericIsActive) {}
210 
211  public:
212  bool operator==(const IteratorT<IsConst> &Rhs) const {
213  return &MHost == &Rhs.MHost && MGenericIsActive == Rhs.MGenericIsActive &&
214  ((MGenericIsActive && MGCIt == Rhs.MGCIt) ||
215  (!MGenericIsActive && MHACIt == Rhs.MHACIt));
216  }
217 
218  bool operator!=(const IteratorT<IsConst> &Rhs) const {
219  return &MHost != &Rhs.MHost || MGenericIsActive != Rhs.MGenericIsActive ||
220  ((MGenericIsActive && MGCIt != Rhs.MGCIt) ||
221  (!MGenericIsActive && MHACIt != Rhs.MHACIt));
222  }
223 
225 
226  // pre-increment
228  increment();
229  return *this;
230  }
231 
232  // post-increment
234  IteratorT<IsConst> Other(*this);
235  increment();
236 
237  return Other;
238  }
239 
241  if (MGenericIsActive && MGCIt != MHost.MGenericCommands.end())
242  return *MGCIt;
243 
244  if (!MGenericIsActive && MHACIt != MHost.endHostAccessor())
245  return *MHACIt;
246 
247  assert(false);
248 
249  return nullptr;
250  }
251 
252  private:
253  void increment() {
254  if (MGenericIsActive) {
255  ++MGCIt;
256 
257  if (MGCIt == MHost.MGenericCommands.end()) {
258  MGenericIsActive = false;
259  MHACIt = MHost.MHostAccessorCommands.begin();
260  return;
261  }
262 
263  return;
264  }
265 
266  assert(MGCIt == MHost.MGenericCommands.end());
267 
268  if (MHACIt == MHost.endHostAccessor())
269  return;
270 
271  ++MHACIt;
272  }
273  };
274 };
275 
276 } // namespace detail
277 } // namespace _V1
278 } // namespace sycl
The Command class represents some action that needs to be performed on one or more memory objects.
Definition: commands.hpp:107
bool operator!=(const IteratorT< IsConst > &Rhs) const
typename Ref< IsConst, LeavesCollection >::type HostT
IteratorT & operator=(const IteratorT< IsConst > &)=delete
typename Iterator< IsConst, HostAccessorCommandsT >::type HACItT
IteratorT(const IteratorT< IsConst > &Other)
typename Iterator< IsConst, GenericCommandsT >::type GCItT
bool operator==(const IteratorT< IsConst > &Rhs) const
A wrapper for CircularBuffer class along with collection for host accessor's EmptyCommands.
CircularBuffer< Command * > GenericCommandsT
std::list< EmptyCommand * > HostAccessorCommandsT
const GenericCommandsT & getGenericCommands() const
LeavesCollection(MemObjRecord *Record, std::size_t GenericCommandsCapacity, AllocateDependencyF AllocateDependency)
size_t remove(value_type Cmd)
Replacement for std::remove with subsequent call to erase(newEnd, end()).
bool push_back(value_type Cmd, EnqueueListT &ToEnqueue)
Returns true if insertion took place. Returns false otherwise.
std::function< void(Command *, Command *, MemObjRecord *, EnqueueListT &)> AllocateDependencyF
const HostAccessorCommandsT getHostAccessorCommands() const
std::vector< value_type > toVector() const
std::vector< Command * > EnqueueListT
const void value_type
Definition: multi_ptr.hpp:457
Definition: access.hpp:18
Memory Object Record.
Definition: scheduler.hpp:202