I have a thrust device vector with 16.679.056 float elements in it.
The result of int result_count_0 = thrust::count(d_result.begin(),d_result.end(), 0);
is 14.786.283
But at the same time the following approach with thrust::count_if gives a different result (15.733.822)
struct is_zero
{
__host__ __device__
bool operator()(int x)
{
return x == 0;
}
};
...
is_zero iszero;
int result_count_isZero = thrust::count_if(d_result.begin(),d_result.end(),iszero);
Why is this so? The result of count_if makes more sense, because the number of non zero elements is 945.234 (945234 + 15733822 is 16679056, the exakt size of my device vector).
It seems the difference exists due to tuancations of float numbers to numbers of the type int
in the function object
bool operator()(int x)
{
return x == 0;
}
Change the type of the parameter in the operator function to the type of stored objects.
Here is a demonstration program that uses standard algorithms std::count
and std::count_if
that demonstrates the reason of the difference.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
struct is_zero
{
bool operator()( int x ) const
{
return x == 0;
}
};
std::vector<float> v = { 1.0f, 0.0f, 0.5f, -0.9f };
std::cout << std::count( v.begin(), v.end(), 0.0f ) << '\n';
std::cout << std::count_if( v.begin(), v.end(), is_zero() ) << '\n';
}
The program output is
1
3