246 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			246 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								//---------------------------------------------------------------------------//
							 | 
						||
| 
								 | 
							
								// 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_CONTEXT_HPP
							 | 
						||
| 
								 | 
							
								#define BOOST_COMPUTE_CONTEXT_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <vector>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/throw_exception.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/compute/config.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/device.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/exception/opencl_error.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/detail/assert_cl_success.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost {
							 | 
						||
| 
								 | 
							
								namespace compute {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// \class context
							 | 
						||
| 
								 | 
							
								/// \brief A compute context.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// The context class represents a compute context.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// A context object manages a set of OpenCL resources including memory
							 | 
						||
| 
								 | 
							
								/// buffers and program objects. Before allocating memory on the device or
							 | 
						||
| 
								 | 
							
								/// executing kernels you must set up a context object.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// To create a context for the default device on the system:
							 | 
						||
| 
								 | 
							
								/// \code
							 | 
						||
| 
								 | 
							
								/// // get the default compute device
							 | 
						||
| 
								 | 
							
								/// boost::compute::device gpu = boost::compute::system::default_device();
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// // create a context for the device
							 | 
						||
| 
								 | 
							
								/// boost::compute::context context(gpu);
							 | 
						||
| 
								 | 
							
								/// \endcode
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// Once a context is created, memory can be allocated using the buffer class
							 | 
						||
| 
								 | 
							
								/// and kernels can be executed using the command_queue class.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// \see device, command_queue
							 | 
						||
| 
								 | 
							
								class context
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    /// Create a null context object.
							 | 
						||
| 
								 | 
							
								    context()
							 | 
						||
| 
								 | 
							
								        : m_context(0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Creates a new context for \p device with \p properties.
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    /// \see_opencl_ref{clCreateContext}
							 | 
						||
| 
								 | 
							
								    explicit context(const device &device,
							 | 
						||
| 
								 | 
							
								                     const cl_context_properties *properties = 0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        BOOST_ASSERT(device.id() != 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        cl_device_id device_id = device.id();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        cl_int error = 0;
							 | 
						||
| 
								 | 
							
								        m_context = clCreateContext(properties, 1, &device_id, 0, 0, &error);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if(!m_context){
							 | 
						||
| 
								 | 
							
								            BOOST_THROW_EXCEPTION(opencl_error(error));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Creates a new context for \p devices with \p properties.
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    /// \see_opencl_ref{clCreateContext}
							 | 
						||
| 
								 | 
							
								    explicit context(const std::vector<device> &devices,
							 | 
						||
| 
								 | 
							
								                     const cl_context_properties *properties = 0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        BOOST_ASSERT(!devices.empty());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        cl_int error = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        m_context = clCreateContext(
							 | 
						||
| 
								 | 
							
								            properties,
							 | 
						||
| 
								 | 
							
								            static_cast<cl_uint>(devices.size()),
							 | 
						||
| 
								 | 
							
								            reinterpret_cast<const cl_device_id *>(&devices[0]),
							 | 
						||
| 
								 | 
							
								            0,
							 | 
						||
| 
								 | 
							
								            0,
							 | 
						||
| 
								 | 
							
								            &error
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if(!m_context){
							 | 
						||
| 
								 | 
							
								            BOOST_THROW_EXCEPTION(opencl_error(error));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Creates a new context object for \p context. If \p retain is
							 | 
						||
| 
								 | 
							
								    /// \c true, the reference count for \p context will be incremented.
							 | 
						||
| 
								 | 
							
								    explicit context(cl_context context, bool retain = true)
							 | 
						||
| 
								 | 
							
								        : m_context(context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if(m_context && retain){
							 | 
						||
| 
								 | 
							
								            clRetainContext(m_context);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Creates a new context object as a copy of \p other.
							 | 
						||
| 
								 | 
							
								    context(const context &other)
							 | 
						||
| 
								 | 
							
								        : m_context(other.m_context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if(m_context){
							 | 
						||
| 
								 | 
							
								            clRetainContext(m_context);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Copies the context object from \p other to \c *this.
							 | 
						||
| 
								 | 
							
								    context& operator=(const context &other)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if(this != &other){
							 | 
						||
| 
								 | 
							
								            if(m_context){
							 | 
						||
| 
								 | 
							
								                clReleaseContext(m_context);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            m_context = other.m_context;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(m_context){
							 | 
						||
| 
								 | 
							
								                clRetainContext(m_context);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return *this;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
							 | 
						||
| 
								 | 
							
								    /// Move-constructs a new context object from \p other.
							 | 
						||
| 
								 | 
							
								    context(context&& other) BOOST_NOEXCEPT
							 | 
						||
| 
								 | 
							
								        : m_context(other.m_context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        other.m_context = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Move-assigns the context from \p other to \c *this.
							 | 
						||
| 
								 | 
							
								    context& operator=(context&& other) BOOST_NOEXCEPT
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if(m_context){
							 | 
						||
| 
								 | 
							
								            clReleaseContext(m_context);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        m_context = other.m_context;
							 | 
						||
| 
								 | 
							
								        other.m_context = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return *this;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Destroys the context object.
							 | 
						||
| 
								 | 
							
								    ~context()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if(m_context){
							 | 
						||
| 
								 | 
							
								            BOOST_COMPUTE_ASSERT_CL_SUCCESS(
							 | 
						||
| 
								 | 
							
								                clReleaseContext(m_context)
							 | 
						||
| 
								 | 
							
								            );
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns the underlying OpenCL context.
							 | 
						||
| 
								 | 
							
								    cl_context& get() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return const_cast<cl_context &>(m_context);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns the device for the context. If the context contains multiple
							 | 
						||
| 
								 | 
							
								    /// devices, the first is returned.
							 | 
						||
| 
								 | 
							
								    device get_device() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        std::vector<device> devices = get_devices();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if(devices.empty()) {
							 | 
						||
| 
								 | 
							
								            return device();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return devices.front();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns a vector of devices for the context.
							 | 
						||
| 
								 | 
							
								    std::vector<device> get_devices() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return get_info<std::vector<device> >(CL_CONTEXT_DEVICES);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns information about the context.
							 | 
						||
| 
								 | 
							
								    ///
							 | 
						||
| 
								 | 
							
								    /// \see_opencl_ref{clGetContextInfo}
							 | 
						||
| 
								 | 
							
								    template<class T>
							 | 
						||
| 
								 | 
							
								    T get_info(cl_context_info info) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return detail::get_object_info<T>(clGetContextInfo, m_context, info);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// \overload
							 | 
						||
| 
								 | 
							
								    template<int Enum>
							 | 
						||
| 
								 | 
							
								    typename detail::get_object_info_type<context, Enum>::type
							 | 
						||
| 
								 | 
							
								    get_info() const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns \c true if the context is the same as \p other.
							 | 
						||
| 
								 | 
							
								    bool operator==(const context &other) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_context == other.m_context;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// Returns \c true if the context is different from \p other.
							 | 
						||
| 
								 | 
							
								    bool operator!=(const context &other) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_context != other.m_context;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /// \internal_
							 | 
						||
| 
								 | 
							
								    operator cl_context() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return m_context;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    cl_context m_context;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// \internal_ define get_info() specializations for context
							 | 
						||
| 
								 | 
							
								BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(context,
							 | 
						||
| 
								 | 
							
								    ((cl_uint, CL_CONTEXT_REFERENCE_COUNT))
							 | 
						||
| 
								 | 
							
								    ((std::vector<cl_device_id>, CL_CONTEXT_DEVICES))
							 | 
						||
| 
								 | 
							
								    ((std::vector<cl_context_properties>, CL_CONTEXT_PROPERTIES))
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef CL_VERSION_1_1
							 | 
						||
| 
								 | 
							
								BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(context,
							 | 
						||
| 
								 | 
							
								    ((cl_uint, CL_CONTEXT_NUM_DEVICES))
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								#endif // CL_VERSION_1_1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // end compute namespace
							 | 
						||
| 
								 | 
							
								} // end boost namespace
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // BOOST_COMPUTE_CONTEXT_HPP
							 |