Update Kokkos library in LAMMPS to v3.6.1
This commit is contained in:
@ -422,54 +422,34 @@ class BinSort {
|
||||
|
||||
template <class KeyViewType>
|
||||
struct BinOp1D {
|
||||
int max_bins_;
|
||||
double mul_;
|
||||
typename KeyViewType::const_value_type range_;
|
||||
typename KeyViewType::const_value_type min_;
|
||||
int max_bins_ = {};
|
||||
double mul_ = {};
|
||||
double min_ = {};
|
||||
|
||||
BinOp1D()
|
||||
: max_bins_(0),
|
||||
mul_(0.0),
|
||||
range_(typename KeyViewType::const_value_type()),
|
||||
min_(typename KeyViewType::const_value_type()) {}
|
||||
BinOp1D() = default;
|
||||
|
||||
// Construct BinOp with number of bins, minimum value and maxuimum value
|
||||
BinOp1D(int max_bins__, typename KeyViewType::const_value_type min,
|
||||
typename KeyViewType::const_value_type max)
|
||||
: max_bins_(max_bins__ + 1),
|
||||
// Cast to int64_t to avoid possible overflow when using integer
|
||||
mul_(std::is_integral<typename KeyViewType::const_value_type>::value
|
||||
? 1.0 * max_bins__ / (int64_t(max) - int64_t(min))
|
||||
: 1.0 * max_bins__ / (max - min)),
|
||||
range_(max - min),
|
||||
min_(min) {
|
||||
// Cast to double to avoid possible overflow when using integer
|
||||
mul_(static_cast<double>(max_bins__) /
|
||||
(static_cast<double>(max) - static_cast<double>(min))),
|
||||
min_(static_cast<double>(min)) {
|
||||
// For integral types the number of bins may be larger than the range
|
||||
// in which case we can exactly have one unique value per bin
|
||||
// and then don't need to sort bins.
|
||||
if (std::is_integral<typename KeyViewType::const_value_type>::value &&
|
||||
static_cast<uint64_t>(range_) <= static_cast<uint64_t>(max_bins__)) {
|
||||
(static_cast<double>(max) - static_cast<double>(min)) <=
|
||||
static_cast<double>(max_bins__)) {
|
||||
mul_ = 1.;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine bin index from key value
|
||||
template <
|
||||
class ViewType,
|
||||
std::enable_if_t<!std::is_integral<typename ViewType::value_type>::value,
|
||||
bool> = true>
|
||||
template <class ViewType>
|
||||
KOKKOS_INLINE_FUNCTION int bin(ViewType& keys, const int& i) const {
|
||||
return int(mul_ * (keys(i) - min_));
|
||||
}
|
||||
|
||||
// Determine bin index from key value
|
||||
template <
|
||||
class ViewType,
|
||||
std::enable_if_t<std::is_integral<typename ViewType::value_type>::value,
|
||||
bool> = true>
|
||||
KOKKOS_INLINE_FUNCTION int bin(ViewType& keys, const int& i) const {
|
||||
// The cast to int64_t is necessary because otherwise HIP returns the wrong
|
||||
// result.
|
||||
return int(mul_ * (int64_t(keys(i)) - int64_t(min_)));
|
||||
return static_cast<int>(mul_ * (static_cast<double>(keys(i)) - min_));
|
||||
}
|
||||
|
||||
// Return maximum bin index + 1
|
||||
@ -486,10 +466,9 @@ struct BinOp1D {
|
||||
|
||||
template <class KeyViewType>
|
||||
struct BinOp3D {
|
||||
int max_bins_[3];
|
||||
double mul_[3];
|
||||
typename KeyViewType::non_const_value_type range_[3];
|
||||
typename KeyViewType::non_const_value_type min_[3];
|
||||
int max_bins_[3] = {};
|
||||
double mul_[3] = {};
|
||||
double min_[3] = {};
|
||||
|
||||
BinOp3D() = default;
|
||||
|
||||
@ -498,15 +477,15 @@ struct BinOp3D {
|
||||
max_bins_[0] = max_bins__[0];
|
||||
max_bins_[1] = max_bins__[1];
|
||||
max_bins_[2] = max_bins__[2];
|
||||
mul_[0] = 1.0 * max_bins__[0] / (max[0] - min[0]);
|
||||
mul_[1] = 1.0 * max_bins__[1] / (max[1] - min[1]);
|
||||
mul_[2] = 1.0 * max_bins__[2] / (max[2] - min[2]);
|
||||
range_[0] = max[0] - min[0];
|
||||
range_[1] = max[1] - min[1];
|
||||
range_[2] = max[2] - min[2];
|
||||
min_[0] = min[0];
|
||||
min_[1] = min[1];
|
||||
min_[2] = min[2];
|
||||
mul_[0] = static_cast<double>(max_bins__[0]) /
|
||||
(static_cast<double>(max[0]) - static_cast<double>(min[0]));
|
||||
mul_[1] = static_cast<double>(max_bins__[1]) /
|
||||
(static_cast<double>(max[1]) - static_cast<double>(min[1]));
|
||||
mul_[2] = static_cast<double>(max_bins__[2]) /
|
||||
(static_cast<double>(max[2]) - static_cast<double>(min[2]));
|
||||
min_[0] = static_cast<double>(min[0]);
|
||||
min_[1] = static_cast<double>(min[1]);
|
||||
min_[2] = static_cast<double>(min[2]);
|
||||
}
|
||||
|
||||
template <class ViewType>
|
||||
@ -596,9 +575,9 @@ std::enable_if_t<Kokkos::is_execution_space<ExecutionSpace>::value> sort(
|
||||
// TODO: figure out better max_bins then this ...
|
||||
int64_t max_bins = view.extent(0) / 2;
|
||||
if (std::is_integral<typename ViewType::non_const_value_type>::value) {
|
||||
// Cast to int64_t to avoid possible overflow when using integer
|
||||
int64_t const max_val = result.max_val;
|
||||
int64_t const min_val = result.min_val;
|
||||
// Cast to double to avoid possible overflow when using integer
|
||||
auto const max_val = static_cast<double>(result.max_val);
|
||||
auto const min_val = static_cast<double>(result.min_val);
|
||||
// using 10M as the cutoff for special behavior (roughly 40MB for the count
|
||||
// array)
|
||||
if ((max_val - min_val) < 10000000) {
|
||||
@ -606,6 +585,10 @@ std::enable_if_t<Kokkos::is_execution_space<ExecutionSpace>::value> sort(
|
||||
sort_in_bins = false;
|
||||
}
|
||||
}
|
||||
if (std::is_floating_point<typename ViewType::non_const_value_type>::value) {
|
||||
KOKKOS_ASSERT(std::isfinite(static_cast<double>(result.max_val) -
|
||||
static_cast<double>(result.min_val)));
|
||||
}
|
||||
|
||||
BinSort<ViewType, CompType> bin_sort(
|
||||
view, CompType(max_bins, result.min_val, result.max_val), sort_in_bins);
|
||||
|
||||
@ -353,6 +353,55 @@ void test_issue_1160_impl() {
|
||||
}
|
||||
}
|
||||
|
||||
template <class ExecutionSpace>
|
||||
void test_issue_4978_impl() {
|
||||
Kokkos::View<long long*, ExecutionSpace> element_("element", 9);
|
||||
|
||||
auto h_element = Kokkos::create_mirror_view(element_);
|
||||
|
||||
h_element(0) = LLONG_MIN;
|
||||
h_element(1) = 0;
|
||||
h_element(2) = 3;
|
||||
h_element(3) = 2;
|
||||
h_element(4) = 1;
|
||||
h_element(5) = 3;
|
||||
h_element(6) = 6;
|
||||
h_element(7) = 4;
|
||||
h_element(8) = 3;
|
||||
|
||||
ExecutionSpace exec;
|
||||
Kokkos::deep_copy(exec, element_, h_element);
|
||||
|
||||
Kokkos::sort(exec, element_);
|
||||
|
||||
Kokkos::deep_copy(exec, h_element, element_);
|
||||
exec.fence();
|
||||
|
||||
ASSERT_EQ(h_element(0), LLONG_MIN);
|
||||
ASSERT_EQ(h_element(1), 0);
|
||||
ASSERT_EQ(h_element(2), 1);
|
||||
ASSERT_EQ(h_element(3), 2);
|
||||
ASSERT_EQ(h_element(4), 3);
|
||||
ASSERT_EQ(h_element(5), 3);
|
||||
ASSERT_EQ(h_element(6), 3);
|
||||
ASSERT_EQ(h_element(7), 4);
|
||||
ASSERT_EQ(h_element(8), 6);
|
||||
}
|
||||
|
||||
template <class ExecutionSpace, class T>
|
||||
void test_sort_integer_overflow() {
|
||||
// array with two extrema in reverse order to expose integer overflow bug in
|
||||
// bin calculation
|
||||
T a[2] = {Kokkos::Experimental::finite_max<T>::value,
|
||||
Kokkos::Experimental::finite_min<T>::value};
|
||||
auto vd = Kokkos::create_mirror_view_and_copy(
|
||||
ExecutionSpace(), Kokkos::View<T[2], Kokkos::HostSpace>(a));
|
||||
Kokkos::sort(vd, /*force using Kokkos bin sort*/ true);
|
||||
auto vh = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), vd);
|
||||
EXPECT_TRUE(std::is_sorted(vh.data(), vh.data() + 2))
|
||||
<< "view (" << vh[0] << ", " << vh[1] << ") is not sorted";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <class ExecutionSpace, typename KeyType>
|
||||
@ -376,6 +425,11 @@ void test_issue_1160_sort() {
|
||||
test_issue_1160_impl<ExecutionSpace>();
|
||||
}
|
||||
|
||||
template <class ExecutionSpace>
|
||||
void test_issue_4978_sort() {
|
||||
test_issue_4978_impl<ExecutionSpace>();
|
||||
}
|
||||
|
||||
template <class ExecutionSpace, typename KeyType>
|
||||
void test_sort(unsigned int N) {
|
||||
test_1D_sort<ExecutionSpace, KeyType>(N);
|
||||
@ -385,6 +439,10 @@ void test_sort(unsigned int N) {
|
||||
test_dynamic_view_sort<ExecutionSpace, KeyType>(N);
|
||||
#endif
|
||||
test_issue_1160_sort<ExecutionSpace>();
|
||||
test_issue_4978_sort<ExecutionSpace>();
|
||||
test_sort_integer_overflow<ExecutionSpace, long long>();
|
||||
test_sort_integer_overflow<ExecutionSpace, unsigned long long>();
|
||||
test_sort_integer_overflow<ExecutionSpace, int>();
|
||||
}
|
||||
} // namespace Impl
|
||||
} // namespace Test
|
||||
|
||||
Reference in New Issue
Block a user