Skip to content

Commit

Permalink
Merge pull request #894 from aprokop/6.5-fix-root-bounding_volume
Browse files Browse the repository at this point in the history
Properly compute tree bounds with indexables
  • Loading branch information
aprokop committed Jul 22, 2023
2 parents 73b6b55 + 22bf054 commit 9dcb3ba
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 53 deletions.
47 changes: 10 additions & 37 deletions src/ArborX_LinearBVH.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,6 @@ class BasicBoundingVolumeHierarchy
using leaf_node_type = Details::LeafNode<value_type>;
using internal_node_type = Details::InternalNode<bounding_volume_type>;

KOKKOS_FUNCTION
bounding_volume_type const *getRootBoundingVolumePtr() const
{
int const n = size();
// Need address of the root node's bounding box to copy it back on the host,
// but can't access node elements from the constructor since the data is on
// the device.
assert((n == 1 || Details::HappyTreeFriends::getRoot(*this) == n) &&
"workaround below assumes root is stored as first element");
return (n > 1 ? &_internal_nodes.data()->bounding_volume
: &_leaf_nodes.data()->value.bounding_volume);
}

size_type _size{0};
bounding_volume_type _bounds;
Kokkos::View<leaf_node_type *, MemorySpace> _leaf_nodes;
Expand Down Expand Up @@ -196,6 +183,15 @@ BasicBoundingVolumeHierarchy<MemorySpace, Value, IndexableGetter,
return;
}

if (size() == 1)
{
Details::TreeConstruction::initializeSingleLeafTree(
space,
Details::LegacyValues<Primitives, bounding_volume_type>{primitives},
_indexable_getter, _leaf_nodes, _bounds);
return;
}

Kokkos::Profiling::pushRegion(
"ArborX::BVH::BVH::calculate_scene_bounding_box");

Expand All @@ -205,22 +201,6 @@ BasicBoundingVolumeHierarchy<MemorySpace, Value, IndexableGetter,
space, Details::Indexables<Primitives>{primitives}, bbox);

Kokkos::Profiling::popRegion();

if (size() == 1)
{
Details::TreeConstruction::initializeSingleLeafNode(
space,
Details::LegacyValues<Primitives, bounding_volume_type>{primitives},
_leaf_nodes);
Kokkos::deep_copy(
space,
Kokkos::View<BoundingVolume, Kokkos::HostSpace,
Kokkos::MemoryUnmanaged>(&_bounds),
Kokkos::View<BoundingVolume const, MemorySpace,
Kokkos::MemoryUnmanaged>(getRootBoundingVolumePtr()));
return;
}

Kokkos::Profiling::pushRegion("ArborX::BVH::BVH::compute_linear_ordering");

// Map indexables from multidimensional domain to one-dimensional interval
Expand Down Expand Up @@ -251,14 +231,7 @@ BasicBoundingVolumeHierarchy<MemorySpace, Value, IndexableGetter,
space,
Details::LegacyValues<Primitives, bounding_volume_type>{primitives},
_indexable_getter, permutation_indices, linear_ordering_indices,
_leaf_nodes, _internal_nodes);

Kokkos::deep_copy(
space,
Kokkos::View<BoundingVolume, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(
&_bounds),
Kokkos::View<BoundingVolume const, MemorySpace, Kokkos::MemoryUnmanaged>(
getRootBoundingVolumePtr()));
_leaf_nodes, _internal_nodes, _bounds);

Kokkos::Profiling::popRegion();
}
Expand Down
58 changes: 46 additions & 12 deletions src/details/ArborX_DetailsTreeConstruction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,34 @@ inline void projectOntoSpaceFillingCurve(ExecutionSpace const &space,
});
}

template <typename ExecutionSpace, typename Values, typename Nodes>
inline void initializeSingleLeafNode(ExecutionSpace const &space,
Values const &values,
Nodes const &leaf_nodes)
template <typename ExecutionSpace, typename Values, typename IndexableGetter,
typename Nodes, typename BoundingVolume>
inline void
initializeSingleLeafTree(ExecutionSpace const &space, Values const &values,
IndexableGetter const &indexable_getter,
Nodes const &leaf_nodes, BoundingVolume &bounds)
{
ARBORX_ASSERT(leaf_nodes.extent(0) == 1);
ARBORX_ASSERT(values.size() == 1);

// Skip initialization so that we don't execute a kernel launch
Kokkos::View<BoundingVolume, typename Nodes::memory_space> bounding_volume(
Kokkos::view_alloc(space, Kokkos::WithoutInitializing,
"ArborX::BVH::getSingleLeafBounds::bounding_volume"));
Kokkos::parallel_for(
"ArborX::TreeConstruction::initialize_single_leaf",
Kokkos::RangePolicy<ExecutionSpace>(space, 0, 1),
KOKKOS_LAMBDA(int) { leaf_nodes(0) = makeLeafNode(values(0)); });
"ArborX::TreeConstruction::initialize_single_leaf_tree",
Kokkos::RangePolicy<ExecutionSpace>(space, 0, 1), KOKKOS_LAMBDA(int) {
leaf_nodes(0) = makeLeafNode(values(0));
BoundingVolume bv;
expand(bv, indexable_getter(leaf_nodes(0).value));
bounding_volume() = bv;
});

