Spaces:
Runtime error
Runtime error
#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; | |
} | |
}; | |
} // end anon namespace | |
void TestFindAsymmetricEquality() | |
{ // Regression test for thrust/thrust#1229 | |
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); | |