Skip to content

Commit

Permalink
make an optional default feature
Browse files Browse the repository at this point in the history
  • Loading branch information
dbenson24 committed Feb 19, 2024
1 parent aad477d commit eb1b9de
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 34 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ log = "0.4"
serde = { optional = true, version = "1", features = ["derive"] }
num = "0.4.0"
nalgebra = { version = "0.32.2", features = ["default", "serde-serialize"] }
rayon = "1.8.1"
rayon = {optional = true, version = "1.8.1" }

[dev-dependencies]
proptest = "1.0"
Expand All @@ -30,6 +30,7 @@ float_eq = "1"
doc-comment = "0.3"

[features]
default = ["rayon"]
bench = []
simd = []

Expand Down
1 change: 0 additions & 1 deletion src/aabb.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Axis Aligned Bounding Boxes.
use nalgebra::{Point, SVector};
use num::{Float, FromPrimitive, Signed};
use std::fmt;
use std::ops::Index;

Expand Down
14 changes: 13 additions & 1 deletion src/bounding_hierarchy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ use nalgebra::{ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, Scalar, SimdPartialOr
use num::{Float, FromPrimitive, Signed};

use crate::aabb::Bounded;
#[cfg(feature = "rayon")]
use crate::bvh::rayon_executor;
use crate::bvh::BvhNodeBuildArgs;
use crate::ray::Ray;

/// Encapsulates the required traits for the type used in the Bvh.
/// Encapsulates the required traits for the value type used in the Bvh.
pub trait BHValue:
Scalar
+ Copy
Expand Down Expand Up @@ -159,6 +161,16 @@ pub trait BoundingHierarchy<T: BHValue, const D: usize> {
executor: Executor,
) -> Self;

/// Builds the bvh with a rayon based executor.
#[cfg(feature = "rayon")]
fn build_par<Shape: BHShape<T, D> + Send>(shapes: &mut [Shape]) -> Self
where
T: Send,
Self: Sized,
{
Self::build_with_executor(shapes, rayon_executor)
}

/// Traverses the [`BoundingHierarchy`].
/// Returns a subset of `shapes`, in which the [`Aabb`]s of the elements were hit by `ray`.
///
Expand Down
51 changes: 31 additions & 20 deletions src/bvh/bvh_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
//! [`BvhNode`]: struct.BvhNode.html
//!
use num::{Float, ToPrimitive};

use crate::aabb::{Aabb, Bounded};
// use crate::axis::Axis;
use crate::bounding_hierarchy::{BHShape, BHValue, BoundingHierarchy};
Expand Down Expand Up @@ -126,19 +124,6 @@ impl<'a, S, T: BHValue, const D: usize> BvhNodeBuildArgs<'a, S, T, D> {
}
}

/// Rayon based executor
pub fn rayon_executor<S, T: Send + BHValue, const D: usize>(
left: BvhNodeBuildArgs<S, T, D>,
right: BvhNodeBuildArgs<S, T, D>,
) where
S: BHShape<T, D> + Send,
{
rayon::join(
|| left.build_with_executor(rayon_executor),
|| right.build_with_executor(rayon_executor),
);
}

/// The [`BvhNode`] enum that describes a node in a [`Bvh`].
/// It's either a leaf node and references a shape (by holding its index)
/// or a regular node that has two child nodes.
Expand Down Expand Up @@ -978,6 +963,25 @@ impl<T: BHValue + std::fmt::Display, const D: usize> BoundingHierarchy<T, D> for
}
}

/// Rayon based executor
#[cfg(feature = "rayon")]
pub fn rayon_executor<S, T: Send + BHValue, const D: usize>(
left: BvhNodeBuildArgs<S, T, D>,
right: BvhNodeBuildArgs<S, T, D>,
) where
S: BHShape<T, D> + Send,
{
if left.indices.len() + right.indices.len() < 64 {
left.build();
right.build();
} else {
rayon::join(
|| left.build_with_executor(rayon_executor),
|| right.build_with_executor(rayon_executor),
);
}
}

