test_event.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. // See http://boostorg.github.com/compute for more information.
  9. //---------------------------------------------------------------------------//
  10. #define BOOST_TEST_MODULE TestEvent
  11. #include <boost/test/unit_test.hpp>
  12. #include <vector>
  13. #ifdef BOOST_COMPUTE_USE_CPP11
  14. #include <mutex>
  15. #include <future>
  16. #endif // BOOST_COMPUTE_USE_CPP11
  17. #include <boost/compute/async/future.hpp>
  18. #include <boost/compute/event.hpp>
  19. #include "context_setup.hpp"
  20. BOOST_AUTO_TEST_CASE(null_event)
  21. {
  22. boost::compute::event null;
  23. BOOST_CHECK(null.get() == cl_event());
  24. }
  25. #if defined(BOOST_COMPUTE_CL_VERSION_1_1) && defined(BOOST_COMPUTE_USE_CPP11)
  26. std::mutex callback_mutex;
  27. std::condition_variable callback_condition_variable;
  28. static bool callback_invoked = false;
  29. static void BOOST_COMPUTE_CL_CALLBACK
  30. callback(cl_event event, cl_int status, void *user_data)
  31. {
  32. std::lock_guard<std::mutex> lock(callback_mutex);
  33. callback_invoked = true;
  34. callback_condition_variable.notify_one();
  35. }
  36. BOOST_AUTO_TEST_CASE(event_callback)
  37. {
  38. REQUIRES_OPENCL_VERSION(1,2);
  39. // ensure callback has not yet been executed
  40. BOOST_CHECK_EQUAL(callback_invoked, false);
  41. // enqueue marker and set callback to be invoked
  42. boost::compute::event marker = queue.enqueue_marker();
  43. marker.set_callback(callback);
  44. marker.wait();
  45. // wait up to one second for the callback to be executed
  46. std::unique_lock<std::mutex> lock(callback_mutex);
  47. callback_condition_variable.wait_for(
  48. lock, std::chrono::seconds(1), [&](){ return callback_invoked; }
  49. );
  50. // ensure callback has been executed
  51. BOOST_CHECK_EQUAL(callback_invoked, true);
  52. }
  53. BOOST_AUTO_TEST_CASE(lambda_callback)
  54. {
  55. REQUIRES_OPENCL_VERSION(1,2);
  56. bool lambda_invoked = false;
  57. boost::compute::event marker = queue.enqueue_marker();
  58. marker.set_callback([&](){
  59. std::lock_guard<std::mutex> lock(callback_mutex);
  60. lambda_invoked = true;
  61. callback_condition_variable.notify_one();
  62. });
  63. marker.wait();
  64. // wait up to one second for the callback to be executed
  65. std::unique_lock<std::mutex> lock(callback_mutex);
  66. callback_condition_variable.wait_for(
  67. lock, std::chrono::seconds(1), [&](){ return lambda_invoked; }
  68. );
  69. BOOST_CHECK_EQUAL(lambda_invoked, true);
  70. }
  71. BOOST_AUTO_TEST_CASE(future_then_callback)
  72. {
  73. REQUIRES_OPENCL_VERSION(1,2);
  74. bool callback_invoked = false;
  75. boost::compute::future<void> future(queue.enqueue_marker());
  76. future.then([&](){
  77. std::lock_guard<std::mutex> lock(callback_mutex);
  78. callback_invoked = true;
  79. callback_condition_variable.notify_one();
  80. });
  81. future.wait();
  82. // wait up to one second for the callback to be executed
  83. std::unique_lock<std::mutex> lock(callback_mutex);
  84. callback_condition_variable.wait_for(
  85. lock, std::chrono::seconds(1), [&](){ return callback_invoked; }
  86. );
  87. BOOST_CHECK_EQUAL(callback_invoked, true);
  88. }
  89. void BOOST_COMPUTE_CL_CALLBACK
  90. event_promise_fulfiller_callback(cl_event event, cl_int status, void *user_data)
  91. {
  92. auto *promise = static_cast<std::promise<void> *>(user_data);
  93. promise->set_value();
  94. delete promise;
  95. }
  96. BOOST_AUTO_TEST_CASE(event_to_std_future)
  97. {
  98. REQUIRES_OPENCL_VERSION(1,2);
  99. // enqueue an asynchronous copy to the device
  100. std::vector<float> vector(1000, 3.14f);
  101. boost::compute::buffer buffer(context, 1000 * sizeof(float));
  102. auto event = queue.enqueue_write_buffer_async(
  103. buffer, 0, 1000 * sizeof(float), vector.data()
  104. );
  105. // create a promise and future to be set by the callback
  106. auto *promise = new std::promise<void>;
  107. std::future<void> future = promise->get_future();
  108. event.set_callback(event_promise_fulfiller_callback, CL_COMPLETE, promise);
  109. // ensure commands are submitted to the device before waiting
  110. queue.flush();
  111. // wait for future to become ready
  112. future.wait();
  113. }
  114. #endif // BOOST_COMPUTE_CL_VERSION_1_1
  115. BOOST_AUTO_TEST_SUITE_END()