99#include < hpx/init.hpp>
1010#include < hpx/runtime.hpp>
1111//
12+ #include < cmath>
1213#include < iostream>
1314#include < random>
1415#include < utility>
2223// any fail = !pass rule, then this example shows how to do it.
2324// The user can experiment with the failure rate to see if the statistics match
2425// their expectations.
25- // Also. Routine can use either a lambda, or a function under control of USE_LAMBDA
26+ // Al
2627
27- # define TEST_SUCCESS 1
28- # define TEST_FAIL 0
28+ constexpr int TEST_SUCCESS = 1 ;
29+ constexpr int TEST_FAIL = 0 ;
2930//
30- # define FAILURE_RATE_PERCENT 5
31- # define SAMPLES_PER_LOOP 10
32- # define TEST_LOOPS 1000
31+ constexpr int FAILURE_RATE_PERCENT = 0 ;
32+ constexpr int SAMPLES_PER_LOOP = 10 ;
33+ constexpr int TEST_LOOPS = 1000 ;
3334//
34- std::random_device rseed ;
35- std::mt19937 gen (rseed() );
36- std::uniform_int_distribution<int > dist (0 , 99 ); // interval [0,100)
35+ constexpr unsigned SEED = 42u ;
36+ static std::mt19937 gen (SEED );
37+ static std::uniform_int_distribution<int > dist (0 , 99 ); // interval [0,100)
3738
38- # define USE_LAMBDA
39+ constexpr bool USE_LAMBDA = true ;
3940
4041// ----------------------------------------------------------------------------
4142int reduce (hpx::future<std::vector<hpx::future<int >>>&& futvec)
@@ -67,34 +68,37 @@ hpx::future<int> test_reduce()
6768{
6869 std::vector<hpx::future<int >> req_futures;
6970 //
70- for (int i = 0 ; i < SAMPLES_PER_LOOP; i++ )
71+ for (int i = 0 ; i < SAMPLES_PER_LOOP; ++i )
7172 {
72- // generate random sequence of pass/fails using % fail rate per incident
73- hpx::future<int > result = hpx::async (generate_one);
74- req_futures.push_back (std::move (result));
73+ req_futures.push_back (hpx::async (&generate_one));
7574 }
7675
7776 hpx::future<std::vector<hpx::future<int >>> all_ready =
7877 hpx::when_all (req_futures);
7978
80- #ifdef USE_LAMBDA
81- hpx::future<int > result = all_ready.then (
82- [](hpx::future<std::vector<hpx::future<int >>>&& futvec) -> int {
83- // futvec is ready or the lambda would not be called
84- std::vector<hpx::future<int >> vfs = futvec.get ();
85- // all futures in v are ready as fut is ready
86- int res = TEST_SUCCESS;
87- for (hpx::future<int >& f : vfs)
88- {
89- if (f.get () == TEST_FAIL)
90- return TEST_FAIL;
91- }
92- return res;
93- });
94- #else
95- hpx::future<int > result = all_ready.then (reduce);
96- #endif
97- //
79+ hpx::future<int > result;
80+ if constexpr (USE_LAMBDA)
81+ {
82+ result = all_ready.then (
83+ [](hpx::future<std::vector<hpx::future<int >>>&& futvec) -> int {
84+ std::vector<hpx::future<int >> vfs = futvec.get ();
85+ int res = TEST_SUCCESS;
86+
87+ hpx::wait_each (
88+ [&res](hpx::future<int > f) {
89+ if (f.get () == TEST_FAIL)
90+ res = TEST_FAIL;
91+ },
92+ vfs);
93+
94+ return res;
95+ });
96+ }
97+ else
98+ {
99+ result = all_ready.then (reduce);
100+ }
101+
98102 return result;
99103}
100104
@@ -104,18 +108,20 @@ int hpx_main()
104108 hpx::chrono::high_resolution_timer htimer;
105109 // run N times and see if we get approximately the right amount of fails
106110 int count = 0 ;
107- for (int i = 0 ; i < TEST_LOOPS; i++ )
111+ for (int i = 0 ; i < TEST_LOOPS; ++i )
108112 {
109113 int result = test_reduce ().get ();
110114 count += result;
111115 }
116+
112117 double pr_pass =
113118 std::pow (1.0 - FAILURE_RATE_PERCENT / 100.0 , SAMPLES_PER_LOOP);
114119 double exp_pass = TEST_LOOPS * pr_pass;
115- std::cout << " From " << TEST_LOOPS << " tests, we got "
116- << " \n " << count << " passes"
117- << " \n " << exp_pass << " expected \n "
118- << " \n " << htimer.elapsed () << " seconds \n "
120+
121+ std::cout << " From " << TEST_LOOPS << " tests, we got\n "
122+ << " " << count << " passes\n "
123+ << " " << exp_pass << " expected\n\n "
124+ << " Elapsed: " << htimer.elapsed () << " seconds\n "
119125 << std::flush;
120126 // Initiate shutdown of the runtime system.
121127 return hpx::local::finalize ();
0 commit comments