/
tstDetailsHalfTraversal.cpp
103 lines (90 loc) · 3.25 KB
/
tstDetailsHalfTraversal.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/****************************************************************************
* Copyright (c) 2017-2023 by the ArborX authors *
* All rights reserved. *
* *
* This file is part of the ArborX library. ArborX is *
* distributed under a BSD 3-clause license. For the licensing terms see *
* the LICENSE file in the top-level directory. *
* *
* SPDX-License-Identifier: BSD-3-Clause *
****************************************************************************/
#include "ArborXTest_StdVectorToKokkosView.hpp"
#include "ArborX_EnableDeviceTypes.hpp" // ARBORX_DEVICE_TYPES
#include "ArborX_EnableViewComparison.hpp"
#include <ArborX_DetailsHalfTraversal.hpp>
#include <ArborX_LinearBVH.hpp>
#include "BoostTest_CUDA_clang_workarounds.hpp"
#include <boost/test/unit_test.hpp>
namespace Test
{
template <class ExecutionSpace>
Kokkos::View<ArborX::Point *, ExecutionSpace>
make_points(ExecutionSpace const &space, int n)
{
Kokkos::View<ArborX::Point *, ExecutionSpace> points(
Kokkos::view_alloc(space, Kokkos::WithoutInitializing, "Test::points"),
n);
Kokkos::parallel_for(
"Test::make_points", Kokkos::RangePolicy<ExecutionSpace>(space, 0, n),
KOKKOS_LAMBDA(int i) {
points(i) = {(float)i, (float)i, (float)i};
});
return points;
}
// Workaround NVCC's extended lambda restrictions
struct AlwaysTrue
{
template <class ValueType>
KOKKOS_FUNCTION bool operator()(ValueType const &) const
{
return true;
}
};
struct PredicateGetter
{
template <class ValueType>
KOKKOS_FUNCTION AlwaysTrue operator()(ValueType) const
{
return {};
}
};
} // namespace Test
BOOST_AUTO_TEST_CASE_TEMPLATE(half_traversal, DeviceType, ARBORX_DEVICE_TYPES)
{
using MemorySpace = typename DeviceType::memory_space;
using ExecutionSpace = typename DeviceType::execution_space;
ExecutionSpace exec_space;
int const n = 24;
auto points = Test::make_points(exec_space, n);
ArborX::BVH<MemorySpace> bvh(exec_space, points);
Kokkos::View<int *, MemorySpace> count("Test::count", n * (n + 1) / 2);
// [0][1][2]...[j][i].........[n]
// [0] 0
// [1] 1 0
// [2] 1 1 0
// ... 1 1 1 0 i*(i+1)/2+i
// ... 1 1 1 1 0 /
// [i] 1 1 1 1 1 0
// ... 1 1 1 /
// ... 1 1 1 i*(i+1)/2+j
// ... 1 1 1
// [n] 1 1 1 1 1 1 1 1 1 0
using ArborX::Details::HalfTraversal;
HalfTraversal(
exec_space, bvh,
KOKKOS_LAMBDA(auto const &value1, auto const &value2) {
int i = value1.index;
int j = value2.index;
auto [min_ij, max_ij] = Kokkos::minmax(i, j);
Kokkos::atomic_increment(&count(max_ij * (max_ij + 1) / 2 + min_ij));
},
Test::PredicateGetter{});
std::vector<int> count_ref(n * (n + 1) / 2, 1);
for (int i = 0; i < n; ++i)
{
count_ref[i * (i + 1) / 2 + i] = 0;
}
BOOST_TEST(count_ref == Kokkos::create_mirror_view_and_copy(
Kokkos::HostSpace{}, count),
boost::test_tools::per_element());
}