1 ////////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2014-2015 Oregon University
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ////////////////////////////////////////////////////////////////////////////////
7
8 // Naive SMP version implemented with futures.
9
10 #include <hpx/hpx_init.hpp>
11 #include <hpx/include/actions.hpp>
12 #include <hpx/include/lcos.hpp>
13 #include <hpx/include/util.hpp>
14
15 #include <apex_api.hpp>
16
17 #include <cmath>
18 #include <cstdint>
19 #include <iostream>
20 #include <list>
21 #include <random>
22 #include <vector>
23
24 double do_work(std::uint64_t n);
25
26 HPX_PLAIN_ACTION(do_work, do_work_action);
27
do_work(std::uint64_t n)28 double do_work(std::uint64_t n) {
29 double result = 1;
30 for(std::uint64_t i = 0; i < n; ++i) {
31 result += std::sin((double)i) * (double)i;
32 }
33 return result;
34 }
35
36
next_locality(const std::vector<double> & probs)37 size_t next_locality( const std::vector<double> & probs) {
38 static std::default_random_engine generator;
39 static std::uniform_real_distribution<double> distribution(0.0, 1.0);
40 const double eps = 1e-9;
41 double r = distribution(generator);
42
43 size_t i = 0;
44 for(const double p : probs) {
45 r -= p;
46 if(r < eps) {
47 return i;
48 }
49 ++i;
50 }
51 return 0;
52 }
53
hpx_main(boost::program_options::variables_map & vm)54 int hpx_main(boost::program_options::variables_map& vm)
55 {
56 // extract command line argument, i.e. fib(N)
57 std::uint64_t n = vm["n-value"].as<std::uint64_t>();
58 std::uint64_t units = vm["units"].as<std::uint64_t>();
59 std::uint64_t blocks = vm["blocks"].as<std::uint64_t>();
60
61 // Keep track of the time required to execute.
62 hpx::util::high_resolution_timer t;
63
64 std::vector<hpx::naming::id_type> localities = hpx::find_all_localities();
65 std::vector<double> probabilities(localities.size());
66 probabilities[0] = 1.0;
67
68 std::cout << "There are " << localities.size() << " localities." << std::endl;
69 std::cout << "Units: " << units << " n: " << n << std::endl;
70
71 for(std::uint64_t block = 0; block < blocks; ++block) {
72 std::cout << "Block " << block << std::endl;
73 std::list<std::uint64_t> work(units, n);
74 std::list<hpx::lcos::future<double> > futures;
75 for(std::uint64_t & item : work) {
76 do_work_action act;
77 size_t next = next_locality(probabilities);
78 std::cout << "Will issue work to loc " << next << std::endl;
79 futures.push_back(hpx::async(act, localities[next], item));
80 }
81 std::cout << "Issued work for block " << block << std::endl;
82 hpx::lcos::wait_all(futures.begin(), futures.end());
83 std::cout << "Work done for block " << block << std::endl;
84 }
85
86
87 char const* fmt = "elapsed time: {1} [s]\n";
88 hpx::util::format_to(std::cout, fmt, t.elapsed());
89
90 return hpx::finalize(); // Handles HPX shutdown
91 }
92
register_policy(void)93 void register_policy(void) {
94 apex::register_periodic_policy(1000000, [](apex_context const& context) {
95 std::cout << "Periodic policy!" << std::endl;
96 return APEX_NOERROR;
97 });
98 }
99
100 ///////////////////////////////////////////////////////////////////////////////
main(int argc,char * argv[])101 int main(int argc, char* argv[])
102 {
103 // Configure application-specific options
104 boost::program_options::options_description
105 desc_commandline("Usage: " HPX_APPLICATION_STRING " [options]");
106
107 desc_commandline.add_options()
108 ( "n-value",
109 boost::program_options::value<std::uint64_t>()->default_value(1000000),
110 "n value for do_work")
111 ;
112
113 desc_commandline.add_options()
114 ( "units",
115 boost::program_options::value<std::uint64_t>()->default_value(100),
116 "units of work per block")
117 ;
118
119 desc_commandline.add_options()
120 ( "blocks",
121 boost::program_options::value<std::uint64_t>()->default_value(10),
122 "blocks before program completion")
123 ;
124 hpx::register_startup_function(register_policy);
125
126 // Initialize and run HPX
127 return hpx::init(desc_commandline, argc, argv);
128 }
129