Files
lammps/lib/kokkos/core/unit_test/TestMinMaxClamp.hpp
2023-11-21 15:02:12 -07:00

290 lines
8.6 KiB
C++

//@HEADER
// ************************************************************************
//
// Kokkos v. 4.0
// Copyright (2022) 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.
//
// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
// See https://kokkos.org/LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//@HEADER
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
namespace Test {
template <class T>
struct Greater {
KOKKOS_FUNCTION constexpr bool operator()(T const& lhs, T const& rhs) {
return lhs > rhs;
}
};
struct PairIntCompareFirst {
int first;
int second;
private:
friend KOKKOS_FUNCTION constexpr bool operator<(
PairIntCompareFirst const& lhs, PairIntCompareFirst const& rhs) {
return lhs.first < rhs.first;
}
};
} // namespace Test
// ----------------------------------------------------------
// test max()
// ----------------------------------------------------------
TEST(TEST_CATEGORY, max) {
int a = 1;
int b = 2;
EXPECT_EQ(Kokkos::max(a, b), 2);
a = 3;
b = 1;
EXPECT_EQ(Kokkos::max(a, b), 3);
static_assert(Kokkos::max(1, 2) == 2);
static_assert(Kokkos::max(1, 2, ::Test::Greater<int>{}) == 1);
EXPECT_EQ(Kokkos::max({3.f, -1.f, 0.f}), 3.f);
static_assert(Kokkos::max({3, -1, 0}) == 3);
static_assert(Kokkos::max({3, -1, 0}, ::Test::Greater<int>{}) == -1);
static_assert(Kokkos::max({
::Test::PairIntCompareFirst{255, 0},
::Test::PairIntCompareFirst{255, 1},
::Test::PairIntCompareFirst{0, 2},
::Test::PairIntCompareFirst{0, 3},
::Test::PairIntCompareFirst{255, 4},
::Test::PairIntCompareFirst{0, 5},
})
.second == 0); // leftmost element
}
template <class ViewType>
struct StdAlgoMinMaxOpsTestMax {
ViewType m_view;
KOKKOS_INLINE_FUNCTION
void operator()(const int& ind) const {
auto v1 = 10.;
if (Kokkos::max(v1, m_view(ind)) == 10.) {
m_view(ind) = 6.;
}
}
KOKKOS_INLINE_FUNCTION
StdAlgoMinMaxOpsTestMax(ViewType aIn) : m_view(aIn) {}
};
TEST(TEST_CATEGORY, max_within_parfor) {
namespace KE = Kokkos::Experimental;
using view_t = Kokkos::View<double*>;
view_t a("a", 10);
StdAlgoMinMaxOpsTestMax<view_t> fnc(a);
Kokkos::parallel_for(a.extent(0), fnc);
auto a_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), a);
for (int i = 0; i < 10; ++i) {
EXPECT_DOUBLE_EQ(a_h(0), 6.);
}
}
// ----------------------------------------------------------
// test min()
// ----------------------------------------------------------
TEST(TEST_CATEGORY, min) {
int a = 1;
int b = 2;
EXPECT_EQ(Kokkos::min(a, b), 1);
a = 3;
b = 2;
EXPECT_EQ(Kokkos::min(a, b), 2);
static_assert(Kokkos::min(3.f, 2.f) == 2.f);
static_assert(Kokkos::min(3.f, 2.f, ::Test::Greater<int>{}) == 3.f);
EXPECT_EQ(Kokkos::min({3.f, -1.f, 0.f}), -1.f);
static_assert(Kokkos::min({3, -1, 0}) == -1);
static_assert(Kokkos::min({3, -1, 0}, ::Test::Greater<int>{}) == 3);
static_assert(Kokkos::min({
::Test::PairIntCompareFirst{255, 0},
::Test::PairIntCompareFirst{255, 1},
::Test::PairIntCompareFirst{0, 2},
::Test::PairIntCompareFirst{0, 3},
::Test::PairIntCompareFirst{255, 4},
::Test::PairIntCompareFirst{0, 5},
})
.second == 2); // leftmost element
}
template <class ViewType>
struct StdAlgoMinMaxOpsTestMin {
ViewType m_view;
KOKKOS_INLINE_FUNCTION
void operator()(const int& ind) const {
auto v1 = 10.;
if (Kokkos::min(v1, m_view(ind)) == 0.) {
m_view(ind) = 8.;
}
}
KOKKOS_INLINE_FUNCTION
StdAlgoMinMaxOpsTestMin(ViewType aIn) : m_view(aIn) {}
};
TEST(TEST_CATEGORY, min_within_parfor) {
namespace KE = Kokkos::Experimental;
using view_t = Kokkos::View<double*>;
view_t a("a", 10);
StdAlgoMinMaxOpsTestMin<view_t> fnc(a);
Kokkos::parallel_for(a.extent(0), fnc);
auto a_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), a);
for (int i = 0; i < 10; ++i) {
EXPECT_DOUBLE_EQ(a_h(0), 8.);
}
}
// ----------------------------------------------------------
// test minmax()
// ----------------------------------------------------------
TEST(TEST_CATEGORY, minmax) {
int a = 1;
int b = 2;
const auto& r = Kokkos::minmax(a, b);
EXPECT_EQ(r.first, 1);
EXPECT_EQ(r.second, 2);
a = 3;
b = 2;
const auto& r2 = Kokkos::minmax(a, b);
EXPECT_EQ(r2.first, 2);
EXPECT_EQ(r2.second, 3);
static_assert((Kokkos::pair<float, float>(Kokkos::minmax(3.f, 2.f)) ==
Kokkos::make_pair(2.f, 3.f)));
static_assert(
(Kokkos::pair<float, float>(Kokkos::minmax(
3.f, 2.f, ::Test::Greater<int>{})) == Kokkos::make_pair(3.f, 2.f)));
EXPECT_EQ(Kokkos::minmax({3.f, -1.f, 0.f}), Kokkos::make_pair(-1.f, 3.f));
static_assert(Kokkos::minmax({3, -1, 0}) == Kokkos::make_pair(-1, 3));
static_assert(Kokkos::minmax({3, -1, 0}, ::Test::Greater<int>{}) ==
Kokkos::make_pair(3, -1));
static_assert(Kokkos::minmax({
::Test::PairIntCompareFirst{255, 0},
::Test::PairIntCompareFirst{255, 1},
::Test::PairIntCompareFirst{0, 2},
::Test::PairIntCompareFirst{0, 3},
::Test::PairIntCompareFirst{255, 4},
::Test::PairIntCompareFirst{0, 5},
})
.first.second == 2); // leftmost
static_assert(Kokkos::minmax({
::Test::PairIntCompareFirst{255, 0},
::Test::PairIntCompareFirst{255, 1},
::Test::PairIntCompareFirst{0, 2},
::Test::PairIntCompareFirst{0, 3},
::Test::PairIntCompareFirst{255, 4},
::Test::PairIntCompareFirst{0, 5},
})
.second.second == 4); // rightmost
}
template <class ViewType>
struct StdAlgoMinMaxOpsTestMinMax {
ViewType m_view;
KOKKOS_INLINE_FUNCTION
void operator()(const int& ind) const {
auto v1 = 7.;
const auto& r = Kokkos::minmax(v1, m_view(ind));
m_view(ind) = (double)(r.first - r.second);
}
KOKKOS_INLINE_FUNCTION
StdAlgoMinMaxOpsTestMinMax(ViewType aIn) : m_view(aIn) {}
};
TEST(TEST_CATEGORY, minmax_within_parfor) {
using view_t = Kokkos::View<double*>;
view_t a("a", 10);
StdAlgoMinMaxOpsTestMinMax<view_t> fnc(a);
Kokkos::parallel_for(a.extent(0), fnc);
auto a_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), a);
for (int i = 0; i < 10; ++i) {
EXPECT_DOUBLE_EQ(a_h(0), -7.);
}
}
// ----------------------------------------------------------
// test clamp()
// ----------------------------------------------------------
TEST(TEST_CATEGORY, clamp) {
int a = 1;
int b = 2;
int c = 19;
const auto& r = Kokkos::clamp(a, b, c);
EXPECT_EQ(&r, &b);
EXPECT_EQ(r, b);
a = 5;
b = -2;
c = 3;
const auto& r2 = Kokkos::clamp(a, b, c);
EXPECT_EQ(&r2, &c);
EXPECT_EQ(r2, c);
a = 5;
b = -2;
c = 7;
const auto& r3 = Kokkos::clamp(a, b, c);
EXPECT_EQ(&r3, &a);
EXPECT_EQ(r3, a);
}
template <class ViewType>
struct StdAlgoMinMaxOpsTestClamp {
ViewType m_view;
KOKKOS_INLINE_FUNCTION
void operator()(const int& ind) const {
m_view(ind) = 10.;
const auto b = -2.;
const auto c = 3.;
const auto& r = Kokkos::clamp(m_view(ind), b, c);
m_view(ind) = (double)(r);
}
KOKKOS_INLINE_FUNCTION
StdAlgoMinMaxOpsTestClamp(ViewType aIn) : m_view(aIn) {}
};
TEST(TEST_CATEGORY, clamp_within_parfor) {
using view_t = Kokkos::View<double*>;
view_t a("a", 10);
StdAlgoMinMaxOpsTestClamp<view_t> fnc(a);
Kokkos::parallel_for(a.extent(0), fnc);
auto a_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), a);
for (std::size_t i = 0; i < a.extent(0); ++i) {
EXPECT_DOUBLE_EQ(a_h(0), 3.);
}
}