251 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			251 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								//---------------------------------------------------------------------------//
							 | 
						||
| 
								 | 
							
								// Copyright (c) 2013-2014 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_CONTAINER_MAPPED_VIEW_HPP
							 | 
						||
| 
								 | 
							
								#define BOOST_COMPUTE_CONTAINER_MAPPED_VIEW_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <cstddef>
							 | 
						||
| 
								 | 
							
								#include <exception>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/config.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/throw_exception.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/compute/buffer.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/system.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/context.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/command_queue.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/iterator/buffer_iterator.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost {
							 | 
						||
| 
								 | 
							
								namespace compute {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// \class mapped_view
							 | 
						||
| 
								 | 
							
								/// \brief A mapped view of host memory.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// The mapped_view class simplifies mapping host-memory to a compute
							 | 
						||
| 
								 | 
							
								/// device. This allows for host-allocated memory to be used with the
							 | 
						||
| 
								 | 
							
								/// Boost.Compute algorithms.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// The following example shows how to map a simple C-array containing
							 | 
						||
| 
								 | 
							
								/// data on the host to the device and run the reduce() algorithm to
							 | 
						||
| 
								 | 
							
								/// calculate the sum:
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// \snippet test/test_mapped_view.cpp reduce
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// \see buffer
							 | 
						||
| 
								 | 
							
								template<class T>
							 | 
						||
| 
								 | 
							
								class mapped_view
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    typedef T value_type;
							 | 
						||
| 
								 | 
							
								    typedef size_t size_type;
							 | 
						||
| 
								 | 
							
								    typedef ptrdiff_t difference_type;
							 | 
						||
| 
								 | 
							
								    typedef buffer_iterator<T> iterator;
							 | 
						||
| 
								 | 
							
								    typedef buffer_iterator<T> const_iterator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Creates a null mapped_view object.
							 | 
						||
| 
								 | 
							
								    mapped_view()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_mapped_ptr = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Creates a mapped_view for \p host_ptr with \p n elements. After
							 | 
						||
| 
								 | 
							
								    /// constructing a mapped_view the data is available for use by a
							 | 
						||
| 
								 | 
							
								    /// compute device. Use the \p unmap() method to make the updated data
							 | 
						||
| 
								 | 
							
								    /// available to the host.
							 | 
						||
| 
								 | 
							
								    mapped_view(T *host_ptr,
							 | 
						||
| 
								 | 
							
								                size_type n,
							 | 
						||
| 
								 | 
							
								                const context &context = system::default_context())
							 | 
						||
| 
								 | 
							
								        : m_buffer(_make_mapped_buffer(host_ptr, n, context))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_mapped_ptr = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Creates a read-only mapped_view for \p host_ptr with \p n elements.
							 | 
						||
| 
								 | 
							
								    /// After constructing a mapped_view the data is available for use by a
							 | 
						||
| 
								 | 
							
								    /// compute device. Use the \p unmap() method to make the updated data
							 | 
						||
| 
								 | 
							
								    /// available to the host.
							 | 
						||
| 
								 | 
							
								    mapped_view(const T *host_ptr,
							 | 
						||
| 
								 | 
							
								                size_type n,
							 | 
						||
| 
								 | 
							
								                const context &context = system::default_context())
							 | 
						||
| 
								 | 
							
								        : m_buffer(_make_mapped_buffer(host_ptr, n, context))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_mapped_ptr = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Creates a copy of \p other.
							 | 
						||
| 
								 | 
							
								    mapped_view(const mapped_view<T> &other)
							 | 
						||
| 
								 | 
							
								        : m_buffer(other.m_buffer)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_mapped_ptr = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Copies the mapped buffer from \p other.
							 | 
						||
| 
								 | 
							
								    mapped_view<T>& operator=(const mapped_view<T> &other)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if(this != &other){
							 | 
						||
| 
								 | 
							
								            m_buffer = other.m_buffer;
							 | 
						||
| 
								 | 
							
								            m_mapped_ptr = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return *this;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Destroys the mapped_view object.
							 | 
						||
| 
								 | 
							
								    ~mapped_view()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns an iterator to the first element in the mapped_view.
							 | 
						||
| 
								 | 
							
								    iterator begin()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return ::boost::compute::make_buffer_iterator<T>(m_buffer, 0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns a const_iterator to the first element in the mapped_view.
							 | 
						||
| 
								 | 
							
								    const_iterator begin() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return ::boost::compute::make_buffer_iterator<T>(m_buffer, 0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns a const_iterator to the first element in the mapped_view.
							 | 
						||
| 
								 | 
							
								    const_iterator cbegin() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return begin();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns an iterator to one past the last element in the mapped_view.
							 | 
						||
| 
								 | 
							
								    iterator end()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return ::boost::compute::make_buffer_iterator<T>(m_buffer, size());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns a const_iterator to one past the last element in the mapped_view.
							 | 
						||
| 
								 | 
							
								    const_iterator end() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return ::boost::compute::make_buffer_iterator<T>(m_buffer, size());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns a const_iterator to one past the last element in the mapped_view.
							 | 
						||
| 
								 | 
							
								    const_iterator cend() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return end();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns the number of elements in the mapped_view.
							 | 
						||
| 
								 | 
							
								    size_type size() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_buffer.size() / sizeof(T);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns the host data pointer.
							 | 
						||
| 
								 | 
							
								    T* get_host_ptr()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return static_cast<T *>(m_buffer.get_info<void *>(CL_MEM_HOST_PTR));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns the host data pointer.
							 | 
						||
| 
								 | 
							
								    const T* get_host_ptr() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return static_cast<T *>(m_buffer.get_info<void *>(CL_MEM_HOST_PTR));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Resizes the mapped_view to \p size elements.
							 | 
						||
| 
								 | 
							
								    void resize(size_type size)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        T *old_ptr = get_host_ptr();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        m_buffer = _make_mapped_buffer(old_ptr, size, m_buffer.get_context());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns \c true if the mapped_view is empty.
							 | 
						||
| 
								 | 
							
								    bool empty() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return size() == 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns the mapped buffer.
							 | 
						||
| 
								 | 
							
								    const buffer& get_buffer() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_buffer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Maps the buffer into the host address space.
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    /// \see_opencl_ref{clEnqueueMapBuffer}
							 | 
						||
| 
								 | 
							
								    void map(cl_map_flags flags, command_queue &queue)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        BOOST_ASSERT(m_mapped_ptr == 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        m_mapped_ptr = queue.enqueue_map_buffer(
							 | 
						||
| 
								 | 
							
								            m_buffer, flags, 0, m_buffer.size()
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Maps the buffer into the host address space for reading and writing.
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    /// Equivalent to:
							 | 
						||
| 
								 | 
							
								    /// \code
							 | 
						||
| 
								 | 
							
								    /// map(CL_MAP_READ | CL_MAP_WRITE, queue);
							 | 
						||
| 
								 | 
							
								    /// \endcode
							 | 
						||
| 
								 | 
							
								    void map(command_queue &queue)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        map(CL_MAP_READ | CL_MAP_WRITE, queue);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Unmaps the buffer from the host address space.
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    /// \see_opencl_ref{clEnqueueUnmapMemObject}
							 | 
						||
| 
								 | 
							
								    void unmap(command_queue &queue)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        BOOST_ASSERT(m_mapped_ptr != 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        queue.enqueue_unmap_buffer(m_buffer, m_mapped_ptr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        m_mapped_ptr = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    /// \internal_
							 | 
						||
| 
								 | 
							
								    static buffer _make_mapped_buffer(T *host_ptr,
							 | 
						||
| 
								 | 
							
								                                      size_t n,
							 | 
						||
| 
								 | 
							
								                                      const context &context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return buffer(
							 | 
						||
| 
								 | 
							
								            context,
							 | 
						||
| 
								 | 
							
								            n * sizeof(T),
							 | 
						||
| 
								 | 
							
								            buffer::read_write | buffer::use_host_ptr,
							 | 
						||
| 
								 | 
							
								            host_ptr
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// \internal_
							 | 
						||
| 
								 | 
							
								    static buffer _make_mapped_buffer(const T *host_ptr,
							 | 
						||
| 
								 | 
							
								                                      size_t n,
							 | 
						||
| 
								 | 
							
								                                      const context &context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return buffer(
							 | 
						||
| 
								 | 
							
								            context,
							 | 
						||
| 
								 | 
							
								            n * sizeof(T),
							 | 
						||
| 
								 | 
							
								            buffer::read_only | buffer::use_host_ptr,
							 | 
						||
| 
								 | 
							
								            const_cast<void *>(static_cast<const void *>(host_ptr))
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    buffer m_buffer;
							 | 
						||
| 
								 | 
							
								    void *m_mapped_ptr;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // end compute namespace
							 | 
						||
| 
								 | 
							
								} // end boost namespace
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // BOOST_COMPUTE_CONTAINER_MAPPED_VIEW_HPP
							 |