| 21 | namespace compute = boost::compute; |
| 22 | |
| 23 | int main() |
| 24 | { |
| 25 | // get default device and setup context |
| 26 | compute::device gpu = compute::system::default_device(); |
| 27 | compute::context context(gpu); |
| 28 | compute::command_queue queue(context, gpu); |
| 29 | |
| 30 | std::cout << "device: " << gpu.name() << std::endl; |
| 31 | |
| 32 | using compute::uint_; |
| 33 | using compute::uint2_; |
| 34 | |
| 35 | |
| 36 | #ifdef CI_BUILD // lower number of points for CI builds |
| 37 | size_t n = 2000; |
| 38 | #else |
| 39 | // ten million random points |
| 40 | size_t n = 10000000; |
| 41 | #endif |
| 42 | |
| 43 | // generate random numbers |
| 44 | compute::default_random_engine rng(queue); |
| 45 | compute::vector<uint_> vector(n * 2, context); |
| 46 | rng.generate(vector.begin(), vector.end(), queue); |
| 47 | |
| 48 | // function returing true if the point is within the unit circle |
| 49 | BOOST_COMPUTE_FUNCTION(bool, is_in_unit_circle, (const uint2_ point), |
| 50 | { |
| 51 | const float x = point.x / (float) UINT_MAX - 1; |
| 52 | const float y = point.y / (float) UINT_MAX - 1; |
| 53 | |
| 54 | return (x*x + y*y) < 1.0f; |
| 55 | }); |
| 56 | |
| 57 | // iterate over vector<uint> as vector<uint2> |
| 58 | compute::buffer_iterator<uint2_> start = |
| 59 | compute::make_buffer_iterator<uint2_>(vector.get_buffer(), 0); |
| 60 | compute::buffer_iterator<uint2_> end = |
| 61 | compute::make_buffer_iterator<uint2_>(vector.get_buffer(), vector.size() / 2); |
| 62 | |
| 63 | // count number of random points within the unit circle |
| 64 | size_t count = compute::count_if(start, end, is_in_unit_circle, queue); |
| 65 | |
| 66 | // print out values |
| 67 | float count_f = static_cast<float>(count); |
| 68 | std::cout << "count: " << count << " / " << n << std::endl; |
| 69 | std::cout << "ratio: " << count_f / float(n) << std::endl; |
| 70 | std::cout << "pi = " << (count_f / float(n)) * 4.0f << std::endl; |
| 71 | |
| 72 | return 0; |
| 73 | } |