test_buffer.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013 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 TestBuffer
  11. #include <boost/test/unit_test.hpp>
  12. #include <boost/compute/buffer.hpp>
  13. #include <boost/compute/system.hpp>
  14. #include <boost/bind.hpp>
  15. #ifdef BOOST_COMPUTE_USE_CPP11
  16. #include <mutex>
  17. #include <future>
  18. #endif // BOOST_COMPUTE_USE_CPP11
  19. #include "quirks.hpp"
  20. #include "context_setup.hpp"
  21. namespace bc = boost::compute;
  22. BOOST_AUTO_TEST_CASE(size)
  23. {
  24. bc::buffer buffer(context, 100);
  25. BOOST_CHECK_EQUAL(buffer.size(), size_t(100));
  26. BOOST_VERIFY(buffer.max_size() > buffer.size());
  27. }
  28. BOOST_AUTO_TEST_CASE(cl_context)
  29. {
  30. bc::buffer buffer(context, 100);
  31. BOOST_VERIFY(buffer.get_context() == context);
  32. }
  33. BOOST_AUTO_TEST_CASE(equality_operator)
  34. {
  35. bc::buffer a(context, 10);
  36. bc::buffer b(context, 10);
  37. BOOST_VERIFY(a == a);
  38. BOOST_VERIFY(b == b);
  39. BOOST_VERIFY(!(a == b));
  40. BOOST_VERIFY(a != b);
  41. a = b;
  42. BOOST_VERIFY(a == b);
  43. BOOST_VERIFY(!(a != b));
  44. }
  45. BOOST_AUTO_TEST_CASE(construct_from_cl_mem)
  46. {
  47. // create cl_mem
  48. cl_mem mem = clCreateBuffer(context, CL_MEM_READ_WRITE, 16, 0, 0);
  49. BOOST_VERIFY(mem);
  50. // create boost::compute::buffer
  51. boost::compute::buffer buffer(mem);
  52. // check buffer
  53. BOOST_CHECK(buffer.get() == mem);
  54. BOOST_CHECK(buffer.get_context() == context);
  55. BOOST_CHECK_EQUAL(buffer.size(), size_t(16));
  56. // cleanup cl_mem
  57. clReleaseMemObject(mem);
  58. }
  59. BOOST_AUTO_TEST_CASE(reference_count)
  60. {
  61. using boost::compute::uint_;
  62. boost::compute::buffer buf(context, 16);
  63. BOOST_CHECK_GE(buf.reference_count(), uint_(1));
  64. }
  65. BOOST_AUTO_TEST_CASE(get_size)
  66. {
  67. boost::compute::buffer buf(context, 16);
  68. BOOST_CHECK_EQUAL(buf.size(), size_t(16));
  69. BOOST_CHECK_EQUAL(buf.get_info<CL_MEM_SIZE>(), size_t(16));
  70. BOOST_CHECK_EQUAL(buf.get_info<size_t>(CL_MEM_SIZE), size_t(16));
  71. }
  72. #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
  73. BOOST_AUTO_TEST_CASE(move_constructor)
  74. {
  75. boost::compute::buffer buffer1(context, 16);
  76. BOOST_CHECK(buffer1.get() != 0);
  77. BOOST_CHECK_EQUAL(buffer1.size(), size_t(16));
  78. boost::compute::buffer buffer2(std::move(buffer1));
  79. BOOST_CHECK(buffer1.get() == 0);
  80. BOOST_CHECK(buffer2.get() != 0);
  81. BOOST_CHECK_EQUAL(buffer2.size(), size_t(16));
  82. }
  83. #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
  84. BOOST_AUTO_TEST_CASE(clone_buffer)
  85. {
  86. boost::compute::buffer buffer1(context, 16);
  87. boost::compute::buffer buffer2 = buffer1.clone(queue);
  88. BOOST_CHECK(buffer1.get() != buffer2.get());
  89. BOOST_CHECK_EQUAL(buffer1.size(), buffer2.size());
  90. BOOST_CHECK(buffer1.get_memory_flags() == buffer2.get_memory_flags());
  91. }
  92. #ifdef BOOST_COMPUTE_CL_VERSION_1_1
  93. #ifdef BOOST_COMPUTE_USE_CPP11
  94. std::mutex callback_mutex;
  95. std::condition_variable callback_condition_variable;
  96. static void BOOST_COMPUTE_CL_CALLBACK
  97. destructor_callback_function(cl_mem, void *user_data)
  98. {
  99. std::lock_guard<std::mutex> lock(callback_mutex);
  100. bool *flag = static_cast<bool *>(user_data);
  101. *flag = true;
  102. callback_condition_variable.notify_one();
  103. }
  104. BOOST_AUTO_TEST_CASE(destructor_callback)
  105. {
  106. REQUIRES_OPENCL_VERSION(1,2);
  107. if(!supports_destructor_callback(device))
  108. {
  109. return;
  110. }
  111. bool invoked = false;
  112. {
  113. boost::compute::buffer buf(context, 128);
  114. buf.set_destructor_callback(destructor_callback_function, &invoked);
  115. }
  116. std::unique_lock<std::mutex> lock(callback_mutex);
  117. callback_condition_variable.wait_for(
  118. lock, std::chrono::seconds(1), [&](){ return invoked; }
  119. );
  120. BOOST_CHECK(invoked == true);
  121. }
  122. static void BOOST_COMPUTE_CL_CALLBACK
  123. destructor_templated_callback_function(bool *flag)
  124. {
  125. std::lock_guard<std::mutex> lock(callback_mutex);
  126. *flag = true;
  127. callback_condition_variable.notify_one();
  128. }
  129. BOOST_AUTO_TEST_CASE(destructor_templated_callback)
  130. {
  131. REQUIRES_OPENCL_VERSION(1,2);
  132. if(!supports_destructor_callback(device))
  133. {
  134. return;
  135. }
  136. bool invoked = false;
  137. {
  138. boost::compute::buffer buf(context, 128);
  139. buf.set_destructor_callback(boost::bind(destructor_templated_callback_function, &invoked));
  140. }
  141. std::unique_lock<std::mutex> lock(callback_mutex);
  142. callback_condition_variable.wait_for(
  143. lock, std::chrono::seconds(1), [&](){ return invoked; }
  144. );
  145. BOOST_CHECK(invoked == true);
  146. }
  147. #endif // BOOST_COMPUTE_USE_CPP11
  148. BOOST_AUTO_TEST_CASE(create_subbuffer)
  149. {
  150. REQUIRES_OPENCL_VERSION(1, 1);
  151. size_t base_addr_align = device.get_info<CL_DEVICE_MEM_BASE_ADDR_ALIGN>() / 8;
  152. size_t multiplier = 16;
  153. size_t buffer_size = base_addr_align * multiplier;
  154. size_t subbuffer_size = 64;
  155. boost::compute::buffer buffer(context, buffer_size);
  156. for(size_t i = 0; i < multiplier; ++i)
  157. {
  158. boost::compute::buffer subbuffer = buffer.create_subbuffer(
  159. boost::compute::buffer::read_write, base_addr_align * i, subbuffer_size);
  160. BOOST_CHECK(buffer.get() != subbuffer.get());
  161. BOOST_CHECK_EQUAL(subbuffer.size(), subbuffer_size);
  162. }
  163. }
  164. #endif // BOOST_COMPUTE_CL_VERSION_1_1
  165. BOOST_AUTO_TEST_CASE(create_buffer_doctest)
  166. {
  167. //! [constructor]
  168. boost::compute::buffer buf(context, 32 * sizeof(float));
  169. //! [constructor]
  170. BOOST_CHECK_EQUAL(buf.size(), 32 * sizeof(float));
  171. }
  172. BOOST_AUTO_TEST_SUITE_END()