#[cfg(test)]
mod tests {
use crate::testbase::{build_some_bh, traverse_some_bh, TBvh3, TBvhNode3};
Expand Down Expand Up @@ -1025,13 +1029,17 @@ mod tests {

#[cfg(all(feature = "bench", test))]
mod bench {
use crate::bvh::rayon_executor;
#[cfg(feature = "rayon")]
use crate::bounding_hierarchy::BoundingHierarchy;
use crate::testbase::{
build_1200_triangles_bh, build_1200_triangles_bh_rayon, build_120k_triangles_bh,
build_120k_triangles_bh_rayon, build_12k_triangles_bh, build_12k_triangles_bh_rayon,
build_1200_triangles_bh, build_120k_triangles_bh, build_12k_triangles_bh,
intersect_1200_triangles_bh, intersect_120k_triangles_bh, intersect_12k_triangles_bh,
intersect_bh, load_sponza_scene, TBvh3,
};
#[cfg(feature = "rayon")]
use crate::testbase::{
build_1200_triangles_bh_rayon, build_120k_triangles_bh_rayon, build_12k_triangles_bh_rayon,
};

#[bench]
/// Benchmark the construction of a [`Bvh`] with 1,200 triangles.
Expand Down Expand Up @@ -1060,33 +1068,36 @@ mod bench {
});
}

#[cfg(feature = "rayon")]
#[bench]
/// Benchmark the construction of a `BVH` with 1,200 triangles.
fn bench_build_1200_triangles_bvh_rayon(b: &mut ::test::Bencher) {
build_1200_triangles_bh_rayon::<TBvh3>(b);
}

#[bench]
#[cfg(feature = "rayon")]
/// Benchmark the construction of a `BVH` with 12,000 triangles.
fn bench_build_12k_triangles_bvh_rayon(b: &mut ::test::Bencher) {
build_12k_triangles_bh_rayon::<TBvh3>(b);
}

#[bench]
#[cfg(feature = "rayon")]
/// Benchmark the construction of a `BVH` with 120,000 triangles.
fn bench_build_120k_triangles_bvh_rayon(b: &mut ::test::Bencher) {
build_120k_triangles_bh_rayon::<TBvh3>(b);
}

#[bench]
#[cfg(feature = "rayon")]
/// Benchmark the construction of a `BVH` for the Sponza scene.
fn bench_build_sponza_bvh_rayon(b: &mut ::test::Bencher) {
let (mut triangles, _) = load_sponza_scene();
b.iter(|| {
TBvh3::build_with_executor(&mut triangles, rayon_executor);
TBvh3::build_par(&mut triangles);
});
}

#[bench]
/// Benchmark intersecting 1,200 triangles using the recursive [`Bvh`].
fn bench_intersect_1200_triangles_bvh(b: &mut ::test::Bencher) {
Expand Down
2 changes: 0 additions & 2 deletions src/bvh/optimization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ use crate::bvh::*;

use log::info;

use num::{FromPrimitive, Zero};

// TODO Consider: Instead of getting the scene's shapes passed, let leaf nodes store an `Aabb`
// that is updated from the outside, perhaps by passing not only the indices of the changed
// shapes, but also their new `Aabb`'s into update_shapes().
Expand Down
2 changes: 0 additions & 2 deletions src/ray/intersect_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
use super::Ray;
use crate::{aabb::Aabb, bounding_hierarchy::BHValue, utils::fast_max};

use num::Zero;

/// The [`RayIntersection`] trait allows for generic implementation of ray intersection
/// useful for our SIMD optimizations.
pub trait RayIntersection<T: BHValue, const D: usize> {
Expand Down
12 changes: 5 additions & 7 deletions src/testbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,31 +491,29 @@ pub fn build_120k_triangles_bh<T: BoundingHierarchy<f32, 3>>(b: &mut ::test::Ben
build_n_triangles_bh::<T>(10_000, b);
}

#[cfg(feature = "bench")]
#[cfg(all(feature = "bench", feature = "rayon"))]
fn build_n_triangles_bh_rayon<T: BoundingHierarchy<f32, 3>>(n: usize, b: &mut ::test::Bencher) {
use crate::bvh::rayon_executor;

let bounds = default_bounds();
let mut triangles = create_n_cubes(n, &bounds);
b.iter(|| {
T::build_with_executor(&mut triangles, rayon_executor);
T::build_par(&mut triangles);
});
}

/// Benchmark the construction of a [`BoundingHierarchy`] with 1,200 triangles.
#[cfg(feature = "bench")]
#[cfg(all(feature = "bench", feature = "rayon"))]
pub fn build_1200_triangles_bh_rayon<T: BoundingHierarchy<f32, 3>>(b: &mut ::test::Bencher) {
build_n_triangles_bh_rayon::<T>(100, b);
}

/// Benchmark the construction of a [`BoundingHierarchy`] with 12,000 triangles.
#[cfg(feature = "bench")]
#[cfg(all(feature = "bench", feature = "rayon"))]
pub fn build_12k_triangles_bh_rayon<T: BoundingHierarchy<f32, 3>>(b: &mut ::test::Bencher) {
build_n_triangles_bh_rayon::<T>(1_000, b);
}

/// Benchmark the construction of a [`BoundingHierarchy`] with 120,000 triangles.
#[cfg(feature = "bench")]
#[cfg(all(feature = "bench", feature = "rayon"))]
pub fn build_120k_triangles_bh_rayon<T: BoundingHierarchy<f32, 3>>(b: &mut ::test::Bencher) {
build_n_triangles_bh_rayon::<T>(10_000, b);
}
Expand Down

0 comments on commit eb1b9de

Please sign in to comment.