Skip to content

Commit

Permalink
Refactor platform-specific intrinsics to avoid the use of __ and us…
Browse files Browse the repository at this point in the history
…e functions instead of macros whenever possible
  • Loading branch information
madmann91 committed Feb 7, 2021
1 parent de65bf8 commit 729bdd5
Show file tree
Hide file tree
Showing 14 changed files with 113 additions and 102 deletions.
4 changes: 2 additions & 2 deletions include/bvh/bottom_up_algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class BottomUpAlgorithm {
BottomUpAlgorithm(Bvh& bvh)
: bvh(bvh)
{
bvh__assert_not_in_parallel();
bvh::assert_not_in_parallel();
parents = std::make_unique<size_t[]>(bvh.node_count);
flags = std::make_unique<int[]>(bvh.node_count);

Expand All @@ -49,7 +49,7 @@ class BottomUpAlgorithm {
const ProcessLeaf& process_leaf,
const ProcessInnerNode& process_inner_node)
{
bvh__assert_in_parallel();
bvh::assert_in_parallel();

#pragma omp single nowait
{
Expand Down
28 changes: 14 additions & 14 deletions include/bvh/bounding_box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,71 +11,71 @@ struct BoundingBox {
Vector3<Scalar> min, max;

BoundingBox() = default;
bvh__always_inline__ BoundingBox(const Vector3<Scalar>& v) : min(v), max(v) {}
bvh__always_inline__ BoundingBox(const Vector3<Scalar>& min, const Vector3<Scalar>& max) : min(min), max(max) {}
bvh_always_inline BoundingBox(const Vector3<Scalar>& v) : min(v), max(v) {}
bvh_always_inline BoundingBox(const Vector3<Scalar>& min, const Vector3<Scalar>& max) : min(min), max(max) {}

bvh__always_inline__ BoundingBox& shrink(const BoundingBox& bbox) {
bvh_always_inline BoundingBox& shrink(const BoundingBox& bbox) {
min = bvh::max(min, bbox.min);
max = bvh::min(max, bbox.max);
return *this;
}

bvh__always_inline__ BoundingBox& extend(const BoundingBox& bbox) {
bvh_always_inline BoundingBox& extend(const BoundingBox& bbox) {
min = bvh::min(min, bbox.min);
max = bvh::max(max, bbox.max);
return *this;
}

bvh__always_inline__ BoundingBox& extend(const Vector3<Scalar>& v) {
bvh_always_inline BoundingBox& extend(const Vector3<Scalar>& v) {
min = bvh::min(min, v);
max = bvh::max(max, v);
return *this;
}

bvh__always_inline__ Vector3<Scalar> diagonal() const {
bvh_always_inline Vector3<Scalar> diagonal() const {
return max - min;
}

bvh__always_inline__ Vector3<Scalar> center() const {
bvh_always_inline Vector3<Scalar> center() const {
return (max + min) * Scalar(0.5);
}

bvh__always_inline__ Scalar half_area() const {
bvh_always_inline Scalar half_area() const {
auto d = diagonal();
return (d[0] + d[1]) * d[2] + d[0] * d[1];
}

bvh__always_inline__ Scalar volume() const {
bvh_always_inline Scalar volume() const {
auto d = diagonal();
return d[0] * d[1] * d[2];
}

bvh__always_inline__ size_t largest_axis() const {
bvh_always_inline size_t largest_axis() const {
auto d = diagonal();
size_t axis = 0;
if (d[0] < d[1]) axis = 1;
if (d[axis] < d[2]) axis = 2;
return axis;
}

bvh__always_inline__ Scalar largest_extent() const {
bvh_always_inline Scalar largest_extent() const {
return diagonal()[largest_axis()];
}

bvh__always_inline__ bool is_contained_in(const BoundingBox& other) const {
bvh_always_inline bool is_contained_in(const BoundingBox& other) const {
return
max[0] <= other.max[0] && min[0] >= other.min[0] &&
max[1] <= other.max[1] && min[1] >= other.min[1] &&
max[2] <= other.max[2] && min[2] >= other.min[2];
}

bvh__always_inline__ static BoundingBox full() {
bvh_always_inline static BoundingBox full() {
return BoundingBox(
Vector3<Scalar>(-std::numeric_limits<Scalar>::max()),
Vector3<Scalar>(std::numeric_limits<Scalar>::max()));
}

bvh__always_inline__ static BoundingBox empty() {
bvh_always_inline static BoundingBox empty() {
return BoundingBox(
Vector3<Scalar>(std::numeric_limits<Scalar>::max()),
Vector3<Scalar>(-std::numeric_limits<Scalar>::max()));
Expand Down
2 changes: 1 addition & 1 deletion include/bvh/hierarchy_refitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class HierarchyRefitter : public BottomUpAlgorithm<Bvh> {

template <typename UpdateLeaf>
void refit_in_parallel(const UpdateLeaf& update_leaf) {
bvh__assert_in_parallel();
bvh::assert_in_parallel();

// Refit every node of the tree in parallel
traverse_in_parallel(
Expand Down
2 changes: 1 addition & 1 deletion include/bvh/leaf_collapser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class LeafCollapser : public SahBasedAlgorithm<Bvh>, public BottomUpAlgorithm<Bv
{}

void collapse() {
if (bvh__unlikely(bvh.nodes[0].is_leaf()))
if (bvh_unlikely(bvh.nodes[0].is_leaf()))
return;

std::unique_ptr<size_t[]> primitive_indices_copy;
Expand Down
12 changes: 6 additions & 6 deletions include/bvh/linear_bvh_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ class LinearBvhBuilder : public MortonCodeBasedBuilder<Bvh, Morton> {
PrefixSum<size_t> prefix_sum;

std::pair<size_t, size_t> merge(
const Node* bvh__restrict__ input_nodes,
Node* bvh__restrict__ output_nodes,
const Level* bvh__restrict__ input_levels,
Level* bvh__restrict__ output_levels,
size_t* bvh__restrict__ merged_index,
size_t* bvh__restrict__ needs_merge,
const Node* bvh_restrict input_nodes,
Node* bvh_restrict output_nodes,
const Level* bvh_restrict input_levels,
Level* bvh_restrict output_levels,
size_t* bvh_restrict merged_index,
size_t* bvh_restrict needs_merge,
size_t begin, size_t end,
size_t previous_end)
{
Expand Down
12 changes: 6 additions & 6 deletions include/bvh/locally_ordered_clustering_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ class LocallyOrderedClusteringBuilder : public MortonCodeBasedBuilder<Bvh, Morto
}

std::pair<size_t, size_t> cluster(
const Node* bvh__restrict__ input,
Node* bvh__restrict__ output,
size_t* bvh__restrict__ neighbors,
size_t* bvh__restrict__ merged_index,
const Node* bvh_restrict input,
Node* bvh_restrict output,
size_t* bvh_restrict neighbors,
size_t* bvh_restrict merged_index,
size_t begin, size_t end,
size_t previous_end)
{
Expand All @@ -48,8 +48,8 @@ class LocallyOrderedClusteringBuilder : public MortonCodeBasedBuilder<Bvh, Morto

#pragma omp parallel if (end - begin > loop_parallel_threshold)
{
auto thread_count = bvh__get_num_threads();
auto thread_id = bvh__get_thread_num();
auto thread_count = bvh::get_thread_count();
auto thread_id = bvh::get_thread_id();
auto chunk_size = (end - begin) / thread_count;
auto chunk_begin = begin + thread_id * chunk_size;
auto chunk_end = thread_id != thread_count - 1 ? chunk_begin + chunk_size : end;
Expand Down
8 changes: 4 additions & 4 deletions include/bvh/node_intersectors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ struct NodeIntersector {
{}

template <bool IsMin>
bvh__always_inline__
bvh_always_inline
Scalar intersect_axis(int axis, Scalar p, const Ray<Scalar>& ray) const {
return static_cast<const Derived*>(this)->template intersect_axis<IsMin>(axis, p, ray);
}

bvh__always_inline__
bvh_always_inline
std::pair<Scalar, Scalar> intersect(const typename Bvh::Node& node, const Ray<Scalar>& ray) const {
Vector3<Scalar> entry, exit;
entry[0] = intersect_axis<true >(0, node.bounds[0 * 2 + octant[0]], ray);
Expand Down Expand Up @@ -70,7 +70,7 @@ struct RobustNodeIntersector : public NodeIntersector<Bvh, RobustNodeIntersector
}

template <bool IsMin>
bvh__always_inline__
bvh_always_inline
Scalar intersect_axis(int axis, Scalar p, const Ray<Scalar>& ray) const {
return (p - ray.origin[axis]) * (IsMin ? inverse_direction[axis] : padded_inverse_direction[axis]);
}
Expand All @@ -94,7 +94,7 @@ struct FastNodeIntersector : public NodeIntersector<Bvh, FastNodeIntersector<Bvh
}

template <bool>
bvh__always_inline__
bvh_always_inline
Scalar intersect_axis(int axis, Scalar p, const Ray<Scalar>&) const {
return fast_multiply_add(p, inverse_direction[axis], scaled_origin[axis]);
}
Expand Down
55 changes: 33 additions & 22 deletions include/bvh/platform.hpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
#ifndef BVH_PLATFORM_HPP
#define BVH_PLATFORM_HPP

#include <cstddef>
#include <cassert>

#ifdef _OPENMP
#include <omp.h>
#include <cassert>
#define bvh__get_num_threads() omp_get_num_threads()
#define bvh__get_thread_num() omp_get_thread_num()
#define bvh__assert_not_in_parallel() assert(omp_get_level() == 0);
#define bvh__assert_in_parallel() assert(omp_get_level() > 0);
#else
#define bvh__get_num_threads() 1
#define bvh__get_thread_num() 0
#define bvh__assert_not_in_parallel() (void)0
#define bvh__assert_in_parallel() (void)0
#endif

#if defined(__GNUC__) || defined(__clang__)
#define bvh__restrict__ __restrict
#define bvh__always_inline__ __attribute__((always_inline))
#define bvh__likely(x) __builtin_expect(x, true)
#define bvh__unlikely(x) __builtin_expect(x, false)
#define bvh_restrict __restrict
#define bvh_always_inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define bvh__restrict__ __restrict
#define bvh__always_inline__ __forceinline
#define bvh__likely(x) x
#define bvh__unlikely(x) x
#define bvh_restrict __restrict
#define bvh_always_inline __forceinline
#else
#define bvh_restrict
#define bvh_always_inline
#endif

#if defined(__GNUC__) || defined(__clang__)
#define bvh_likely(x) __builtin_expect(x, true)
#define bvh_unlikely(x) __builtin_expect(x, false)
#else
#define bvh__restrict__
#define bvh__always_inline__
#define bvh__likely(x) x
#define bvh__unlikely(x) x
#define bvh_likely(x) x
#define bvh_unlikely(x) x
#endif

namespace bvh {

#ifdef _OPENMP
inline size_t get_thread_count() { return omp_get_num_threads(); }
inline size_t get_thread_id() { return omp_get_thread_num(); }
inline void assert_not_in_parallel() { assert(omp_get_level() == 0); }
inline void assert_in_parallel() { assert(omp_get_level() > 0); }
#else
inline constexpr size_t get_thread_count() { return 1; }
inline constexpr size_t get_thread_id() { return 0; }
inline void assert_not_in_parallel() {}
inline void assert_in_parallel() {}
#endif

} // namespace bvh

#endif
6 changes: 3 additions & 3 deletions include/bvh/prefix_sum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ class PrefixSum {
/// Performs the prefix sum. Must be called from a parallel region.
template <typename F = std::plus<T>>
void sum_in_parallel(const T* input, T* output, size_t count, F f = F()) {
bvh__assert_in_parallel();
bvh::assert_in_parallel();

size_t thread_count = bvh__get_num_threads();
size_t thread_id = bvh__get_thread_num();
size_t thread_count = bvh::get_thread_count();
size_t thread_id = bvh::get_thread_id();

// This algorithm is not effective when there are fewer than 2 threads.
if (thread_count <= 2) {
Expand Down
14 changes: 7 additions & 7 deletions include/bvh/radix_sort.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ class RadixSort {
/// Performs the sort. Must be called from a parallel region.
template <typename Key, typename Value>
void sort_in_parallel(
Key* bvh__restrict__& keys,
Key* bvh__restrict__& keys_copy,
Value* bvh__restrict__& values,
Value* bvh__restrict__& values_copy,
Key* bvh_restrict& keys,
Key* bvh_restrict& keys_copy,
Value* bvh_restrict& values,
Value* bvh_restrict& values_copy,
size_t count, size_t bit_count)
{
bvh__assert_in_parallel();
bvh::assert_in_parallel();

static constexpr size_t bucket_count = 1 << bits_per_iteration;
static constexpr Key mask = (Key(1) << bits_per_iteration) - 1;

size_t thread_count = bvh__get_num_threads();
size_t thread_id = bvh__get_thread_num();
size_t thread_count = bvh::get_thread_count();
size_t thread_id = bvh::get_thread_id();

// Allocate temporary storage
#pragma omp single
Expand Down
14 changes: 7 additions & 7 deletions include/bvh/single_ray_traverser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class SingleRayTraverser {
};

template <typename PrimitiveIntersector, typename Statistics>
bvh__always_inline__
bvh_always_inline
std::optional<typename PrimitiveIntersector::Result>& intersect_leaf(
const typename Bvh::Node& node,
Ray<Scalar>& ray,
Expand All @@ -63,13 +63,13 @@ class SingleRayTraverser {
}

template <typename PrimitiveIntersector, typename Statistics>
bvh__always_inline__
bvh_always_inline
std::optional<typename PrimitiveIntersector::Result>
intersect(Ray<Scalar> ray, PrimitiveIntersector& primitive_intersector, Statistics& statistics) const {
auto best_hit = std::optional<typename PrimitiveIntersector::Result>(std::nullopt);

// If the root is a leaf, intersect it and return
if (bvh__unlikely(bvh.nodes[0].is_leaf()))
if (bvh_unlikely(bvh.nodes[0].is_leaf()))
return intersect_leaf(bvh.nodes[0], ray, best_hit, primitive_intersector, statistics);

NodeIntersector node_intersector(ray);
Expand All @@ -87,7 +87,7 @@ class SingleRayTraverser {
auto distance_right = node_intersector.intersect(*right_child, ray);

if (distance_left.first <= distance_left.second) {
if (bvh__unlikely(left_child->is_leaf())) {
if (bvh_unlikely(left_child->is_leaf())) {
if (intersect_leaf(*left_child, ray, best_hit, primitive_intersector, statistics) &&
primitive_intersector.any_hit)
break;
Expand All @@ -97,7 +97,7 @@ class SingleRayTraverser {
left_child = nullptr;

if (distance_right.first <= distance_right.second) {
if (bvh__unlikely(right_child->is_leaf())) {
if (bvh_unlikely(right_child->is_leaf())) {
if (intersect_leaf(*right_child, ray, best_hit, primitive_intersector, statistics) &&
primitive_intersector.any_hit)
break;
Expand Down Expand Up @@ -140,7 +140,7 @@ class SingleRayTraverser {

/// Intersects the BVH with the given ray and intersector.
template <typename PrimitiveIntersector>
bvh__always_inline__
bvh_always_inline
std::optional<typename PrimitiveIntersector::Result>
traverse(const Ray<Scalar>& ray, PrimitiveIntersector& intersector) const {
struct {
Expand All @@ -156,7 +156,7 @@ class SingleRayTraverser {
/// Intersects the BVH with the given ray and intersector.
/// Record statistics on the number of traversal and intersection steps.
template <typename PrimitiveIntersector>
bvh__always_inline__
bvh_always_inline
std::optional<typename PrimitiveIntersector::Result>
traverse(const Ray<Scalar>& ray, PrimitiveIntersector& primitive_intersector, Statistics& statistics) const {
return intersect(ray, primitive_intersector, statistics);
Expand Down
2 changes: 1 addition & 1 deletion include/bvh/spatial_split_bvh_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ class SpatialSplitBvhBuildTask : public TopDownBuildTask {
BoundingBox<Scalar>* accumulated_bboxes;
std::vector<bool> reference_marks;

std::array<Reference* bvh__restrict__, 3> references;
std::array<Reference* bvh_restrict, 3> references;

size_t& reference_count;
size_t primitive_count;
Expand Down
4 changes: 2 additions & 2 deletions include/bvh/sweep_sah_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ class SweepSahBuildTask : public TopDownBuildTask {
const BoundingBox<Scalar>* bboxes;
const Vector3<Scalar>* centers;

std::array<size_t* bvh__restrict__, 3> references;
std::array<Scalar* bvh__restrict__, 3> costs;
std::array<size_t* bvh_restrict, 3> references;
std::array<Scalar* bvh_restrict, 3> costs;
Mark* marks;

std::pair<Scalar, size_t> find_split(int axis, size_t begin, size_t end) {
Expand Down
Loading

0 comments on commit 729bdd5

Please sign in to comment.