File: test_event.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (143 lines) | stat: -rw-r--r-- 4,301 bytes parent folder | download | duplicates (15)
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()