test_valarray.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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 TestValarray
  11. #include <boost/test/unit_test.hpp>
  12. #include <boost/compute/system.hpp>
  13. #include <boost/compute/command_queue.hpp>
  14. #include <boost/compute/container/valarray.hpp>
  15. #include "check_macros.hpp"
  16. #include "context_setup.hpp"
  17. BOOST_AUTO_TEST_CASE(size)
  18. {
  19. boost::compute::valarray<float> array;
  20. BOOST_CHECK_EQUAL(array.size(), size_t(0));
  21. array.resize(10);
  22. BOOST_CHECK_EQUAL(array.size(), size_t(10));
  23. }
  24. BOOST_AUTO_TEST_CASE(at)
  25. {
  26. int data[] = { 1, 2, 3, 4, 5 };
  27. boost::compute::valarray<int> array(data, 5);
  28. BOOST_CHECK_EQUAL(array.size(), size_t(5));
  29. boost::compute::system::finish();
  30. BOOST_CHECK_EQUAL(int(array[0]), int(1));
  31. BOOST_CHECK_EQUAL(int(array[1]), int(2));
  32. BOOST_CHECK_EQUAL(int(array[2]), int(3));
  33. BOOST_CHECK_EQUAL(int(array[3]), int(4));
  34. BOOST_CHECK_EQUAL(int(array[4]), int(5));
  35. }
  36. BOOST_AUTO_TEST_CASE(min_and_max)
  37. {
  38. int data[] = { 5, 2, 3, 7, 1, 9, 6, 5 };
  39. boost::compute::valarray<int> array(data, 8);
  40. BOOST_CHECK_EQUAL(array.size(), size_t(8));
  41. BOOST_CHECK_EQUAL((array.min)(), int(1));
  42. BOOST_CHECK_EQUAL((array.max)(), int(9));
  43. }
  44. BOOST_AUTO_TEST_CASE(sum)
  45. {
  46. int data[] = { 1, 2, 3, 4 };
  47. boost::compute::valarray<int> array(data, 4);
  48. boost::compute::system::finish();
  49. BOOST_CHECK_EQUAL(array.size(), size_t(4));
  50. BOOST_CHECK_EQUAL(array.sum(), int(10));
  51. }
  52. BOOST_AUTO_TEST_CASE(apply)
  53. {
  54. int data[] = { -1, 2, -3, 4 };
  55. boost::compute::valarray<int> array(data, 4);
  56. boost::compute::abs<int> abs;
  57. boost::compute::valarray<int> result = array.apply(abs);
  58. boost::compute::system::finish();
  59. BOOST_CHECK_EQUAL(int(result[0]), int(1));
  60. BOOST_CHECK_EQUAL(int(result[1]), int(2));
  61. BOOST_CHECK_EQUAL(int(result[2]), int(3));
  62. BOOST_CHECK_EQUAL(int(result[3]), int(4));
  63. }
  64. /// \internal_
  65. /// Tests for compound assignment operators that works for floating
  66. /// point types.
  67. #define BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(op, op_name) \
  68. BOOST_AUTO_TEST_CASE(op_name##_ca_operator_no_fp) \
  69. { \
  70. float data[] = { 1, 2, 3, 4 }; \
  71. boost::compute::valarray<float> array1(data, 4); \
  72. boost::compute::valarray<float> array2(data, 4); \
  73. boost::compute::system::finish(); \
  74. \
  75. array1 op##= 1; \
  76. boost::compute::system::finish(); \
  77. BOOST_CHECK_CLOSE(float(array1[0]), float(1.0f op 1.0f), 1e-4f); \
  78. BOOST_CHECK_CLOSE(float(array1[1]), float(2.0f op 1.0f), 1e-4f); \
  79. BOOST_CHECK_CLOSE(float(array1[2]), float(3.0f op 1.0f), 1e-4f); \
  80. BOOST_CHECK_CLOSE(float(array1[3]), float(4.0f op 1.0f), 1e-4f); \
  81. \
  82. array1 = boost::compute::valarray<float>(data, 4); \
  83. boost::compute::system::finish(); \
  84. \
  85. array1 op##= array2; \
  86. boost::compute::system::finish(); \
  87. BOOST_CHECK_CLOSE(float(array1[0]), float(1.0f op 1.0f), 1e-4f); \
  88. BOOST_CHECK_CLOSE(float(array1[1]), float(2.0f op 2.0f), 1e-4f); \
  89. BOOST_CHECK_CLOSE(float(array1[2]), float(3.0f op 3.0f), 1e-4f); \
  90. BOOST_CHECK_CLOSE(float(array1[3]), float(4.0f op 4.0f), 1e-4f); \
  91. \
  92. array2 op##= array2; \
  93. boost::compute::system::finish(); \
  94. BOOST_CHECK_CLOSE(float(array2[0]), float(1.0f op 1.0f), 1e-4f); \
  95. BOOST_CHECK_CLOSE(float(array2[1]), float(2.0f op 2.0f), 1e-4f); \
  96. BOOST_CHECK_CLOSE(float(array2[2]), float(3.0f op 3.0f), 1e-4f); \
  97. BOOST_CHECK_CLOSE(float(array2[3]), float(4.0f op 4.0f), 1e-4f); \
  98. \
  99. }
  100. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(+, plus)
  101. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(-, minus)
  102. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(*, multiplies)
  103. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT(/, divides)
  104. #undef BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT
  105. /// \internal_
  106. /// Tests for compound assignment operators that does NOT work for floating
  107. /// point types.
  108. /// Note: modulo operator works only for integer types.
  109. #define BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(op, op_name) \
  110. BOOST_AUTO_TEST_CASE(op_name##_ca_operator) \
  111. { \
  112. int data[] = { 1, 2, 3, 4 }; \
  113. boost::compute::valarray<int> array1(data, 4); \
  114. boost::compute::valarray<int> array2(data, 4); \
  115. boost::compute::system::finish(); \
  116. \
  117. array1 op##= 1; \
  118. boost::compute::system::finish(); \
  119. BOOST_CHECK_EQUAL(int(array1[0]), int(1 op 1)); \
  120. BOOST_CHECK_EQUAL(int(array1[1]), int(2 op 1)); \
  121. BOOST_CHECK_EQUAL(int(array1[2]), int(3 op 1)); \
  122. BOOST_CHECK_EQUAL(int(array1[3]), int(4 op 1)); \
  123. \
  124. array1 = boost::compute::valarray<int>(data, 4); \
  125. boost::compute::system::finish(); \
  126. \
  127. array1 op##= array2; \
  128. boost::compute::system::finish(); \
  129. BOOST_CHECK_EQUAL(int(array1[0]), int(1 op 1)); \
  130. BOOST_CHECK_EQUAL(int(array1[1]), int(2 op 2)); \
  131. BOOST_CHECK_EQUAL(int(array1[2]), int(3 op 3)); \
  132. BOOST_CHECK_EQUAL(int(array1[3]), int(4 op 4)); \
  133. \
  134. array2 op##= array2; \
  135. boost::compute::system::finish(); \
  136. BOOST_CHECK_EQUAL(int(array2[0]), int(1 op 1)); \
  137. BOOST_CHECK_EQUAL(int(array2[1]), int(2 op 2)); \
  138. BOOST_CHECK_EQUAL(int(array2[2]), int(3 op 3)); \
  139. BOOST_CHECK_EQUAL(int(array2[3]), int(4 op 4)); \
  140. \
  141. }
  142. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(%, modulus)
  143. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(^, bit_xor)
  144. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(&, bit_and)
  145. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(|, bit_or)
  146. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(<<, shift_left)
  147. BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP(>>, shift_right)
  148. #undef BOOST_COMPUTE_TEST_VALARRAY_COMPOUND_ASSIGNMENT_NO_FP
  149. BOOST_AUTO_TEST_CASE(unary_plus_operator)
  150. {
  151. int data[] = { 1, 2, 3, 4 };
  152. boost::compute::valarray<int> array(data, 4);
  153. boost::compute::system::finish();
  154. boost::compute::valarray<int> result = +array;
  155. boost::compute::system::finish();
  156. BOOST_CHECK_EQUAL(int(result[0]), +(int(1)));
  157. BOOST_CHECK_EQUAL(int(result[1]), +(int(2)));
  158. BOOST_CHECK_EQUAL(int(result[2]), +(int(3)));
  159. BOOST_CHECK_EQUAL(int(result[3]), +(int(4)));
  160. }
  161. BOOST_AUTO_TEST_CASE(unary_minus_operator)
  162. {
  163. int data[] = { -1, 2, 0, 4 };
  164. boost::compute::valarray<int> array(data, 4);
  165. boost::compute::system::finish();
  166. boost::compute::valarray<int> result = -array;
  167. boost::compute::system::finish();
  168. BOOST_CHECK_EQUAL(int(result[0]), int(1));
  169. BOOST_CHECK_EQUAL(int(result[1]), int(-2));
  170. BOOST_CHECK_EQUAL(int(result[2]), int(0));
  171. BOOST_CHECK_EQUAL(int(result[3]), int(-4));
  172. }
  173. BOOST_AUTO_TEST_CASE(unary_bitwise_not_operator)
  174. {
  175. int data[] = { 1, 2, 3, 4 };
  176. boost::compute::valarray<int> array(data, 4);
  177. boost::compute::system::finish();
  178. boost::compute::valarray<int> result = ~array;
  179. boost::compute::system::finish();
  180. BOOST_CHECK_EQUAL(int(result[0]), ~(int(1)));
  181. BOOST_CHECK_EQUAL(int(result[1]), ~(int(2)));
  182. BOOST_CHECK_EQUAL(int(result[2]), ~(int(3)));
  183. BOOST_CHECK_EQUAL(int(result[3]), ~(int(4)));
  184. }
  185. BOOST_AUTO_TEST_CASE(unary_logical_not_operator)
  186. {
  187. int data[] = { 1, -2, 0, 4 };
  188. boost::compute::valarray<int> array(data, 4);
  189. boost::compute::system::finish();
  190. boost::compute::valarray<char> result = !array;
  191. boost::compute::system::finish();
  192. BOOST_CHECK_EQUAL(bool(result[0]), !(int(1)));
  193. BOOST_CHECK_EQUAL(bool(result[1]), !(int(-2)));
  194. BOOST_CHECK_EQUAL(bool(result[2]), !(int(0)));
  195. BOOST_CHECK_EQUAL(bool(result[3]), !(int(4)));
  196. }
  197. /// \internal_
  198. /// Tests for binary operators that works for floating
  199. /// point types.
  200. #define BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(op, op_name) \
  201. BOOST_AUTO_TEST_CASE(op_name##_binary_operator) \
  202. { \
  203. float data1[] = { 1, 2, 3, 4 }; \
  204. float data2[] = { 4, 2, 3, 0 }; \
  205. boost::compute::valarray<float> array1(data1, 4); \
  206. boost::compute::valarray<float> array2(data2, 4); \
  207. boost::compute::system::finish(); \
  208. \
  209. boost::compute::valarray<float> result = 2.0f op array1; \
  210. boost::compute::system::finish(); \
  211. BOOST_CHECK_CLOSE(float(result[0]), float(2.0f op 1.0f), 1e-4f); \
  212. BOOST_CHECK_CLOSE(float(result[1]), float(2.0f op 2.0f), 1e-4f); \
  213. BOOST_CHECK_CLOSE(float(result[2]), float(2.0f op 3.0f), 1e-4f); \
  214. BOOST_CHECK_CLOSE(float(result[3]), float(2.0f op 4.0f), 1e-4f); \
  215. \
  216. result = array1 op 2.0f; \
  217. boost::compute::system::finish(); \
  218. BOOST_CHECK_CLOSE(float(result[0]), float(1.0f op 2.0f), 1e-4f); \
  219. BOOST_CHECK_CLOSE(float(result[1]), float(2.0f op 2.0f), 1e-4f); \
  220. BOOST_CHECK_CLOSE(float(result[2]), float(3.0f op 2.0f), 1e-4f); \
  221. BOOST_CHECK_CLOSE(float(result[3]), float(4.0f op 2.0f), 1e-4f); \
  222. \
  223. result = array2 op array1; \
  224. boost::compute::system::finish(); \
  225. BOOST_CHECK_CLOSE(float(result[0]), float(4.0f op 1.0f), 1e-4f); \
  226. BOOST_CHECK_CLOSE(float(result[1]), float(2.0f op 2.0f), 1e-4f); \
  227. BOOST_CHECK_CLOSE(float(result[2]), float(3.0f op 3.0f), 1e-4f); \
  228. BOOST_CHECK_CLOSE(float(result[3]), float(0.0f op 4.0f), 1e-4f); \
  229. }
  230. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(+, plus)
  231. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(-, minus)
  232. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(*, multiplies)
  233. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR(/, divides)
  234. #undef BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR
  235. /// \internal_
  236. /// Tests for compound assignment operators that does NOT work for floating
  237. /// point types.
  238. /// Note: modulo operator works only for integer types.
  239. #define BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(op, op_name) \
  240. BOOST_AUTO_TEST_CASE(op_name##_binary_operator) \
  241. { \
  242. int data1[] = { 1, 2, 3, 4 }; \
  243. int data2[] = { 4, 5, 2, 1 }; \
  244. boost::compute::valarray<int> array1(data1, 4); \
  245. boost::compute::valarray<int> array2(data2, 4); \
  246. boost::compute::system::finish(); \
  247. \
  248. boost::compute::valarray<int> result = 5 op array1; \
  249. boost::compute::system::finish(); \
  250. BOOST_CHECK_EQUAL(int(result[0]), int(5 op 1)); \
  251. BOOST_CHECK_EQUAL(int(result[1]), int(5 op 2)); \
  252. BOOST_CHECK_EQUAL(int(result[2]), int(5 op 3)); \
  253. BOOST_CHECK_EQUAL(int(result[3]), int(5 op 4)); \
  254. \
  255. result = array1 op 5; \
  256. boost::compute::system::finish(); \
  257. BOOST_CHECK_EQUAL(int(result[0]), int(1 op 5)); \
  258. BOOST_CHECK_EQUAL(int(result[1]), int(2 op 5)); \
  259. BOOST_CHECK_EQUAL(int(result[2]), int(3 op 5)); \
  260. BOOST_CHECK_EQUAL(int(result[3]), int(4 op 5)); \
  261. \
  262. result = array1 op array2; \
  263. boost::compute::system::finish(); \
  264. BOOST_CHECK_EQUAL(int(result[0]), int(1 op 4)); \
  265. BOOST_CHECK_EQUAL(int(result[1]), int(2 op 5)); \
  266. BOOST_CHECK_EQUAL(int(result[2]), int(3 op 2)); \
  267. BOOST_CHECK_EQUAL(int(result[3]), int(4 op 1)); \
  268. }
  269. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(^, bit_xor)
  270. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(&, bit_and)
  271. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(|, bit_or)
  272. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(<<, shift_left)
  273. BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP(>>, shift_right)
  274. #undef BOOST_COMPUTE_TEST_VALARRAY_BINARY_OPERATOR_NO_FP
  275. /// \internal_
  276. /// Macro for generating tests for valarray comparison operators.
  277. #define BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(op, op_name) \
  278. BOOST_AUTO_TEST_CASE(op_name##_comparision_operator) \
  279. { \
  280. int data1[] = { 1, 2, 0, 4 }; \
  281. int data2[] = { 4, 0, 2, 1 }; \
  282. boost::compute::valarray<int> array1(data1, 4); \
  283. boost::compute::valarray<int> array2(data2, 4); \
  284. boost::compute::system::finish(); \
  285. \
  286. boost::compute::valarray<char> result = 2 op array1; \
  287. boost::compute::system::finish(); \
  288. BOOST_CHECK_EQUAL(bool(result[0]), bool(2 op 1)); \
  289. BOOST_CHECK_EQUAL(bool(result[1]), bool(2 op 2)); \
  290. BOOST_CHECK_EQUAL(bool(result[2]), bool(2 op 0)); \
  291. BOOST_CHECK_EQUAL(bool(result[3]), bool(2 op 4)); \
  292. \
  293. result = array1 op 2; \
  294. boost::compute::system::finish(); \
  295. BOOST_CHECK_EQUAL(bool(result[0]), bool(1 op 2)); \
  296. BOOST_CHECK_EQUAL(bool(result[1]), bool(2 op 2)); \
  297. BOOST_CHECK_EQUAL(bool(result[2]), bool(0 op 2)); \
  298. BOOST_CHECK_EQUAL(bool(result[3]), bool(4 op 2)); \
  299. \
  300. result = array1 op array2; \
  301. boost::compute::system::finish(); \
  302. BOOST_CHECK_EQUAL(bool(result[0]), bool(1 op 4)); \
  303. BOOST_CHECK_EQUAL(bool(result[1]), bool(2 op 0)); \
  304. BOOST_CHECK_EQUAL(bool(result[2]), bool(0 op 2)); \
  305. BOOST_CHECK_EQUAL(bool(result[3]), bool(4 op 1)); \
  306. }
  307. BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(==, equal_to)
  308. BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(!=, not_equal_to)
  309. BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(>, greater)
  310. BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(<, less)
  311. BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(>=, greater_equal)
  312. BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(<=, less_equal)
  313. /// \internal_
  314. /// Macro for generating tests for valarray binary logical operators.
  315. #define BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR(op, op_name) \
  316. BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR(op, op_name)
  317. BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR(&&, logical_and)
  318. BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR(||, logical_or)
  319. #undef BOOST_COMPUTE_TEST_VALARRAY_LOGICAL_OPERATOR
  320. #undef BOOST_COMPUTE_TEST_VALARRAY_COMPARISON_OPERATOR
  321. BOOST_AUTO_TEST_SUITE_END()