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 <gtest/gtest.h>
47
48 /// @Kokkos_Feature_Level_Required:5
49 // Unit test for reduction of native data type.
50 // Assigns an index based value to elements of an array.
51 // Performs an reduction over the addition operation.
52
53 namespace Test {
54
55 using value_type = double;
56 constexpr double value = 0.5;
57
58 struct ReduceFunctor {
59 KOKKOS_INLINE_FUNCTION
operator ()Test::ReduceFunctor60 void operator()(const int i, double &UpdateSum) const {
61 UpdateSum += (i + 1) * value;
62 }
63 };
64
65 struct NonTrivialReduceFunctor {
66 KOKKOS_INLINE_FUNCTION
operator ()Test::NonTrivialReduceFunctor67 void operator()(const int i, double &UpdateSum) const {
68 UpdateSum += (i + 1) * value;
69 }
70
71 NonTrivialReduceFunctor() = default;
72 NonTrivialReduceFunctor(NonTrivialReduceFunctor const &) = default;
73 NonTrivialReduceFunctor(NonTrivialReduceFunctor &&) = default;
74 NonTrivialReduceFunctor &operator=(NonTrivialReduceFunctor &&) = default;
75 NonTrivialReduceFunctor &operator=(NonTrivialReduceFunctor const &) = default;
~NonTrivialReduceFunctorTest::NonTrivialReduceFunctor76 ~NonTrivialReduceFunctor() {}
77 };
78
79 template <class ExecSpace>
80 struct TestReduction {
81 value_type sum = 0.0;
82 const int m_num_elements;
83
TestReductionTest::TestReduction84 TestReduction(int num_elements) : m_num_elements(num_elements) {}
85
86 // compare and equal
check_correctnessTest::TestReduction87 void check_correctness() {
88 const int sum_local = (m_num_elements * (m_num_elements + 1)) / 2;
89
90 ASSERT_EQ(sum, sum_local * value)
91 << "The reduced value does not match the expected answer";
92 }
93
94 // Routine to allocate memory in a specific memory space.
95 template <class MemSpace>
allocate_memTest::TestReduction96 value_type *allocate_mem(int N) {
97 return (static_cast<value_type *>(
98 Kokkos::kokkos_malloc<MemSpace>("deviceData", N * sizeof(value_type))));
99 }
100
101 // Routine to free the memory from a specific memory space.
102 template <class MemSpace>
free_memTest::TestReduction103 void free_mem(value_type *data) {
104 Kokkos::kokkos_free<MemSpace>(data);
105 }
106
sum_reductionTest::TestReduction107 void sum_reduction() {
108 sum = 0.0;
109
110 // Creates a range policy that uses dynamic schedule.
111 using range_policy =
112 Kokkos::RangePolicy<ExecSpace, Kokkos::Schedule<Kokkos::Dynamic> >;
113
114 // parallel_reduce call with range policy over num_elements number of
115 // iterations
116 Kokkos::parallel_reduce("Reduction", range_policy(0, m_num_elements),
117 ReduceFunctor{}, sum);
118
119 check_correctness();
120 }
121
non_trivial_sum_reductionTest::TestReduction122 void non_trivial_sum_reduction() {
123 sum = 0.0;
124
125 // Creates a range policy that uses dynamic schedule.
126 using range_policy =
127 Kokkos::RangePolicy<ExecSpace, Kokkos::Schedule<Kokkos::Dynamic> >;
128
129 // parallel_reduce call with range policy over num_elements number of
130 // iterations
131 Kokkos::parallel_reduce("Reduction", range_policy(0, m_num_elements),
132 NonTrivialReduceFunctor{}, sum);
133
134 check_correctness();
135 }
136 };
137
TEST(TEST_CATEGORY,IncrTest_05_reduction)138 TEST(TEST_CATEGORY, IncrTest_05_reduction) {
139 for (unsigned int i = 0; i < 100; ++i) {
140 TestReduction<TEST_EXECSPACE> test(i);
141 test.sum_reduction();
142 test.non_trivial_sum_reduction();
143 }
144 }
145
146 } // namespace Test
147