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 #ifndef KOKKOS_TEST_DYNAMICVIEW_HPP
46 #define KOKKOS_TEST_DYNAMICVIEW_HPP
47
48 #include <gtest/gtest.h>
49 #include <iostream>
50 #include <cstdlib>
51 #include <cstdio>
52 #include <Kokkos_Core.hpp>
53
54 #include <Kokkos_DynamicView.hpp>
55 #include <impl/Kokkos_Timer.hpp>
56
57 namespace Test {
58
59 template <typename Scalar, class Space>
60 struct TestDynamicView {
61 using execution_space = typename Space::execution_space;
62 using memory_space = typename Space::memory_space;
63
64 using view_type = Kokkos::Experimental::DynamicView<Scalar*, Space>;
65
66 using value_type = double;
67
runTest::TestDynamicView68 static void run(unsigned arg_total_size) {
69 // Test: Create DynamicView, initialize size (via resize), run through
70 // parallel_for to set values, check values (via parallel_reduce); resize
71 // values and repeat
72 // Case 1: min_chunk_size is a power of 2
73 {
74 {
75 view_type d1;
76 ASSERT_FALSE(d1.is_allocated());
77
78 d1 = view_type("d1", 1024, arg_total_size);
79 view_type d2(d1);
80 view_type d3("d3", 1024, arg_total_size);
81
82 ASSERT_FALSE(d1.is_allocated());
83 ASSERT_FALSE(d2.is_allocated());
84 ASSERT_FALSE(d3.is_allocated());
85
86 unsigned d_size = arg_total_size / 8;
87 d1.resize_serial(d_size);
88 d2.resize_serial(d_size);
89 d3.resize_serial(d_size);
90
91 ASSERT_TRUE(d1.is_allocated());
92 ASSERT_TRUE(d2.is_allocated());
93 ASSERT_TRUE(d3.is_allocated());
94 }
95 view_type da("da", 1024, arg_total_size);
96 ASSERT_EQ(da.size(), 0);
97 // Init
98 unsigned da_size = arg_total_size / 8;
99 da.resize_serial(da_size);
100 ASSERT_EQ(da.size(), da_size);
101
102 #if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA)
103 Kokkos::parallel_for(
104 Kokkos::RangePolicy<execution_space>(0, da_size),
105 KOKKOS_LAMBDA(const int i) { da(i) = Scalar(i); });
106
107 value_type result_sum = 0.0;
108 Kokkos::parallel_reduce(
109 Kokkos::RangePolicy<execution_space>(0, da_size),
110 KOKKOS_LAMBDA(const int i, value_type& partial_sum) {
111 partial_sum += (value_type)da(i);
112 },
113 result_sum);
114
115 ASSERT_EQ(result_sum, (value_type)(da_size * (da_size - 1) / 2));
116 #endif
117
118 // add 3x more entries i.e. 4x larger than previous size
119 // the first 1/4 should remain the same
120 unsigned da_resize = arg_total_size / 2;
121 da.resize_serial(da_resize);
122 ASSERT_EQ(da.size(), da_resize);
123
124 #if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA)
125 Kokkos::parallel_for(
126 Kokkos::RangePolicy<execution_space>(da_size, da_resize),
127 KOKKOS_LAMBDA(const int i) { da(i) = Scalar(i); });
128
129 value_type new_result_sum = 0.0;
130 Kokkos::parallel_reduce(
131 Kokkos::RangePolicy<execution_space>(da_size, da_resize),
132 KOKKOS_LAMBDA(const int i, value_type& partial_sum) {
133 partial_sum += (value_type)da(i);
134 },
135 new_result_sum);
136
137 ASSERT_EQ(new_result_sum + result_sum,
138 (value_type)(da_resize * (da_resize - 1) / 2));
139 #endif
140 } // end scope
141
142 // Test: Create DynamicView, initialize size (via resize), run through
143 // parallel_for to set values, check values (via parallel_reduce); resize
144 // values and repeat
145 // Case 2: min_chunk_size is NOT a power of 2
146 {
147 view_type da("da", 1023, arg_total_size);
148 ASSERT_EQ(da.size(), 0);
149 // Init
150 unsigned da_size = arg_total_size / 8;
151 da.resize_serial(da_size);
152 ASSERT_EQ(da.size(), da_size);
153
154 #if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA)
155 Kokkos::parallel_for(
156 Kokkos::RangePolicy<execution_space>(0, da_size),
157 KOKKOS_LAMBDA(const int i) { da(i) = Scalar(i); });
158
159 value_type result_sum = 0.0;
160 Kokkos::parallel_reduce(
161 Kokkos::RangePolicy<execution_space>(0, da_size),
162 KOKKOS_LAMBDA(const int i, value_type& partial_sum) {
163 partial_sum += (value_type)da(i);
164 },
165 result_sum);
166
167 ASSERT_EQ(result_sum, (value_type)(da_size * (da_size - 1) / 2));
168 #endif
169
170 // add 3x more entries i.e. 4x larger than previous size
171 // the first 1/4 should remain the same
172 unsigned da_resize = arg_total_size / 2;
173 da.resize_serial(da_resize);
174 ASSERT_EQ(da.size(), da_resize);
175
176 #if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA)
177 Kokkos::parallel_for(
178 Kokkos::RangePolicy<execution_space>(da_size, da_resize),
179 KOKKOS_LAMBDA(const int i) { da(i) = Scalar(i); });
180
181 value_type new_result_sum = 0.0;
182 Kokkos::parallel_reduce(
183 Kokkos::RangePolicy<execution_space>(da_size, da_resize),
184 KOKKOS_LAMBDA(const int i, value_type& partial_sum) {
185 partial_sum += (value_type)da(i);
186 },
187 new_result_sum);
188
189 ASSERT_EQ(new_result_sum + result_sum,
190 (value_type)(da_resize * (da_resize - 1) / 2));
191 #endif
192 } // end scope
193
194 // Test: Create DynamicView, initialize size (via resize), run through
195 // parallel_for to set values, check values (via parallel_reduce); resize
196 // values and repeat
197 // Case 3: resize reduces the size
198 {
199 view_type da("da", 1023, arg_total_size);
200 ASSERT_EQ(da.size(), 0);
201 // Init
202 unsigned da_size = arg_total_size / 2;
203 da.resize_serial(da_size);
204 ASSERT_EQ(da.size(), da_size);
205
206 #if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA)
207 Kokkos::parallel_for(
208 Kokkos::RangePolicy<execution_space>(0, da_size),
209 KOKKOS_LAMBDA(const int i) { da(i) = Scalar(i); });
210
211 value_type result_sum = 0.0;
212 Kokkos::parallel_reduce(
213 Kokkos::RangePolicy<execution_space>(0, da_size),
214 KOKKOS_LAMBDA(const int i, value_type& partial_sum) {
215 partial_sum += (value_type)da(i);
216 },
217 result_sum);
218
219 ASSERT_EQ(result_sum, (value_type)(da_size * (da_size - 1) / 2));
220 #endif
221
222 // remove the final 3/4 entries i.e. first 1/4 remain
223 unsigned da_resize = arg_total_size / 8;
224 da.resize_serial(da_resize);
225 ASSERT_EQ(da.size(), da_resize);
226
227 #if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA)
228 Kokkos::parallel_for(
229 Kokkos::RangePolicy<execution_space>(0, da_resize),
230 KOKKOS_LAMBDA(const int i) { da(i) = Scalar(i); });
231
232 value_type new_result_sum = 0.0;
233 Kokkos::parallel_reduce(
234 Kokkos::RangePolicy<execution_space>(0, da_resize),
235 KOKKOS_LAMBDA(const int i, value_type& partial_sum) {
236 partial_sum += (value_type)da(i);
237 },
238 new_result_sum);
239
240 ASSERT_EQ(new_result_sum, (value_type)(da_resize * (da_resize - 1) / 2));
241 #endif
242 } // end scope
243 }
244 };
245
TEST(TEST_CATEGORY,dynamic_view)246 TEST(TEST_CATEGORY, dynamic_view) {
247 using TestDynView = TestDynamicView<double, TEST_EXECSPACE>;
248
249 for (int i = 0; i < 10; ++i) {
250 TestDynView::run(100000 + 100 * i);
251 }
252 }
253
254 } // namespace Test
255
256 #endif /* #ifndef KOKKOS_TEST_DYNAMICVIEW_HPP */
257