The MWE
using LinearAlgebra
using Random
using BenchmarkTools
function distance(x, y, p::Real = 2)
norm((x[1] - y[1], x[2] - y[2]), p)
end
function jfa_serial!(grid, sites, p::Real=2)
for (color, (x, y)) in enumerate(sites)
grid[x, y] = convert(eltype(grid), color)
end
gridp = copy(grid)
k = max(size(grid)...)
while k > 1
k = k ÷ 2 + k % 2
for (x, y) in collect(Iterators.product(1:size(grid, 1), 1:size(grid, 2)))
for j in (-k, 0, k), i in (-k, 0, k)
checkbounds(Bool, grid, x + i, y + j) || continue
colorq = grid[x + i, y + j]
colorq !== 0 || continue
colorp = grid[x, y]
if colorp === 0
gridp[x, y] = colorq
elseif distance(sites[colorp], (x, y), p) > distance(sites[colorq], (x, y), p)
gridp[x, y] = colorq
end
end
end
grid .= gridp
end
return grid
end
function jfa_parallel!(grid, sites, p::Real=2)
for (color, (x, y)) in enumerate(sites)
grid[x, y] = convert(eltype(grid), color)
end
gridp = copy(grid)
k = max(size(grid)...)
while k > 1
k = k ÷ 2 + k % 2
Threads.@threads for (x, y) in collect(Iterators.product(1:size(grid, 1), 1:size(grid, 2)))
for j in (-k, 0, k), i in (-k, 0, k)
checkbounds(Bool, grid, x + i, y + j) || continue
colorq = grid[x + i, y + j]
colorq !== 0 || continue
colorp = grid[x, y]
if colorp === 0
gridp[x, y] = colorq
elseif distance(sites[colorp], (x, y), p) > distance(sites[colorq], (x, y), p)
gridp[x, y] = colorq
end
end
end
grid .= gridp
end
return grid
end
function rand_sites(M, N, K)
idx = [(m, n) for m in 1:M, n in 1:N]
shuffle!(idx)
idx[1:K]
end
@btime jfa_serial!(grid, sites) setup = (grid = zeros(Int, 100, 100); sites = collect(rand_sites(size(grid)..., 100)))
@btime jfa_parallel!(grid, sites) setup = (grid = zeros(Int, 100, 100); sites = collect(rand_sites(size(grid)..., 100)))
yields
7.030 ms (16 allocations: 1.14 MiB) #jfa_serial
55.060 ms (2747567 allocations: 75.80 MiB) #jfa_parallel
- A workaround for this behavior is moving the inner part of the
@threads for
loop into an auxiliary function. - Is it this issue. If yes, why?
- Is it time to check out
Polyester
? - I would be most grateful for an explanation or experience report.
Thanks!