1 //---------------------------------------------------------------------------// 2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com> 3 // 4 // Distributed under the Boost Software License, Version 1.0 5 // See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt 7 // 8 // See http://boostorg.github.com/compute for more information. 9 //---------------------------------------------------------------------------// 10 11 #ifndef BOOST_COMPUTE_UTILITY_WAIT_LIST_HPP 12 #define BOOST_COMPUTE_UTILITY_WAIT_LIST_HPP 13 14 #include <vector> 15 16 #include <boost/compute/config.hpp> 17 18 #ifndef BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST 19 #include <initializer_list> 20 #endif 21 22 #include <boost/compute/event.hpp> 23 24 namespace boost { 25 namespace compute { 26 27 template<class T> class future; 28 29 /// \class wait_list 30 /// \brief Stores a list of events. 31 /// 32 /// The wait_list class stores a set of event objects and can be used to 33 /// specify dependencies for OpenCL operations or to wait on the host until 34 /// all of the events have completed. 35 /// 36 /// This class also provides convenience functions for interacting with 37 /// OpenCL APIs which typically accept event dependencies as a \c cl_event* 38 /// pointer and a \c cl_uint size. For example: 39 /// \code 40 /// wait_list events = ...; 41 /// 42 /// clEnqueueNDRangeKernel(..., events.get_event_ptr(), events.size(), ...); 43 /// \endcode 44 /// 45 /// \see event, \ref future "future<T>" 46 class wait_list 47 { 48 public: 49 typedef std::vector<event>::iterator iterator; 50 typedef std::vector<event>::const_iterator const_iterator; 51 52 /// Creates an empty wait-list. wait_list()53 wait_list() 54 { 55 } 56 57 /// Creates a wait-list containing \p event. wait_list(const event & event)58 wait_list(const event &event) 59 { 60 insert(event); 61 } 62 63 /// Creates a new wait-list as a copy of \p other. wait_list(const wait_list & other)64 wait_list(const wait_list &other) 65 : m_events(other.m_events) 66 { 67 } 68 69 #ifndef BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST 70 /// Creates a wait-list from \p events wait_list(std::initializer_list<event> events)71 wait_list(std::initializer_list<event> events) 72 : m_events(events) 73 { 74 } 75 #endif // BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST 76 77 /// Copies the events in the wait-list from \p other. operator =(const wait_list & other)78 wait_list& operator=(const wait_list &other) 79 { 80 if(this != &other){ 81 m_events = other.m_events; 82 } 83 84 return *this; 85 } 86 87 #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES 88 /// Move-constructs a new wait list object from \p other. wait_list(wait_list && other)89 wait_list(wait_list&& other) 90 : m_events(std::move(other.m_events)) 91 { 92 } 93 94 /// Move-assigns the wait list from \p other to \c *this. operator =(wait_list && other)95 wait_list& operator=(wait_list&& other) 96 { 97 m_events = std::move(other.m_events); 98 99 return *this; 100 } 101 #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES 102 103 /// Destroys the wait-list. ~wait_list()104 ~wait_list() 105 { 106 } 107 108 /// Returns \c true if the wait-list is empty. empty() const109 bool empty() const 110 { 111 return m_events.empty(); 112 } 113 114 /// Returns the number of events in the wait-list. size() const115 uint_ size() const 116 { 117 return static_cast<uint_>(m_events.size()); 118 } 119 120 /// Removes all of the events from the wait-list. clear()121 void clear() 122 { 123 m_events.clear(); 124 } 125 126 /// Returns a cl_event pointer to the first event in the wait-list. 127 /// Returns \c 0 if the wait-list is empty. 128 /// 129 /// This can be used to pass the wait-list to OpenCL functions which 130 /// expect a \c cl_event pointer to refer to a list of events. get_event_ptr() const131 const cl_event* get_event_ptr() const 132 { 133 if(empty()){ 134 return 0; 135 } 136 137 return reinterpret_cast<const cl_event *>(&m_events[0]); 138 } 139 140 /// Reserves a minimum length of storage for the wait list object. reserve(size_t new_capacity)141 void reserve(size_t new_capacity) { 142 m_events.reserve(new_capacity); 143 } 144 145 /// Inserts \p event into the wait-list. insert(const event & event)146 void insert(const event &event) 147 { 148 m_events.push_back(event); 149 } 150 151 /// Inserts the event from \p future into the wait-list. 152 template<class T> insert(const future<T> & future)153 void insert(const future<T> &future) 154 { 155 insert(future.get_event()); 156 } 157 158 /// Blocks until all of the events in the wait-list have completed. 159 /// 160 /// Does nothing if the wait-list is empty. wait() const161 void wait() const 162 { 163 if(!empty()){ 164 BOOST_COMPUTE_ASSERT_CL_SUCCESS( 165 clWaitForEvents(size(), get_event_ptr()) 166 ); 167 } 168 } 169 170 /// Returns a reference to the event at specified location \p pos. operator [](size_t pos) const171 const event& operator[](size_t pos) const { 172 return m_events[pos]; 173 } 174 175 /// Returns a reference to the event at specified location \p pos. operator [](size_t pos)176 event& operator[](size_t pos) { 177 return m_events[pos]; 178 } 179 180 /// Returns an iterator to the first element of the wait-list. begin()181 iterator begin() { 182 return m_events.begin(); 183 } 184 185 /// Returns an iterator to the first element of the wait-list. begin() const186 const_iterator begin() const { 187 return m_events.begin(); 188 } 189 190 /// Returns an iterator to the first element of the wait-list. cbegin() const191 const_iterator cbegin() const { 192 return m_events.begin(); 193 } 194 195 /// Returns an iterator to the element following the last element of the wait-list. end()196 iterator end() { 197 return m_events.end(); 198 } 199 200 /// Returns an iterator to the element following the last element of the wait-list. end() const201 const_iterator end() const { 202 return m_events.end(); 203 } 204 205 /// Returns an iterator to the element following the last element of the wait-list. cend() const206 const_iterator cend() const { 207 return m_events.end(); 208 } 209 210 private: 211 std::vector<event> m_events; 212 }; 213 214 } // end compute namespace 215 } // end boost namespace 216 217 #endif // BOOST_COMPUTE_UTILITY_WAIT_LIST_HPP 218