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:
Anthony C
2019-05-09 01:51:58 +08:00
parent 73580396ef
commit 2583e31214
7 changed files with 98 additions and 49 deletions
+2
View File
@@ -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]
+1
View File
@@ -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
+34 -29
View File
@@ -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;
+7 -14
View File
@@ -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)
+6 -5
View File
@@ -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();