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 <cstdio>
46 
47 #include <gtest/gtest.h>
48 
49 #include <Kokkos_Core.hpp>
50 
51 namespace Test {
52 
53 namespace {
54 
55 template <class ViewType>
56 struct CheckResult {
57   using value_type = typename ViewType::non_const_value_type;
58   ViewType v;
59   value_type value;
CheckResultTest::__anon64ebde7d0111::CheckResult60   CheckResult(ViewType v_, value_type value_) : v(v_), value(value_){};
61   KOKKOS_FUNCTION
operator ()Test::__anon64ebde7d0111::CheckResult62   void operator()(const int i, int& lsum) const {
63     for (int j = 0; j < static_cast<int>(v.extent(1)); j++) {
64       if (v.access(i, j) != value) lsum++;
65     }
66   }
67 };
68 
69 template <class ViewType>
run_check(ViewType v,typename ViewType::value_type value)70 bool run_check(ViewType v, typename ViewType::value_type value) {
71   using exec_space = typename ViewType::memory_space::execution_space;
72   int errors       = 0;
73   Kokkos::fence();
74   Kokkos::parallel_reduce(Kokkos::RangePolicy<exec_space>(0, v.extent(0)),
75                           CheckResult<ViewType>(v, value), errors);
76   return errors == 0;
77 }
78 
79 }  // namespace
80 
TEST(TEST_CATEGORY,view_copy_tests)81 TEST(TEST_CATEGORY, view_copy_tests) {
82   int N = 10000;
83   int M = 10;
84 
85   Kokkos::View<int**, Kokkos::LayoutRight, TEST_EXECSPACE> defaulted;
86   Kokkos::View<int**, Kokkos::LayoutRight, TEST_EXECSPACE> a("A", N, M);
87   Kokkos::View<int**, Kokkos::LayoutRight, TEST_EXECSPACE> b("B", N, M);
88   auto h_a  = Kokkos::create_mirror(a);
89   auto h_b  = Kokkos::create_mirror(b);
90   auto m_a  = Kokkos::create_mirror_view(a);
91   auto s_a  = Kokkos::subview(a, Kokkos::ALL, 1);
92   auto s_b  = Kokkos::subview(b, Kokkos::ALL, 1);
93   auto hs_a = Kokkos::subview(h_a, Kokkos::ALL, 1);
94   auto hs_b = Kokkos::subview(h_b, Kokkos::ALL, 1);
95   auto dev  = typename TEST_EXECSPACE::execution_space();
96   auto host = Kokkos::DefaultHostExecutionSpace();
97 
98   constexpr bool DevExecCanAccessHost =
99       Kokkos::Impl::SpaceAccessibility<typename TEST_EXECSPACE::execution_space,
100                                        Kokkos::HostSpace>::accessible;
101 
102   constexpr bool HostExecCanAccessDev = Kokkos::Impl::SpaceAccessibility<
103       typename Kokkos::HostSpace::execution_space,
104       typename TEST_EXECSPACE::memory_space>::accessible;
105 
106   // Contiguous copies
107   { Kokkos::deep_copy(defaulted, defaulted); }
108   {
109     Kokkos::deep_copy(a, 1);
110     ASSERT_TRUE(run_check(a, 1));
111   }
112   {
113     Kokkos::deep_copy(a, a);
114     ASSERT_TRUE(run_check(a, 1));
115   }
116   {
117     Kokkos::deep_copy(m_a, a);
118     ASSERT_TRUE(run_check(m_a, 1));
119   }
120   {
121     Kokkos::deep_copy(m_a, 2);
122     ASSERT_TRUE(run_check(m_a, 2));
123   }
124   {
125     Kokkos::deep_copy(a, m_a);
126     ASSERT_TRUE(run_check(a, 2));
127   }
128   {
129     Kokkos::deep_copy(b, 3);
130     ASSERT_TRUE(run_check(b, 3));
131   }
132   {
133     Kokkos::deep_copy(h_a, 4);
134     ASSERT_TRUE(run_check(h_a, 4));
135   }
136   {
137     Kokkos::deep_copy(a, b);
138     ASSERT_TRUE(run_check(a, 3));
139   }
140   {
141     Kokkos::deep_copy(h_b, h_a);
142     ASSERT_TRUE(run_check(h_b, 4));
143   }
144   {
145     Kokkos::deep_copy(h_a, a);
146     ASSERT_TRUE(run_check(h_a, 3));
147   }
148   {
149     Kokkos::deep_copy(b, h_b);
150     ASSERT_TRUE(run_check(b, 4));
151   }
152   // Non contiguous copies
153   {
154     Kokkos::deep_copy(s_a, 5);
155     ASSERT_TRUE(run_check(s_a, 5));
156   }
157   {
158     Kokkos::deep_copy(hs_a, 6);
159     ASSERT_TRUE(run_check(hs_a, 6));
160   }
161   {
162     Kokkos::deep_copy(s_b, s_a);
163     ASSERT_TRUE(run_check(s_b, 5));
164   }
165   {
166     Kokkos::deep_copy(hs_b, hs_a);
167     ASSERT_TRUE(run_check(hs_b, 6));
168   }
169   if (DevExecCanAccessHost || HostExecCanAccessDev) {
170     {
171       Kokkos::deep_copy(hs_b, s_b);
172       ASSERT_TRUE(run_check(hs_b, 5));
173     }
174     {
175       Kokkos::deep_copy(s_a, hs_a);
176       ASSERT_TRUE(run_check(s_a, 6));
177     }
178   }
179 
180   // Contiguous copies
181   { Kokkos::deep_copy(dev, defaulted, defaulted); }
182   {
183     Kokkos::deep_copy(dev, a, 1);
184     ASSERT_TRUE(run_check(a, 1));
185   }
186   {
187     Kokkos::deep_copy(dev, a, a);
188     ASSERT_TRUE(run_check(a, 1));
189   }
190   {
191     Kokkos::deep_copy(dev, m_a, a);
192     ASSERT_TRUE(run_check(m_a, 1));
193   }
194   {
195     Kokkos::deep_copy(dev, m_a, 2);
196     ASSERT_TRUE(run_check(m_a, 2));
197   }
198   {
199     Kokkos::deep_copy(dev, a, m_a);
200     ASSERT_TRUE(run_check(a, 2));
201   }
202   {
203     Kokkos::deep_copy(dev, b, 3);
204     ASSERT_TRUE(run_check(b, 3));
205   }
206   {
207     Kokkos::deep_copy(dev, h_a, 4);
208     ASSERT_TRUE(run_check(h_a, 4));
209   }
210   {
211     Kokkos::deep_copy(dev, a, b);
212     ASSERT_TRUE(run_check(a, 3));
213   }
214   {
215     Kokkos::deep_copy(dev, h_b, h_a);
216     ASSERT_TRUE(run_check(h_b, 4));
217   }
218   {
219     Kokkos::deep_copy(dev, h_a, a);
220     ASSERT_TRUE(run_check(h_a, 3));
221   }
222   {
223     Kokkos::deep_copy(dev, b, h_b);
224     ASSERT_TRUE(run_check(b, 4));
225   }
226   // Non contiguous copies
227   {
228     Kokkos::deep_copy(dev, s_a, 5);
229     ASSERT_TRUE(run_check(s_a, 5));
230   }
231   {
232     Kokkos::deep_copy(dev, hs_a, 6);
233     ASSERT_TRUE(run_check(hs_a, 6));
234   }
235   {
236     Kokkos::deep_copy(dev, s_b, s_a);
237     ASSERT_TRUE(run_check(s_b, 5));
238   }
239   {
240     Kokkos::deep_copy(dev, hs_b, hs_a);
241     ASSERT_TRUE(run_check(hs_b, 6));
242   }
243   if (DevExecCanAccessHost || HostExecCanAccessDev) {
244     {
245       Kokkos::deep_copy(dev, hs_b, s_b);
246       ASSERT_TRUE(run_check(hs_b, 5));
247     }
248     {
249       Kokkos::deep_copy(dev, s_a, hs_a);
250       ASSERT_TRUE(run_check(s_a, 6));
251     }
252   }
253 
254   // Contiguous copies
255   { Kokkos::deep_copy(host, defaulted, defaulted); }
256   {
257     Kokkos::deep_copy(host, a, 1);
258     ASSERT_TRUE(run_check(a, 1));
259   }
260   {
261     Kokkos::deep_copy(host, a, a);
262     ASSERT_TRUE(run_check(a, 1));
263   }
264   {
265     Kokkos::deep_copy(host, m_a, a);
266     ASSERT_TRUE(run_check(m_a, 1));
267   }
268   {
269     Kokkos::deep_copy(host, m_a, 2);
270     ASSERT_TRUE(run_check(m_a, 2));
271   }
272   {
273     Kokkos::deep_copy(host, a, m_a);
274     ASSERT_TRUE(run_check(a, 2));
275   }
276   {
277     Kokkos::deep_copy(host, b, 3);
278     ASSERT_TRUE(run_check(b, 3));
279   }
280   {
281     Kokkos::deep_copy(host, h_a, 4);
282     ASSERT_TRUE(run_check(h_a, 4));
283   }
284   {
285     Kokkos::deep_copy(host, a, b);
286     ASSERT_TRUE(run_check(a, 3));
287   }
288   {
289     Kokkos::deep_copy(host, h_b, h_a);
290     ASSERT_TRUE(run_check(h_b, 4));
291   }
292   {
293     Kokkos::deep_copy(host, h_a, a);
294     ASSERT_TRUE(run_check(h_a, 3));
295   }
296   {
297     Kokkos::deep_copy(host, b, h_b);
298     ASSERT_TRUE(run_check(b, 4));
299   }
300   // Non contiguous copies
301   {
302     Kokkos::deep_copy(host, s_a, 5);
303     ASSERT_TRUE(run_check(s_a, 5));
304   }
305   {
306     Kokkos::deep_copy(host, hs_a, 6);
307     ASSERT_TRUE(run_check(hs_a, 6));
308   }
309   {
310     Kokkos::deep_copy(host, s_b, s_a);
311     ASSERT_TRUE(run_check(s_b, 5));
312   }
313   {
314     Kokkos::deep_copy(host, hs_b, hs_a);
315     ASSERT_TRUE(run_check(hs_b, 6));
316   }
317   if (DevExecCanAccessHost || HostExecCanAccessDev) {
318     {
319       Kokkos::deep_copy(host, hs_b, s_b);
320       ASSERT_TRUE(run_check(hs_b, 5));
321     }
322     {
323       Kokkos::deep_copy(host, s_a, hs_a);
324       ASSERT_TRUE(run_check(s_a, 6));
325     }
326   }
327 }
328 }  // namespace Test
329