mirror of
https://github.com/boostorg/compute.git
synced 2026-07-21 13:13:36 +00:00
Multiple refactors
- attaching user command queue failure now throws a `set_default_queue_error` exception - default_queue() now takes optional const reference of user queue instead of pointer to user queue - add missing items in documentation
This commit is contained in:
@@ -149,6 +149,8 @@ Header: `<boost/compute/exception.hpp>`
|
||||
* [classref boost::compute::no_device_found no_device_found]
|
||||
* [classref boost::compute::opencl_error opencl_error]
|
||||
* [classref boost::compute::unsupported_extension_error unsupported_extension_error]
|
||||
* [classref boost::compute::program_build_failure program_build_failure]
|
||||
* [classref boost::compute::set_default_queue_error set_default_queue_error]
|
||||
|
||||
[h3 Iterators]
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/compute/config.hpp>
|
||||
#include <boost/compute/device.hpp>
|
||||
#include <boost/compute/exception/opencl_error.hpp>
|
||||
#include <boost/compute/exception/set_default_queue_error.hpp>
|
||||
#include <boost/compute/detail/assert_cl_success.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2019 Anthony Chang <ac.chang@outlook.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_EXCEPTION_SET_DEFAULT_QUEUE_ERROR_HPP
|
||||
#define BOOST_COMPUTE_EXCEPTION_SET_DEFAULT_QUEUE_ERROR_HPP
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
|
||||
/// \class set_default_queue_error
|
||||
/// \brief Exception thrown when failure to set default command queue
|
||||
///
|
||||
/// This exception is thrown when Boost.Compute fails to set up user-provided
|
||||
/// default command queue for the system.
|
||||
class set_default_queue_error : public std::exception
|
||||
{
|
||||
public:
|
||||
/// Creates a new set_default_queue_error exception object.
|
||||
set_default_queue_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
/// Destroys the set_default_queue_error object.
|
||||
~set_default_queue_error() throw()
|
||||
{
|
||||
}
|
||||
|
||||
/// Returns a string with a description of the error.
|
||||
const char* what() const throw()
|
||||
{
|
||||
return "User command queue mismatches default device and/or context";
|
||||
}
|
||||
};
|
||||
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_EXCEPTION_SET_DEFAULT_QUEUE_ERROR_HPP
|
||||
@@ -169,10 +169,16 @@ public:
|
||||
/// and default device will be set up appropriately so that the default queue
|
||||
/// matches the default context and device.
|
||||
///
|
||||
/// If the OpenCL context and device associated with user-provided command queue
|
||||
/// does not match the default context and device that have already been set,
|
||||
/// a set_default_queue_error exception is thrown. For example:
|
||||
///
|
||||
/// \snippet test/test_attach_user_queue_error.cpp queue_mismatch
|
||||
///
|
||||
/// The default queue is created once on the first time this function is
|
||||
/// called. Calling this function multiple times will always result in the
|
||||
/// same command queue object being returned.
|
||||
static command_queue& default_queue(command_queue* user_queue = 0)
|
||||
static command_queue& default_queue(const command_queue &user_queue = command_queue())
|
||||
{
|
||||
return init_default_queue(user_queue);
|
||||
}
|
||||
@@ -297,9 +303,10 @@ private:
|
||||
}
|
||||
|
||||
/// \internal_
|
||||
static device init_default_device(device* user_device = 0)
|
||||
static device init_default_device(const device &user_device = device())
|
||||
{
|
||||
static device default_device;
|
||||
|
||||
#ifdef BOOST_COMPUTE_THREAD_SAFE
|
||||
#ifdef BOOST_COMPUTE_USE_CPP11
|
||||
using namespace std;
|
||||
@@ -316,24 +323,24 @@ private:
|
||||
is_init_value = is_init.load(memory_order_consume);
|
||||
if (!is_init_value)
|
||||
{
|
||||
default_device = user_device ?
|
||||
*user_device : find_default_device();
|
||||
default_device = user_device.get() ?
|
||||
user_device : find_default_device();
|
||||
|
||||
is_init.store(true, memory_order_release);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#else // BOOST_COMPUTE_THREAD_SAFE
|
||||
if (!default_device.get())
|
||||
{
|
||||
default_device = user_device ?
|
||||
*user_device : find_default_device();
|
||||
default_device = user_device.get() ?
|
||||
user_device : find_default_device();
|
||||
}
|
||||
#endif
|
||||
#endif // BOOST_COMPUTE_THREAD_SAFE
|
||||
return default_device;
|
||||
}
|
||||
|
||||
/// \internal_
|
||||
static context init_default_context(context* user_context = 0)
|
||||
static context init_default_context(const context &user_context = context())
|
||||
{
|
||||
static context default_context;
|
||||
|
||||
@@ -353,8 +360,8 @@ private:
|
||||
is_init_value = is_init.load(memory_order_consume);
|
||||
if (!is_init_value)
|
||||
{
|
||||
default_context = user_context ?
|
||||
*user_context : context(default_device());
|
||||
default_context = user_context.get() ?
|
||||
user_context : context(default_device());
|
||||
|
||||
is_init.store(true, memory_order_release);
|
||||
}
|
||||
@@ -362,31 +369,29 @@ private:
|
||||
#else // BOOST_COMPUTE_THREAD_SAFE
|
||||
if (!default_context.get())
|
||||
{
|
||||
default_context = user_context ?
|
||||
*user_context : context(default_device());
|
||||
default_context = user_context.get() ?
|
||||
user_context : context(default_device());
|
||||
}
|
||||
#endif // BOOST_COMPUTE_THREAD_SAFE
|
||||
return default_context;
|
||||
}
|
||||
|
||||
/// \internal_
|
||||
static void init_default_device_and_context(command_queue* user_queue)
|
||||
static void init_default_device_and_context(const command_queue &user_queue)
|
||||
{
|
||||
device user_device = user_queue->get_device();
|
||||
context user_context = user_queue->get_context();
|
||||
device user_device = user_queue.get_device();
|
||||
context user_context = user_queue.get_context();
|
||||
|
||||
if ( (user_device != init_default_device(&user_device)) ||
|
||||
(user_context != init_default_context(&user_context)) )
|
||||
if ( (user_device != init_default_device(user_device)) ||
|
||||
(user_context != init_default_context(user_context)) )
|
||||
{
|
||||
// Try invoking default_queue() before anything else
|
||||
BOOST_THROW_EXCEPTION(context_error(&user_context,
|
||||
"Error: User command queue mismatches default device and/or context",
|
||||
0, 0));
|
||||
BOOST_THROW_EXCEPTION(set_default_queue_error());
|
||||
}
|
||||
}
|
||||
|
||||
/// \internal_
|
||||
static command_queue& init_default_queue(command_queue* user_queue = 0)
|
||||
static command_queue& init_default_queue(const command_queue &user_queue = command_queue())
|
||||
{
|
||||
static command_queue default_queue;
|
||||
|
||||
@@ -406,11 +411,11 @@ private:
|
||||
is_init_value = is_init.load(memory_order_consume);
|
||||
if (!is_init_value)
|
||||
{
|
||||
if (user_queue)
|
||||
if (user_queue.get())
|
||||
init_default_device_and_context(user_queue);
|
||||
|
||||
default_queue = user_queue ?
|
||||
*user_queue :
|
||||
default_queue = user_queue.get() ?
|
||||
user_queue :
|
||||
command_queue(default_context(), default_device());
|
||||
|
||||
is_init.store(true, memory_order_release);
|
||||
@@ -419,17 +424,17 @@ private:
|
||||
#else // BOOST_COMPUTE_THREAD_SAFE
|
||||
if (!default_queue.get())
|
||||
{
|
||||
if (user_queue)
|
||||
if (user_queue.get())
|
||||
init_default_device_and_context(user_queue);
|
||||
|
||||
default_queue = user_queue ?
|
||||
*user_queue :
|
||||
default_queue = user_queue.get() ?
|
||||
user_queue :
|
||||
command_queue(default_context(), default_device());
|
||||
}
|
||||
#endif // BOOST_COMPUTE_THREAD_SAFE
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT_MSG(user_queue == 0,
|
||||
BOOST_ASSERT_MSG(user_queue.get() == 0,
|
||||
"Default command queue has already been set.");
|
||||
}
|
||||
return default_queue;
|
||||
|
||||
@@ -20,24 +20,17 @@ namespace compute = boost::compute;
|
||||
// For correct usage of setting up global default queue, see test_system.cpp
|
||||
BOOST_AUTO_TEST_CASE(user_context_device_mismatch)
|
||||
{
|
||||
//! [queue_mismatch]
|
||||
compute::device user_device = compute::system::devices().front();
|
||||
compute::context user_context(user_device);
|
||||
compute::command_queue user_queue(user_context, user_device);
|
||||
|
||||
// Don't call default_device() or default_context() before calling
|
||||
// default_queue(command_queue* = 0) if you wish to attach your command queue
|
||||
compute::system::default_device();
|
||||
// default_queue() if you wish to attach your command queue
|
||||
compute::system::default_context();
|
||||
|
||||
try
|
||||
{
|
||||
compute::system::default_queue(&user_queue);
|
||||
}
|
||||
catch (boost::compute::context_error& e)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(
|
||||
std::string(e.what()),
|
||||
std::string("Error: User command queue mismatches default device and/or context")
|
||||
);
|
||||
return;
|
||||
}
|
||||
BOOST_CHECK_THROW(
|
||||
compute::system::default_queue(user_queue),
|
||||
compute::set_default_queue_error);
|
||||
//! [queue_mismatch]
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ void attach_user_queue_worker_threads(
|
||||
compute::command_queue* queues)
|
||||
{
|
||||
compute::command_queue user_queue(user_context, user_device);
|
||||
queues[id] = compute::system::default_queue(&user_queue);
|
||||
queues[id] = compute::system::default_queue(user_queue);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(user_default_context_thread_safety)
|
||||
|
||||
@@ -39,20 +39,21 @@ BOOST_AUTO_TEST_CASE(user_default_queue)
|
||||
|
||||
compute::command_queue queue1(context, device);
|
||||
{
|
||||
compute::system::default_queue(&queue1);
|
||||
compute::system::default_queue(queue1);
|
||||
compute::command_queue default_queue = compute::system::default_queue();
|
||||
BOOST_ASSERT(queue1 == default_queue);
|
||||
BOOST_CHECK(queue1 == default_queue);
|
||||
}
|
||||
#ifdef NDEBUG
|
||||
compute::command_queue queue2(context, device);
|
||||
{
|
||||
compute::system::default_queue(&queue2); // no longer settable after first initialization
|
||||
compute::system::default_queue(queue2); // no longer settable after first initialization
|
||||
compute::command_queue default_queue = compute::system::default_queue();
|
||||
BOOST_ASSERT(queue2 != default_queue);
|
||||
BOOST_ASSERT(queue1 == default_queue);
|
||||
BOOST_CHECK(queue2 != default_queue);
|
||||
BOOST_CHECK(queue1 == default_queue);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(find_device)
|
||||
{
|
||||
compute::device device = compute::system::default_device();
|
||||
|
||||
Reference in New Issue
Block a user