test_accumulate.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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 TestAccumulate
  11. #include <boost/test/unit_test.hpp>
  12. #include <numeric>
  13. #include <boost/compute/command_queue.hpp>
  14. #include <boost/compute/algorithm/accumulate.hpp>
  15. #include <boost/compute/algorithm/iota.hpp>
  16. #include <boost/compute/container/mapped_view.hpp>
  17. #include <boost/compute/container/vector.hpp>
  18. #include <boost/compute/iterator/counting_iterator.hpp>
  19. #include "context_setup.hpp"
  20. BOOST_AUTO_TEST_CASE(sum_int)
  21. {
  22. int data[] = { 2, 4, 6, 8 };
  23. boost::compute::vector<int> vector(data, data + 4, queue);
  24. BOOST_CHECK_EQUAL(
  25. boost::compute::accumulate(vector.begin(), vector.end(), 0, queue),
  26. 20
  27. );
  28. BOOST_CHECK_EQUAL(
  29. boost::compute::accumulate(vector.begin(), vector.end(), -10, queue),
  30. 10
  31. );
  32. BOOST_CHECK_EQUAL(
  33. boost::compute::accumulate(vector.begin(), vector.end(), 5, queue),
  34. 25
  35. );
  36. }
  37. BOOST_AUTO_TEST_CASE(product_int)
  38. {
  39. int data[] = { 2, 4, 6, 8 };
  40. boost::compute::vector<int> vector(data, data + 4, queue);
  41. BOOST_CHECK_EQUAL(
  42. boost::compute::accumulate(
  43. vector.begin(), vector.end(), 1, boost::compute::multiplies<int>(),
  44. queue),
  45. 384
  46. );
  47. BOOST_CHECK_EQUAL(
  48. boost::compute::accumulate(
  49. vector.begin(), vector.end(), -1, boost::compute::multiplies<int>(),
  50. queue),
  51. -384
  52. );
  53. BOOST_CHECK_EQUAL(
  54. boost::compute::accumulate(
  55. vector.begin(), vector.end(), 2, boost::compute::multiplies<int>(),
  56. queue),
  57. 768
  58. );
  59. }
  60. BOOST_AUTO_TEST_CASE(quotient_int)
  61. {
  62. int data[] = { 2, 8, 16 };
  63. boost::compute::vector<int> vector(data, data + 3, queue);
  64. BOOST_CHECK_EQUAL(
  65. boost::compute::accumulate(
  66. vector.begin(),
  67. vector.end(),
  68. 1024,
  69. boost::compute::divides<int>(),
  70. queue
  71. ),
  72. 4
  73. );
  74. }
  75. BOOST_AUTO_TEST_CASE(sum_counting_iterator)
  76. {
  77. // sum 0 -> 9
  78. BOOST_CHECK_EQUAL(
  79. boost::compute::accumulate(
  80. boost::compute::make_counting_iterator(0),
  81. boost::compute::make_counting_iterator(10),
  82. 0,
  83. boost::compute::plus<int>(),
  84. queue
  85. ),
  86. 45
  87. );
  88. // sum 0 -> 9 + 7
  89. BOOST_CHECK_EQUAL(
  90. boost::compute::accumulate(
  91. boost::compute::make_counting_iterator(0),
  92. boost::compute::make_counting_iterator(10),
  93. 7,
  94. boost::compute::plus<int>(),
  95. queue
  96. ),
  97. 52
  98. );
  99. // sum 15 -> 24
  100. BOOST_CHECK_EQUAL(
  101. boost::compute::accumulate(
  102. boost::compute::make_counting_iterator(15),
  103. boost::compute::make_counting_iterator(25),
  104. 0,
  105. boost::compute::plus<int>(),
  106. queue
  107. ),
  108. 195
  109. );
  110. // sum -5 -> 10
  111. BOOST_CHECK_EQUAL(
  112. boost::compute::accumulate(
  113. boost::compute::make_counting_iterator(-5),
  114. boost::compute::make_counting_iterator(10),
  115. 0,
  116. boost::compute::plus<int>(),
  117. queue
  118. ),
  119. 30
  120. );
  121. // sum -5 -> 10 - 2
  122. BOOST_CHECK_EQUAL(
  123. boost::compute::accumulate(
  124. boost::compute::make_counting_iterator(-5),
  125. boost::compute::make_counting_iterator(10),
  126. -2,
  127. boost::compute::plus<int>(),
  128. queue
  129. ),
  130. 28
  131. );
  132. }
  133. BOOST_AUTO_TEST_CASE(sum_iota)
  134. {
  135. // size 0
  136. boost::compute::vector<int> vector(0, context);
  137. BOOST_CHECK_EQUAL(
  138. boost::compute::accumulate(vector.begin(), vector.end(), 0, queue),
  139. 0
  140. );
  141. BOOST_CHECK_EQUAL(
  142. boost::compute::accumulate(vector.begin(), vector.end(), 4, queue),
  143. 4
  144. );
  145. // size 50
  146. vector.resize(50);
  147. boost::compute::iota(vector.begin(), vector.end(), 0, queue);
  148. BOOST_CHECK_EQUAL(
  149. boost::compute::accumulate(vector.begin(), vector.end(), 0, queue),
  150. 1225
  151. );
  152. BOOST_CHECK_EQUAL(
  153. boost::compute::accumulate(vector.begin(), vector.end(), 11, queue),
  154. 1236
  155. );
  156. // size 1000
  157. vector.resize(1000);
  158. boost::compute::iota(vector.begin(), vector.end(), 0, queue);
  159. BOOST_CHECK_EQUAL(
  160. boost::compute::accumulate(vector.begin(), vector.end(), 0, queue),
  161. 499500
  162. );
  163. BOOST_CHECK_EQUAL(
  164. boost::compute::accumulate(vector.begin(), vector.end(), -45, queue),
  165. 499455
  166. );
  167. // size 1025
  168. vector.resize(1025);
  169. boost::compute::iota(vector.begin(), vector.end(), 0, queue);
  170. BOOST_CHECK_EQUAL(
  171. boost::compute::accumulate(vector.begin(), vector.end(), 0, queue),
  172. 524800
  173. );
  174. BOOST_CHECK_EQUAL(
  175. boost::compute::accumulate(vector.begin(), vector.end(), 2, queue),
  176. 524802
  177. );
  178. }
  179. BOOST_AUTO_TEST_CASE(min_and_max)
  180. {
  181. using boost::compute::int2_;
  182. int data[] = { 5, 3, 1, 6, 4, 2 };
  183. boost::compute::vector<int> vector(data, data + 6, queue);
  184. BOOST_COMPUTE_FUNCTION(int2_, min_and_max, (int2_ accumulator, const int value),
  185. {
  186. return (int2)((min)(accumulator.x, value), (max)(accumulator.y, value));
  187. });
  188. int2_ result = boost::compute::accumulate(
  189. vector.begin(), vector.end(), int2_(100, -100), min_and_max, queue
  190. );
  191. BOOST_CHECK_EQUAL(result[0], 1);
  192. BOOST_CHECK_EQUAL(result[1], 6);
  193. }
  194. BOOST_AUTO_TEST_CASE(min_max)
  195. {
  196. float data[] = { 1.2f, 5.5f, 0.1f, 9.6f, 4.2f, 6.7f, 9.0f, 3.4f };
  197. boost::compute::vector<float> vec(data, data + 8, queue);
  198. using ::boost::compute::min;
  199. using ::boost::compute::max;
  200. float min_value = boost::compute::accumulate(
  201. vec.begin(), vec.end(), (std::numeric_limits<float>::max)(), min<float>(), queue
  202. );
  203. BOOST_CHECK_EQUAL(min_value, 0.1f);
  204. float max_value = boost::compute::accumulate(
  205. vec.begin(), vec.end(), (std::numeric_limits<float>::min)(), max<float>(), queue
  206. );
  207. BOOST_CHECK_EQUAL(max_value, 9.6f);
  208. // find min with init less than any value in the array
  209. min_value = boost::compute::accumulate(
  210. vec.begin(), vec.end(), -1.f, min<float>(), queue
  211. );
  212. BOOST_CHECK_EQUAL(min_value, -1.f);
  213. // find max with init greater than any value in the array
  214. max_value = boost::compute::accumulate(
  215. vec.begin(), vec.end(), 10.f, max<float>(), queue
  216. );
  217. BOOST_CHECK_EQUAL(max_value, 10.f);
  218. }
  219. template<class T>
  220. void ensure_std_accumulate_equality(const std::vector<T> &data,
  221. boost::compute::command_queue &queue)
  222. {
  223. boost::compute::mapped_view<T> view(&data[0], data.size(), queue.get_context());
  224. BOOST_CHECK_EQUAL(
  225. std::accumulate(data.begin(), data.end(), 0),
  226. boost::compute::accumulate(view.begin(), view.end(), 0, queue)
  227. );
  228. }
  229. BOOST_AUTO_TEST_CASE(std_accumulate_equality)
  230. {
  231. // test accumulate() with int
  232. int data1[] = { 1, 2, 3, 4 };
  233. std::vector<int> vec1(data1, data1 + 4);
  234. ensure_std_accumulate_equality(vec1, queue);
  235. vec1.resize(10000);
  236. std::fill(vec1.begin(), vec1.end(), 2);
  237. ensure_std_accumulate_equality(vec1, queue);
  238. // test accumulate() with float
  239. float data2[] = { 1.2f, 2.3f, 4.5f, 6.7f, 8.9f };
  240. std::vector<float> vec2(data2, data2 + 5);
  241. ensure_std_accumulate_equality(vec2, queue);
  242. vec2.resize(10000);
  243. std::fill(vec2.begin(), vec2.end(), 1.01f);
  244. ensure_std_accumulate_equality(vec2, queue);
  245. // test accumulate() with double
  246. if(device.supports_extension("cl_khr_fp64")){
  247. double data3[] = { 1.2, 2.3, 4.5, 6.7, 8.9 };
  248. std::vector<double> vec3(data3, data3 + 5);
  249. ensure_std_accumulate_equality(vec3, queue);
  250. vec3.resize(10000);
  251. std::fill(vec3.begin(), vec3.end(), 2.02);
  252. ensure_std_accumulate_equality(vec3, queue);
  253. }
  254. }
  255. BOOST_AUTO_TEST_SUITE_END()