| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009 |
- //---------------------------------------------------------------------------//
- // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
- //
- // Distributed under the Boost Software License, Version 1.0
- // See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt
- //
- // See http://boostorg.github.com/compute for more information.
- //---------------------------------------------------------------------------//
- #ifndef BOOST_COMPUTE_COMMAND_QUEUE_HPP
- #define BOOST_COMPUTE_COMMAND_QUEUE_HPP
- #include <cstddef>
- #include <algorithm>
- #include <boost/assert.hpp>
- #include <boost/compute/config.hpp>
- #include <boost/compute/event.hpp>
- #include <boost/compute/buffer.hpp>
- #include <boost/compute/device.hpp>
- #include <boost/compute/kernel.hpp>
- #include <boost/compute/context.hpp>
- #include <boost/compute/exception.hpp>
- #include <boost/compute/image/image1d.hpp>
- #include <boost/compute/image/image2d.hpp>
- #include <boost/compute/image/image3d.hpp>
- #include <boost/compute/image/image_object.hpp>
- #include <boost/compute/utility/wait_list.hpp>
- #include <boost/compute/detail/get_object_info.hpp>
- #include <boost/compute/detail/assert_cl_success.hpp>
- #include <boost/compute/detail/diagnostic.hpp>
- #include <boost/compute/utility/extents.hpp>
- namespace boost {
- namespace compute {
- namespace detail {
- inline void BOOST_COMPUTE_CL_CALLBACK
- nullary_native_kernel_trampoline(void *user_func_ptr)
- {
- void (*user_func)();
- std::memcpy(&user_func, user_func_ptr, sizeof(user_func));
- user_func();
- }
- } // end detail namespace
- /// \class command_queue
- /// \brief A command queue.
- ///
- /// Command queues provide the interface for interacting with compute
- /// devices. The command_queue class provides methods to copy data to
- /// and from a compute device as well as execute compute kernels.
- ///
- /// Command queues are created for a compute device within a compute
- /// context.
- ///
- /// For example, to create a context and command queue for the default device
- /// on the system (this is the normal set up code used by almost all OpenCL
- /// programs):
- /// \code
- /// #include <boost/compute/core.hpp>
- ///
- /// // get the default compute device
- /// boost::compute::device device = boost::compute::system::default_device();
- ///
- /// // set up a compute context and command queue
- /// boost::compute::context context(device);
- /// boost::compute::command_queue queue(context, device);
- /// \endcode
- ///
- /// The default command queue for the system can be obtained with the
- /// system::default_queue() method.
- ///
- /// \see buffer, context, kernel
- class command_queue
- {
- public:
- enum properties {
- enable_profiling = CL_QUEUE_PROFILING_ENABLE,
- enable_out_of_order_execution = CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
- #ifdef BOOST_COMPUTE_CL_VERSION_2_0
- ,
- on_device = CL_QUEUE_ON_DEVICE,
- on_device_default = CL_QUEUE_ON_DEVICE_DEFAULT
- #endif
- };
- enum map_flags {
- map_read = CL_MAP_READ,
- map_write = CL_MAP_WRITE
- #ifdef BOOST_COMPUTE_CL_VERSION_1_2
- ,
- map_write_invalidate_region = CL_MAP_WRITE_INVALIDATE_REGION
- #endif
- };
- #ifdef BOOST_COMPUTE_CL_VERSION_1_2
- enum mem_migration_flags {
- migrate_to_host = CL_MIGRATE_MEM_OBJECT_HOST,
- migrate_content_undefined = CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED
- };
- #endif // BOOST_COMPUTE_CL_VERSION_1_2
- /// Creates a null command queue.
- command_queue()
- : m_queue(0)
- {
- }
- explicit command_queue(cl_command_queue queue, bool retain = true)
- : m_queue(queue)
- {
- if(m_queue && retain){
- clRetainCommandQueue(m_queue);
- }
- }
- /// Creates a command queue in \p context for \p device with
- /// \p properties.
- ///
- /// \see_opencl_ref{clCreateCommandQueue}
- command_queue(const context &context,
- const device &device,
- cl_command_queue_properties properties = 0)
- {
- BOOST_ASSERT(device.id() != 0);
- cl_int error = 0;
- #ifdef BOOST_COMPUTE_CL_VERSION_2_0
- if (device.check_version(2, 0)){
- std::vector<cl_queue_properties> queue_properties;
- if(properties){
- queue_properties.push_back(CL_QUEUE_PROPERTIES);
- queue_properties.push_back(cl_queue_properties(properties));
- queue_properties.push_back(cl_queue_properties(0));
- }
- const cl_queue_properties *queue_properties_ptr =
- queue_properties.empty() ? 0 : &queue_properties[0];
- m_queue = clCreateCommandQueueWithProperties(
- context, device.id(), queue_properties_ptr, &error
- );
- } else
- #endif
- {
- // Suppress deprecated declarations warning
- BOOST_COMPUTE_DISABLE_DEPRECATED_DECLARATIONS();
- m_queue = clCreateCommandQueue(
- context, device.id(), properties, &error
- );
- BOOST_COMPUTE_ENABLE_DEPRECATED_DECLARATIONS();
- }
- if(!m_queue){
- BOOST_THROW_EXCEPTION(opencl_error(error));
- }
- }
- /// Creates a new command queue object as a copy of \p other.
- command_queue(const command_queue &other)
- : m_queue(other.m_queue)
- {
- if(m_queue){
- clRetainCommandQueue(m_queue);
- }
- }
- /// Copies the command queue object from \p other to \c *this.
- command_queue& operator=(const command_queue &other)
- {
- if(this != &other){
- if(m_queue){
- clReleaseCommandQueue(m_queue);
- }
- m_queue = other.m_queue;
- if(m_queue){
- clRetainCommandQueue(m_queue);
- }
- }
- return *this;
- }
- #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
- /// Move-constructs a new command queue object from \p other.
- command_queue(command_queue&& other) BOOST_NOEXCEPT
- : m_queue(other.m_queue)
- {
- other.m_queue = 0;
- }
- /// Move-assigns the command queue from \p other to \c *this.
- command_queue& operator=(command_queue&& other) BOOST_NOEXCEPT
- {
- if(m_queue){
- clReleaseCommandQueue(m_queue);
- }
- m_queue = other.m_queue;
- other.m_queue = 0;
- return *this;
- }
- #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
- /// Destroys the command queue.
- ///
- /// \see_opencl_ref{clReleaseCommandQueue}
- ~command_queue()
- {
- if(m_queue){
- BOOST_COMPUTE_ASSERT_CL_SUCCESS(
- clReleaseCommandQueue(m_queue)
- );
- }
- }
- /// Returns the underlying OpenCL command queue.
- cl_command_queue& get() const
- {
- return const_cast<cl_command_queue &>(m_queue);
- }
- /// Returns the device that the command queue issues commands to.
- device get_device() const
- {
- return device(get_info<cl_device_id>(CL_QUEUE_DEVICE));
- }
- /// Returns the context for the command queue.
- context get_context() const
- {
- return context(get_info<cl_context>(CL_QUEUE_CONTEXT));
- }
- /// Returns information about the command queue.
- ///
- /// \see_opencl_ref{clGetCommandQueueInfo}
- template<class T>
- T get_info(cl_command_queue_info info) const
- {
- return detail::get_object_info<T>(clGetCommandQueueInfo, m_queue, info);
- }
- /// \overload
- template<int Enum>
- typename detail::get_object_info_type<command_queue, Enum>::type
- get_info() const;
- /// Returns the properties for the command queue.
- cl_command_queue_properties get_properties() const
- {
- return get_info<cl_command_queue_properties>(CL_QUEUE_PROPERTIES);
- }
- #if defined(BOOST_COMPUTE_CL_VERSION_2_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Returns the current default device command queue for the underlying device.
- ///
- /// \opencl_version_warning{2,1}
- command_queue get_default_device_queue() const
- {
- return command_queue(get_info<cl_command_queue>(CL_QUEUE_DEVICE_DEFAULT));
- }
- /// Replaces the default device command queue for the underlying device
- /// with this command queue. Command queue must have been created
- /// with CL_QUEUE_ON_DEVICE flag.
- ///
- /// \see_opencl21_ref{clSetDefaultDeviceCommandQueue}
- ///
- /// \opencl_version_warning{2,1}
- void set_as_default_device_queue() const
- {
- cl_int ret = clSetDefaultDeviceCommandQueue(
- this->get_context().get(),
- this->get_device().get(),
- m_queue
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- }
- #endif // BOOST_COMPUTE_CL_VERSION_2_1
- /// Enqueues a command to read data from \p buffer to host memory.
- ///
- /// \see_opencl_ref{clEnqueueReadBuffer}
- ///
- /// \see copy()
- event enqueue_read_buffer(const buffer &buffer,
- size_t offset,
- size_t size,
- void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(size <= buffer.size());
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- BOOST_ASSERT(host_ptr != 0);
- event event_;
- cl_int ret = clEnqueueReadBuffer(
- m_queue,
- buffer.get(),
- CL_TRUE,
- offset,
- size,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to read data from \p buffer to host memory. The
- /// copy will be performed asynchronously.
- ///
- /// \see_opencl_ref{clEnqueueReadBuffer}
- ///
- /// \see copy_async()
- event enqueue_read_buffer_async(const buffer &buffer,
- size_t offset,
- size_t size,
- void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(size <= buffer.size());
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- BOOST_ASSERT(host_ptr != 0);
- event event_;
- cl_int ret = clEnqueueReadBuffer(
- m_queue,
- buffer.get(),
- CL_FALSE,
- offset,
- size,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #if defined(BOOST_COMPUTE_CL_VERSION_1_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a command to read a rectangular region from \p buffer to
- /// host memory.
- ///
- /// \see_opencl_ref{clEnqueueReadBufferRect}
- ///
- /// \opencl_version_warning{1,1}
- event enqueue_read_buffer_rect(const buffer &buffer,
- const size_t buffer_origin[3],
- const size_t host_origin[3],
- const size_t region[3],
- size_t buffer_row_pitch,
- size_t buffer_slice_pitch,
- size_t host_row_pitch,
- size_t host_slice_pitch,
- void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- BOOST_ASSERT(host_ptr != 0);
- event event_;
- cl_int ret = clEnqueueReadBufferRect(
- m_queue,
- buffer.get(),
- CL_TRUE,
- buffer_origin,
- host_origin,
- region,
- buffer_row_pitch,
- buffer_slice_pitch,
- host_row_pitch,
- host_slice_pitch,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to read a rectangular region from \p buffer to
- /// host memory. The copy will be performed asynchronously.
- ///
- /// \see_opencl_ref{clEnqueueReadBufferRect}
- ///
- /// \opencl_version_warning{1,1}
- event enqueue_read_buffer_rect_async(const buffer &buffer,
- const size_t buffer_origin[3],
- const size_t host_origin[3],
- const size_t region[3],
- size_t buffer_row_pitch,
- size_t buffer_slice_pitch,
- size_t host_row_pitch,
- size_t host_slice_pitch,
- void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- BOOST_ASSERT(host_ptr != 0);
- event event_;
- cl_int ret = clEnqueueReadBufferRect(
- m_queue,
- buffer.get(),
- CL_FALSE,
- buffer_origin,
- host_origin,
- region,
- buffer_row_pitch,
- buffer_slice_pitch,
- host_row_pitch,
- host_slice_pitch,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_1_1
- /// Enqueues a command to write data from host memory to \p buffer.
- ///
- /// \see_opencl_ref{clEnqueueWriteBuffer}
- ///
- /// \see copy()
- event enqueue_write_buffer(const buffer &buffer,
- size_t offset,
- size_t size,
- const void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(size <= buffer.size());
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- BOOST_ASSERT(host_ptr != 0);
- event event_;
- cl_int ret = clEnqueueWriteBuffer(
- m_queue,
- buffer.get(),
- CL_TRUE,
- offset,
- size,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to write data from host memory to \p buffer.
- /// The copy is performed asynchronously.
- ///
- /// \see_opencl_ref{clEnqueueWriteBuffer}
- ///
- /// \see copy_async()
- event enqueue_write_buffer_async(const buffer &buffer,
- size_t offset,
- size_t size,
- const void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(size <= buffer.size());
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- BOOST_ASSERT(host_ptr != 0);
- event event_;
- cl_int ret = clEnqueueWriteBuffer(
- m_queue,
- buffer.get(),
- CL_FALSE,
- offset,
- size,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #if defined(BOOST_COMPUTE_CL_VERSION_1_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a command to write a rectangular region from host memory
- /// to \p buffer.
- ///
- /// \see_opencl_ref{clEnqueueWriteBufferRect}
- ///
- /// \opencl_version_warning{1,1}
- event enqueue_write_buffer_rect(const buffer &buffer,
- const size_t buffer_origin[3],
- const size_t host_origin[3],
- const size_t region[3],
- size_t buffer_row_pitch,
- size_t buffer_slice_pitch,
- size_t host_row_pitch,
- size_t host_slice_pitch,
- void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- BOOST_ASSERT(host_ptr != 0);
- event event_;
- cl_int ret = clEnqueueWriteBufferRect(
- m_queue,
- buffer.get(),
- CL_TRUE,
- buffer_origin,
- host_origin,
- region,
- buffer_row_pitch,
- buffer_slice_pitch,
- host_row_pitch,
- host_slice_pitch,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to write a rectangular region from host memory
- /// to \p buffer. The copy is performed asynchronously.
- ///
- /// \see_opencl_ref{clEnqueueWriteBufferRect}
- ///
- /// \opencl_version_warning{1,1}
- event enqueue_write_buffer_rect_async(const buffer &buffer,
- const size_t buffer_origin[3],
- const size_t host_origin[3],
- const size_t region[3],
- size_t buffer_row_pitch,
- size_t buffer_slice_pitch,
- size_t host_row_pitch,
- size_t host_slice_pitch,
- void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- BOOST_ASSERT(host_ptr != 0);
- event event_;
- cl_int ret = clEnqueueWriteBufferRect(
- m_queue,
- buffer.get(),
- CL_FALSE,
- buffer_origin,
- host_origin,
- region,
- buffer_row_pitch,
- buffer_slice_pitch,
- host_row_pitch,
- host_slice_pitch,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_1_1
- /// Enqueues a command to copy data from \p src_buffer to
- /// \p dst_buffer.
- ///
- /// \see_opencl_ref{clEnqueueCopyBuffer}
- ///
- /// \see copy()
- event enqueue_copy_buffer(const buffer &src_buffer,
- const buffer &dst_buffer,
- size_t src_offset,
- size_t dst_offset,
- size_t size,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(src_offset + size <= src_buffer.size());
- BOOST_ASSERT(dst_offset + size <= dst_buffer.size());
- BOOST_ASSERT(src_buffer.get_context() == this->get_context());
- BOOST_ASSERT(dst_buffer.get_context() == this->get_context());
- event event_;
- cl_int ret = clEnqueueCopyBuffer(
- m_queue,
- src_buffer.get(),
- dst_buffer.get(),
- src_offset,
- dst_offset,
- size,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #if defined(BOOST_COMPUTE_CL_VERSION_1_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a command to copy a rectangular region from
- /// \p src_buffer to \p dst_buffer.
- ///
- /// \see_opencl_ref{clEnqueueCopyBufferRect}
- ///
- /// \opencl_version_warning{1,1}
- event enqueue_copy_buffer_rect(const buffer &src_buffer,
- const buffer &dst_buffer,
- const size_t src_origin[3],
- const size_t dst_origin[3],
- const size_t region[3],
- size_t buffer_row_pitch,
- size_t buffer_slice_pitch,
- size_t host_row_pitch,
- size_t host_slice_pitch,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(src_buffer.get_context() == this->get_context());
- BOOST_ASSERT(dst_buffer.get_context() == this->get_context());
- event event_;
- cl_int ret = clEnqueueCopyBufferRect(
- m_queue,
- src_buffer.get(),
- dst_buffer.get(),
- src_origin,
- dst_origin,
- region,
- buffer_row_pitch,
- buffer_slice_pitch,
- host_row_pitch,
- host_slice_pitch,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_1_1
- #if defined(BOOST_COMPUTE_CL_VERSION_1_2) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a command to fill \p buffer with \p pattern.
- ///
- /// \see_opencl_ref{clEnqueueFillBuffer}
- ///
- /// \opencl_version_warning{1,2}
- ///
- /// \see fill()
- event enqueue_fill_buffer(const buffer &buffer,
- const void *pattern,
- size_t pattern_size,
- size_t offset,
- size_t size,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(offset + size <= buffer.size());
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- event event_;
- cl_int ret = clEnqueueFillBuffer(
- m_queue,
- buffer.get(),
- pattern,
- pattern_size,
- offset,
- size,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_1_2
- /// Enqueues a command to map \p buffer into the host address space.
- /// Event associated with map operation is returned through
- /// \p map_buffer_event parameter.
- ///
- /// \see_opencl_ref{clEnqueueMapBuffer}
- void* enqueue_map_buffer(const buffer &buffer,
- cl_map_flags flags,
- size_t offset,
- size_t size,
- event &map_buffer_event,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(offset + size <= buffer.size());
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- cl_int ret = 0;
- void *pointer = clEnqueueMapBuffer(
- m_queue,
- buffer.get(),
- CL_TRUE,
- flags,
- offset,
- size,
- events.size(),
- events.get_event_ptr(),
- &map_buffer_event.get(),
- &ret
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return pointer;
- }
- /// \overload
- void* enqueue_map_buffer(const buffer &buffer,
- cl_map_flags flags,
- size_t offset,
- size_t size,
- const wait_list &events = wait_list())
- {
- event event_;
- return enqueue_map_buffer(buffer, flags, offset, size, event_, events);
- }
- /// Enqueues a command to map \p buffer into the host address space.
- /// Map operation is performed asynchronously. The pointer to the mapped
- /// region cannot be used until the map operation has completed.
- ///
- /// Event associated with map operation is returned through
- /// \p map_buffer_event parameter.
- ///
- /// \see_opencl_ref{clEnqueueMapBuffer}
- void* enqueue_map_buffer_async(const buffer &buffer,
- cl_map_flags flags,
- size_t offset,
- size_t size,
- event &map_buffer_event,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(offset + size <= buffer.size());
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- cl_int ret = 0;
- void *pointer = clEnqueueMapBuffer(
- m_queue,
- buffer.get(),
- CL_FALSE,
- flags,
- offset,
- size,
- events.size(),
- events.get_event_ptr(),
- &map_buffer_event.get(),
- &ret
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return pointer;
- }
- /// Enqueues a command to unmap \p buffer from the host memory space.
- ///
- /// \see_opencl_ref{clEnqueueUnmapMemObject}
- event enqueue_unmap_buffer(const buffer &buffer,
- void *mapped_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(buffer.get_context() == this->get_context());
- return enqueue_unmap_mem_object(buffer.get(), mapped_ptr, events);
- }
- /// Enqueues a command to unmap \p mem from the host memory space.
- ///
- /// \see_opencl_ref{clEnqueueUnmapMemObject}
- event enqueue_unmap_mem_object(cl_mem mem,
- void *mapped_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueUnmapMemObject(
- m_queue,
- mem,
- mapped_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to read data from \p image to host memory.
- ///
- /// \see_opencl_ref{clEnqueueReadImage}
- event enqueue_read_image(const image_object& image,
- const size_t *origin,
- const size_t *region,
- size_t row_pitch,
- size_t slice_pitch,
- void *host_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueReadImage(
- m_queue,
- image.get(),
- CL_TRUE,
- origin,
- region,
- row_pitch,
- slice_pitch,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// \overload
- template<size_t N>
- event enqueue_read_image(const image_object& image,
- const extents<N> origin,
- const extents<N> region,
- void *host_ptr,
- size_t row_pitch = 0,
- size_t slice_pitch = 0,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(image.get_context() == this->get_context());
- size_t origin3[3] = { 0, 0, 0 };
- size_t region3[3] = { 1, 1, 1 };
- std::copy(origin.data(), origin.data() + N, origin3);
- std::copy(region.data(), region.data() + N, region3);
- return enqueue_read_image(
- image, origin3, region3, row_pitch, slice_pitch, host_ptr, events
- );
- }
- /// Enqueues a command to write data from host memory to \p image.
- ///
- /// \see_opencl_ref{clEnqueueWriteImage}
- event enqueue_write_image(image_object& image,
- const size_t *origin,
- const size_t *region,
- const void *host_ptr,
- size_t input_row_pitch = 0,
- size_t input_slice_pitch = 0,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueWriteImage(
- m_queue,
- image.get(),
- CL_TRUE,
- origin,
- region,
- input_row_pitch,
- input_slice_pitch,
- host_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// \overload
- template<size_t N>
- event enqueue_write_image(image_object& image,
- const extents<N> origin,
- const extents<N> region,
- const void *host_ptr,
- const size_t input_row_pitch = 0,
- const size_t input_slice_pitch = 0,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(image.get_context() == this->get_context());
- size_t origin3[3] = { 0, 0, 0 };
- size_t region3[3] = { 1, 1, 1 };
- std::copy(origin.data(), origin.data() + N, origin3);
- std::copy(region.data(), region.data() + N, region3);
- return enqueue_write_image(
- image, origin3, region3, host_ptr, input_row_pitch, input_slice_pitch, events
- );
- }
- /// Enqueues a command to map \p image into the host address space.
- ///
- /// Event associated with map operation is returned through
- /// \p map_image_event parameter.
- ///
- /// \see_opencl_ref{clEnqueueMapImage}
- void* enqueue_map_image(const image_object &image,
- cl_map_flags flags,
- const size_t *origin,
- const size_t *region,
- size_t &output_row_pitch,
- size_t &output_slice_pitch,
- event &map_image_event,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(image.get_context() == this->get_context());
- cl_int ret = 0;
- void *pointer = clEnqueueMapImage(
- m_queue,
- image.get(),
- CL_TRUE,
- flags,
- origin,
- region,
- &output_row_pitch,
- &output_slice_pitch,
- events.size(),
- events.get_event_ptr(),
- &map_image_event.get(),
- &ret
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return pointer;
- }
- /// \overload
- void* enqueue_map_image(const image_object &image,
- cl_map_flags flags,
- const size_t *origin,
- const size_t *region,
- size_t &output_row_pitch,
- size_t &output_slice_pitch,
- const wait_list &events = wait_list())
- {
- event event_;
- return enqueue_map_image(
- image, flags, origin, region,
- output_row_pitch, output_slice_pitch, event_, events
- );
- }
- /// \overload
- template<size_t N>
- void* enqueue_map_image(image_object& image,
- cl_map_flags flags,
- const extents<N> origin,
- const extents<N> region,
- size_t &output_row_pitch,
- size_t &output_slice_pitch,
- event &map_image_event,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(image.get_context() == this->get_context());
- size_t origin3[3] = { 0, 0, 0 };
- size_t region3[3] = { 1, 1, 1 };
- std::copy(origin.data(), origin.data() + N, origin3);
- std::copy(region.data(), region.data() + N, region3);
- return enqueue_map_image(
- image, flags, origin3, region3,
- output_row_pitch, output_slice_pitch, map_image_event, events
- );
- }
- /// \overload
- template<size_t N>
- void* enqueue_map_image(image_object& image,
- cl_map_flags flags,
- const extents<N> origin,
- const extents<N> region,
- size_t &output_row_pitch,
- size_t &output_slice_pitch,
- const wait_list &events = wait_list())
- {
- event event_;
- return enqueue_map_image(
- image, flags, origin, region,
- output_row_pitch, output_slice_pitch, event_, events
- );
- }
- /// Enqueues a command to map \p image into the host address space.
- /// Map operation is performed asynchronously. The pointer to the mapped
- /// region cannot be used until the map operation has completed.
- ///
- /// Event associated with map operation is returned through
- /// \p map_image_event parameter.
- ///
- /// \see_opencl_ref{clEnqueueMapImage}
- void* enqueue_map_image_async(const image_object &image,
- cl_map_flags flags,
- const size_t *origin,
- const size_t *region,
- size_t &output_row_pitch,
- size_t &output_slice_pitch,
- event &map_image_event,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(image.get_context() == this->get_context());
- cl_int ret = 0;
- void *pointer = clEnqueueMapImage(
- m_queue,
- image.get(),
- CL_FALSE,
- flags,
- origin,
- region,
- &output_row_pitch,
- &output_slice_pitch,
- events.size(),
- events.get_event_ptr(),
- &map_image_event.get(),
- &ret
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return pointer;
- }
- /// \overload
- template<size_t N>
- void* enqueue_map_image_async(image_object& image,
- cl_map_flags flags,
- const extents<N> origin,
- const extents<N> region,
- size_t &output_row_pitch,
- size_t &output_slice_pitch,
- event &map_image_event,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(image.get_context() == this->get_context());
- size_t origin3[3] = { 0, 0, 0 };
- size_t region3[3] = { 1, 1, 1 };
- std::copy(origin.data(), origin.data() + N, origin3);
- std::copy(region.data(), region.data() + N, region3);
- return enqueue_map_image_async(
- image, flags, origin3, region3,
- output_row_pitch, output_slice_pitch, map_image_event, events
- );
- }
- /// Enqueues a command to unmap \p image from the host memory space.
- ///
- /// \see_opencl_ref{clEnqueueUnmapMemObject}
- event enqueue_unmap_image(const image_object &image,
- void *mapped_ptr,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(image.get_context() == this->get_context());
- return enqueue_unmap_mem_object(image.get(), mapped_ptr, events);
- }
- /// Enqueues a command to copy data from \p src_image to \p dst_image.
- ///
- /// \see_opencl_ref{clEnqueueCopyImage}
- event enqueue_copy_image(const image_object& src_image,
- image_object& dst_image,
- const size_t *src_origin,
- const size_t *dst_origin,
- const size_t *region,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueCopyImage(
- m_queue,
- src_image.get(),
- dst_image.get(),
- src_origin,
- dst_origin,
- region,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// \overload
- template<size_t N>
- event enqueue_copy_image(const image_object& src_image,
- image_object& dst_image,
- const extents<N> src_origin,
- const extents<N> dst_origin,
- const extents<N> region,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(src_image.get_context() == this->get_context());
- BOOST_ASSERT(dst_image.get_context() == this->get_context());
- BOOST_ASSERT_MSG(src_image.format() == dst_image.format(),
- "Source and destination image formats must match.");
- size_t src_origin3[3] = { 0, 0, 0 };
- size_t dst_origin3[3] = { 0, 0, 0 };
- size_t region3[3] = { 1, 1, 1 };
- std::copy(src_origin.data(), src_origin.data() + N, src_origin3);
- std::copy(dst_origin.data(), dst_origin.data() + N, dst_origin3);
- std::copy(region.data(), region.data() + N, region3);
- return enqueue_copy_image(
- src_image, dst_image, src_origin3, dst_origin3, region3, events
- );
- }
- /// Enqueues a command to copy data from \p src_image to \p dst_buffer.
- ///
- /// \see_opencl_ref{clEnqueueCopyImageToBuffer}
- event enqueue_copy_image_to_buffer(const image_object& src_image,
- memory_object& dst_buffer,
- const size_t *src_origin,
- const size_t *region,
- size_t dst_offset,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueCopyImageToBuffer(
- m_queue,
- src_image.get(),
- dst_buffer.get(),
- src_origin,
- region,
- dst_offset,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to copy data from \p src_buffer to \p dst_image.
- ///
- /// \see_opencl_ref{clEnqueueCopyBufferToImage}
- event enqueue_copy_buffer_to_image(const memory_object& src_buffer,
- image_object& dst_image,
- size_t src_offset,
- const size_t *dst_origin,
- const size_t *region,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueCopyBufferToImage(
- m_queue,
- src_buffer.get(),
- dst_image.get(),
- src_offset,
- dst_origin,
- region,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #if defined(BOOST_COMPUTE_CL_VERSION_1_2) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a command to fill \p image with \p fill_color.
- ///
- /// \see_opencl_ref{clEnqueueFillImage}
- ///
- /// \opencl_version_warning{1,2}
- event enqueue_fill_image(image_object& image,
- const void *fill_color,
- const size_t *origin,
- const size_t *region,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueFillImage(
- m_queue,
- image.get(),
- fill_color,
- origin,
- region,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// \overload
- template<size_t N>
- event enqueue_fill_image(image_object& image,
- const void *fill_color,
- const extents<N> origin,
- const extents<N> region,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(image.get_context() == this->get_context());
- size_t origin3[3] = { 0, 0, 0 };
- size_t region3[3] = { 1, 1, 1 };
- std::copy(origin.data(), origin.data() + N, origin3);
- std::copy(region.data(), region.data() + N, region3);
- return enqueue_fill_image(
- image, fill_color, origin3, region3, events
- );
- }
- /// Enqueues a command to migrate \p mem_objects.
- ///
- /// \see_opencl_ref{clEnqueueMigrateMemObjects}
- ///
- /// \opencl_version_warning{1,2}
- event enqueue_migrate_memory_objects(uint_ num_mem_objects,
- const cl_mem *mem_objects,
- cl_mem_migration_flags flags,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueMigrateMemObjects(
- m_queue,
- num_mem_objects,
- mem_objects,
- flags,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_1_2
- /// Enqueues a kernel for execution.
- ///
- /// \see_opencl_ref{clEnqueueNDRangeKernel}
- event enqueue_nd_range_kernel(const kernel &kernel,
- size_t work_dim,
- const size_t *global_work_offset,
- const size_t *global_work_size,
- const size_t *local_work_size,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(kernel.get_context() == this->get_context());
- event event_;
- cl_int ret = clEnqueueNDRangeKernel(
- m_queue,
- kernel,
- static_cast<cl_uint>(work_dim),
- global_work_offset,
- global_work_size,
- local_work_size,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// \overload
- template<size_t N>
- event enqueue_nd_range_kernel(const kernel &kernel,
- const extents<N> &global_work_offset,
- const extents<N> &global_work_size,
- const extents<N> &local_work_size,
- const wait_list &events = wait_list())
- {
- return enqueue_nd_range_kernel(
- kernel,
- N,
- global_work_offset.data(),
- global_work_size.data(),
- local_work_size.data(),
- events
- );
- }
- /// Convenience method which calls enqueue_nd_range_kernel() with a
- /// one-dimensional range.
- event enqueue_1d_range_kernel(const kernel &kernel,
- size_t global_work_offset,
- size_t global_work_size,
- size_t local_work_size,
- const wait_list &events = wait_list())
- {
- return enqueue_nd_range_kernel(
- kernel,
- 1,
- &global_work_offset,
- &global_work_size,
- local_work_size ? &local_work_size : 0,
- events
- );
- }
- /// Enqueues a kernel to execute using a single work-item.
- ///
- /// \see_opencl_ref{clEnqueueTask}
- event enqueue_task(const kernel &kernel, const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- BOOST_ASSERT(kernel.get_context() == this->get_context());
- event event_;
- // clEnqueueTask() was deprecated in OpenCL 2.0. In that case we
- // just forward to the equivalent clEnqueueNDRangeKernel() call.
- #ifdef BOOST_COMPUTE_CL_VERSION_2_0
- size_t one = 1;
- cl_int ret = clEnqueueNDRangeKernel(
- m_queue, kernel, 1, 0, &one, &one,
- events.size(), events.get_event_ptr(), &event_.get()
- );
- #else
- cl_int ret = clEnqueueTask(
- m_queue, kernel, events.size(), events.get_event_ptr(), &event_.get()
- );
- #endif
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a function to execute on the host.
- event enqueue_native_kernel(void (BOOST_COMPUTE_CL_CALLBACK *user_func)(void *),
- void *args,
- size_t cb_args,
- uint_ num_mem_objects,
- const cl_mem *mem_list,
- const void **args_mem_loc,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = clEnqueueNativeKernel(
- m_queue,
- user_func,
- args,
- cb_args,
- num_mem_objects,
- mem_list,
- args_mem_loc,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Convenience overload for enqueue_native_kernel() which enqueues a
- /// native kernel on the host with a nullary function.
- event enqueue_native_kernel(void (BOOST_COMPUTE_CL_CALLBACK *user_func)(void),
- const wait_list &events = wait_list())
- {
- return enqueue_native_kernel(
- detail::nullary_native_kernel_trampoline,
- reinterpret_cast<void *>(&user_func),
- sizeof(user_func),
- 0,
- 0,
- 0,
- events
- );
- }
- /// Flushes the command queue.
- ///
- /// \see_opencl_ref{clFlush}
- void flush()
- {
- BOOST_ASSERT(m_queue != 0);
- cl_int ret = clFlush(m_queue);
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- }
- /// Blocks until all outstanding commands in the queue have finished.
- ///
- /// \see_opencl_ref{clFinish}
- void finish()
- {
- BOOST_ASSERT(m_queue != 0);
- cl_int ret = clFinish(m_queue);
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- }
- /// Enqueues a barrier in the queue.
- void enqueue_barrier()
- {
- BOOST_ASSERT(m_queue != 0);
- cl_int ret = CL_SUCCESS;
- #ifdef BOOST_COMPUTE_CL_VERSION_1_2
- if(get_device().check_version(1, 2)){
- ret = clEnqueueBarrierWithWaitList(m_queue, 0, 0, 0);
- } else
- #endif // BOOST_COMPUTE_CL_VERSION_1_2
- {
- // Suppress deprecated declarations warning
- BOOST_COMPUTE_DISABLE_DEPRECATED_DECLARATIONS();
- ret = clEnqueueBarrier(m_queue);
- BOOST_COMPUTE_ENABLE_DEPRECATED_DECLARATIONS();
- }
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- }
- #if defined(BOOST_COMPUTE_CL_VERSION_1_2) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a barrier in the queue after \p events.
- ///
- /// \opencl_version_warning{1,2}
- event enqueue_barrier(const wait_list &events)
- {
- BOOST_ASSERT(m_queue != 0);
- event event_;
- cl_int ret = CL_SUCCESS;
- ret = clEnqueueBarrierWithWaitList(
- m_queue, events.size(), events.get_event_ptr(), &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_1_2
- /// Enqueues a marker in the queue and returns an event that can be
- /// used to track its progress.
- event enqueue_marker()
- {
- event event_;
- cl_int ret = CL_SUCCESS;
- #ifdef BOOST_COMPUTE_CL_VERSION_1_2
- if(get_device().check_version(1, 2)){
- ret = clEnqueueMarkerWithWaitList(m_queue, 0, 0, &event_.get());
- } else
- #endif
- {
- // Suppress deprecated declarations warning
- BOOST_COMPUTE_DISABLE_DEPRECATED_DECLARATIONS();
- ret = clEnqueueMarker(m_queue, &event_.get());
- BOOST_COMPUTE_ENABLE_DEPRECATED_DECLARATIONS();
- }
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #if defined(BOOST_COMPUTE_CL_VERSION_1_2) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a marker after \p events in the queue and returns an
- /// event that can be used to track its progress.
- ///
- /// \opencl_version_warning{1,2}
- event enqueue_marker(const wait_list &events)
- {
- event event_;
- cl_int ret = clEnqueueMarkerWithWaitList(
- m_queue, events.size(), events.get_event_ptr(), &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_1_2
- #if defined(BOOST_COMPUTE_CL_VERSION_2_0) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a command to copy \p size bytes of data from \p src_ptr to
- /// \p dst_ptr.
- ///
- /// \opencl_version_warning{2,0}
- ///
- /// \see_opencl2_ref{clEnqueueSVMMemcpy}
- event enqueue_svm_memcpy(void *dst_ptr,
- const void *src_ptr,
- size_t size,
- const wait_list &events = wait_list())
- {
- event event_;
- cl_int ret = clEnqueueSVMMemcpy(
- m_queue,
- CL_TRUE,
- dst_ptr,
- src_ptr,
- size,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to copy \p size bytes of data from \p src_ptr to
- /// \p dst_ptr. The operation is performed asynchronously.
- ///
- /// \opencl_version_warning{2,0}
- ///
- /// \see_opencl2_ref{clEnqueueSVMMemcpy}
- event enqueue_svm_memcpy_async(void *dst_ptr,
- const void *src_ptr,
- size_t size,
- const wait_list &events = wait_list())
- {
- event event_;
- cl_int ret = clEnqueueSVMMemcpy(
- m_queue,
- CL_FALSE,
- dst_ptr,
- src_ptr,
- size,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to fill \p size bytes of data at \p svm_ptr with
- /// \p pattern.
- ///
- /// \opencl_version_warning{2,0}
- ///
- /// \see_opencl2_ref{clEnqueueSVMMemFill}
- event enqueue_svm_fill(void *svm_ptr,
- const void *pattern,
- size_t pattern_size,
- size_t size,
- const wait_list &events = wait_list())
- {
- event event_;
- cl_int ret = clEnqueueSVMMemFill(
- m_queue,
- svm_ptr,
- pattern,
- pattern_size,
- size,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to free \p svm_ptr.
- ///
- /// \opencl_version_warning{2,0}
- ///
- /// \see_opencl2_ref{clEnqueueSVMFree}
- ///
- /// \see svm_free()
- event enqueue_svm_free(void *svm_ptr,
- const wait_list &events = wait_list())
- {
- event event_;
- cl_int ret = clEnqueueSVMFree(
- m_queue,
- 1,
- &svm_ptr,
- 0,
- 0,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to map \p svm_ptr to the host memory space.
- ///
- /// \opencl_version_warning{2,0}
- ///
- /// \see_opencl2_ref{clEnqueueSVMMap}
- event enqueue_svm_map(void *svm_ptr,
- size_t size,
- cl_map_flags flags,
- const wait_list &events = wait_list())
- {
- event event_;
- cl_int ret = clEnqueueSVMMap(
- m_queue,
- CL_TRUE,
- flags,
- svm_ptr,
- size,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to unmap \p svm_ptr from the host memory space.
- ///
- /// \opencl_version_warning{2,0}
- ///
- /// \see_opencl2_ref{clEnqueueSVMUnmap}
- event enqueue_svm_unmap(void *svm_ptr,
- const wait_list &events = wait_list())
- {
- event event_;
- cl_int ret = clEnqueueSVMUnmap(
- m_queue,
- svm_ptr,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_2_0
- #if defined(BOOST_COMPUTE_CL_VERSION_2_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
- /// Enqueues a command to indicate which device a set of ranges of SVM allocations
- /// should be associated with. The pair \p svm_ptrs[i] and \p sizes[i] together define
- /// the starting address and number of bytes in a range to be migrated.
- ///
- /// If \p sizes is empty, then that means every allocation containing any \p svm_ptrs[i]
- /// is to be migrated. Also, if \p sizes[i] is zero, then the entire allocation containing
- /// \p svm_ptrs[i] is migrated.
- ///
- /// \opencl_version_warning{2,1}
- ///
- /// \see_opencl21_ref{clEnqueueSVMMigrateMem}
- event enqueue_svm_migrate_memory(const std::vector<const void*> &svm_ptrs,
- const std::vector<size_t> &sizes,
- const cl_mem_migration_flags flags = 0,
- const wait_list &events = wait_list())
- {
- BOOST_ASSERT(svm_ptrs.size() == sizes.size() || sizes.size() == 0);
- event event_;
- cl_int ret = clEnqueueSVMMigrateMem(
- m_queue,
- static_cast<cl_uint>(svm_ptrs.size()),
- const_cast<void const **>(&svm_ptrs[0]),
- sizes.size() > 0 ? &sizes[0] : NULL,
- flags,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- /// Enqueues a command to indicate which device a range of SVM allocation
- /// should be associated with. The pair \p svm_ptr and \p size together define
- /// the starting address and number of bytes in a range to be migrated.
- ///
- /// If \p size is 0, then the entire allocation containing \p svm_ptr is
- /// migrated. The default value for \p size is 0.
- ///
- /// \opencl_version_warning{2,1}
- ///
- /// \see_opencl21_ref{clEnqueueSVMMigrateMem}
- event enqueue_svm_migrate_memory(const void* svm_ptr,
- const size_t size = 0,
- const cl_mem_migration_flags flags = 0,
- const wait_list &events = wait_list())
- {
- event event_;
- cl_int ret = clEnqueueSVMMigrateMem(
- m_queue,
- cl_uint(1),
- &svm_ptr,
- &size,
- flags,
- events.size(),
- events.get_event_ptr(),
- &event_.get()
- );
- if(ret != CL_SUCCESS){
- BOOST_THROW_EXCEPTION(opencl_error(ret));
- }
- return event_;
- }
- #endif // BOOST_COMPUTE_CL_VERSION_2_1
- /// Returns \c true if the command queue is the same at \p other.
- bool operator==(const command_queue &other) const
- {
- return m_queue == other.m_queue;
- }
- /// Returns \c true if the command queue is different from \p other.
- bool operator!=(const command_queue &other) const
- {
- return m_queue != other.m_queue;
- }
- /// \internal_
- operator cl_command_queue() const
- {
- return m_queue;
- }
- /// \internal_
- bool check_device_version(int major, int minor) const
- {
- return get_device().check_version(major, minor);
- }
- private:
- cl_command_queue m_queue;
- };
- inline buffer buffer::clone(command_queue &queue) const
- {
- buffer copy(get_context(), size(), get_memory_flags());
- queue.enqueue_copy_buffer(*this, copy, 0, 0, size());
- return copy;
- }
- inline image1d image1d::clone(command_queue &queue) const
- {
- image1d copy(
- get_context(), width(), format(), get_memory_flags()
- );
- queue.enqueue_copy_image(*this, copy, origin(), copy.origin(), size());
- return copy;
- }
- inline image2d image2d::clone(command_queue &queue) const
- {
- image2d copy(
- get_context(), width(), height(), format(), get_memory_flags()
- );
- queue.enqueue_copy_image(*this, copy, origin(), copy.origin(), size());
- return copy;
- }
- inline image3d image3d::clone(command_queue &queue) const
- {
- image3d copy(
- get_context(), width(), height(), depth(), format(), get_memory_flags()
- );
- queue.enqueue_copy_image(*this, copy, origin(), copy.origin(), size());
- return copy;
- }
- /// \internal_ define get_info() specializations for command_queue
- BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(command_queue,
- ((cl_context, CL_QUEUE_CONTEXT))
- ((cl_device_id, CL_QUEUE_DEVICE))
- ((uint_, CL_QUEUE_REFERENCE_COUNT))
- ((cl_command_queue_properties, CL_QUEUE_PROPERTIES))
- )
- #ifdef BOOST_COMPUTE_CL_VERSION_2_1
- BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(command_queue,
- ((cl_command_queue, CL_QUEUE_DEVICE_DEFAULT))
- )
- #endif // BOOST_COMPUTE_CL_VERSION_2_1
- } // end compute namespace
- } // end boost namespace
- #endif // BOOST_COMPUTE_COMMAND_QUEUE_HPP
|