| | #include <unittest/unittest.h> |
| | #include <thrust/sequence.h> |
| | #include <thrust/find.h> |
| | #include <thrust/iterator/retag.h> |
| |
|
| |
|
| | template <typename T> |
| | struct equal_to_value_pred |
| | { |
| | T value; |
| |
|
| | equal_to_value_pred(T value) : value(value) {} |
| |
|
| | __host__ __device__ |
| | bool operator()(T v) const { return v == value; } |
| | }; |
| |
|
| | template <typename T> |
| | struct not_equal_to_value_pred |
| | { |
| | T value; |
| |
|
| | not_equal_to_value_pred(T value) : value(value) {} |
| |
|
| | __host__ __device__ |
| | bool operator()(T v) const { return v != value; } |
| | }; |
| |
|
| | template<typename T> |
| | struct less_than_value_pred |
| | { |
| | T value; |
| |
|
| | less_than_value_pred(T value) : value(value) {} |
| |
|
| | __host__ __device__ |
| | bool operator()(T v) const { return v < value; } |
| | }; |
| |
|
| | template <class Vector> |
| | void TestFindSimple(void) |
| | { |
| | Vector vec(5); |
| | vec[0] = 1; |
| | vec[1] = 2; |
| | vec[2] = 3; |
| | vec[3] = 3; |
| | vec[4] = 5; |
| |
|
| | ASSERT_EQUAL(thrust::find(vec.begin(), vec.end(), 0) - vec.begin(), 5); |
| | ASSERT_EQUAL(thrust::find(vec.begin(), vec.end(), 1) - vec.begin(), 0); |
| | ASSERT_EQUAL(thrust::find(vec.begin(), vec.end(), 2) - vec.begin(), 1); |
| | ASSERT_EQUAL(thrust::find(vec.begin(), vec.end(), 3) - vec.begin(), 2); |
| | ASSERT_EQUAL(thrust::find(vec.begin(), vec.end(), 4) - vec.begin(), 5); |
| | ASSERT_EQUAL(thrust::find(vec.begin(), vec.end(), 5) - vec.begin(), 4); |
| | } |
| | DECLARE_VECTOR_UNITTEST(TestFindSimple); |
| |
|
| | template<typename InputIterator, typename T> |
| | InputIterator find(my_system &system, InputIterator first, InputIterator, const T&) |
| | { |
| | system.validate_dispatch(); |
| | return first; |
| | } |
| |
|
| | void TestFindDispatchExplicit() |
| | { |
| | thrust::device_vector<int> vec(1); |
| |
|
| | my_system sys(0); |
| | thrust::find(sys, |
| | vec.begin(), |
| | vec.end(), |
| | 0); |
| |
|
| | ASSERT_EQUAL(true, sys.is_valid()); |
| | } |
| | DECLARE_UNITTEST(TestFindDispatchExplicit); |
| |
|
| |
|
| | template<typename InputIterator, typename T> |
| | InputIterator find(my_tag, InputIterator first, InputIterator, const T&) |
| | { |
| | *first = 13; |
| | return first; |
| | } |
| |
|
| | void TestFindDispatchImplicit() |
| | { |
| | thrust::device_vector<int> vec(1); |
| |
|
| | thrust::find(thrust::retag<my_tag>(vec.begin()), |
| | thrust::retag<my_tag>(vec.end()), |
| | 0); |
| |
|
| | ASSERT_EQUAL(13, vec.front()); |
| | } |
| | DECLARE_UNITTEST(TestFindDispatchImplicit); |
| |
|
| |
|
| | template <class Vector> |
| | void TestFindIfSimple(void) |
| | { |
| | typedef typename Vector::value_type T; |
| |
|
| | Vector vec(5); |
| | vec[0] = 1; |
| | vec[1] = 2; |
| | vec[2] = 3; |
| | vec[3] = 3; |
| | vec[4] = 5; |
| |
|
| | ASSERT_EQUAL(thrust::find_if(vec.begin(), vec.end(), equal_to_value_pred<T>(0)) - vec.begin(), 5); |
| | ASSERT_EQUAL(thrust::find_if(vec.begin(), vec.end(), equal_to_value_pred<T>(1)) - vec.begin(), 0); |
| | ASSERT_EQUAL(thrust::find_if(vec.begin(), vec.end(), equal_to_value_pred<T>(2)) - vec.begin(), 1); |
| | ASSERT_EQUAL(thrust::find_if(vec.begin(), vec.end(), equal_to_value_pred<T>(3)) - vec.begin(), 2); |
| | ASSERT_EQUAL(thrust::find_if(vec.begin(), vec.end(), equal_to_value_pred<T>(4)) - vec.begin(), 5); |
| | ASSERT_EQUAL(thrust::find_if(vec.begin(), vec.end(), equal_to_value_pred<T>(5)) - vec.begin(), 4); |
| | } |
| | DECLARE_VECTOR_UNITTEST(TestFindIfSimple); |
| |
|
| | template<typename InputIterator, typename Predicate> |
| | InputIterator find_if(my_system &system, InputIterator first, InputIterator, Predicate) |
| | { |
| | system.validate_dispatch(); |
| | return first; |
| | } |
| |
|
| | void TestFindIfDispatchExplicit() |
| | { |
| | thrust::device_vector<int> vec(1); |
| |
|
| | my_system sys(0); |
| | thrust::find_if(sys, |
| | vec.begin(), |
| | vec.end(), |
| | thrust::identity<int>()); |
| |
|
| | ASSERT_EQUAL(true, sys.is_valid()); |
| | } |
| | DECLARE_UNITTEST(TestFindIfDispatchExplicit); |
| |
|
| |
|
| | template<typename InputIterator, typename Predicate> |
| | InputIterator find_if(my_tag, InputIterator first, InputIterator, Predicate) |
| | { |
| | *first = 13; |
| | return first; |
| | } |
| |
|
| | void TestFindIfDispatchImplicit() |
| | { |
| | thrust::device_vector<int> vec(1); |
| |
|
| | thrust::find_if(thrust::retag<my_tag>(vec.begin()), |
| | thrust::retag<my_tag>(vec.end()), |
| | thrust::identity<int>()); |
| |
|
| | ASSERT_EQUAL(13, vec.front()); |
| | } |
| | DECLARE_UNITTEST(TestFindIfDispatchImplicit); |
| |
|
| |
|
| | template <class Vector> |
| | void TestFindIfNotSimple(void) |
| | { |
| | typedef typename Vector::value_type T; |
| |
|
| | Vector vec(5); |
| | vec[0] = 0; |
| | vec[1] = 1; |
| | vec[2] = 2; |
| | vec[3] = 3; |
| | vec[4] = 4; |
| |
|
| | ASSERT_EQUAL(0, thrust::find_if_not(vec.begin(), vec.end(), less_than_value_pred<T>(0)) - vec.begin()); |
| | ASSERT_EQUAL(1, thrust::find_if_not(vec.begin(), vec.end(), less_than_value_pred<T>(1)) - vec.begin()); |
| | ASSERT_EQUAL(2, thrust::find_if_not(vec.begin(), vec.end(), less_than_value_pred<T>(2)) - vec.begin()); |
| | ASSERT_EQUAL(3, thrust::find_if_not(vec.begin(), vec.end(), less_than_value_pred<T>(3)) - vec.begin()); |
| | ASSERT_EQUAL(4, thrust::find_if_not(vec.begin(), vec.end(), less_than_value_pred<T>(4)) - vec.begin()); |
| | ASSERT_EQUAL(5, thrust::find_if_not(vec.begin(), vec.end(), less_than_value_pred<T>(5)) - vec.begin()); |
| | } |
| | DECLARE_VECTOR_UNITTEST(TestFindIfNotSimple); |
| |
|
| |
|
| | template<typename InputIterator, typename Predicate> |
| | InputIterator find_if_not(my_system &system, InputIterator first, InputIterator, Predicate) |
| | { |
| | system.validate_dispatch(); |
| | return first; |
| | } |
| |
|
| | void TestFindIfNotDispatchExplicit() |
| | { |
| | thrust::device_vector<int> vec(1); |
| |
|
| | my_system sys(0); |
| | thrust::find_if_not(sys, |
| | vec.begin(), |
| | vec.end(), |
| | thrust::identity<int>()); |
| |
|
| | ASSERT_EQUAL(true, sys.is_valid()); |
| | } |
| | DECLARE_UNITTEST(TestFindIfNotDispatchExplicit); |
| |
|
| |
|
| | template<typename InputIterator, typename Predicate> |
| | InputIterator find_if_not(my_tag, InputIterator first, InputIterator, Predicate) |
| | { |
| | *first = 13; |
| | return first; |
| | } |
| |
|
| | void TestFindIfNotDispatchImplicit() |
| | { |
| | thrust::device_vector<int> vec(1); |
| |
|
| | thrust::find_if_not(thrust::retag<my_tag>(vec.begin()), |
| | thrust::retag<my_tag>(vec.end()), |
| | thrust::identity<int>()); |
| |
|
| | ASSERT_EQUAL(13, vec.front()); |
| | } |
| | DECLARE_UNITTEST(TestFindIfNotDispatchImplicit); |
| |
|
| |
|
| | template <typename T> |
| | struct TestFind |
| | { |
| | void operator()(const size_t n) |
| | { |
| | thrust::host_vector<T> h_data = unittest::random_integers<T>(n); |
| | thrust::device_vector<T> d_data = h_data; |
| |
|
| | typename thrust::host_vector<T>::iterator h_iter; |
| | typename thrust::device_vector<T>::iterator d_iter; |
| |
|
| | h_iter = thrust::find(h_data.begin(), h_data.end(), T(0)); |
| | d_iter = thrust::find(d_data.begin(), d_data.end(), T(0)); |
| | ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); |
| |
|
| | for (size_t i = 1; i < n; i *= 2) |
| | { |
| | T sample = h_data[i]; |
| | h_iter = thrust::find(h_data.begin(), h_data.end(), sample); |
| | d_iter = thrust::find(d_data.begin(), d_data.end(), sample); |
| | ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); |
| | } |
| | } |
| | }; |
| | VariableUnitTest<TestFind, SignedIntegralTypes> TestFindInstance; |
| |
|
| |
|
| | template <typename T> |
| | struct TestFindIf |
| | { |
| | void operator()(const size_t n) |
| | { |
| | thrust::host_vector<T> h_data = unittest::random_integers<T>(n); |
| | thrust::device_vector<T> d_data = h_data; |
| |
|
| | typename thrust::host_vector<T>::iterator h_iter; |
| | typename thrust::device_vector<T>::iterator d_iter; |
| |
|
| | h_iter = thrust::find_if(h_data.begin(), h_data.end(), equal_to_value_pred<T>(0)); |
| | d_iter = thrust::find_if(d_data.begin(), d_data.end(), equal_to_value_pred<T>(0)); |
| | ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); |
| |
|
| | for (size_t i = 1; i < n; i *= 2) |
| | { |
| | T sample = h_data[i]; |
| | h_iter = thrust::find_if(h_data.begin(), h_data.end(), equal_to_value_pred<T>(sample)); |
| | d_iter = thrust::find_if(d_data.begin(), d_data.end(), equal_to_value_pred<T>(sample)); |
| | ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); |
| | } |
| | } |
| | }; |
| | VariableUnitTest<TestFindIf, SignedIntegralTypes> TestFindIfInstance; |
| |
|
| |
|
| | template <typename T> |
| | struct TestFindIfNot |
| | { |
| | void operator()(const size_t n) |
| | { |
| | thrust::host_vector<T> h_data = unittest::random_integers<T>(n); |
| | thrust::device_vector<T> d_data = h_data; |
| |
|
| | typename thrust::host_vector<T>::iterator h_iter; |
| | typename thrust::device_vector<T>::iterator d_iter; |
| |
|
| | h_iter = thrust::find_if_not(h_data.begin(), h_data.end(), not_equal_to_value_pred<T>(0)); |
| | d_iter = thrust::find_if_not(d_data.begin(), d_data.end(), not_equal_to_value_pred<T>(0)); |
| | ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); |
| |
|
| | for (size_t i = 1; i < n; i *= 2) |
| | { |
| | T sample = h_data[i]; |
| | h_iter = thrust::find_if_not(h_data.begin(), h_data.end(), not_equal_to_value_pred<T>(sample)); |
| | d_iter = thrust::find_if_not(d_data.begin(), d_data.end(), not_equal_to_value_pred<T>(sample)); |
| | ASSERT_EQUAL(h_iter - h_data.begin(), d_iter - d_data.begin()); |
| | } |
| | } |
| | }; |
| | VariableUnitTest<TestFindIfNot, SignedIntegralTypes> TestFindIfNotInstance; |
| |
|
| | void TestFindWithBigIndexesHelper(int magnitude) |
| | { |
| | thrust::counting_iterator<long long> begin(1); |
| | thrust::counting_iterator<long long> end = begin + (1ll << magnitude); |
| | ASSERT_EQUAL(thrust::distance(begin, end), 1ll << magnitude); |
| |
|
| | thrust::detail::intmax_t distance_low_value = thrust::distance( |
| | begin, |
| | thrust::find( |
| | thrust::device, |
| | begin, |
| | end, |
| | 17)); |
| |
|
| | thrust::detail::intmax_t distance_high_value = thrust::distance( |
| | begin, |
| | thrust::find( |
| | thrust::device, |
| | begin, |
| | end, |
| | (1ll << magnitude) - 17)); |
| |
|
| | ASSERT_EQUAL(distance_low_value, 16); |
| | ASSERT_EQUAL(distance_high_value, (1ll << magnitude) - 18); |
| | } |
| |
|
| | void TestFindWithBigIndexes() |
| | { |
| | TestFindWithBigIndexesHelper(30); |
| | TestFindWithBigIndexesHelper(31); |
| | TestFindWithBigIndexesHelper(32); |
| | TestFindWithBigIndexesHelper(33); |
| | } |
| | DECLARE_UNITTEST(TestFindWithBigIndexes); |
| |
|
| | namespace |
| | { |
| |
|
| | class Weird |
| | { |
| | int value; |
| |
|
| | public: |
| | __host__ __device__ Weird(int val, int) |
| | : value(val) |
| | {} |
| |
|
| | friend __host__ __device__ |
| | bool operator==(int x, Weird y) |
| | { |
| | return x == y.value; |
| | } |
| | }; |
| |
|
| | } |
| |
|
| | void TestFindAsymmetricEquality() |
| | { |
| | thrust::host_vector<int> v(1000); |
| | thrust::sequence(v.begin(), v.end()); |
| | thrust::device_vector<int> dv(v); |
| | auto result = thrust::find(dv.begin(), dv.end(), Weird(333, 0)); |
| | ASSERT_EQUAL(*result, 333); |
| | ASSERT_EQUAL(result - dv.begin(), 333); |
| | } |
| | DECLARE_UNITTEST(TestFindAsymmetricEquality); |
| |
|