#include #include #include #include #include #include #include #if defined(THRUST_GCC_VERSION) && \ THRUST_GCC_VERSION >= 110000 && \ THRUST_GCC_VERSION < 120000 #define WAIVE_GCC11_FAILURES #endif template struct is_even { __host__ __device__ bool operator()(T x) const { return ((int) x % 2) == 0; } }; typedef unittest::type_list PartitionTypes; template void TestPartitionSimple(void) { typedef typename Vector::value_type T; typedef typename Vector::iterator Iterator; // GCC 11 miscompiles and segfaults for certain versions of this test. // It's not reproducible on other compilers, and the test passes when // optimizations are disabled. It only affects 32-bit value types, and // impacts all CPU host/device combinations tested. #ifdef WAIVE_GCC11_FAILURES if (sizeof(T) == 4) { return; } #endif Vector data(5); data[0] = 1; data[1] = 2; data[2] = 1; data[3] = 1; data[4] = 2; Iterator iter = thrust::partition(data.begin(), data.end(), is_even()); Vector ref(5); ref[0] = 2; ref[1] = 2; ref[2] = 1; ref[3] = 1; ref[4] = 1; ASSERT_EQUAL(iter - data.begin(), 2); ASSERT_EQUAL(data, ref); } DECLARE_INTEGRAL_VECTOR_UNITTEST(TestPartitionSimple); template void TestPartitionStencilSimple(void) { typedef typename Vector::value_type T; typedef typename Vector::iterator Iterator; Vector data(5); data[0] = 0; data[1] = 1; data[2] = 0; data[3] = 0; data[4] = 1; Vector stencil(5); stencil[0] = 1; stencil[1] = 2; stencil[2] = 1; stencil[3] = 1; stencil[4] = 2; Iterator iter = thrust::partition(data.begin(), data.end(), stencil.begin(), is_even()); Vector ref(5); ref[0] = 1; ref[1] = 1; ref[2] = 0; ref[3] = 0; ref[4] = 0; ASSERT_EQUAL(iter - data.begin(), 2); ASSERT_EQUAL(data, ref); } DECLARE_INTEGRAL_VECTOR_UNITTEST(TestPartitionStencilSimple); template void TestPartitionCopySimple(void) { typedef typename Vector::value_type T; Vector data(5); data[0] = 1; data[1] = 2; data[2] = 1; data[3] = 1; data[4] = 2; Vector true_results(2); Vector false_results(3); thrust::pair ends = thrust::partition_copy(data.begin(), data.end(), true_results.begin(), false_results.begin(), is_even()); Vector true_ref(2); true_ref[0] = 2; true_ref[1] = 2; Vector false_ref(3); false_ref[0] = 1; false_ref[1] = 1; false_ref[2] = 1; ASSERT_EQUAL(2, ends.first - true_results.begin()); ASSERT_EQUAL(3, ends.second - false_results.begin()); ASSERT_EQUAL(true_ref, true_results); ASSERT_EQUAL(false_ref, false_results); } DECLARE_INTEGRAL_VECTOR_UNITTEST(TestPartitionCopySimple); template void TestPartitionCopyStencilSimple(void) { typedef typename Vector::value_type T; Vector data(5); data[0] = 0; data[1] = 1; data[2] = 0; data[3] = 0; data[4] = 1; Vector stencil(5); stencil[0] = 1; stencil[1] = 2; stencil[2] = 1; stencil[3] = 1; stencil[4] = 2; Vector true_results(2); Vector false_results(3); thrust::pair ends = thrust::partition_copy(data.begin(), data.end(), stencil.begin(), true_results.begin(), false_results.begin(), is_even()); Vector true_ref(2); true_ref[0] = 1; true_ref[1] = 1; Vector false_ref(3); false_ref[0] = 0; false_ref[1] = 0; false_ref[2] = 0; ASSERT_EQUAL(2, ends.first - true_results.begin()); ASSERT_EQUAL(3, ends.second - false_results.begin()); ASSERT_EQUAL(true_ref, true_results); ASSERT_EQUAL(false_ref, false_results); } DECLARE_INTEGRAL_VECTOR_UNITTEST(TestPartitionCopyStencilSimple); template void TestStablePartitionSimple(void) { typedef typename Vector::value_type T; typedef typename Vector::iterator Iterator; Vector data(5); data[0] = 1; data[1] = 2; data[2] = 1; data[3] = 3; data[4] = 2; Iterator iter = thrust::stable_partition(data.begin(), data.end(), is_even()); Vector ref(5); ref[0] = 2; ref[1] = 2; ref[2] = 1; ref[3] = 1; ref[4] = 3; ASSERT_EQUAL(iter - data.begin(), 2); ASSERT_EQUAL(data, ref); } DECLARE_INTEGRAL_VECTOR_UNITTEST(TestStablePartitionSimple); template void TestStablePartitionStencilSimple(void) { typedef typename Vector::value_type T; typedef typename Vector::iterator Iterator; Vector data(5); data[0] = 1; data[1] = 2; data[2] = 1; data[3] = 3; data[4] = 2; Vector stencil(5); stencil[0] = 0; stencil[1] = 1; stencil[2] = 0; stencil[3] = 0; stencil[4] = 1; Iterator iter = thrust::stable_partition(data.begin(), data.end(), stencil.begin(), thrust::identity()); Vector ref(5); ref[0] = 2; ref[1] = 2; ref[2] = 1; ref[3] = 1; ref[4] = 3; ASSERT_EQUAL(iter - data.begin(), 2); ASSERT_EQUAL(data, ref); } DECLARE_VECTOR_UNITTEST(TestStablePartitionStencilSimple); template void TestStablePartitionCopySimple(void) { typedef typename Vector::value_type T; Vector data(5); data[0] = 1; data[1] = 2; data[2] = 1; data[3] = 1; data[4] = 2; Vector true_results(2); Vector false_results(3); thrust::pair ends = thrust::stable_partition_copy(data.begin(), data.end(), true_results.begin(), false_results.begin(), is_even()); Vector true_ref(2); true_ref[0] = 2; true_ref[1] = 2; Vector false_ref(3); false_ref[0] = 1; false_ref[1] = 1; false_ref[2] = 1; ASSERT_EQUAL(2, ends.first - true_results.begin()); ASSERT_EQUAL(3, ends.second - false_results.begin()); ASSERT_EQUAL(true_ref, true_results); ASSERT_EQUAL(false_ref, false_results); } DECLARE_INTEGRAL_VECTOR_UNITTEST(TestStablePartitionCopySimple); template void TestStablePartitionCopyStencilSimple(void) { typedef typename Vector::value_type T; Vector data(5); data[0] = 1; data[1] = 2; data[2] = 1; data[3] = 1; data[4] = 2; Vector stencil(5); stencil[0] = false; stencil[1] = true; stencil[2] = false; stencil[3] = false; stencil[4] = true; Vector true_results(2); Vector false_results(3); thrust::pair ends = thrust::stable_partition_copy(data.begin(), data.end(), stencil.begin(), true_results.begin(), false_results.begin(), thrust::identity()); Vector true_ref(2); true_ref[0] = 2; true_ref[1] = 2; Vector false_ref(3); false_ref[0] = 1; false_ref[1] = 1; false_ref[2] = 1; ASSERT_EQUAL(2, ends.first - true_results.begin()); ASSERT_EQUAL(3, ends.second - false_results.begin()); ASSERT_EQUAL(true_ref, true_results); ASSERT_EQUAL(false_ref, false_results); } DECLARE_VECTOR_UNITTEST(TestStablePartitionCopyStencilSimple); template struct TestPartition { void operator()(const size_t n) { // setup ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::device_vector d_data = h_data; typename thrust::host_vector::iterator h_iter = thrust::partition(h_data.begin(), h_data.end(), is_even()); typename thrust::device_vector::iterator d_iter = thrust::partition(d_data.begin(), d_data.end(), is_even()); thrust::sort(h_data.begin(), h_iter); thrust::sort(h_iter, h_data.end()); thrust::sort(d_data.begin(), d_iter); thrust::sort(d_iter, d_data.end()); ASSERT_EQUAL(h_data, d_data); ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); } }; VariableUnitTest TestPartitionInstance; template struct TestPartitionStencil { void operator()(const size_t n) { // GCC 11 miscompiles and segfaults for certain versions of this test. // It's not reproducible on other compilers, and the test passes when // optimizations are disabled. It only affects 32-bit value types, and // impacts all CPU host/device combinations tested. #ifdef WAIVE_GCC11_FAILURES if (n == 0 && sizeof(T) == 4) { return; } #endif // setup ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::host_vector h_stencil = unittest::random_integers(n); thrust::device_vector d_data = h_data; thrust::device_vector d_stencil = h_stencil; typename thrust::host_vector::iterator h_iter = thrust::partition(h_data.begin(), h_data.end(), h_stencil.begin(), is_even()); typename thrust::device_vector::iterator d_iter = thrust::partition(d_data.begin(), d_data.end(), d_stencil.begin(), is_even()); thrust::sort(h_data.begin(), h_iter); thrust::sort(h_iter, h_data.end()); thrust::sort(d_data.begin(), d_iter); thrust::sort(d_iter, d_data.end()); ASSERT_EQUAL(h_data, d_data); ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); } }; VariableUnitTest TestPartitionStencilInstance; template struct TestPartitionCopy { void operator()(const size_t n) { // setup input ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::device_vector d_data = h_data; std::ptrdiff_t n_true = thrust::count_if(h_data.begin(), h_data.end(), is_even()); std::ptrdiff_t n_false = n - n_true; // setup output ranges thrust::host_vector h_true_results (n_true, 0); thrust::host_vector h_false_results(n_false, 0); thrust::device_vector d_true_results (n_true, 0); thrust::device_vector d_false_results(n_false, 0); thrust::pair::iterator, typename thrust::host_vector::iterator> h_ends = thrust::partition_copy(h_data.begin(), h_data.end(), h_true_results.begin(), h_false_results.begin(), is_even()); thrust::pair::iterator, typename thrust::device_vector::iterator> d_ends = thrust::partition_copy(d_data.begin(), d_data.end(), d_true_results.begin(), d_false_results.begin(), is_even()); // check true output ASSERT_EQUAL(h_ends.first - h_true_results.begin(), n_true); ASSERT_EQUAL(d_ends.first - d_true_results.begin(), n_true); thrust::sort(h_true_results.begin(), h_true_results.end()); thrust::sort(d_true_results.begin(), d_true_results.end()); ASSERT_EQUAL(h_true_results, d_true_results); // check false output ASSERT_EQUAL(h_ends.second - h_false_results.begin(), n_false); ASSERT_EQUAL(d_ends.second - d_false_results.begin(), n_false); thrust::sort(h_false_results.begin(), h_false_results.end()); thrust::sort(d_false_results.begin(), d_false_results.end()); ASSERT_EQUAL(h_false_results, d_false_results); } }; VariableUnitTest TestPartitionCopyInstance; template struct TestPartitionCopyStencil { void operator()(const size_t n) { // setup input ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::host_vector h_stencil = unittest::random_integers(n); thrust::device_vector d_data = h_data; thrust::device_vector d_stencil = h_stencil; std::ptrdiff_t n_true = thrust::count_if(h_data.begin(), h_data.end(), is_even()); std::ptrdiff_t n_false = n - n_true; // setup output ranges thrust::host_vector h_true_results (n_true, 0); thrust::host_vector h_false_results(n_false, 0); thrust::device_vector d_true_results (n_true, 0); thrust::device_vector d_false_results(n_false, 0); thrust::pair::iterator, typename thrust::host_vector::iterator> h_ends = thrust::partition_copy(h_data.begin(), h_data.end(), h_stencil.begin(), h_true_results.begin(), h_false_results.begin(), is_even()); thrust::pair::iterator, typename thrust::device_vector::iterator> d_ends = thrust::partition_copy(d_data.begin(), d_data.end(), d_stencil.begin(), d_true_results.begin(), d_false_results.begin(), is_even()); // check true output ASSERT_EQUAL(h_ends.first - h_true_results.begin(), n_true); ASSERT_EQUAL(d_ends.first - d_true_results.begin(), n_true); thrust::sort(h_true_results.begin(), h_true_results.end()); thrust::sort(d_true_results.begin(), d_true_results.end()); ASSERT_EQUAL(h_true_results, d_true_results); // check false output ASSERT_EQUAL(h_ends.second - h_false_results.begin(), n_false); ASSERT_EQUAL(d_ends.second - d_false_results.begin(), n_false); thrust::sort(h_false_results.begin(), h_false_results.end()); thrust::sort(d_false_results.begin(), d_false_results.end()); ASSERT_EQUAL(h_false_results, d_false_results); } }; VariableUnitTest TestPartitionCopyStencilInstance; template struct TestStablePartitionCopyStencil { void operator()(const size_t n) { // setup input ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::host_vector h_stencil = unittest::random_integers(n); thrust::device_vector d_data = h_data; thrust::device_vector d_stencil = h_stencil; std::ptrdiff_t n_true = thrust::count_if(h_stencil.begin(), h_stencil.end(), is_even()); std::ptrdiff_t n_false = n - n_true; // setup output ranges thrust::host_vector h_true_results (n_true, 0); thrust::host_vector h_false_results(n_false, 0); thrust::device_vector d_true_results (n_true, 0); thrust::device_vector d_false_results(n_false, 0); thrust::pair::iterator, typename thrust::host_vector::iterator> h_ends = thrust::stable_partition_copy(h_data.begin(), h_data.end(), h_stencil.begin(), h_true_results.begin(), h_false_results.begin(), is_even()); thrust::pair::iterator, typename thrust::device_vector::iterator> d_ends = thrust::stable_partition_copy(d_data.begin(), d_data.end(), d_stencil.begin(), d_true_results.begin(), d_false_results.begin(), is_even()); // check true output ASSERT_EQUAL(h_ends.first - h_true_results.begin(), n_true); ASSERT_EQUAL(d_ends.first - d_true_results.begin(), n_true); thrust::sort(h_true_results.begin(), h_true_results.end()); thrust::sort(d_true_results.begin(), d_true_results.end()); ASSERT_EQUAL(h_true_results, d_true_results); // check false output ASSERT_EQUAL(h_ends.second - h_false_results.begin(), n_false); ASSERT_EQUAL(d_ends.second - d_false_results.begin(), n_false); thrust::sort(h_false_results.begin(), h_false_results.end()); thrust::sort(d_false_results.begin(), d_false_results.end()); ASSERT_EQUAL(h_false_results, d_false_results); } }; VariableUnitTest TestStablePartitionCopyStencilInstance; template struct TestPartitionCopyToDiscardIterator { void operator()(const size_t n) { // setup input ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::device_vector d_data = h_data; std::ptrdiff_t n_true = thrust::count_if(h_data.begin(), h_data.end(), is_even()); std::ptrdiff_t n_false = n - n_true; // mask both ranges thrust::pair, thrust::discard_iterator<> > h_result1 = thrust::partition_copy(h_data.begin(), h_data.end(), thrust::make_discard_iterator(), thrust::make_discard_iterator(), is_even()); thrust::pair, thrust::discard_iterator<> > d_result1 = thrust::partition_copy(d_data.begin(), d_data.end(), thrust::make_discard_iterator(), thrust::make_discard_iterator(), is_even()); thrust::pair, thrust::discard_iterator<> > reference1 = thrust::make_pair(thrust::make_discard_iterator(n_true), thrust::make_discard_iterator(n_false)); ASSERT_EQUAL_QUIET(reference1, h_result1); ASSERT_EQUAL_QUIET(reference1, d_result1); // mask the false range thrust::host_vector h_trues(n_true); thrust::device_vector d_trues(n_true); thrust::pair::iterator, thrust::discard_iterator<> > h_result2 = thrust::partition_copy(h_data.begin(), h_data.end(), h_trues.begin(), thrust::make_discard_iterator(), is_even()); thrust::pair::iterator, thrust::discard_iterator<> > d_result2 = thrust::partition_copy(d_data.begin(), d_data.end(), d_trues.begin(), thrust::make_discard_iterator(), is_even()); thrust::pair::iterator, thrust::discard_iterator<> > h_reference2 = thrust::make_pair(h_trues.begin() + n_true, thrust::make_discard_iterator(n_false)); thrust::pair::iterator, thrust::discard_iterator<> > d_reference2 = thrust::make_pair(d_trues.begin() + n_true, thrust::make_discard_iterator(n_false)); ASSERT_EQUAL(h_trues, d_trues); ASSERT_EQUAL_QUIET(h_reference2, h_result2); ASSERT_EQUAL_QUIET(d_reference2, d_result2); // mask the true range thrust::host_vector h_falses(n_false); thrust::device_vector d_falses(n_false); thrust::pair, typename thrust::host_vector::iterator> h_result3 = thrust::partition_copy(h_data.begin(), h_data.end(), thrust::make_discard_iterator(), h_falses.begin(), is_even()); thrust::pair, typename thrust::device_vector::iterator> d_result3 = thrust::partition_copy(d_data.begin(), d_data.end(), thrust::make_discard_iterator(), d_falses.begin(), is_even()); thrust::pair, typename thrust::host_vector::iterator> h_reference3 = thrust::make_pair(thrust::make_discard_iterator(n_true), h_falses.begin() + n_false); thrust::pair, typename thrust::device_vector::iterator> d_reference3 = thrust::make_pair(thrust::make_discard_iterator(n_true), d_falses.begin() + n_false); ASSERT_EQUAL(h_falses, d_falses); ASSERT_EQUAL_QUIET(h_reference3, h_result3); ASSERT_EQUAL_QUIET(d_reference3, d_result3); } }; VariableUnitTest TestPartitionCopyToDiscardIteratorInstance; template struct TestPartitionCopyStencilToDiscardIterator { void operator()(const size_t n) { // setup input ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::host_vector h_stencil = unittest::random_integers(n); thrust::device_vector d_data = h_data; thrust::device_vector d_stencil = h_stencil; std::ptrdiff_t n_true = thrust::count_if(h_stencil.begin(), h_stencil.end(), is_even()); std::ptrdiff_t n_false = n - n_true; // mask both ranges thrust::pair, thrust::discard_iterator<> > h_result1 = thrust::partition_copy(h_data.begin(), h_data.end(), h_stencil.begin(), thrust::make_discard_iterator(), thrust::make_discard_iterator(), is_even()); thrust::pair, thrust::discard_iterator<> > d_result1 = thrust::partition_copy(d_data.begin(), d_data.end(), d_stencil.begin(), thrust::make_discard_iterator(), thrust::make_discard_iterator(), is_even()); thrust::pair, thrust::discard_iterator<> > reference1 = thrust::make_pair(thrust::make_discard_iterator(n_true), thrust::make_discard_iterator(n_false)); ASSERT_EQUAL_QUIET(reference1, h_result1); ASSERT_EQUAL_QUIET(reference1, d_result1); // mask the false range thrust::host_vector h_trues(n_true); thrust::device_vector d_trues(n_true); thrust::pair::iterator, thrust::discard_iterator<> > h_result2 = thrust::partition_copy(h_data.begin(), h_data.end(), h_stencil.begin(), h_trues.begin(), thrust::make_discard_iterator(), is_even()); thrust::pair::iterator, thrust::discard_iterator<> > d_result2 = thrust::partition_copy(d_data.begin(), d_data.end(), d_stencil.begin(), d_trues.begin(), thrust::make_discard_iterator(), is_even()); thrust::pair::iterator, thrust::discard_iterator<> > h_reference2 = thrust::make_pair(h_trues.begin() + n_true, thrust::make_discard_iterator(n_false)); thrust::pair::iterator, thrust::discard_iterator<> > d_reference2 = thrust::make_pair(d_trues.begin() + n_true, thrust::make_discard_iterator(n_false)); ASSERT_EQUAL(h_trues, d_trues); ASSERT_EQUAL_QUIET(h_reference2, h_result2); ASSERT_EQUAL_QUIET(d_reference2, d_result2); // mask the true range thrust::host_vector h_falses(n_false); thrust::device_vector d_falses(n_false); thrust::pair, typename thrust::host_vector::iterator> h_result3 = thrust::partition_copy(h_data.begin(), h_data.end(), h_stencil.begin(), thrust::make_discard_iterator(), h_falses.begin(), is_even()); thrust::pair, typename thrust::device_vector::iterator> d_result3 = thrust::partition_copy(d_data.begin(), d_data.end(), d_stencil.begin(), thrust::make_discard_iterator(), d_falses.begin(), is_even()); thrust::pair, typename thrust::host_vector::iterator> h_reference3 = thrust::make_pair(thrust::make_discard_iterator(n_true), h_falses.begin() + n_false); thrust::pair, typename thrust::device_vector::iterator> d_reference3 = thrust::make_pair(thrust::make_discard_iterator(n_true), d_falses.begin() + n_false); ASSERT_EQUAL(h_falses, d_falses); ASSERT_EQUAL_QUIET(h_reference3, h_result3); ASSERT_EQUAL_QUIET(d_reference3, d_result3); } }; VariableUnitTest TestPartitionCopyStencilToDiscardIteratorInstance; template struct TestStablePartition { void operator()(const size_t n) { // GCC 11 miscompiles and segfaults for certain versions of this test. // It's not reproducible on other compilers, and the test passes when // optimizations are disabled. It only affects 32-bit value types, and // impacts all CPU host/device combinations tested. #ifdef WAIVE_GCC11_FAILURES if (n == 0 && sizeof(T) == 4) { return; } #endif // setup ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::device_vector d_data = h_data; typename thrust::host_vector::iterator h_iter = thrust::stable_partition(h_data.begin(), h_data.end(), is_even()); typename thrust::device_vector::iterator d_iter = thrust::stable_partition(d_data.begin(), d_data.end(), is_even()); ASSERT_EQUAL(h_data, d_data); ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); } }; VariableUnitTest TestStablePartitionInstance; template struct TestStablePartitionStencil { void operator()(const size_t n) { // GCC 11 miscompiles and segfaults for certain versions of this test. // It's not reproducible on other compilers, and the test passes when // optimizations are disabled. It only affects 32-bit value types, and // impacts all CPU host/device combinations tested. #ifdef WAIVE_GCC11_FAILURES if (n == 0 && sizeof(T) == 4) { return; } #endif // setup ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::host_vector h_stencil = unittest::random_integers(n); thrust::device_vector d_data = h_data; thrust::device_vector d_stencil = h_stencil; typename thrust::host_vector::iterator h_iter = thrust::stable_partition(h_data.begin(), h_data.end(), h_stencil.begin(), is_even()); typename thrust::device_vector::iterator d_iter = thrust::stable_partition(d_data.begin(), d_data.end(), d_stencil.begin(), is_even()); ASSERT_EQUAL(h_data, d_data); ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); } }; VariableUnitTest TestStablePartitionStencilInstance; template struct TestStablePartitionCopy { void operator()(const size_t n) { // setup input ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::device_vector d_data = h_data; std::ptrdiff_t n_true = thrust::count_if(h_data.begin(), h_data.end(), is_even()); std::ptrdiff_t n_false = n - n_true; // setup output ranges thrust::host_vector h_true_results (n_true, 0); thrust::host_vector h_false_results(n_false, 0); thrust::device_vector d_true_results (n_true, 0); thrust::device_vector d_false_results(n_false, 0); thrust::pair::iterator, typename thrust::host_vector::iterator> h_ends = thrust::stable_partition_copy(h_data.begin(), h_data.end(), h_true_results.begin(), h_false_results.begin(), is_even()); thrust::pair::iterator, typename thrust::device_vector::iterator> d_ends = thrust::stable_partition_copy(d_data.begin(), d_data.end(), d_true_results.begin(), d_false_results.begin(), is_even()); // check true output ASSERT_EQUAL(h_ends.first - h_true_results.begin(), n_true); ASSERT_EQUAL(d_ends.first - d_true_results.begin(), n_true); ASSERT_EQUAL(h_true_results, d_true_results); // check false output ASSERT_EQUAL(h_ends.second - h_false_results.begin(), n_false); ASSERT_EQUAL(d_ends.second - d_false_results.begin(), n_false); ASSERT_EQUAL(h_false_results, d_false_results); } }; VariableUnitTest TestStablePartitionCopyInstance; template struct TestStablePartitionCopyToDiscardIterator { void operator()(const size_t n) { // setup input ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::device_vector d_data = h_data; std::ptrdiff_t n_true = thrust::count_if(h_data.begin(), h_data.end(), is_even()); std::ptrdiff_t n_false = n - n_true; // mask both ranges thrust::pair, thrust::discard_iterator<> > h_result1 = thrust::stable_partition_copy(h_data.begin(), h_data.end(), thrust::make_discard_iterator(), thrust::make_discard_iterator(), is_even()); thrust::pair, thrust::discard_iterator<> > d_result1 = thrust::stable_partition_copy(d_data.begin(), d_data.end(), thrust::make_discard_iterator(), thrust::make_discard_iterator(), is_even()); thrust::pair, thrust::discard_iterator<> > reference1 = thrust::make_pair(thrust::make_discard_iterator(n_true), thrust::make_discard_iterator(n_false)); ASSERT_EQUAL_QUIET(reference1, h_result1); ASSERT_EQUAL_QUIET(reference1, d_result1); // mask the false range thrust::host_vector h_trues(n_true); thrust::device_vector d_trues(n_true); thrust::pair::iterator, thrust::discard_iterator<> > h_result2 = thrust::stable_partition_copy(h_data.begin(), h_data.end(), h_trues.begin(), thrust::make_discard_iterator(), is_even()); thrust::pair::iterator, thrust::discard_iterator<> > d_result2 = thrust::stable_partition_copy(d_data.begin(), d_data.end(), d_trues.begin(), thrust::make_discard_iterator(), is_even()); thrust::pair::iterator, thrust::discard_iterator<> > h_reference2 = thrust::make_pair(h_trues.begin() + n_true, thrust::make_discard_iterator(n_false)); thrust::pair::iterator, thrust::discard_iterator<> > d_reference2 = thrust::make_pair(d_trues.begin() + n_true, thrust::make_discard_iterator(n_false)); ASSERT_EQUAL(h_trues, d_trues); ASSERT_EQUAL_QUIET(h_reference2, h_result2); ASSERT_EQUAL_QUIET(d_reference2, d_result2); // mask the true range thrust::host_vector h_falses(n_false); thrust::device_vector d_falses(n_false); thrust::pair, typename thrust::host_vector::iterator> h_result3 = thrust::stable_partition_copy(h_data.begin(), h_data.end(), thrust::make_discard_iterator(), h_falses.begin(), is_even()); thrust::pair, typename thrust::device_vector::iterator> d_result3 = thrust::stable_partition_copy(d_data.begin(), d_data.end(), thrust::make_discard_iterator(), d_falses.begin(), is_even()); thrust::pair, typename thrust::host_vector::iterator> h_reference3 = thrust::make_pair(thrust::make_discard_iterator(n_true), h_falses.begin() + n_false); thrust::pair, typename thrust::device_vector::iterator> d_reference3 = thrust::make_pair(thrust::make_discard_iterator(n_true), d_falses.begin() + n_false); ASSERT_EQUAL(h_falses, d_falses); ASSERT_EQUAL_QUIET(h_reference3, h_result3); ASSERT_EQUAL_QUIET(d_reference3, d_result3); } }; VariableUnitTest TestStablePartitionCopyToDiscardIteratorInstance; template struct TestStablePartitionCopyStencilToDiscardIterator { void operator()(const size_t n) { // setup input ranges thrust::host_vector h_data = unittest::random_integers(n); thrust::host_vector h_stencil = unittest::random_integers(n); thrust::device_vector d_data = h_data; thrust::device_vector d_stencil = h_stencil; std::ptrdiff_t n_true = thrust::count_if(h_stencil.begin(), h_stencil.end(), is_even()); std::ptrdiff_t n_false = n - n_true; // mask both ranges thrust::pair, thrust::discard_iterator<> > h_result1 = thrust::stable_partition_copy(h_data.begin(), h_data.end(), h_stencil.begin(), thrust::make_discard_iterator(), thrust::make_discard_iterator(), is_even()); thrust::pair, thrust::discard_iterator<> > d_result1 = thrust::stable_partition_copy(d_data.begin(), d_data.end(), d_stencil.begin(), thrust::make_discard_iterator(), thrust::make_discard_iterator(), is_even()); thrust::pair, thrust::discard_iterator<> > reference1 = thrust::make_pair(thrust::make_discard_iterator(n_true), thrust::make_discard_iterator(n_false)); ASSERT_EQUAL_QUIET(reference1, h_result1); ASSERT_EQUAL_QUIET(reference1, d_result1); // mask the false range thrust::host_vector h_trues(n_true); thrust::device_vector d_trues(n_true); thrust::pair::iterator, thrust::discard_iterator<> > h_result2 = thrust::stable_partition_copy(h_data.begin(), h_data.end(), h_stencil.begin(), h_trues.begin(), thrust::make_discard_iterator(), is_even()); thrust::pair::iterator, thrust::discard_iterator<> > d_result2 = thrust::stable_partition_copy(d_data.begin(), d_data.end(), d_stencil.begin(), d_trues.begin(), thrust::make_discard_iterator(), is_even()); thrust::pair::iterator, thrust::discard_iterator<> > h_reference2 = thrust::make_pair(h_trues.begin() + n_true, thrust::make_discard_iterator(n_false)); thrust::pair::iterator, thrust::discard_iterator<> > d_reference2 = thrust::make_pair(d_trues.begin() + n_true, thrust::make_discard_iterator(n_false)); ASSERT_EQUAL(h_trues, d_trues); ASSERT_EQUAL_QUIET(h_reference2, h_result2); ASSERT_EQUAL_QUIET(d_reference2, d_result2); // mask the true range thrust::host_vector h_falses(n_false); thrust::device_vector d_falses(n_false); thrust::pair, typename thrust::host_vector::iterator> h_result3 = thrust::stable_partition_copy(h_data.begin(), h_data.end(), h_stencil.begin(), thrust::make_discard_iterator(), h_falses.begin(), is_even()); thrust::pair, typename thrust::device_vector::iterator> d_result3 = thrust::stable_partition_copy(d_data.begin(), d_data.end(), d_stencil.begin(), thrust::make_discard_iterator(), d_falses.begin(), is_even()); thrust::pair, typename thrust::host_vector::iterator> h_reference3 = thrust::make_pair(thrust::make_discard_iterator(n_true), h_falses.begin() + n_false); thrust::pair, typename thrust::device_vector::iterator> d_reference3 = thrust::make_pair(thrust::make_discard_iterator(n_true), d_falses.begin() + n_false); ASSERT_EQUAL(h_falses, d_falses); ASSERT_EQUAL_QUIET(h_reference3, h_result3); ASSERT_EQUAL_QUIET(d_reference3, d_result3); } }; VariableUnitTest TestStablePartitionCopyStencilToDiscardIteratorInstance; struct is_ordered { template __host__ __device__ bool operator()(const Tuple& t) const { return thrust::get<0>(t) <= thrust::get<1>(t); } }; template void TestPartitionZipIterator(void) { Vector data1(5); Vector data2(5); data1[0] = 1; data2[0] = 2; data1[1] = 2; data2[1] = 1; data1[2] = 1; data2[2] = 2; data1[3] = 1; data2[3] = 2; data1[4] = 2; data2[4] = 1; typedef typename Vector::iterator Iterator; typedef thrust::tuple IteratorTuple; typedef thrust::zip_iterator ZipIterator; ZipIterator begin = thrust::make_zip_iterator(thrust::make_tuple(data1.begin(), data2.begin())); ZipIterator end = thrust::make_zip_iterator(thrust::make_tuple(data1.end(), data2.end())); ZipIterator iter = thrust::partition(begin, end, is_ordered()); Vector ref1(5); Vector ref2(5); ref1[0] = 1; ref2[0] = 2; ref1[1] = 1; ref2[1] = 2; ref1[2] = 1; ref2[2] = 2; ref1[3] = 2; ref2[3] = 1; ref1[4] = 2; ref2[4] = 1; ASSERT_EQUAL(iter - begin, 3); ASSERT_EQUAL(data1, ref1); ASSERT_EQUAL(data2, ref2); } DECLARE_VECTOR_UNITTEST(TestPartitionZipIterator); template void TestPartitionStencilZipIterator(void) { Vector data(5); data[0] = 1; data[1] = 0; data[2] = 1; data[3] = 1; data[4] = 0; Vector stencil1(5); Vector stencil2(5); stencil1[0] = 1; stencil2[0] = 2; stencil1[1] = 2; stencil2[1] = 1; stencil1[2] = 1; stencil2[2] = 2; stencil1[3] = 1; stencil2[3] = 2; stencil1[4] = 2; stencil2[4] = 1; typedef typename Vector::iterator Iterator; typedef thrust::tuple IteratorTuple; typedef thrust::zip_iterator ZipIterator; ZipIterator stencil_begin = thrust::make_zip_iterator(thrust::make_tuple(stencil1.begin(), stencil2.begin())); Iterator iter = thrust::partition(data.begin(), data.end(), stencil_begin, is_ordered()); Vector ref(5); ref[0] = 1; ref[1] = 1; ref[2] = 1; ref[3] = 0; ref[4] = 0; ASSERT_EQUAL(iter - data.begin(), 3); ASSERT_EQUAL(data, ref); } DECLARE_VECTOR_UNITTEST(TestPartitionStencilZipIterator); template void TestStablePartitionZipIterator(void) { Vector data1(5); Vector data2(5); data1[0] = 1; data2[0] = 2; data1[1] = 2; data2[1] = 0; data1[2] = 1; data2[2] = 3; data1[3] = 1; data2[3] = 2; data1[4] = 2; data2[4] = 1; typedef typename Vector::iterator Iterator; typedef thrust::tuple IteratorTuple; typedef thrust::zip_iterator ZipIterator; ZipIterator begin = thrust::make_zip_iterator(thrust::make_tuple(data1.begin(), data2.begin())); ZipIterator end = thrust::make_zip_iterator(thrust::make_tuple(data1.end(), data2.end())); ZipIterator iter = thrust::stable_partition(begin, end, is_ordered()); Vector ref1(5); Vector ref2(5); ref1[0] = 1; ref2[0] = 2; ref1[1] = 1; ref2[1] = 3; ref1[2] = 1; ref2[2] = 2; ref1[3] = 2; ref2[3] = 0; ref1[4] = 2; ref2[4] = 1; ASSERT_EQUAL(data1, ref1); ASSERT_EQUAL(data2, ref2); ASSERT_EQUAL(iter - begin, 3); } DECLARE_VECTOR_UNITTEST(TestStablePartitionZipIterator); template void TestStablePartitionStencilZipIterator(void) { Vector data(5); data[0] = 1; data[1] = 0; data[2] = 1; data[3] = 1; data[4] = 0; Vector stencil1(5); Vector stencil2(5); stencil1[0] = 1; stencil2[0] = 2; stencil1[1] = 2; stencil2[1] = 0; stencil1[2] = 1; stencil2[2] = 3; stencil1[3] = 1; stencil2[3] = 2; stencil1[4] = 2; stencil2[4] = 1; typedef typename Vector::iterator Iterator; typedef thrust::tuple IteratorTuple; typedef thrust::zip_iterator ZipIterator; ZipIterator stencil_begin = thrust::make_zip_iterator(thrust::make_tuple(stencil1.begin(), stencil2.begin())); Iterator mid = thrust::stable_partition(data.begin(), data.end(), stencil_begin, is_ordered()); Vector ref(5); ref[0] = 1; ref[1] = 1; ref[2] = 1; ref[3] = 0; ref[4] = 0; ASSERT_EQUAL(ref, data); ASSERT_EQUAL(mid - data.begin(), 3); } DECLARE_VECTOR_UNITTEST(TestStablePartitionStencilZipIterator); template ForwardIterator partition(my_system &system, ForwardIterator first, ForwardIterator, Predicate) { system.validate_dispatch(); return first; } void TestPartitionDispatchExplicit() { thrust::device_vector vec(1); my_system sys(0); thrust::partition(sys, vec.begin(), vec.begin(), 0); ASSERT_EQUAL(true, sys.is_valid()); } DECLARE_UNITTEST(TestPartitionDispatchExplicit); template ForwardIterator partition(my_system &system, ForwardIterator first, ForwardIterator, InputIterator, Predicate) { system.validate_dispatch(); return first; } void TestPartitionStencilDispatchExplicit() { thrust::device_vector vec(1); my_system sys(0); thrust::partition(sys, vec.begin(), vec.begin(), vec.begin(), 0); ASSERT_EQUAL(true, sys.is_valid()); } DECLARE_UNITTEST(TestPartitionStencilDispatchExplicit); template ForwardIterator partition(my_tag, ForwardIterator first, ForwardIterator, Predicate) { *first = 13; return first; } void TestPartitionDispatchImplicit() { thrust::device_vector vec(1); thrust::partition(thrust::retag(vec.begin()), thrust::retag(vec.begin()), 0); ASSERT_EQUAL(13, vec.front()); } DECLARE_UNITTEST(TestPartitionDispatchImplicit); template ForwardIterator partition(my_tag, ForwardIterator first, ForwardIterator, InputIterator, Predicate) { *first = 13; return first; } void TestPartitionStencilDispatchImplicit() { thrust::device_vector vec(1); thrust::partition(thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), 0); ASSERT_EQUAL(13, vec.front()); } DECLARE_UNITTEST(TestPartitionStencilDispatchImplicit); template thrust::pair partition_copy(my_system &system, InputIterator, InputIterator, OutputIterator1 out_true, OutputIterator2 out_false, Predicate) { system.validate_dispatch(); return thrust::make_pair(out_true,out_false); } void TestPartitionCopyDispatchExplicit() { thrust::device_vector vec(1); my_system sys(0); thrust::partition_copy(sys, vec.begin(), vec.begin(), vec.begin(), vec.begin(), 0); ASSERT_EQUAL(true, sys.is_valid()); } DECLARE_UNITTEST(TestPartitionCopyDispatchExplicit); template thrust::pair partition_copy(my_system &system, InputIterator1, InputIterator1, InputIterator2, OutputIterator1 out_true, OutputIterator2 out_false, Predicate) { system.validate_dispatch(); return thrust::make_pair(out_true,out_false); } void TestPartitionCopyStencilDispatchExplicit() { thrust::device_vector vec(1); my_system sys(0); thrust::partition_copy(sys, vec.begin(), vec.begin(), vec.begin(), vec.begin(), vec.begin(), 0); ASSERT_EQUAL(true, sys.is_valid()); } DECLARE_UNITTEST(TestPartitionCopyStencilDispatchExplicit); template thrust::pair partition_copy(my_tag, InputIterator first, InputIterator, OutputIterator1 out_true, OutputIterator2 out_false, Predicate) { *first = 13; return thrust::make_pair(out_true,out_false); } void TestPartitionCopyDispatchImplicit() { thrust::device_vector vec(1); thrust::partition_copy(thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), 0); ASSERT_EQUAL(13, vec.front()); } DECLARE_UNITTEST(TestPartitionCopyDispatchImplicit); template thrust::pair partition_copy(my_tag, InputIterator1 first, InputIterator1, InputIterator2, OutputIterator1 out_true, OutputIterator2 out_false, Predicate) { *first = 13; return thrust::make_pair(out_true,out_false); } void TestPartitionCopyStencilDispatchImplicit() { thrust::device_vector vec(1); thrust::partition_copy(thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), 0); ASSERT_EQUAL(13, vec.front()); } DECLARE_UNITTEST(TestPartitionCopyStencilDispatchImplicit); template ForwardIterator stable_partition(my_system &system, ForwardIterator first, ForwardIterator, Predicate) { system.validate_dispatch(); return first; } void TestStablePartitionDispatchExplicit() { thrust::device_vector vec(1); my_system sys(0); thrust::stable_partition(sys, vec.begin(), vec.begin(), 0); ASSERT_EQUAL(true, sys.is_valid()); } DECLARE_UNITTEST(TestStablePartitionDispatchExplicit); template ForwardIterator stable_partition(my_system &system, ForwardIterator first, ForwardIterator, InputIterator, Predicate) { system.validate_dispatch(); return first; } void TestStablePartitionStencilDispatchExplicit() { thrust::device_vector vec(1); my_system sys(0); thrust::stable_partition(sys, vec.begin(), vec.begin(), vec.begin(), 0); ASSERT_EQUAL(true, sys.is_valid()); } DECLARE_UNITTEST(TestStablePartitionStencilDispatchExplicit); template ForwardIterator stable_partition(my_tag, ForwardIterator first, ForwardIterator, Predicate) { *first = 13; return first; } void TestStablePartitionDispatchImplicit() { thrust::device_vector vec(1); thrust::stable_partition(thrust::retag(vec.begin()), thrust::retag(vec.begin()), 0); ASSERT_EQUAL(13, vec.front()); } DECLARE_UNITTEST(TestStablePartitionDispatchImplicit); template ForwardIterator stable_partition(my_tag, ForwardIterator first, ForwardIterator, InputIterator, Predicate) { *first = 13; return first; } void TestStablePartitionStencilDispatchImplicit() { thrust::device_vector vec(1); thrust::stable_partition(thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), 0); ASSERT_EQUAL(13, vec.front()); } DECLARE_UNITTEST(TestStablePartitionStencilDispatchImplicit); template thrust::pair stable_partition_copy(my_system &system, InputIterator, InputIterator, OutputIterator1 out_true, OutputIterator2 out_false, Predicate) { system.validate_dispatch(); return thrust::make_pair(out_true,out_false); } void TestStablePartitionCopyDispatchExplicit() { thrust::device_vector vec(1); my_system sys(0); thrust::stable_partition_copy(sys, vec.begin(), vec.begin(), vec.begin(), vec.begin(), 0); ASSERT_EQUAL(true, sys.is_valid()); } DECLARE_UNITTEST(TestStablePartitionCopyDispatchExplicit); template thrust::pair stable_partition_copy(my_system &system, InputIterator1, InputIterator1, InputIterator2, OutputIterator1 out_true, OutputIterator2 out_false, Predicate) { system.validate_dispatch(); return thrust::make_pair(out_true,out_false); } void TestStablePartitionCopyStencilDispatchExplicit() { thrust::device_vector vec(1); my_system sys(0); thrust::stable_partition_copy(sys, vec.begin(), vec.begin(), vec.begin(), vec.begin(), vec.begin(), 0); ASSERT_EQUAL(true, sys.is_valid()); } DECLARE_UNITTEST(TestStablePartitionCopyStencilDispatchExplicit); template thrust::pair stable_partition_copy(my_tag, InputIterator first, InputIterator, OutputIterator1 out_true, OutputIterator2 out_false, Predicate) { *first = 13; return thrust::make_pair(out_true,out_false); } void TestStablePartitionCopyDispatchImplicit() { thrust::device_vector vec(1); thrust::stable_partition_copy(thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), 0); ASSERT_EQUAL(13, vec.front()); } DECLARE_UNITTEST(TestStablePartitionCopyDispatchImplicit); template thrust::pair stable_partition_copy(my_tag, InputIterator1 first, InputIterator1, InputIterator2, OutputIterator1 out_true, OutputIterator2 out_false, Predicate) { *first = 13; return thrust::make_pair(out_true,out_false); } void TestStablePartitionCopyStencilDispatchImplicit() { thrust::device_vector vec(1); thrust::stable_partition_copy(thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), thrust::retag(vec.begin()), 0); ASSERT_EQUAL(13, vec.front()); } DECLARE_UNITTEST(TestStablePartitionCopyStencilDispatchImplicit);