|
#include <thrust/random.h> |
|
#include <thrust/iterator/counting_iterator.h> |
|
#include <thrust/functional.h> |
|
#include <thrust/transform_reduce.h> |
|
|
|
#include <iostream> |
|
#include <iomanip> |
|
#include <cmath> |
|
|
|
|
|
|
|
__host__ __device__ |
|
unsigned int hash(unsigned int a) |
|
{ |
|
a = (a+0x7ed55d16) + (a<<12); |
|
a = (a^0xc761c23c) ^ (a>>19); |
|
a = (a+0x165667b1) + (a<<5); |
|
a = (a+0xd3a2646c) ^ (a<<9); |
|
a = (a+0xfd7046c5) + (a<<3); |
|
a = (a^0xb55a4f09) ^ (a>>16); |
|
return a; |
|
} |
|
|
|
struct estimate_pi : public thrust::unary_function<unsigned int,float> |
|
{ |
|
__host__ __device__ |
|
float operator()(unsigned int thread_id) |
|
{ |
|
float sum = 0; |
|
unsigned int N = 10000; |
|
|
|
unsigned int seed = hash(thread_id); |
|
|
|
|
|
thrust::default_random_engine rng(seed); |
|
|
|
|
|
thrust::uniform_real_distribution<float> u01(0,1); |
|
|
|
|
|
for(unsigned int i = 0; i < N; ++i) |
|
{ |
|
|
|
float x = u01(rng); |
|
float y = u01(rng); |
|
|
|
|
|
float dist = sqrtf(x*x + y*y); |
|
|
|
|
|
if(dist <= 1.0f) |
|
sum += 1.0f; |
|
} |
|
|
|
|
|
sum *= 4.0f; |
|
|
|
|
|
return sum / N; |
|
} |
|
}; |
|
|
|
int main(void) |
|
{ |
|
|
|
int M = 30000; |
|
|
|
float estimate = thrust::transform_reduce(thrust::counting_iterator<int>(0), |
|
thrust::counting_iterator<int>(M), |
|
estimate_pi(), |
|
0.0f, |
|
thrust::plus<float>()); |
|
estimate /= M; |
|
|
|
std::cout << std::setprecision(3); |
|
std::cout << "pi is approximately " << estimate << std::endl; |
|
|
|
return 0; |
|
} |
|
|
|
|