forked from boostorg/compute
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_event.cpp
143 lines (115 loc) · 4.2 KB
/
test_event.cpp
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()