From f29bbda7f89ee7cc7bb89309a7a4f7f5dcc7d592 Mon Sep 17 00:00:00 2001 From: Jakub Szuppe Date: Sat, 23 Apr 2016 18:06:21 +0200 Subject: [PATCH] Tests for radix sort in desc order --- test/test_radix_sort.cpp | 263 ++++++++++++++++++++++++++++++++ test/test_radix_sort_by_key.cpp | 109 +++++++++++++ 2 files changed, 372 insertions(+) diff --git a/test/test_radix_sort.cpp b/test/test_radix_sort.cpp index ffa8725c..c22845f7 100644 --- a/test/test_radix_sort.cpp +++ b/test/test_radix_sort.cpp @@ -21,6 +21,8 @@ namespace bc = boost::compute; +const bool descending = false; + BOOST_AUTO_TEST_CASE(sort_char_vector) { using boost::compute::char_; @@ -177,6 +179,267 @@ BOOST_AUTO_TEST_CASE(sort_double_vector) ); } +BOOST_AUTO_TEST_CASE(sort_char_vector_desc) +{ + using boost::compute::char_; + + char_ data[] = { 'c', 'a', '0', '7', 'B', 'F', '\0', '$' }; + boost::compute::vector vector(data, data + 8, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(8)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + char_, 8, vector, + ('c', 'a', 'F', 'B', '7', '0', '$', '\0') + ); +} + +BOOST_AUTO_TEST_CASE(sort_uchar_vector_desc) +{ + using boost::compute::uchar_; + + uchar_ data[] = { 0x12, 0x00, 0xFF, 0xB4, 0x80, 0x32, 0x64, 0xA2 }; + boost::compute::vector vector(data, data + 8, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(8)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + uchar_, 8, vector, + (0xFF, 0xB4, 0xA2, 0x80, 0x64, 0x32, 0x12, 0x00) + ); +} + +BOOST_AUTO_TEST_CASE(sort_short_vector_desc) +{ + using boost::compute::short_; + + short_ data[] = { -4, 152, -94, 963, 31002, -456, 0, -2113 }; + boost::compute::vector vector(data, data + 8, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(8)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + short_, 8, vector, + (31002, 963, 152, 0, -4, -94, -456, -2113) + ); +} + +BOOST_AUTO_TEST_CASE(sort_ushort_vector_desc) +{ + using boost::compute::ushort_; + + ushort_ data[] = { 4, 152, 94, 963, 63202, 34560, 0, 2113 }; + boost::compute::vector vector(data, data + 8, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(8)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + ushort_, 8, vector, + (63202, 34560, 2113, 963, 152, 94, 4, 0) + ); +} + +BOOST_AUTO_TEST_CASE(sort_int_vector_desc) +{ + using boost::compute::int_; + + int_ data[] = { -4, 152, -5000, 963, 75321, -456, 0, 1112 }; + boost::compute::vector vector(data, data + 8, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(8)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + int_, 8, vector, + (75321, 1112, 963, 152, 0, -4, -456, -5000) + ); +} + +BOOST_AUTO_TEST_CASE(sort_uint_vector_desc) +{ + using boost::compute::uint_; + + uint_ data[] = { 500, 1988, 123456, 562, 0, 4000000, 9852, 102030 }; + boost::compute::vector vector(data, data + 8, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(8)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + uint_, 8, vector, + (4000000, 123456, 102030, 9852, 1988, 562, 500, 0) + ); +} + +BOOST_AUTO_TEST_CASE(sort_long_vector_desc) +{ + using boost::compute::long_; + + long_ data[] = { -500, 1988, 123456, 562, 0, 4000000, 9852, 102030 }; + boost::compute::vector vector(data, data + 8, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(8)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + long_, 8, vector, + (4000000, 123456, 102030, 9852, 1988, 562, 0, -500) + ); +} + +BOOST_AUTO_TEST_CASE(sort_ulong_vector_desc) +{ + using boost::compute::ulong_; + + ulong_ data[] = { 500, 1988, 123456, 562, 0, 4000000, 9852, 102030 }; + boost::compute::vector vector(data, data + 8, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(8)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + ulong_, 8, vector, + (4000000, 123456, 102030, 9852, 1988, 562, 500, 0) + ); +} + +BOOST_AUTO_TEST_CASE(sort_float_vector_desc) +{ + float data[] = { + -6023.0f, 152.5f, -63.0f, 1234567.0f, 11.2f, + -5000.1f, 0.0f, 14.0f, -8.25f, -0.0f + }; + + boost::compute::vector vector(data, data + 10, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(10)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + float, 10, vector, + (1234567.0f, 152.5f, 14.0f, 11.2f, 0.0f, -0.0f, -8.25f, -63.0f, -5000.1f, -6023.0f) + ); + + // copy data, sort, and check again (to check program caching) + boost::compute::copy(data, data + 10, vector.begin(), queue); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + CHECK_RANGE_EQUAL( + float, 10, vector, + (1234567.0f, 152.5f, 14.0f, 11.2f, 0.0f, -0.0f, -8.25f, -63.0f, -5000.1f, -6023.0f) + ); +} + +BOOST_AUTO_TEST_CASE(sort_double_vector_desc) +{ + if(!device.supports_extension("cl_khr_fp64")){ + std::cout << "skipping test: device does not support double" << std::endl; + return; + } + + double data[] = { + -6023.0, 152.5, -63.0, 1234567.0, 11.2, -5000.1, 0.0, 14.0, -8.25, -0.0 + }; + + boost::compute::vector vector(data, data + 10, queue); + BOOST_CHECK_EQUAL(vector.size(), size_t(10)); + + BOOST_CHECK(!boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + boost::compute::detail::radix_sort( + vector.begin(), vector.end(), descending, queue + ); + BOOST_CHECK(boost::compute::is_sorted( + vector.begin(), vector.end(), boost::compute::greater(), queue + )); + + CHECK_RANGE_EQUAL( + double, 10, vector, + (1234567.0, 152.5, 14.0, 11.2, 0.0, -0.0, -8.25, -63.0, -5000.1, -6023.0) + ); +} + BOOST_AUTO_TEST_CASE(sort_partial_vector) { int data[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; diff --git a/test/test_radix_sort_by_key.cpp b/test/test_radix_sort_by_key.cpp index ab757ee1..e3c14f08 100644 --- a/test/test_radix_sort_by_key.cpp +++ b/test/test_radix_sort_by_key.cpp @@ -21,6 +21,8 @@ namespace compute = boost::compute; +const bool descending = false; + // radix_sort_by_key should be stable BOOST_AUTO_TEST_CASE(stable_radix_sort_int_by_int) { @@ -46,6 +48,41 @@ BOOST_AUTO_TEST_CASE(stable_radix_sort_int_by_int) ); } +// radix_sort_by_key should be stable +BOOST_AUTO_TEST_CASE(stable_radix_sort_int_by_int_desc) +{ + compute::int_ keys_data[] = { 10, 9, 2, 7, 6, -1, 4, 2, 2, 10 }; + compute::int_ values_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + compute::vector keys(keys_data, keys_data + 10, queue); + compute::vector values(values_data, values_data + 10, queue); + + BOOST_CHECK( + !compute::is_sorted( + keys.begin(), keys.end(), compute::greater(), queue + ) + ); + compute::detail::radix_sort_by_key( + keys.begin(), keys.end(), values.begin(), descending, queue + ); + BOOST_CHECK( + compute::is_sorted( + keys.begin(), keys.end(), compute::greater(), queue + ) + ); + + CHECK_RANGE_EQUAL( + compute::int_, 10, keys, + (10, 10, 9, 7, 6, 4, 2, 2, 2, -1) // keys + // ( 1, 10, 2, 4, 5, 7, 3, 8, 9, 6) values + ); + CHECK_RANGE_EQUAL( + compute::int_, 10, values, + // (10, 10, 9, 7, 6, 4, 2, 2, 2, -1) // keys + ( 1, 10, 2, 4, 5, 7, 3, 8, 9, 6) // values + ); +} + // radix_sort_by_key should be stable BOOST_AUTO_TEST_CASE(stable_radix_sort_uint_by_uint) { @@ -71,6 +108,42 @@ BOOST_AUTO_TEST_CASE(stable_radix_sort_uint_by_uint) ); } +// radix_sort_by_key should be stable +BOOST_AUTO_TEST_CASE(stable_radix_sort_uint_by_uint_desc) +{ + compute::uint_ keys_data[] = { 10, 9, 2, 7, 6, 1, 4, 2, 2, 10 }; + compute::uint_ values_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + compute::vector keys(keys_data, keys_data + 10, queue); + compute::vector values(values_data, values_data + 10, queue); + + BOOST_CHECK( + !compute::is_sorted( + keys.begin(), keys.end(), compute::greater(), queue + ) + ); + compute::detail::radix_sort_by_key( + keys.begin(), keys.end(), values.begin(), descending, queue + ); + BOOST_CHECK( + compute::is_sorted( + keys.begin(), keys.end(), compute::greater(), queue + ) + ); + + CHECK_RANGE_EQUAL( + compute::uint_, 10, keys, + (10, 10, 9, 7, 6, 4, 2, 2, 2, 1) // keys + // ( 1, 10, 2, 4, 5, 7, 3, 8, 9, 6) values + ); + CHECK_RANGE_EQUAL( + compute::uint_, 10, values, + // (10, 10, 9, 7, 6, 4, 2, 2, 2, 1) // keys + ( 1, 10, 2, 4, 5, 7, 3, 8, 9, 6) // values + ); +} + + // radix_sort_by_key should be stable BOOST_AUTO_TEST_CASE(stable_radix_sort_int_by_float) { @@ -96,6 +169,42 @@ BOOST_AUTO_TEST_CASE(stable_radix_sort_int_by_float) ); } +// radix_sort_by_key should be stable +BOOST_AUTO_TEST_CASE(stable_radix_sort_int_by_float_desc) +{ + compute::float_ keys_data[] = { 10., 5.5, 10., 7., 5.5}; + compute::int_ values_data[] = { 1, 200, -10, 2, 4 }; + + compute::vector keys(keys_data, keys_data + 5, queue); + compute::vector values(values_data, values_data + 5, queue); + + BOOST_CHECK( + !compute::is_sorted( + keys.begin(), keys.end(), compute::greater(), queue + ) + ); + compute::detail::radix_sort_by_key( + keys.begin(), keys.end(), values.begin(), descending, queue + ); + BOOST_CHECK( + compute::is_sorted( + keys.begin(), keys.end(), compute::greater(), queue + ) + ); + + CHECK_RANGE_EQUAL( + compute::float_, 5, keys, + (10., 10., 7., 5.5, 5.5) // keys + // ( 1, -10, 2, 200, 4) values + ); + CHECK_RANGE_EQUAL( + compute::int_, 5, values, + // (10., 10., 7., 5.5, 5.5) // keys + ( 1, -10, 2, 200, 4) // values + ); +} + + // radix_sort_by_key should be stable BOOST_AUTO_TEST_CASE(stable_radix_sort_char_by_int) {