Skip to content

Commit

Permalink
switch to using AK TaskPartitioner. Added logo
Browse files Browse the repository at this point in the history
  • Loading branch information
anicusan committed Nov 3, 2024
1 parent 4f33412 commit 23337b3
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 211 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ AcceleratedKernels = "0.1"
ArgCheck = "2.3.0"
Atomix = "0.1"
DocStringExtensions = "0.9"
GPUArraysCore = "0.1.6"
GPUArraysCore = "0.1.6, 0.2"
KernelAbstractions = "0.9"
LinearAlgebra = "1.6"
julia = "1.6"
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
[![ImplicitBVH](https://github.com/StellaOrg/ImplicitBVH.jl/blob/main/docs/src/static/bunny.png?raw=true)](https://stellaorg.github.io/ImplicitBVH.jl/)
[![ImplicitBVH](https://github.com/StellaOrg/ImplicitBVH.jl/blob/main/docs/src/assets/logo.png?raw=true)](https://stellaorg.github.io/ImplicitBVH.jl/)
[![ImplicitBVH](https://github.com/StellaOrg/ImplicitBVH.jl/blob/main/docs/src/assets/bunny.png?raw=true)](https://stellaorg.github.io/ImplicitBVH.jl/)


[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://stellaorg.github.io/ImplicitBVH.jl/stable)
[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://stellaorg.github.io/ImplicitBVH.jl/dev)
[![Docs Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://stellaorg.github.io/ImplicitBVH.jl/stable)
[![Docs Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://stellaorg.github.io/ImplicitBVH.jl/dev)
[![Build Status](https://github.com/StellaOrg/ImplicitBVH.jl/workflows/CI/badge.svg)](https://github.com/StellaOrg/ImplicitBVH.jl/actions?query=workflow%3ACI+branch%3Amaster)


# ImplicitBVH.jl
*High-Performance Cross-Architecture Bounding Volume Hierarchy for Collision Detection*
*High-Performance Cross-Architecture Bounding Volume Hierarchy for Collision Detection and Ray Tracing*

**New in v0.5.0: GPU acceleration via [AcceleratedKernels.jl](https://github.com/anicusan/AcceleratedKernels.jl)/[KernelAbstractions.jl](https://github.com/JuliaGPU/KernelAbstractions.jl) targeting all JuliaGPU backends, i.e. Nvidia CUDA, AMD ROCm, Intel oneAPI, Apple Metal.**
**New in v0.5.0: Ray Tracing and GPU acceleration via [AcceleratedKernels.jl](https://github.com/anicusan/AcceleratedKernels.jl)/[KernelAbstractions.jl](https://github.com/JuliaGPU/KernelAbstractions.jl) targeting all JuliaGPU backends, i.e. Nvidia CUDA, AMD ROCm, Intel oneAPI, Apple Metal.**

It uses an implicit bounding volume hierarchy constructed from an iterable of some geometric
primitives' (e.g. triangles in a mesh) bounding volumes forming the `ImplicitTree` leaves. The leaves
Expand Down
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ makedocs(
sitename = "ImplicitBVH.jl",
format = Documenter.HTML(
# Only create web pretty-URLs on the CI
prettyurls = get(ENV, "CI", nothing) == "true",
prettyurls=get(ENV, "CI", nothing) == "true",
sidebar_sitename=false,
),
)
deploydocs(repo = "github.com/StellaOrg/ImplicitBVH.jl.git")
File renamed without changes
Binary file added docs/src/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion docs/src/utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
```@docs
ImplicitBVH.BVHOptions
ImplicitBVH.get_index_type
ImplicitBVH.TaskPartitioner
```
1 change: 1 addition & 0 deletions prototype/Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[deps]
AcceleratedKernels = "6a4ca0a5-0e36-4168-a932-d9be78d558f1"
Atomix = "a9b6321e-bd34-4604-b9c9-b65b8de01458"
AtomixMetal = "fc0d88fc-5db5-40d7-bf35-da84fd759def"
Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f"
ImplicitBVH = "932a18dc-bb55-4cd5-bdd6-1368ec9cea29"
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
Expand Down
2 changes: 1 addition & 1 deletion src/traverse/traverse.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
$(TYPEDEF)
const IndexPair{I} = Tuple{I, I}
Alias for a tuple of two indices representing e.g. a contacting pair.
"""
Expand Down
66 changes: 30 additions & 36 deletions src/traverse/traverse_pair_cpu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,27 @@ function traverse_nodes_pair!(bvh1, bvh2, src, dst, num_src, ::Nothing, level1,

# Split computation into contiguous ranges of minimum 100 elements each; if only single thread
# is needed, inline call
tp = TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
tp = AK.TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
if tp.num_tasks == 1
num_dst = traverse_nodes_pair_range!(
bvh1, bvh2,
src, dst, nothing,
virtual_nodes_before1,
virtual_nodes_before2,
(1, num_src),
1:num_src,
)
else
# Keep track of tasks launched and number of elements written by each task in their unique
# memory region. The unique region is equal to 4 dst elements per src element
tasks = Vector{Task}(undef, tp.num_tasks)
num_written = Vector{Int}(undef, tp.num_tasks)
@inbounds for i in 1:tp.num_tasks
istart, iend = tp[i]
tasks[i] = Threads.@spawn traverse_nodes_pair_range!(
bvh1, bvh2,
src, view(dst, 4istart - 3:4iend), view(num_written, i),
virtual_nodes_before1,
virtual_nodes_before2,
(istart, iend),
tp[i],
)
end

Expand All @@ -43,7 +42,7 @@ function traverse_nodes_pair!(bvh1, bvh2, src, dst, num_src, ::Nothing, level1,

# Repack written contacts by the second, third thread, etc.
if i > 1
istart, iend = tp[i]
istart = tp[i].start
for j in 1:task_num_written
dst[num_dst + j] = dst[4istart - 3 + j - 1]
end
Expand All @@ -63,7 +62,7 @@ function traverse_nodes_pair_range!(
num_dst = 0

# For each BVTT pair of nodes, check for contact
@inbounds for i in irange[1]:irange[2]
@inbounds for i in irange
# Extract implicit indices of BVH nodes to test
implicit1, implicit2 = src[i]

Expand Down Expand Up @@ -130,28 +129,27 @@ function traverse_nodes_left!(bvh1, bvh2, src, dst, num_src, ::Nothing, level1,

# Split computation into contiguous ranges of minimum 100 elements each; if only single thread
# is needed, inline call
tp = TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
tp = AK.TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
if tp.num_tasks == 1
num_dst = traverse_nodes_left_range!(
bvh1, bvh2,
src, dst, nothing,
virtual_nodes_before1,
virtual_nodes_before2,
(1, num_src),
1:num_src,
)
else
# Keep track of tasks launched and number of elements written by each task in their unique
# memory region. The unique region is equal to 2 dst elements per src element
tasks = Vector{Task}(undef, tp.num_tasks)
num_written = Vector{Int}(undef, tp.num_tasks)
@inbounds for i in 1:tp.num_tasks
istart, iend = tp[i]
tasks[i] = Threads.@spawn traverse_nodes_left_range!(
bvh1, bvh2,
src, view(dst, 2istart - 1:2iend), view(num_written, i),
virtual_nodes_before1,
virtual_nodes_before2,
(istart, iend),
tp[i],
)
end

Expand All @@ -163,7 +161,7 @@ function traverse_nodes_left!(bvh1, bvh2, src, dst, num_src, ::Nothing, level1,

# Repack written contacts by the second, third thread, etc.
if i > 1
istart, iend = tp[i]
istart = tp[i].start
for j in 1:task_num_written
dst[num_dst + j] = dst[2istart - 1 + j - 1]
end
Expand All @@ -184,7 +182,7 @@ function traverse_nodes_left_range!(

# For each BVTT pair of nodes, check for contact. Only expand BVTT for BVH1, as BVH2 is already
# one above leaf level
@inbounds for i in irange[1]:irange[2]
@inbounds for i in irange
# Extract implicit indices of BVH nodes to test
implicit1, implicit2 = src[i]

Expand Down Expand Up @@ -231,28 +229,27 @@ function traverse_nodes_right!(bvh1, bvh2, src, dst, num_src, ::Nothing, level1,

# Split computation into contiguous ranges of minimum 100 elements each; if only single thread
# is needed, inline call
tp = TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
tp = AK.TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
if tp.num_tasks == 1
num_dst = traverse_nodes_right_range!(
bvh1, bvh2,
src, dst, nothing,
virtual_nodes_before1,
virtual_nodes_before2,
(1, num_src),
1:num_src,
)
else
# Keep track of tasks launched and number of elements written by each task in their unique
# memory region. The unique region is equal to 2 dst elements per src element
tasks = Vector{Task}(undef, tp.num_tasks)
num_written = Vector{Int}(undef, tp.num_tasks)
@inbounds for i in 1:tp.num_tasks
istart, iend = tp[i]
tasks[i] = Threads.@spawn traverse_nodes_right_range!(
bvh1, bvh2,
src, view(dst, 2istart - 1:2iend), view(num_written, i),
virtual_nodes_before1,
virtual_nodes_before2,
(istart, iend),
tp[i],
)
end

Expand All @@ -264,7 +261,7 @@ function traverse_nodes_right!(bvh1, bvh2, src, dst, num_src, ::Nothing, level1,

# Repack written contacts by the second, third thread, etc.
if i > 1
istart, iend = tp[i]
istart = tp[i].start
for j in 1:task_num_written
dst[num_dst + j] = dst[2istart - 1 + j - 1]
end
Expand All @@ -285,7 +282,7 @@ function traverse_nodes_right_range!(

# For each BVTT pair of nodes, check for contact. Only expand BVTT for BVH2, as BVH1 is already
# one above leaf level
@inbounds for i in irange[1]:irange[2]
@inbounds for i in irange
# Extract implicit indices of BVH nodes to test
implicit1, implicit2 = src[i]

Expand Down Expand Up @@ -329,26 +326,25 @@ function traverse_nodes_leaves_left!(bvh1, bvh2, src, dst, num_src, ::Nothing, l

# Split computation into contiguous ranges of minimum 100 elements each; if only single thread
# is needed, inline call
tp = TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
tp = AK.TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
if tp.num_tasks == 1
num_dst = traverse_nodes_leaves_left_range!(
bvh1, bvh2,
src, dst, nothing,
virtual_nodes_before1,
(1, num_src),
1:num_src,
)
else
# Keep track of tasks launched and number of elements written by each task in their unique
# memory region. The unique region is equal to 2 dst elements per src element
tasks = Vector{Task}(undef, tp.num_tasks)
num_written = Vector{Int}(undef, tp.num_tasks)
@inbounds for i in 1:tp.num_tasks
istart, iend = tp[i]
tasks[i] = Threads.@spawn traverse_nodes_leaves_left_range!(
bvh1, bvh2,
src, view(dst, 2istart - 1:2iend), view(num_written, i),
virtual_nodes_before1,
(istart, iend),
tp[i],
)
end

Expand All @@ -360,7 +356,7 @@ function traverse_nodes_leaves_left!(bvh1, bvh2, src, dst, num_src, ::Nothing, l

# Repack written contacts by the second, third thread, etc.
if i > 1
istart, iend = tp[i]
istart = tp[i].start
for j in 1:task_num_written
dst[num_dst + j] = dst[2istart - 1 + j - 1]
end
Expand All @@ -384,7 +380,7 @@ function traverse_nodes_leaves_left_range!(

# For each BVTT pair of nodes, check for contact. Only expand BVTT for BVH1, as BVH2 is already
# at leaf level
@inbounds for i in irange[1]:irange[2]
@inbounds for i in irange
# Extract implicit indices of BVH nodes to test
implicit1, implicit2 = src[i]

Expand Down Expand Up @@ -430,26 +426,25 @@ function traverse_nodes_leaves_right!(bvh1, bvh2, src, dst, num_src, ::Nothing,

# Split computation into contiguous ranges of minimum 100 elements each; if only single thread
# is needed, inline call
tp = TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
tp = AK.TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
if tp.num_tasks == 1
num_dst = traverse_nodes_leaves_right_range!(
bvh1, bvh2,
src, dst, nothing,
virtual_nodes_before2,
(1, num_src),
1:num_src,
)
else
# Keep track of tasks launched and number of elements written by each task in their unique
# memory region. The unique region is equal to 2 dst elements per src element
tasks = Vector{Task}(undef, tp.num_tasks)
num_written = Vector{Int}(undef, tp.num_tasks)
@inbounds for i in 1:tp.num_tasks
istart, iend = tp[i]
tasks[i] = Threads.@spawn traverse_nodes_leaves_right_range!(
bvh1, bvh2,
src, view(dst, 2istart - 1:2iend), view(num_written, i),
virtual_nodes_before2,
(istart, iend),
tp[i],
)
end

Expand All @@ -461,7 +456,7 @@ function traverse_nodes_leaves_right!(bvh1, bvh2, src, dst, num_src, ::Nothing,

# Repack written contacts by the second, third thread, etc.
if i > 1
istart, iend = tp[i]
istart = tp[i].start
for j in 1:task_num_written
dst[num_dst + j] = dst[2istart - 1 + j - 1]
end
Expand All @@ -485,7 +480,7 @@ function traverse_nodes_leaves_right_range!(

# For each BVTT pair of nodes, check for contact. Only expand BVTT for BVH2, as BVH1 is already
# at leaf level
@inbounds for i in irange[1]:irange[2]
@inbounds for i in irange
# Extract implicit indices of BVH nodes to test
implicit1, implicit2 = src[i]

Expand Down Expand Up @@ -527,12 +522,12 @@ function traverse_leaves_pair!(bvh1, bvh2, src, contacts, num_src, ::Nothing, op

# Split computation into contiguous ranges of minimum 100 elements each; if only single thread
# is needed, inline call
tp = TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
tp = AK.TaskPartitioner(num_src, options.num_threads, options.min_traversals_per_thread)
if tp.num_tasks == 1
num_contacts = traverse_leaves_pair_range!(
bvh1, bvh2,
src, view(contacts, :), nothing,
(1, num_src),
1:num_src,
)
else
num_contacts = 0
Expand All @@ -542,11 +537,10 @@ function traverse_leaves_pair!(bvh1, bvh2, src, contacts, num_src, ::Nothing, op
tasks = Vector{Task}(undef, tp.num_tasks)
num_written = Vector{Int}(undef, tp.num_tasks)
@inbounds for i in 1:tp.num_tasks
istart, iend = tp[i]
tasks[i] = Threads.@spawn traverse_leaves_pair_range!(
bvh1, bvh2,
src, view(contacts, istart:iend), view(num_written, i),
(istart, iend),
tp[i],
)
end
@inbounds for i in 1:tp.num_tasks
Expand All @@ -555,7 +549,7 @@ function traverse_leaves_pair!(bvh1, bvh2, src, contacts, num_src, ::Nothing, op

# Repack written contacts by the second, third thread, etc.
if i > 1
istart, iend = tp[i]
istart = tp[i].start
for j in 1:task_num_written
contacts[num_contacts + j] = contacts[istart + j - 1]
end
Expand All @@ -579,7 +573,7 @@ function traverse_leaves_pair_range!(
num_above2 = pow2(bvh2.tree.levels - 1) - 1

# For each BVTT pair of nodes, check for contact
@inbounds for i in irange[1]:irange[2]
@inbounds for i in irange
# Extract implicit indices of BVH leaves to test
implicit1, implicit2 = src[i]

Expand Down
Loading

0 comments on commit 23337b3

Please sign in to comment.