From 2583e312146fdfa8169ee1918dc4ab12cb0e3e9d Mon Sep 17 00:00:00 2001 From: Anthony C Date: Thu, 9 May 2019 01:51:58 +0800 Subject: [PATCH] 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 --- doc/reference.qbk | 2 + include/boost/compute/context.hpp | 1 + .../exception/set_default_queue_error.hpp | 47 ++++++++++++++ include/boost/compute/system.hpp | 63 ++++++++++--------- test/test_attach_user_queue_error.cpp | 21 +++---- test/test_attach_user_queue_thread_safety.cpp | 2 +- test/test_system.cpp | 11 ++-- 7 files changed, 98 insertions(+), 49 deletions(-) create mode 100644 include/boost/compute/exception/set_default_queue_error.hpp diff --git a/doc/reference.qbk b/doc/reference.qbk index 1af2a47e..4d9e78ab 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -149,6 +149,8 @@ Header: `` * [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] diff --git a/include/boost/compute/context.hpp b/include/boost/compute/context.hpp index 13154a96..3c2bd314 100644 --- a/include/boost/compute/context.hpp +++ b/include/boost/compute/context.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace boost { diff --git a/include/boost/compute/exception/set_default_queue_error.hpp b/include/boost/compute/exception/set_default_queue_error.hpp new file mode 100644 index 00000000..7bab3c0a --- /dev/null +++ b/include/boost/compute/exception/set_default_queue_error.hpp @@ -0,0 +1,47 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2019 Anthony Chang +// +// 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 + +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 diff --git a/include/boost/compute/system.hpp b/include/boost/compute/system.hpp index 666c45d5..beb0e803 100644 --- a/include/boost/compute/system.hpp +++ b/include/boost/compute/system.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; diff --git a/test/test_attach_user_queue_error.cpp b/test/test_attach_user_queue_error.cpp index 9a2836be..2c1a72b8 100644 --- a/test/test_attach_user_queue_error.cpp +++ b/test/test_attach_user_queue_error.cpp @@ -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] } diff --git a/test/test_attach_user_queue_thread_safety.cpp b/test/test_attach_user_queue_thread_safety.cpp index 9081578d..05cc2711 100644 --- a/test/test_attach_user_queue_thread_safety.cpp +++ b/test/test_attach_user_queue_thread_safety.cpp @@ -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) diff --git a/test/test_system.cpp b/test/test_system.cpp index 390486ac..5ab73bdb 100644 --- a/test/test_system.cpp +++ b/test/test_system.cpp @@ -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();