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_benchmarkMethod
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

Arguments

Keywords

  • search_radius_factor = 3.0: Search radius as a multiple of the point spacing. If supported by the benchmark, the type of search_radius_factor determines if the benchmark is run in single or double precision.
  • parallelization_backend = PolyesterBackend(): Parallelization strategy to use. See PointNeighbors.@threaded for 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 of 1.0 corresponds 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}()])
source
run_benchmark_defaultMethod
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:

  • GridNeighborhoodSearch
  • GridNeighborhoodSearch with FullGridCellList
  • PrecomputedNeighborhoodSearch

Arguments

Keywords

  • max_neighbors = 128: Maximum neighbor-list capacity for the precomputed neighborhood search. This needs to be increased for a larger search_radius_factor and 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)
source
run_benchmark_full_gridMethod
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

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)
source
run_benchmark_gpuMethod
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:

  • GridNeighborhoodSearch with FullGridCellList
  • PrecomputedNeighborhoodSearch

Arguments

Keywords

  • max_neighbors = 128: Maximum neighbor-list capacity for the precomputed neighborhood search. This needs to be increased for a larger search_radius_factor and 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)
source
run_benchmark_precomputedMethod
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

Keywords

  • max_neighbors = 128: Maximum neighbor-list capacity for the precomputed neighborhood search. This needs to be increased for a larger search_radius_factor and 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)
source
run_benchmark_updatesMethod
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 larger search_radius_factor and 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)
source

Benchmark Workloads

benchmark_count_neighborsMethod
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.

source
benchmark_n_bodyMethod
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.

source
benchmark_tlsphMethod
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:

source
benchmark_tlsph_deformation_gradMethod
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:

source
benchmark_wcsphMethod
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.

source
benchmark_initializeMethod
benchmark_initialize(neighborhood_search, coordinates;
                     parallelization_backend = default_backend(coordinates))

Benchmark neighborhood search initialization with the given coordinates.

source
benchmark_update_alternatingMethod
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.

source

Plotting

Load the plotting utilities with

using PointNeighbors, Plots
include(joinpath(pkgdir(PointNeighbors), "benchmarks", "plot_benchmarks.jl"));
plot_benchmarkMethod
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")
source