Update Kokkos library in LAMMPS to v3.6.0
This commit is contained in:
716
lib/kokkos/algorithms/unit_tests/TestStdAlgorithmsNumerics.cpp
Normal file
716
lib/kokkos/algorithms/unit_tests/TestStdAlgorithmsNumerics.cpp
Normal file
@ -0,0 +1,716 @@
|
||||
/*
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 3.0
|
||||
// Copyright (2020) National Technology & Engineering
|
||||
// Solutions of Sandia, LLC (NTESS).
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact Christian R. Trott (crtrott@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
*/
|
||||
|
||||
#include <TestStdAlgorithmsCommon.hpp>
|
||||
#include <std_algorithms/Kokkos_Numeric.hpp>
|
||||
|
||||
namespace KE = Kokkos::Experimental;
|
||||
|
||||
namespace Test {
|
||||
namespace stdalgos {
|
||||
|
||||
struct CustomValueType {
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
CustomValueType(){};
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
CustomValueType(value_type val) : value(val){};
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
CustomValueType(const CustomValueType& other) { this->value = other.value; }
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
value_type& operator()() { return value; }
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
const value_type& operator()() const { return value; }
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
CustomValueType& operator+=(const CustomValueType& other) {
|
||||
this->value += other.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
CustomValueType& operator=(const CustomValueType& other) {
|
||||
this->value = other.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
CustomValueType operator+(const CustomValueType& other) const {
|
||||
CustomValueType result;
|
||||
result.value = this->value + other.value;
|
||||
return result;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
CustomValueType operator*(const CustomValueType& other) const {
|
||||
CustomValueType result;
|
||||
result.value = this->value * other.value;
|
||||
return result;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
bool operator==(const CustomValueType& other) const {
|
||||
return this->value == other.value;
|
||||
}
|
||||
|
||||
//
|
||||
// volatile overloads needed for the kokkos reductions
|
||||
//
|
||||
// note the void return
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator+=(const volatile CustomValueType& other) volatile {
|
||||
this->value += other.value;
|
||||
}
|
||||
|
||||
// note the void return
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator=(const CustomValueType& other) volatile {
|
||||
this->value = other.value;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
CustomValueType operator+(const volatile CustomValueType& other) const
|
||||
volatile {
|
||||
CustomValueType result;
|
||||
result.value = this->value + other.value;
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
value_type value = {};
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct TimesTwoUnaryTransformFunctor {
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
ValueType operator()(const ValueType& a) const { return (a * 2.); }
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct MultiplyAndHalveBinaryTransformFunctor {
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
ValueType operator()(const ValueType& a, const ValueType& b) const {
|
||||
return (a * b) * 0.5;
|
||||
}
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct SumJoinFunctor {
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
ValueType operator()(const ValueType& a, const ValueType& b) const {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
ValueType operator()(const volatile ValueType& a,
|
||||
const volatile ValueType& b) const {
|
||||
return a + b;
|
||||
}
|
||||
};
|
||||
|
||||
struct std_algorithms_numerics_test : public ::testing::Test {
|
||||
Kokkos::LayoutStride layout{20, 2};
|
||||
|
||||
// value_type
|
||||
using static_view_t = Kokkos::View<value_type[20]>;
|
||||
using dyn_view_t = Kokkos::View<value_type*>;
|
||||
using strided_view_t = Kokkos::View<value_type*, Kokkos::LayoutStride>;
|
||||
|
||||
static_view_t m_static_view{"std-algo-test-1D-contiguous-view-static"};
|
||||
dyn_view_t m_dynamic_view{"std-algo-test-1D-contiguous-view-dyn", 20};
|
||||
strided_view_t m_strided_view{"std-algo-test-1D-strided-view", layout};
|
||||
|
||||
// custom scalar (cs)
|
||||
using static_view_cs_t = Kokkos::View<CustomValueType[20]>;
|
||||
using dyn_view_cs_t = Kokkos::View<CustomValueType*>;
|
||||
using strided_view_cs_t =
|
||||
Kokkos::View<CustomValueType*, Kokkos::LayoutStride>;
|
||||
|
||||
static_view_cs_t m_static_view_cs{
|
||||
"std-algo-test-1D-contiguous-view-static-custom-scalar"};
|
||||
dyn_view_cs_t m_dynamic_view_cs{
|
||||
"std-algo-test-1D-contiguous-view-dyn-custom_scalar", 20};
|
||||
strided_view_cs_t m_strided_view_cs{
|
||||
"std-algo-test-1D-strided-view-custom-scalar", layout};
|
||||
|
||||
template <class ViewFromType, class ViewToType>
|
||||
void copyPodViewToCustom(ViewFromType v_from, ViewToType v_to) {
|
||||
for (std::size_t i = 0; i < v_from.extent(0); ++i) {
|
||||
v_to(i)() = v_from(i);
|
||||
}
|
||||
}
|
||||
|
||||
void fillFixtureViews() {
|
||||
static_view_t tmpView("tmpView");
|
||||
static_view_cs_t tmpViewCs("tmpViewCs");
|
||||
auto tmp_view_h = Kokkos::create_mirror_view(Kokkos::HostSpace(), tmpView);
|
||||
auto tmp_view_cs_h =
|
||||
Kokkos::create_mirror_view(Kokkos::HostSpace(), tmpViewCs);
|
||||
tmp_view_h(0) = 0.;
|
||||
tmp_view_h(1) = 0.;
|
||||
tmp_view_h(2) = 0.;
|
||||
tmp_view_h(3) = 2.;
|
||||
tmp_view_h(4) = 2.;
|
||||
tmp_view_h(5) = 1.;
|
||||
tmp_view_h(6) = 1.;
|
||||
tmp_view_h(7) = 1.;
|
||||
tmp_view_h(8) = 1.;
|
||||
tmp_view_h(9) = 0.;
|
||||
tmp_view_h(10) = -2.;
|
||||
tmp_view_h(11) = -2.;
|
||||
tmp_view_h(12) = 0.;
|
||||
tmp_view_h(13) = 2.;
|
||||
tmp_view_h(14) = 2.;
|
||||
tmp_view_h(15) = 1.;
|
||||
tmp_view_h(16) = 1.;
|
||||
tmp_view_h(17) = 1.;
|
||||
tmp_view_h(18) = 1.;
|
||||
tmp_view_h(19) = 0.;
|
||||
|
||||
copyPodViewToCustom(tmp_view_h, tmp_view_cs_h);
|
||||
|
||||
Kokkos::deep_copy(tmpView, tmp_view_h);
|
||||
Kokkos::deep_copy(tmpViewCs, tmp_view_cs_h);
|
||||
|
||||
CopyFunctor<static_view_t, static_view_t> F1(tmpView, m_static_view);
|
||||
Kokkos::parallel_for("_std_algo_copy1", 20, F1);
|
||||
|
||||
CopyFunctor<static_view_t, dyn_view_t> F2(tmpView, m_dynamic_view);
|
||||
Kokkos::parallel_for("_std_algo_copy2", 20, F2);
|
||||
|
||||
CopyFunctor<static_view_t, strided_view_t> F3(tmpView, m_strided_view);
|
||||
Kokkos::parallel_for("_std_algo_copy3", 20, F3);
|
||||
|
||||
CopyFunctor<static_view_cs_t, static_view_cs_t> F4(tmpViewCs,
|
||||
m_static_view_cs);
|
||||
Kokkos::parallel_for("_std_algo_copy4", 20, F4);
|
||||
|
||||
CopyFunctor<static_view_cs_t, dyn_view_cs_t> F5(tmpViewCs,
|
||||
m_dynamic_view_cs);
|
||||
Kokkos::parallel_for("_std_algo_copy5", 20, F5);
|
||||
|
||||
CopyFunctor<static_view_cs_t, strided_view_cs_t> F6(tmpViewCs,
|
||||
m_strided_view_cs);
|
||||
Kokkos::parallel_for("_std_algo_copy6", 20, F6);
|
||||
}
|
||||
};
|
||||
|
||||
#if not defined KOKKOS_ENABLE_OPENMPTARGET
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// test default case of transform_reduce
|
||||
//
|
||||
// test for both POD types and custom scalar types
|
||||
// -------------------------------------------------------------------
|
||||
template <class ExecutionSpace, class ViewType1, class ViewType2,
|
||||
class ValueType>
|
||||
void run_and_check_transform_reduce_default(ViewType1 first_view,
|
||||
ViewType2 second_view,
|
||||
ValueType init_value,
|
||||
ValueType result_value) {
|
||||
// trivial cases
|
||||
const auto r1 = KE::transform_reduce(ExecutionSpace(), KE::cbegin(first_view),
|
||||
KE::cbegin(first_view),
|
||||
KE::cbegin(second_view), init_value);
|
||||
|
||||
const auto r2 = KE::transform_reduce(
|
||||
"MYLABEL", ExecutionSpace(), KE::cbegin(first_view),
|
||||
KE::cbegin(first_view), KE::cbegin(second_view), init_value);
|
||||
EXPECT_TRUE(r1 == init_value);
|
||||
EXPECT_TRUE(r2 == init_value);
|
||||
|
||||
// non-trivial cases
|
||||
const auto r3 = KE::transform_reduce(ExecutionSpace(), KE::cbegin(first_view),
|
||||
KE::cend(first_view),
|
||||
KE::cbegin(second_view), init_value);
|
||||
|
||||
const auto r4 = KE::transform_reduce(
|
||||
"MYLABEL", ExecutionSpace(), KE::cbegin(first_view), KE::cend(first_view),
|
||||
KE::cbegin(second_view), init_value);
|
||||
|
||||
const auto r5 = KE::transform_reduce(ExecutionSpace(), first_view,
|
||||
second_view, init_value);
|
||||
const auto r6 = KE::transform_reduce("MYLABEL", ExecutionSpace(), first_view,
|
||||
second_view, init_value);
|
||||
|
||||
EXPECT_TRUE(r3 == result_value);
|
||||
EXPECT_TRUE(r4 == result_value);
|
||||
EXPECT_TRUE(r5 == result_value);
|
||||
EXPECT_TRUE(r6 == result_value);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
transform_reduce_default_functors_using_pod_value_type) {
|
||||
fillFixtureViews();
|
||||
const value_type init0 = 0.;
|
||||
const value_type init5 = 5.;
|
||||
const value_type gold0 = 32.;
|
||||
const value_type gold5 = 37.;
|
||||
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_static_view, m_dynamic_view, init0, gold0);
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_static_view, m_dynamic_view, init5, gold5);
|
||||
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_static_view, m_strided_view, init0, gold0);
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_static_view, m_strided_view, init5, gold5);
|
||||
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_dynamic_view, m_strided_view, init0, gold0);
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_dynamic_view, m_strided_view, init5, gold5);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
transform_reduce_default_functors_using_custom_value_type) {
|
||||
fillFixtureViews();
|
||||
const CustomValueType init0{0.};
|
||||
const CustomValueType init5{5.};
|
||||
const CustomValueType gold0{32.};
|
||||
const CustomValueType gold5{37.};
|
||||
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_static_view_cs, m_dynamic_view_cs, init0, gold0);
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_static_view_cs, m_dynamic_view_cs, init5, gold5);
|
||||
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_static_view_cs, m_strided_view_cs, init0, gold0);
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_static_view_cs, m_strided_view_cs, init5, gold5);
|
||||
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_dynamic_view_cs, m_strided_view_cs, init0, gold0);
|
||||
run_and_check_transform_reduce_default<exespace>(
|
||||
m_dynamic_view_cs, m_strided_view_cs, init5, gold5);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// transform_reduce for custom joiner and custom transform op
|
||||
// test for both POD types and custom scalar types
|
||||
//
|
||||
// test overload1 accepting two intervals
|
||||
//
|
||||
// Note that in the std, the reducer is called BinaryReductionOp
|
||||
// but in the Kokkos naming convention, it corresponds to a "joiner"
|
||||
// that knows how to join two values.
|
||||
// the "joiner" is assumed to be commutative:
|
||||
//
|
||||
// https://en.cppreference.com/w/cpp/algorithm/transform_reduce
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
template <class ExecutionSpace, class ViewType1, class ViewType2,
|
||||
class ValueType, class... Args>
|
||||
void run_and_check_transform_reduce_overloadA(ViewType1 first_view,
|
||||
ViewType2 second_view,
|
||||
ValueType init_value,
|
||||
ValueType result_value,
|
||||
Args&&... args) {
|
||||
// trivial cases
|
||||
const auto r1 = KE::transform_reduce(
|
||||
ExecutionSpace(), KE::cbegin(first_view), KE::cbegin(first_view),
|
||||
KE::cbegin(second_view), init_value, std::forward<Args>(args)...);
|
||||
|
||||
const auto r2 =
|
||||
KE::transform_reduce("MYLABEL", ExecutionSpace(), KE::cbegin(first_view),
|
||||
KE::cbegin(first_view), KE::cbegin(second_view),
|
||||
init_value, std::forward<Args>(args)...);
|
||||
|
||||
EXPECT_TRUE(r1 == init_value);
|
||||
EXPECT_TRUE(r2 == init_value);
|
||||
|
||||
// non trivial cases
|
||||
const auto r3 = KE::transform_reduce(
|
||||
ExecutionSpace(), KE::cbegin(first_view), KE::cend(first_view),
|
||||
KE::cbegin(second_view), init_value, std::forward<Args>(args)...);
|
||||
|
||||
const auto r4 = KE::transform_reduce(
|
||||
"MYLABEL", ExecutionSpace(), KE::cbegin(first_view), KE::cend(first_view),
|
||||
KE::cbegin(second_view), init_value, std::forward<Args>(args)...);
|
||||
|
||||
const auto r5 =
|
||||
KE::transform_reduce(ExecutionSpace(), first_view, second_view,
|
||||
init_value, std::forward<Args>(args)...);
|
||||
const auto r6 =
|
||||
KE::transform_reduce("MYLABEL", ExecutionSpace(), first_view, second_view,
|
||||
init_value, std::forward<Args>(args)...);
|
||||
|
||||
EXPECT_TRUE(r3 == result_value);
|
||||
EXPECT_TRUE(r4 == result_value);
|
||||
EXPECT_TRUE(r5 == result_value);
|
||||
EXPECT_TRUE(r6 == result_value);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
transform_reduce_custom_functors_overloadA_using_pod_value_type) {
|
||||
using joiner_type = SumJoinFunctor<value_type>;
|
||||
using transf_type = MultiplyAndHalveBinaryTransformFunctor<value_type>;
|
||||
|
||||
const value_type init0 = 0.;
|
||||
const value_type init5 = 5.;
|
||||
const value_type gold0 = 16.;
|
||||
const value_type gold5 = 21.;
|
||||
|
||||
fillFixtureViews();
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_static_view, m_dynamic_view, init0, gold0, joiner_type(),
|
||||
transf_type());
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_static_view, m_dynamic_view, init5, gold5, joiner_type(),
|
||||
transf_type());
|
||||
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_static_view, m_strided_view, init0, gold0, joiner_type(),
|
||||
transf_type());
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_static_view, m_strided_view, init5, gold5, joiner_type(),
|
||||
transf_type());
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_dynamic_view, m_strided_view, init0, gold0, joiner_type(),
|
||||
transf_type());
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_dynamic_view, m_strided_view, init5, gold5, joiner_type(),
|
||||
transf_type());
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
transform_reduce_custom_functors_overloadA_using_custom_value_type) {
|
||||
using joiner_type = SumJoinFunctor<CustomValueType>;
|
||||
using transf_type = MultiplyAndHalveBinaryTransformFunctor<CustomValueType>;
|
||||
|
||||
const CustomValueType init0{0.};
|
||||
const CustomValueType init5{5.};
|
||||
const CustomValueType gold0{16.};
|
||||
const CustomValueType gold5{21.};
|
||||
|
||||
fillFixtureViews();
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_static_view_cs, m_dynamic_view_cs, init0, gold0, joiner_type(),
|
||||
transf_type());
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_static_view_cs, m_dynamic_view_cs, init5, gold5, joiner_type(),
|
||||
transf_type());
|
||||
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_static_view_cs, m_strided_view_cs, init0, gold0, joiner_type(),
|
||||
transf_type());
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_static_view_cs, m_strided_view_cs, init5, gold5, joiner_type(),
|
||||
transf_type());
|
||||
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_dynamic_view_cs, m_strided_view_cs, init0, gold0, joiner_type(),
|
||||
transf_type());
|
||||
run_and_check_transform_reduce_overloadA<exespace>(
|
||||
m_dynamic_view_cs, m_strided_view_cs, init5, gold5, joiner_type(),
|
||||
transf_type());
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// transform_reduce for custom joiner and custom transform op
|
||||
// test for both POD types and custom scalar types
|
||||
//
|
||||
// test overload1 accepting single interval/view
|
||||
//
|
||||
// Note that in the std, the reducer is called BinaryReductionOp
|
||||
// but in the Kokkos naming convention, it corresponds to a "joiner"
|
||||
// that knows how to join two values.
|
||||
// the "joiner" is assumed to be commutative:
|
||||
//
|
||||
// https://en.cppreference.com/w/cpp/algorithm/transform_reduce
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
template <class ExecutionSpace, class ViewType, class ValueType, class... Args>
|
||||
void run_and_check_transform_reduce_overloadB(ViewType view,
|
||||
ValueType init_value,
|
||||
ValueType result_value,
|
||||
Args&&... args) {
|
||||
// trivial
|
||||
const auto r1 =
|
||||
KE::transform_reduce(ExecutionSpace(), KE::cbegin(view), KE::cbegin(view),
|
||||
init_value, std::forward<Args>(args)...);
|
||||
|
||||
const auto r2 = KE::transform_reduce("MYLABEL", ExecutionSpace(),
|
||||
KE::cbegin(view), KE::cbegin(view),
|
||||
init_value, std::forward<Args>(args)...);
|
||||
|
||||
EXPECT_TRUE(r1 == init_value);
|
||||
EXPECT_TRUE(r2 == init_value);
|
||||
|
||||
// non trivial
|
||||
const auto r3 =
|
||||
KE::transform_reduce(ExecutionSpace(), KE::cbegin(view), KE::cend(view),
|
||||
init_value, std::forward<Args>(args)...);
|
||||
|
||||
const auto r4 = KE::transform_reduce("MYLABEL", ExecutionSpace(),
|
||||
KE::cbegin(view), KE::cend(view),
|
||||
init_value, std::forward<Args>(args)...);
|
||||
const auto r5 = KE::transform_reduce(ExecutionSpace(), view, init_value,
|
||||
std::forward<Args>(args)...);
|
||||
|
||||
const auto r6 = KE::transform_reduce("MYLABEL", ExecutionSpace(), view,
|
||||
init_value, std::forward<Args>(args)...);
|
||||
|
||||
EXPECT_TRUE(r3 == result_value);
|
||||
EXPECT_TRUE(r4 == result_value);
|
||||
EXPECT_TRUE(r5 == result_value);
|
||||
EXPECT_TRUE(r6 == result_value);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
transform_reduce_custom_functors_overloadB_using_pod_value_type) {
|
||||
using joiner_type = SumJoinFunctor<value_type>;
|
||||
using transf_type = TimesTwoUnaryTransformFunctor<value_type>;
|
||||
|
||||
const value_type init0 = 0.;
|
||||
const value_type init5 = 5.;
|
||||
const value_type gold0 = 24.;
|
||||
const value_type gold5 = 29.;
|
||||
|
||||
fillFixtureViews();
|
||||
run_and_check_transform_reduce_overloadB<exespace>(
|
||||
m_static_view, init0, gold0, joiner_type(), transf_type());
|
||||
run_and_check_transform_reduce_overloadB<exespace>(
|
||||
m_dynamic_view, init5, gold5, joiner_type(), transf_type());
|
||||
run_and_check_transform_reduce_overloadB<exespace>(
|
||||
m_strided_view, init0, gold0, joiner_type(), transf_type());
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
transform_reduce_custom_functors_overloadB_using_custom_value_type) {
|
||||
using joiner_type = SumJoinFunctor<CustomValueType>;
|
||||
using transf_type = TimesTwoUnaryTransformFunctor<CustomValueType>;
|
||||
|
||||
const CustomValueType init0{0.};
|
||||
const CustomValueType init5{5.};
|
||||
const CustomValueType gold0{24.};
|
||||
const CustomValueType gold5{29.};
|
||||
|
||||
fillFixtureViews();
|
||||
run_and_check_transform_reduce_overloadB<exespace>(
|
||||
m_static_view_cs, init0, gold0, joiner_type(), transf_type());
|
||||
run_and_check_transform_reduce_overloadB<exespace>(
|
||||
m_dynamic_view_cs, init5, gold5, joiner_type(), transf_type());
|
||||
run_and_check_transform_reduce_overloadB<exespace>(
|
||||
m_strided_view_cs, init0, gold0, joiner_type(), transf_type());
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// test reduce overload1
|
||||
//
|
||||
// test for both POD types and custom scalar types
|
||||
// -------------------------------------------------------------------
|
||||
template <class ExecutionSpace, class ViewType, class ValueType>
|
||||
void run_and_check_reduce_overloadA(ViewType view, ValueType non_trivial_result,
|
||||
ValueType trivial_result) {
|
||||
// trivial cases
|
||||
const auto r1 =
|
||||
KE::reduce(ExecutionSpace(), KE::cbegin(view), KE::cbegin(view));
|
||||
const auto r2 = KE::reduce("MYLABEL", ExecutionSpace(), KE::cbegin(view),
|
||||
KE::cbegin(view));
|
||||
EXPECT_TRUE(r1 == trivial_result);
|
||||
EXPECT_TRUE(r2 == trivial_result);
|
||||
|
||||
// non trivial cases
|
||||
const auto r3 =
|
||||
KE::reduce(ExecutionSpace(), KE::cbegin(view), KE::cend(view));
|
||||
const auto r4 =
|
||||
KE::reduce("MYLABEL", ExecutionSpace(), KE::cbegin(view), KE::cend(view));
|
||||
const auto r5 = KE::reduce(ExecutionSpace(), view);
|
||||
const auto r6 = KE::reduce("MYLABEL", ExecutionSpace(), view);
|
||||
|
||||
EXPECT_TRUE(r3 == non_trivial_result);
|
||||
EXPECT_TRUE(r4 == non_trivial_result);
|
||||
EXPECT_TRUE(r5 == non_trivial_result);
|
||||
EXPECT_TRUE(r6 == non_trivial_result);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
reduce_default_functors_overloadA_using_pod_value_type) {
|
||||
fillFixtureViews();
|
||||
const value_type trivial_gold = 0.;
|
||||
const value_type non_trivial_gold = 12.;
|
||||
run_and_check_reduce_overloadA<exespace>(m_static_view, non_trivial_gold,
|
||||
trivial_gold);
|
||||
run_and_check_reduce_overloadA<exespace>(m_dynamic_view, non_trivial_gold,
|
||||
trivial_gold);
|
||||
run_and_check_reduce_overloadA<exespace>(m_strided_view, non_trivial_gold,
|
||||
trivial_gold);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
reduce_default_functors_overloadA_using_custom_value_type) {
|
||||
fillFixtureViews();
|
||||
const CustomValueType trivial_gold{0.};
|
||||
const CustomValueType non_trivial_gold{12.};
|
||||
run_and_check_reduce_overloadA<exespace>(m_static_view_cs, non_trivial_gold,
|
||||
trivial_gold);
|
||||
run_and_check_reduce_overloadA<exespace>(m_dynamic_view_cs, non_trivial_gold,
|
||||
trivial_gold);
|
||||
run_and_check_reduce_overloadA<exespace>(m_strided_view_cs, non_trivial_gold,
|
||||
trivial_gold);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// test reduce overload2 with init value
|
||||
//
|
||||
// test for both POD types and custom scalar types
|
||||
// -------------------------------------------------------------------
|
||||
template <class ExecutionSpace, class ViewType, class ValueType>
|
||||
void run_and_check_reduce_overloadB(ViewType view, ValueType result_value,
|
||||
ValueType init_value) {
|
||||
// trivial cases
|
||||
const auto r1 = KE::reduce(ExecutionSpace(), KE::cbegin(view),
|
||||
KE::cbegin(view), init_value);
|
||||
const auto r2 = KE::reduce("MYLABEL", ExecutionSpace(), KE::cbegin(view),
|
||||
KE::cbegin(view), init_value);
|
||||
EXPECT_TRUE(r1 == init_value);
|
||||
EXPECT_TRUE(r2 == init_value);
|
||||
|
||||
// non trivial cases
|
||||
const auto r3 = KE::reduce(ExecutionSpace(), KE::cbegin(view), KE::cend(view),
|
||||
init_value);
|
||||
const auto r4 = KE::reduce("MYLABEL", ExecutionSpace(), KE::cbegin(view),
|
||||
KE::cend(view), init_value);
|
||||
const auto r5 = KE::reduce(ExecutionSpace(), view, init_value);
|
||||
const auto r6 = KE::reduce("MYLABEL", ExecutionSpace(), view, init_value);
|
||||
|
||||
EXPECT_TRUE(r3 == result_value);
|
||||
EXPECT_TRUE(r4 == result_value);
|
||||
EXPECT_TRUE(r5 == result_value);
|
||||
EXPECT_TRUE(r6 == result_value);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
reduce_default_functors_overloadB_using_pod_value_type) {
|
||||
fillFixtureViews();
|
||||
const value_type init = 5.;
|
||||
const value_type gold = 17.;
|
||||
run_and_check_reduce_overloadB<exespace>(m_static_view, gold, init);
|
||||
run_and_check_reduce_overloadB<exespace>(m_dynamic_view, gold, init);
|
||||
run_and_check_reduce_overloadB<exespace>(m_strided_view, gold, init);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
reduce_default_functors_overloadB_using_custom_value_type) {
|
||||
fillFixtureViews();
|
||||
const CustomValueType init{5.};
|
||||
const CustomValueType gold{17.};
|
||||
run_and_check_reduce_overloadB<exespace>(m_static_view_cs, gold, init);
|
||||
run_and_check_reduce_overloadB<exespace>(m_dynamic_view_cs, gold, init);
|
||||
run_and_check_reduce_overloadB<exespace>(m_strided_view_cs, gold, init);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// test reduce overload3 with init value
|
||||
//
|
||||
// test for both POD types and custom scalar types
|
||||
// -------------------------------------------------------------------
|
||||
template <class ExecutionSpace, class ViewType, class ValueType, class BinaryOp>
|
||||
void run_and_check_reduce_overloadC(ViewType view, ValueType result_value,
|
||||
ValueType init_value, BinaryOp joiner) {
|
||||
// trivial cases
|
||||
const auto r1 = KE::reduce(ExecutionSpace(), KE::cbegin(view),
|
||||
KE::cbegin(view), init_value, joiner);
|
||||
const auto r2 = KE::reduce("MYLABEL", ExecutionSpace(), KE::cbegin(view),
|
||||
KE::cbegin(view), init_value, joiner);
|
||||
EXPECT_TRUE(r1 == init_value);
|
||||
EXPECT_TRUE(r2 == init_value);
|
||||
|
||||
// non trivial cases
|
||||
const auto r3 = KE::reduce(ExecutionSpace(), KE::cbegin(view), KE::cend(view),
|
||||
init_value, joiner);
|
||||
const auto r4 = KE::reduce("MYLABEL", ExecutionSpace(), KE::cbegin(view),
|
||||
KE::cend(view), init_value, joiner);
|
||||
const auto r5 = KE::reduce(ExecutionSpace(), view, init_value, joiner);
|
||||
const auto r6 =
|
||||
KE::reduce("MYLABEL", ExecutionSpace(), view, init_value, joiner);
|
||||
|
||||
EXPECT_TRUE(r3 == result_value);
|
||||
EXPECT_TRUE(r4 == result_value);
|
||||
EXPECT_TRUE(r5 == result_value);
|
||||
EXPECT_TRUE(r6 == result_value);
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
reduce_custom_functors_using_pod_value_type) {
|
||||
using joiner_type = SumJoinFunctor<value_type>;
|
||||
|
||||
fillFixtureViews();
|
||||
const value_type init = 5.;
|
||||
const value_type gold = 17.;
|
||||
run_and_check_reduce_overloadC<exespace>(m_static_view, gold, init,
|
||||
joiner_type());
|
||||
run_and_check_reduce_overloadC<exespace>(m_dynamic_view, gold, init,
|
||||
joiner_type());
|
||||
run_and_check_reduce_overloadC<exespace>(m_strided_view, gold, init,
|
||||
joiner_type());
|
||||
}
|
||||
|
||||
TEST_F(std_algorithms_numerics_test,
|
||||
reduce_custom_functors_using_custom_value_type) {
|
||||
using joiner_type = SumJoinFunctor<CustomValueType>;
|
||||
|
||||
fillFixtureViews();
|
||||
const CustomValueType init{5.};
|
||||
const CustomValueType gold{17.};
|
||||
run_and_check_reduce_overloadC<exespace>(m_static_view_cs, gold, init,
|
||||
joiner_type());
|
||||
run_and_check_reduce_overloadC<exespace>(m_dynamic_view_cs, gold, init,
|
||||
joiner_type());
|
||||
run_and_check_reduce_overloadC<exespace>(m_strided_view_cs, gold, init,
|
||||
joiner_type());
|
||||
}
|
||||
|
||||
#endif // not defined KOKKOS_ENABLE_OPENMPTARGET
|
||||
|
||||
} // namespace stdalgos
|
||||
} // namespace Test
|
||||
Reference in New Issue
Block a user