1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
//---------------------------------------------------------------------------//
// 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.
//---------------------------------------------------------------------------//
#define BOOST_TEST_MODULE TestEvent
#include <boost/test/unit_test.hpp>
#include <vector>
#ifdef BOOST_COMPUTE_USE_CPP11
#include <mutex>
#include <future>
#endif // BOOST_COMPUTE_USE_CPP11
#include <boost/compute/async/future.hpp>
#include <boost/compute/event.hpp>
#include "context_setup.hpp"
BOOST_AUTO_TEST_CASE(null_event)
{
boost::compute::event null;
BOOST_CHECK(null.get() == cl_event());
}
#if defined(BOOST_COMPUTE_CL_VERSION_1_1) && defined(BOOST_COMPUTE_USE_CPP11)
std::mutex callback_mutex;
std::condition_variable callback_condition_variable;
static bool callback_invoked = false;
static void BOOST_COMPUTE_CL_CALLBACK
callback(cl_event event, cl_int status, void *user_data)
{
std::lock_guard<std::mutex> lock(callback_mutex);
callback_invoked = true;
callback_condition_variable.notify_one();
}
BOOST_AUTO_TEST_CASE(event_callback)
{
REQUIRES_OPENCL_VERSION(1,2);
// ensure callback has not yet been executed
BOOST_CHECK_EQUAL(callback_invoked, false);
// enqueue marker and set callback to be invoked
boost::compute::event marker = queue.enqueue_marker();
marker.set_callback(callback);
marker.wait();
// wait up to one second for the callback to be executed
std::unique_lock<std::mutex> lock(callback_mutex);
callback_condition_variable.wait_for(
lock, std::chrono::seconds(1), [&](){ return callback_invoked; }
);
// ensure callback has been executed
BOOST_CHECK_EQUAL(callback_invoked, true);
}
BOOST_AUTO_TEST_CASE(lambda_callback)
{
REQUIRES_OPENCL_VERSION(1,2);
bool lambda_invoked = false;
boost::compute::event marker = queue.enqueue_marker();
marker.set_callback([&](){
std::lock_guard<std::mutex> lock(callback_mutex);
lambda_invoked = true;
callback_condition_variable.notify_one();
});
marker.wait();
// wait up to one second for the callback to be executed
std::unique_lock<std::mutex> lock(callback_mutex);
callback_condition_variable.wait_for(
lock, std::chrono::seconds(1), [&](){ return lambda_invoked; }
);
BOOST_CHECK_EQUAL(lambda_invoked, true);
}
BOOST_AUTO_TEST_CASE(future_then_callback)
{
REQUIRES_OPENCL_VERSION(1,2);
bool callback_invoked = false;
boost::compute::future<void> future(queue.enqueue_marker());
future.then([&](){
std::lock_guard<std::mutex> lock(callback_mutex);
callback_invoked = true;
callback_condition_variable.notify_one();
});
future.wait();
// wait up to one second for the callback to be executed
std::unique_lock<std::mutex> lock(callback_mutex);
callback_condition_variable.wait_for(
lock, std::chrono::seconds(1), [&](){ return callback_invoked; }
);
BOOST_CHECK_EQUAL(callback_invoked, true);
}
void BOOST_COMPUTE_CL_CALLBACK
event_promise_fulfiller_callback(cl_event event, cl_int status, void *user_data)
{
auto *promise = static_cast<std::promise<void> *>(user_data);
promise->set_value();
delete promise;
}
BOOST_AUTO_TEST_CASE(event_to_std_future)
{
REQUIRES_OPENCL_VERSION(1,2);
// enqueue an asynchronous copy to the device
std::vector<float> vector(1000, 3.14f);
boost::compute::buffer buffer(context, 1000 * sizeof(float));
auto event = queue.enqueue_write_buffer_async(
buffer, 0, 1000 * sizeof(float), vector.data()
);
// create a promise and future to be set by the callback
auto *promise = new std::promise<void>;
std::future<void> future = promise->get_future();
event.set_callback(event_promise_fulfiller_callback, CL_COMPLETE, promise);
// ensure commands are submitted to the device before waiting
queue.flush();
// wait for future to become ready
future.wait();
}
#endif // BOOST_COMPUTE_CL_VERSION_1_1
BOOST_AUTO_TEST_SUITE_END()
|