Benchmark Suite
PointNeighbors.jl includes a benchmark suite for comparing neighborhood search implementations and update strategies. Load it with
using PointNeighbors, BenchmarkTools, TrixiParticles
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "benchmarks.jl"));Benchmark Runners
run_benchmark — Method
run_benchmarks(benchmark, n_points_per_dimension, iterations, neighborhood_searches;
search_radius_factor = 3.0,
parallelization_backend = PolyesterBackend(),
names = ["Neighborhood search 1" "Neighborhood search 2" ...],
seed = 1, perturbation_factor_position = 1.0, shuffle = false)Run a benchmark with several neighborhood searches multiple times for increasing numbers of points and return the results as (n_particles_vec, times), where n_particles_vec is a vector containing the number of particles for each iteration and times is a matrix containing the runtimes for each neighborhood search and iteration.
See also
plot_benchmarkto plot the results,run_benchmark_defaultto run the benchmark with the most commonly used neighborhood search implementations,run_benchmark_gputo run the benchmark with all GPU-compatible neighborhood search implementations.
Arguments
benchmark: The benchmark function. Seebenchmark_count_neighbors,benchmark_n_body,benchmark_wcsph,benchmark_tlsph, andbenchmark_tlsph_deformation_grad.n_points_per_dimension: Initial resolution as tuple. The product is the initial number of points. For example, use(100, 100)for a 2D benchmark or(10, 10, 10)for a 3D benchmark.iterations: Number of refinement iterations
Keywords
search_radius_factor = 3.0: Search radius as a multiple of the point spacing. If supported by the benchmark, the type ofsearch_radius_factordetermines if the benchmark is run in single or double precision.parallelization_backend = PolyesterBackend(): Parallelization strategy to use. SeePointNeighbors.@threadedfor a list of available backends.names = ["Neighborhood search 1" ...]: Names of the neighborhood searches used in the benchmark output.seed = 1: Seed to perturb the point positions. Different seeds yield slightly different point positions.perturbation_factor_position = 1.0: Scale the point position perturbation by this factor. A factor of1.0corresponds to a standard deviation similar to that of a realistic simulation.shuffle = false: Randomly shuffle the point ordering instead of sorting points by cell index.
Examples
using PointNeighbors
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "benchmarks.jl"));
run_benchmark(benchmark_count_neighbors, (10, 10), 3,
[TrivialNeighborhoodSearch{2}(), GridNeighborhoodSearch{2}()])run_benchmark_default — Method
run_benchmark_default(benchmark, n_points_per_dimension, iterations;
max_neighbors = 128, kwargs...)Shortcut to call run_benchmark with the most commonly used neighborhood search implementations:
GridNeighborhoodSearchGridNeighborhoodSearchwithFullGridCellListPrecomputedNeighborhoodSearch
Arguments
benchmark: The benchmark function. Seebenchmark_count_neighbors,benchmark_n_body,benchmark_wcsph,benchmark_tlsph, andbenchmark_tlsph_deformation_grad.n_points_per_dimension: Initial resolution as tuple. The product is the initial number of points. For example, use(100, 100)for a 2D benchmark or(10, 10, 10)for a 3D benchmark.iterations: Number of refinement iterations
Keywords
max_neighbors = 128: Maximum neighbor-list capacity for the precomputed neighborhood search. This needs to be increased for a largersearch_radius_factorand can be decreased if the benchmark runs out of memory.
See run_benchmark for a list of additional available keywords.
Examples
using PointNeighbors
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "benchmarks.jl"));
run_benchmark_default(benchmark_n_body, (10, 10), 3)run_benchmark_full_grid — Method
run_benchmark_full_grid(benchmark, n_points_per_dimension, iterations; kwargs...)Shortcut to call run_benchmark with a GridNeighborhoodSearch with a FullGridCellList. This is the neighborhood search implementation that is used in TrixiParticles.jl when performance is important. Use this function to benchmark and profile TrixiParticles.jl kernels.
Arguments
benchmark: The benchmark function. Seebenchmark_count_neighbors,benchmark_n_body,benchmark_wcsph,benchmark_tlsph, andbenchmark_tlsph_deformation_grad.n_points_per_dimension: Initial resolution as tuple. The product is the initial number of points. For example, use(100, 100)for a 2D benchmark or(10, 10, 10)for a 3D benchmark.iterations: Number of refinement iterations
Keywords
See run_benchmark for a list of available keywords.
Examples
using PointNeighbors
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "benchmarks.jl"));
run_benchmark_full_grid(benchmark_n_body, (10, 10), 3)run_benchmark_gpu — Method
run_benchmark_gpu(benchmark, n_points_per_dimension, iterations;
max_neighbors = 128, kwargs...)Shortcut to call run_benchmark with all GPU-compatible neighborhood search implementations:
GridNeighborhoodSearchwithFullGridCellListPrecomputedNeighborhoodSearch
Arguments
benchmark: The benchmark function. Seebenchmark_count_neighbors,benchmark_n_body,benchmark_wcsph,benchmark_tlsph, andbenchmark_tlsph_deformation_grad.n_points_per_dimension: Initial resolution as tuple. The product is the initial number of points. For example, use(100, 100)for a 2D benchmark or(10, 10, 10)for a 3D benchmark.iterations: Number of refinement iterations
Keywords
max_neighbors = 128: Maximum neighbor-list capacity for the precomputed neighborhood search. This needs to be increased for a largersearch_radius_factorand can be decreased if the benchmark runs out of memory.
See run_benchmark for a list of additional available keywords.
Examples
using PointNeighbors
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "benchmarks.jl"));
run_benchmark_gpu(benchmark_n_body, (10, 10), 3)run_benchmark_precomputed — Method
run_benchmark_precomputed(benchmark, n_points_per_dimension, iterations;
max_neighbors = 128, kwargs...)Shortcut to call run_benchmark with a PrecomputedNeighborhoodSearch. This is the neighborhood search implementation that is used in TrixiParticles.jl for Total Lagrangian SPH, where the neighborhood is computed in initial coordinates. Use this function to benchmark and profile TrixiParticles.jl kernels.
Arguments
benchmark: The benchmark function. Seebenchmark_count_neighbors,benchmark_n_body,benchmark_wcsph,benchmark_tlsph, andbenchmark_tlsph_deformation_grad.n_points_per_dimension: Initial resolution as tuple. The product is the initial number of points. For example, use(100, 100)for a 2D benchmark or(10, 10, 10)for a 3D benchmark.iterations: Number of refinement iterations
Keywords
max_neighbors = 128: Maximum neighbor-list capacity for the precomputed neighborhood search. This needs to be increased for a largersearch_radius_factorand can be decreased if the benchmark runs out of memory.
See run_benchmark for a list of additional available keywords.
Examples
using PointNeighbors
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "benchmarks.jl"));
run_benchmark_precomputed(benchmark_n_body, (10, 10), 3)run_benchmark_updates — Method
run_benchmark_updates(n_points_per_dimension, iterations;
max_neighbors = 128, kwargs...)Benchmark benchmark_update_alternating with the update strategies ParallelUpdate, ParallelIncrementalUpdate, and SemiParallelUpdate, as well as with a PrecomputedNeighborhoodSearch using ParallelUpdate internally.
The benchmark alternates between two perturbed point clouds. In 3D, approximately 0.7% of the particles change cells between them, representative of an SPH update. This fraction is not relevant for ParallelUpdate, which reinitializes all particles on every update.
Returns (n_particles_vec, times) as described for run_benchmark.
Arguments
n_points_per_dimension: Initial resolution as tuple. The product is the initial number of points. For example, use(100, 100)for a 2D benchmark or(10, 10, 10)for a 3D benchmark.iterations: Number of refinement iterations
Keywords
max_neighbors = 128: Maximum neighbor-list capacity for the precomputed neighborhood search. This needs to be increased for a largersearch_radius_factorand can be decreased if the benchmark runs out of memory.
See run_benchmark for a list of additional available keywords.
Examples
using PointNeighbors
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "benchmarks.jl"));
run_benchmark_updates((10, 10, 10), 3)Benchmark Workloads
benchmark_count_neighbors — Method
benchmark_count_neighbors(neighborhood_search, coordinates;
parallelization_backend = default_backend(coordinates))A very cheap and simple neighborhood search benchmark, only counting the neighbors of each point. For each point-neighbor pair, only an array entry is incremented.
Due to the minimal computational cost, differences between neighborhood search implementations are highlighted. On the other hand, this is the least realistic benchmark.
For a computationally heavier benchmark, see benchmark_n_body.
benchmark_n_body — Method
benchmark_n_body(neighborhood_search, coordinates;
parallelization_backend = default_backend(coordinates))A simple neighborhood search benchmark, computing the right-hand side of an n-body simulation with a cutoff (corresponding to the search radius of neighborhood_search).
This is a more realistic benchmark for particle-based simulations than benchmark_count_neighbors. However, due to the higher computational cost, differences between neighborhood search implementations are less pronounced.
benchmark_tlsph — Method
benchmark_tlsph(neighborhood_search, coordinates;
parallelization_backend = default_backend(coordinates))A benchmark of the interaction forces of a full real-life Total Lagrangian Smoothed Particle Hydrodynamics (TLSPH) simulation with TrixiParticles.jl. This method is used to simulate an elastic structure.
The right-hand side of the TLSPH equations consists of two main parts:
- The deformation gradient (
benchmark_tlsph_deformation_grad). - The interaction forces (
benchmark_tlsph).
benchmark_tlsph_deformation_grad — Method
benchmark_tlsph_deformation_grad(neighborhood_search, coordinates;
parallelization_backend = default_backend(coordinates))A benchmark of the deformation gradient computation of a full real-life Total Lagrangian Smoothed Particle Hydrodynamics (TLSPH) simulation with TrixiParticles.jl. This method is used to simulate an elastic structure.
The right-hand side of the TLSPH equations consists of two main parts:
- The deformation gradient (
benchmark_tlsph_deformation_grad). - The interaction forces (
benchmark_tlsph).
benchmark_wcsph — Method
benchmark_wcsph(neighborhood_search, coordinates;
parallelization_backend = default_backend(coordinates))A benchmark of the right-hand side of a full real-life Weakly Compressible Smoothed Particle Hydrodynamics (WCSPH) simulation with TrixiParticles.jl. This method is used to simulate an incompressible fluid.
benchmark_initialize — Method
benchmark_initialize(neighborhood_search, coordinates;
parallelization_backend = default_backend(coordinates))Benchmark neighborhood search initialization with the given coordinates.
benchmark_update_alternating — Method
benchmark_update_alternating(neighborhood_search, coordinates;
parallelization_backend = default_backend(coordinates))A very simple benchmark for neighborhood search update, alternating between two differently perturbed point clouds.
This is a good benchmark for incremental updates, since most particles stay in their cells. Similar to 3D dam break simulations, ~0.5% of the particles change their cell during an update in 2D and ~0.7% in 3D.
Plotting
Load the plotting utilities with
using PointNeighbors, Plots
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "plot_benchmarks.jl"));plot_benchmark — Method
plot_benchmark(n_particles_vec, times; kwargs...)Plot the results of a benchmark run with run_benchmark. Note that the arguments are the outputs of that function.
Arguments
n_particles_vec: Vector containing the number of particles for each iteration.times: Matrix containing the runtimes for each neighborhood search and iteration.
Keywords
Keyword arguments are passed to Plots.plot. For example, use title = "My title".
Examples
using PointNeighbors
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "benchmarks.jl"));
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "plot_benchmarks.jl"));
n_particles_vec, times = run_benchmark_default(benchmark_count_neighbors, (10, 10), 3)
plot_benchmark(n_particles_vec, times; title = "Count neighbors benchmark")