|
| 1 | +using Plots |
| 2 | +using BenchmarkTools |
| 3 | + |
| 4 | +# Generate a rectangular point cloud |
| 5 | +include("../test/point_cloud.jl") |
| 6 | + |
| 7 | +""" |
| 8 | + plot_benchmarks(benchmark, n_points_per_dimension, iterations; |
| 9 | + seed = 1, perturbation_factor_position = 1.0, |
| 10 | + parallel = true, title = "") |
| 11 | +
|
| 12 | +Run a benchmark for with several neighborhood searches multiple times for increasing numbers |
| 13 | +of points and plot the results. |
| 14 | +
|
| 15 | +# Arguments |
| 16 | +- `benchmark`: The benchmark function. See [`benchmark_count_neighbors`](@ref) |
| 17 | + and [`benchmark_n_body`](@ref). |
| 18 | +- `n_points_per_dimension`: Initial resolution as tuple. The product is the initial number |
| 19 | + of points. For example, use `(100, 100)` for a 2D benchmark or |
| 20 | + `(10, 10, 10)` for a 3D benchmark. |
| 21 | +- `iterations`: Number of refinement iterations |
| 22 | +
|
| 23 | +# Keywords |
| 24 | +- `parallel = true`: Loop over all points in parallel |
| 25 | +- `title = ""`: Title of the plot |
| 26 | +- `seed = 1`: Seed to perturb the point positions. Different seeds yield |
| 27 | + slightly different point positions. |
| 28 | +- `perturbation_factor_position = 1.0`: Perturb point positions by this factor. A factor of |
| 29 | + `1.0` corresponds to points being moved by |
| 30 | + a maximum distance of `0.5` along each axis. |
| 31 | +""" |
| 32 | +function plot_benchmarks(benchmark, n_points_per_dimension, iterations; |
| 33 | + parallel = true, title = "", |
| 34 | + seed = 1, perturbation_factor_position = 1.0) |
| 35 | + neighborhood_searches_names = ["TrivialNeighborhoodSearch";; |
| 36 | + "GridNeighborhoodSearch";; |
| 37 | + "PrecomputedNeighborhoodSearch"] |
| 38 | + |
| 39 | + # Multiply number of points in each iteration (roughly) by this factor |
| 40 | + scaling_factor = 4 |
| 41 | + per_dimension_factor = scaling_factor^(1 / length(n_points_per_dimension)) |
| 42 | + sizes = [round.(Int, n_points_per_dimension .* per_dimension_factor^(iter - 1)) |
| 43 | + for iter in 1:iterations] |
| 44 | + |
| 45 | + n_particles_vec = prod.(sizes) |
| 46 | + times = zeros(iterations, length(neighborhood_searches_names)) |
| 47 | + |
| 48 | + for iter in 1:iterations |
| 49 | + coordinates = point_cloud(sizes[iter], seed = seed, |
| 50 | + perturbation_factor_position = perturbation_factor_position) |
| 51 | + |
| 52 | + search_radius = 3.0 |
| 53 | + NDIMS = size(coordinates, 1) |
| 54 | + n_particles = size(coordinates, 2) |
| 55 | + |
| 56 | + neighborhood_searches = [ |
| 57 | + TrivialNeighborhoodSearch{NDIMS}(; search_radius, eachpoint = 1:n_particles), |
| 58 | + GridNeighborhoodSearch{NDIMS}(; search_radius, n_points = n_particles), |
| 59 | + PrecomputedNeighborhoodSearch{NDIMS}(; search_radius, n_points = n_particles), |
| 60 | + ] |
| 61 | + |
| 62 | + for i in eachindex(neighborhood_searches) |
| 63 | + neighborhood_search = neighborhood_searches[i] |
| 64 | + initialize!(neighborhood_search, coordinates, coordinates) |
| 65 | + |
| 66 | + time = benchmark(neighborhood_search, coordinates, parallel = parallel) |
| 67 | + times[iter, i] = time |
| 68 | + time_string = BenchmarkTools.prettytime(time * 1e9) |
| 69 | + println("$(neighborhood_searches_names[i])") |
| 70 | + println("with $(join(sizes[iter], "x")) = $(prod(sizes[iter])) particles finished in $time_string\n") |
| 71 | + end |
| 72 | + end |
| 73 | + |
| 74 | + plot(n_particles_vec, times, |
| 75 | + xaxis = :log, yaxis = :log, |
| 76 | + xticks = (n_particles_vec, n_particles_vec), |
| 77 | + xlabel = "#particles", ylabel = "Runtime [s]", |
| 78 | + legend = :outerright, size = (750, 400), dpi = 200, |
| 79 | + label = neighborhood_searches_names, title = title) |
| 80 | +end |
0 commit comments