1 // Copyright (c) 2015 Hartmut Kaiser
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <hpx/hpx_main.hpp>
7 #include <hpx/include/components.hpp>
8 #include <hpx/include/actions.hpp>
9 #include <hpx/util/lightweight_test.hpp>
10
11 #include <cstddef>
12 #include <cstdint>
13 #include <string>
14 #include <utility>
15 #include <vector>
16
17 ///////////////////////////////////////////////////////////////////////////////
18 struct test_server : hpx::components::simple_component_base<test_server>
19 {
calltest_server20 hpx::id_type call() const { return hpx::find_here(); }
21
22 HPX_DEFINE_COMPONENT_ACTION(test_server, call);
23 };
24
25 typedef hpx::components::simple_component<test_server> server_type;
26 HPX_REGISTER_COMPONENT(server_type, test_server);
27
28 typedef test_server::call_action call_action;
29 HPX_REGISTER_ACTION(call_action);
30
31 struct test_client : hpx::components::client_base<test_client, test_server>
32 {
33 typedef hpx::components::client_base<test_client, test_server> base_type;
34
test_clienttest_client35 test_client(hpx::future<hpx::id_type>&& id)
36 : base_type(std::move(id))
37 {}
test_clienttest_client38 test_client(hpx::id_type&& id)
39 : base_type(std::move(id))
40 {}
41
calltest_client42 hpx::id_type call()
43 {
44 return hpx::async<call_action>(this->get_id()).get();
45 }
46 };
47
48 ///////////////////////////////////////////////////////////////////////////////
test_binpacking_multiple()49 std::vector<hpx::id_type> test_binpacking_multiple()
50 {
51 std::vector<hpx::id_type> keep_alive;
52
53 // create an increasing number of instances on all available localities
54 std::vector<std::vector<hpx::id_type> > targets;
55
56 std::vector<hpx::id_type> localities = hpx::find_all_localities();
57
58 for (std::size_t i = 0; i != localities.size(); ++i)
59 {
60 hpx::id_type const& loc = localities[i];
61
62 targets.push_back(hpx::new_<test_server[]>(loc, i + 1).get());
63 for (hpx::id_type const& id: targets.back())
64 {
65 HPX_TEST(hpx::async<call_action>(id).get() == loc);
66 keep_alive.push_back(id);
67 }
68 }
69
70 std::string counter_name(hpx::components::default_binpacking_counter_name);
71 counter_name += "test_server";
72
73 std::uint64_t count = 0;
74 for (std::size_t i = 0; i != localities.size(); ++i)
75 {
76 hpx::performance_counters::performance_counter instances(
77 counter_name, localities[i]);
78
79 std::uint64_t c = instances.get_value<std::uint64_t>(hpx::launch::sync);
80 count += c;
81 HPX_TEST_EQ(c, i + 1);
82 }
83
84 HPX_TEST_EQ(count, keep_alive.size());
85
86 // now use bin-packing policy to fill up the number of instances
87 std::vector<hpx::id_type> filled_targets =
88 hpx::new_<test_server[]>(hpx::binpacked(localities), count).get();
89
90 // now, all localities should have the same number of instances
91 std::uint64_t new_count = 0;
92 for (std::size_t i = 0; i != localities.size(); ++i)
93 {
94 hpx::performance_counters::performance_counter instances(
95 counter_name, localities[i]);
96
97 std::uint64_t c =
98 instances.get_value<std::uint64_t>(hpx::launch::sync);
99 new_count += c;
100 HPX_TEST_EQ(c, localities.size() + 1);
101 }
102
103 HPX_TEST_EQ(2*count, new_count);
104
105 for (hpx::id_type const& id: filled_targets)
106 keep_alive.push_back(id);
107
108 return keep_alive;
109 }
110
111 ///////////////////////////////////////////////////////////////////////////////
test_binpacking_single()112 void test_binpacking_single()
113 {
114 // create an increasing number of instances on all available localities
115 std::vector<std::vector<hpx::id_type> > targets;
116
117 std::vector<hpx::id_type> localities = hpx::find_all_localities();
118 for (std::size_t i = 0; i != localities.size(); ++i)
119 {
120 hpx::id_type const& loc = localities[i];
121
122 targets.push_back(hpx::new_<test_server[]>(loc, i+1).get());
123 for (hpx::id_type const& id: targets.back())
124 {
125 HPX_TEST(hpx::async<call_action>(id).get() == loc);
126 }
127 }
128
129 std::string counter_name(hpx::components::default_binpacking_counter_name);
130 counter_name += "test_server";
131
132 hpx::performance_counters::performance_counter instances(
133 counter_name, localities[0]);
134 std::uint64_t before =
135 instances.get_value<std::uint64_t>(hpx::launch::sync);
136
137 // now use bin-packing policy to create one more instance
138 hpx::id_type filled_target = hpx::new_<test_server>(
139 hpx::binpacked(localities)).get();
140
141 // now, the first locality should have one more instance
142 std::uint64_t after =
143 instances.get_value<std::uint64_t>(hpx::launch::sync);
144
145 HPX_TEST_EQ(before+1, after);
146 }
147
main()148 int main()
149 {
150 std::vector<hpx::id_type> ids = test_binpacking_multiple();
151 test_binpacking_single();
152
153 return hpx::util::report_errors();
154 }
155
156