1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2020) National Technology & Engineering
7 // Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44
45 #include <Kokkos_Core.hpp>
46 #include <TestHPX_Category.hpp>
47
48 #include <hpx/config.hpp>
49 #include <hpx/include/lcos.hpp>
50
51 #ifdef KOKKOS_ENABLE_HPX_ASYNC_DISPATCH
52 #ifndef HPX_COMPUTE_DEVICE_CODE
53
54 namespace Test {
55
56 namespace {
57 struct FunctorInitConstant {
58 Kokkos::View<int *, Kokkos::Experimental::HPX> a;
59 int c;
FunctorInitConstantTest::__anon6a1d44e30111::FunctorInitConstant60 FunctorInitConstant(Kokkos::View<int *, Kokkos::Experimental::HPX> a_, int c_)
61 : a(a_), c(c_) {}
62
63 KOKKOS_INLINE_FUNCTION
operator ()Test::__anon6a1d44e30111::FunctorInitConstant64 void operator()(const int i) const { a(i) = c; }
65 };
66
67 struct FunctorAdd {
68 Kokkos::View<int *, Kokkos::Experimental::HPX> a;
69 Kokkos::View<int *, Kokkos::Experimental::HPX> b;
70 int c;
FunctorAddTest::__anon6a1d44e30111::FunctorAdd71 FunctorAdd(Kokkos::View<int *, Kokkos::Experimental::HPX> a_,
72 Kokkos::View<int *, Kokkos::Experimental::HPX> b_, int c_)
73 : a(a_), b(b_), c(c_) {}
74
75 KOKKOS_INLINE_FUNCTION
operator ()Test::__anon6a1d44e30111::FunctorAdd76 void operator()(const int i) const { b(i) += a(i) + c; }
77 };
78
79 struct FunctorAddIndex {
80 Kokkos::View<int *, Kokkos::Experimental::HPX> a;
81 Kokkos::View<int *, Kokkos::Experimental::HPX> b;
FunctorAddIndexTest::__anon6a1d44e30111::FunctorAddIndex82 FunctorAddIndex(Kokkos::View<int *, Kokkos::Experimental::HPX> a_,
83 Kokkos::View<int *, Kokkos::Experimental::HPX> b_)
84 : a(a_), b(b_) {}
85
86 KOKKOS_INLINE_FUNCTION
operator ()Test::__anon6a1d44e30111::FunctorAddIndex87 void operator()(const int i) const { b(i) += a(i) + i; }
88 };
89
90 struct FunctorPointwiseSum {
91 Kokkos::View<int *, Kokkos::Experimental::HPX> a;
92 Kokkos::View<int *, Kokkos::Experimental::HPX> b;
93 Kokkos::View<int *, Kokkos::Experimental::HPX> c;
FunctorPointwiseSumTest::__anon6a1d44e30111::FunctorPointwiseSum94 FunctorPointwiseSum(Kokkos::View<int *, Kokkos::Experimental::HPX> a_,
95 Kokkos::View<int *, Kokkos::Experimental::HPX> b_,
96 Kokkos::View<int *, Kokkos::Experimental::HPX> c_)
97 : a(a_), b(b_), c(c_) {}
98
99 KOKKOS_INLINE_FUNCTION
operator ()Test::__anon6a1d44e30111::FunctorPointwiseSum100 void operator()(const int i) const { c(i) = a(i) + b(i); }
101 };
102
103 struct FunctorReduce {
104 Kokkos::View<int *, Kokkos::Experimental::HPX> a;
FunctorReduceTest::__anon6a1d44e30111::FunctorReduce105 FunctorReduce(Kokkos::View<int *, Kokkos::Experimental::HPX> a_) : a(a_) {}
106
107 KOKKOS_INLINE_FUNCTION
operator ()Test::__anon6a1d44e30111::FunctorReduce108 void operator()(const int i, int &lsum) const { lsum += a(i); }
109 };
110 } // namespace
111
TEST(hpx,independent_instances)112 TEST(hpx, independent_instances) {
113 Kokkos::InitArguments arguments{-1, -1, -1, false};
114 Kokkos::initialize(arguments);
115
116 const int n = 100;
117 const int c = 1;
118 const int d = 3;
119
120 {
121 Kokkos::View<int *, Kokkos::Experimental::HPX> v1("v1", n);
122 Kokkos::View<int *, Kokkos::Experimental::HPX> v2("v2", n);
123 Kokkos::View<int *, Kokkos::Experimental::HPX> v3("v3", n);
124 Kokkos::View<int *, Kokkos::Experimental::HPX> v4("v4", n);
125 Kokkos::View<int, Kokkos::Experimental::HPX> sum_v("sum_v");
126
127 Kokkos::Experimental::HPX hpx1(
128 Kokkos::Experimental::HPX::instance_mode::independent);
129 Kokkos::parallel_for(
130 "Test::hpx::independent_instances::init",
131 Kokkos::Experimental::require(
132 Kokkos::RangePolicy<Kokkos::Experimental::HPX>(hpx1, 0, n),
133 Kokkos::Experimental::WorkItemProperty::HintLightWeight),
134 FunctorInitConstant(v1, c));
135
136 Kokkos::Experimental::HPX hpx2(hpx1.impl_get_future());
137 Kokkos::parallel_for(
138 "Test::hpx::independent_instances::add",
139 Kokkos::Experimental::require(
140 Kokkos::RangePolicy<Kokkos::Experimental::HPX>(hpx2, 0, n),
141 Kokkos::Experimental::WorkItemProperty::HintLightWeight),
142 FunctorAdd(v1, v2, d));
143
144 Kokkos::Experimental::HPX hpx3(hpx1.impl_get_future());
145 Kokkos::parallel_for(
146 "Test::hpx::independent_instances::add_index",
147 Kokkos::Experimental::require(
148 Kokkos::RangePolicy<Kokkos::Experimental::HPX>(hpx3, 0, n),
149 Kokkos::Experimental::WorkItemProperty::HintLightWeight),
150 FunctorAddIndex(v1, v3));
151
152 // NOTE: This monstrosity is used to collapse a future<tuple<future<void>,
153 // future<void>>> (return type of when_all) into a future<void> which is
154 // ready whenever the un-collapsed future would've been ready. HPX does not
155 // currently have the functionality to collapse this automatically.
156 Kokkos::Experimental::HPX hpx4(hpx::util::get<0>(hpx::split_future(
157 hpx::when_all(hpx2.impl_get_future(), hpx3.impl_get_future()))));
158 Kokkos::parallel_for(
159 "Test::hpx::independent_instances::pointwise_sum",
160 Kokkos::Experimental::require(
161 Kokkos::RangePolicy<Kokkos::Experimental::HPX>(hpx4, 0, n),
162 Kokkos::Experimental::WorkItemProperty::HintLightWeight),
163 FunctorPointwiseSum(v2, v3, v4));
164
165 Kokkos::parallel_reduce(
166 "Test::hpx::independent_instances::reduce",
167 Kokkos::Experimental::require(
168 Kokkos::RangePolicy<Kokkos::Experimental::HPX>(hpx4, 0, n),
169 Kokkos::Experimental::WorkItemProperty::HintLightWeight),
170 FunctorReduce(v4), Kokkos::Sum<int>(sum_v));
171
172 hpx4.fence();
173
174 ASSERT_EQ(true, hpx1.impl_get_future().is_ready());
175 ASSERT_EQ(true, hpx2.impl_get_future().is_ready());
176 ASSERT_EQ(true, hpx3.impl_get_future().is_ready());
177 ASSERT_EQ(true, hpx4.impl_get_future().is_ready());
178
179 const int expected_sum = n * (2 * c + d) + (n * (n - 1) / 2);
180 ASSERT_EQ(expected_sum, sum_v());
181 }
182
183 Kokkos::finalize();
184 }
185 } // namespace Test
186
187 #endif
188 #endif
189