1 // Copyright (c) 2017 Antoine Tran Tan
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/partitioned_vector_predef.hpp>
8 #include <hpx/include/partitioned_vector_view.hpp>
9 #include <hpx/lcos/spmd_block.hpp>
10
11 #include <hpx/util/lightweight_test.hpp>
12
13 #include <cstddef>
14 #include <string>
15 #include <type_traits>
16 #include <utility>
17 #include <vector>
18
19 ///////////////////////////////////////////////////////////////////////////////
20 // The vector types to be used are defined in partitioned_vector module.
21 // HPX_REGISTER_PARTITIONED_VECTOR(double);
22
bulk_test(hpx::lcos::spmd_block block,std::size_t size_x,std::size_t size_y,std::size_t size_z,std::size_t elt_size,std::string vec_name)23 void bulk_test( hpx::lcos::spmd_block block,
24 std::size_t size_x,
25 std::size_t size_y,
26 std::size_t size_z,
27 std::size_t elt_size,
28 std::string vec_name)
29 {
30 using const_iterator
31 = typename std::vector<double>::const_iterator;
32 using vector_type
33 = hpx::partitioned_vector<double>;
34 using view_type
35 = hpx::partitioned_vector_view<double,3>;
36 using view_type_iterator
37 = typename view_type::iterator;
38 using const_view_type_iterator
39 = typename view_type::const_iterator;
40
41 vector_type my_vector;
42 my_vector.connect_to(hpx::launch::sync, vec_name);
43
44 view_type my_view(block,
45 my_vector.begin(), my_vector.end(), {size_x,size_y,size_z});
46
47 int idx = 0;
48
49 // Ensure that only one image is putting data into the different
50 // partitions
51 if(block.this_image() == 0)
52 {
53 // Traverse all the co-indexed elements
54 for(auto i = my_view.begin(); i != my_view.end(); i++)
55 {
56 // It's a Put operation
57 *i = std::vector<double>(elt_size,idx++);
58 }
59
60 auto left_it = my_view.begin();
61 auto right_it = my_view.cbegin();
62
63 // Note: Useless computation, since we assign segments to themselves
64 for(; left_it != my_view.end(); left_it++, right_it++)
65 {
66 // Check that dereferencing iterator and const_iterator does not
67 // retrieve the same type
68 HPX_TEST((
69 !std::is_same<decltype(*left_it),decltype(*right_it)>::value));
70
71 // It's a Put operation
72 *left_it = *right_it;
73 }
74 }
75
76 block.sync_all();
77
78 if(block.this_image() == 0)
79 {
80 int idx = 0;
81
82 for (std::size_t k = 0; k<size_z; k++)
83 for (std::size_t j = 0; j<size_y; j++)
84 for (std::size_t i = 0; i<size_x; i++)
85 {
86 std::vector<double> result(elt_size,idx);
87
88 // It's a Get operation
89 std::vector<double> value =
90 (std::vector<double>)my_view(i,j,k);
91
92 const_iterator it1 = result.begin(), it2 = value.begin();
93 const_iterator end1 = result.end();
94
95 for (; it1 != end1; ++it1, ++it2)
96 {
97 HPX_TEST_EQ(*it1, *it2);
98 }
99
100 idx++;
101 }
102
103 idx = 0;
104
105 // Re-check by traversing all the co-indexed elements
106 for(auto i = my_view.cbegin(); i != my_view.cend(); i++)
107 {
108 std::vector<double> result(elt_size,idx);
109
110 // It's a Get operation
111 std::vector<double> value = (std::vector<double>)(*i);
112
113 const_iterator it1 = result.begin(), it2 = value.begin();
114 const_iterator end1 = result.end();
115
116 for (; it1 != end1; ++it1, ++it2)
117 {
118 HPX_TEST_EQ(*it1, *it2);
119 }
120
121 idx++;
122 }
123 }
124 }
125 HPX_PLAIN_ACTION(bulk_test, bulk_test_action);
126
main()127 int main()
128 {
129 using vector_type
130 = hpx::partitioned_vector<double>;
131
132 const std::size_t size_x = 32;
133 const std::size_t size_y = 4;
134 const std::size_t size_z = hpx::get_num_localities(hpx::launch::sync);
135
136 const std::size_t elt_size = 4;
137 const std::size_t num_partitions = size_x*size_y*size_z;
138
139 std::size_t raw_size = num_partitions*elt_size;
140
141 vector_type my_vector(raw_size,
142 hpx::container_layout( num_partitions, hpx::find_all_localities() ));
143
144 std::string vec_name("my_vector");
145 my_vector.register_as(hpx::launch::sync, vec_name);
146
147 hpx::future<void> join =
148 hpx::lcos::define_spmd_block("block", 4, bulk_test_action(),
149 size_x, size_y, size_z, elt_size, vec_name);
150
151 join.get();
152
153 return 0;
154 }
155