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