Kokkos::deep_copy(
space,
Kokkos::View<BoundingVolume, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(
&bounds),
bounding_volume);
}

template <typename Values, typename IndexableGetter,
Expand All @@ -80,14 +96,17 @@ class GenerateHierarchy

using MemorySpace = typename LeafNodes::memory_space;
using LinearOrderingValueType = typename LinearOrdering::non_const_value_type;
using BoundingVolume =
typename InternalNodes::value_type::bounding_volume_type;

public:
template <typename ExecutionSpace>
GenerateHierarchy(ExecutionSpace const &space, Values const &values,
IndexableGetter const &indexable_getter,
PermutationIndices const &permutation_indices,
LinearOrdering const &sorted_morton_codes,
LeafNodes leaf_nodes, InternalNodes internal_nodes)
LeafNodes leaf_nodes, InternalNodes internal_nodes,
BoundingVolume &bounds)
: _values(values)
, _indexable_getter(indexable_getter)
, _permutation_indices(permutation_indices)
Expand All @@ -105,6 +124,22 @@ class GenerateHierarchy
"ArborX::TreeConstruction::generate_hierarchy",
Kokkos::RangePolicy<ExecutionSpace>(space, 0, leaf_nodes.extent(0)),
*this);

Kokkos::deep_copy(
space,
Kokkos::View<BoundingVolume, Kokkos::HostSpace,
Kokkos::MemoryUnmanaged>(&bounds),
Kokkos::View<BoundingVolume const, MemorySpace,
Kokkos::MemoryUnmanaged>(getRootBoundingVolumePtr()));
}

KOKKOS_FUNCTION
BoundingVolume const *getRootBoundingVolumePtr() const
{
// Need address of the root node's bounding box to copy it back on the host,
// but can't access node elements from the constructor since the data is on
// the device.
return &_internal_nodes.data()->bounding_volume;
}

using DeltaValueType = std::make_signed_t<LinearOrderingValueType>;
Expand Down Expand Up @@ -188,8 +223,6 @@ class GenerateHierarchy
auto &leaf_node = _leaf_nodes(i);
leaf_node = makeLeafNode(_values(original_index));

using BoundingVolume =
typename InternalNodes::value_type::bounding_volume_type;
BoundingVolume bounding_volume{};
expand(bounding_volume, _indexable_getter(leaf_node.value));

Expand Down Expand Up @@ -320,7 +353,8 @@ void generateHierarchy(
permutation_indices,
Kokkos::View<LinearOrderingValueType *, LinearOrderingViewProperties...>
sorted_morton_codes,
LeafNodes leaf_nodes, InternalNodes internal_nodes)
LeafNodes leaf_nodes, InternalNodes internal_nodes,
typename InternalNodes::value_type::bounding_volume_type &bounds)
{
using ConstPermutationIndices =
Kokkos::View<unsigned int const *, PermutationIndicesViewProperties...>;
Expand All @@ -330,7 +364,7 @@ void generateHierarchy(
GenerateHierarchy(space, values, indexable_getter,
ConstPermutationIndices(permutation_indices),
ConstLinearOrdering(sorted_morton_codes), leaf_nodes,
internal_nodes);
internal_nodes, bounds);
}

} // namespace ArborX::Details::TreeConstruction
Expand Down
9 changes: 5 additions & 4 deletions test/tstDetailsTreeConstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,14 @@ void generateHierarchy(Primitives primitives, MortonCodes sorted_morton_codes,
"Testing::indices", n);
ArborX::iota(space, permutation_indices);

using BoundingVolume =
typename InternalNodes::value_type::bounding_volume_type;
BoundingVolume bounds;
ArborX::Details::TreeConstruction::generateHierarchy(
space,
ArborX::Details::LegacyValues<
Primitives, typename InternalNodes::value_type::bounding_volume_type>{
primitives},
ArborX::Details::LegacyValues<Primitives, BoundingVolume>{primitives},
ArborX::Details::DefaultIndexableGetter{}, permutation_indices,
sorted_morton_codes, leaf_nodes, internal_nodes);
sorted_morton_codes, leaf_nodes, internal_nodes, bounds);
}

template <typename LeafNodes, typename InternalNodes>
Expand Down

0 comments on commit 9dcb3ba

Please sign in to comment.