| #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; |
| } |
|
|
|
|