Skip to content

Commit a7db672

Browse files
committed
Add missing parallel=:threads implementations
These implementations are extremely basic, but they try to follow the patterns in the other parts of the Parallel module. My real motivation is to be able to move the Distributed implementations into an extension, so that Graphs.jl does not depend on Distributed.
1 parent 6130332 commit a7db672

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

src/Parallel/distance.jl

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,49 @@
11
# used in shortest path calculations
22

33
function eccentricity(
4+
g::AbstractGraph,
5+
vs=vertices(g),
6+
distmx::AbstractMatrix{T}=weights(g);
7+
parallel=:distributed,
8+
) where {T<:Number}
9+
return if parallel === :threads
10+
threaded_eccentricity(g, vs, distmx)
11+
elseif parallel === :distributed
12+
distr_eccentricity(g, vs, distmx)
13+
else
14+
error(
15+
"Unsupported parallel argument '$(repr(parallel))' (supported: ':threads' or ':distributed')",
16+
)
17+
end
18+
end
19+
20+
function distr_eccentricity(
421
g::AbstractGraph, vs=vertices(g), distmx::AbstractMatrix{T}=weights(g)
522
) where {T<:Number}
623
vlen = length(vs)
724
eccs = SharedVector{T}(vlen)
825
@sync @distributed for i in 1:vlen
9-
eccs[i] = maximum(Graphs.dijkstra_shortest_paths(g, vs[i], distmx).dists)
26+
d′ = Graphs.dijkstra_shortest_paths(g, vs[i], distmx)
27+
eccs[i] = maximum(d′.dists)
1028
end
1129
d = sdata(eccs)
1230
maximum(d) == typemax(T) && @warn("Infinite path length detected")
1331
return d
1432
end
1533

34+
function threaded_eccentricity(
35+
g::AbstractGraph, vs=vertices(g), distmx::AbstractMatrix{T}=weights(g)
36+
) where {T<:Number}
37+
vlen = length(vs)
38+
eccs = Vector{T}(vlen)
39+
Base.Threads.@threads for i in 1:vlen
40+
d = Graphs.dijkstra_shortest_paths(g, vs[i], distmx)
41+
eccs[i] = maximum(d.dists)
42+
end
43+
maximum(eccs) == typemax(T) && @warn("Infinite path length detected")
44+
return eccs
45+
end
46+
1647
function eccentricity(g::AbstractGraph, distmx::AbstractMatrix)
1748
return eccentricity(g, vertices(g), distmx)
1849
end

src/Parallel/shortestpaths/dijkstra.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,43 @@ an optional distance matrix `distmx`. Return a [`Parallel.MultipleDijkstraState`
1717
traversal information.
1818
"""
1919
function dijkstra_shortest_paths(
20+
g::AbstractGraph{U},
21+
sources=vertices(g),
22+
distmx::AbstractMatrix{T}=weights(g);
23+
parallel=:distributed,
24+
) where {T<:Number} where {U}
25+
return if parallel === :threads
26+
threaded_dijkstra_shortest_paths(g, sources, distmx)
27+
elseif parallel === :distributed
28+
distr_dijkstra_shortest_paths(g, sources, distmx)
29+
else
30+
error(
31+
"Unsupported parallel argument '$(repr(parallel))' (supported: ':threads' or ':distributed')",
32+
)
33+
end
34+
end
35+
36+
function threaded_dijkstra_shortest_paths(
37+
g::AbstractGraph{U}, sources=vertices(g), distmx::AbstractMatrix{T}=weights(g)
38+
) where {T<:Number} where {U}
39+
n_v = nv(g)
40+
r_v = length(sources)
41+
42+
# TODO: remove `Int` once julialang/#23029 / #23032 are resolved
43+
dists = Matrix{T}(Int(r_v), Int(n_v))
44+
parents = Matrix{U}(Int(r_v), Int(n_v))
45+
46+
Base.Threads.@threads for i in 1:r_v
47+
state = Graphs.dijkstra_shortest_paths(g, sources[i], distmx)
48+
dists[i, :] = state.dists
49+
parents[i, :] = state.parents
50+
end
51+
52+
result = MultipleDijkstraState(dists, parents)
53+
return result
54+
end
55+
56+
function distr_dijkstra_shortest_paths(
2057
g::AbstractGraph{U}, sources=vertices(g), distmx::AbstractMatrix{T}=weights(g)
2158
) where {T<:Number} where {U}
2259
n_v = nv(g)

src/Parallel/traversals/greedy_color.jl

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,29 @@
1-
function random_greedy_color(g::AbstractGraph{T}, reps::Integer) where {T<:Integer}
1+
function random_greedy_color(
2+
g::AbstractGraph{T}, reps::Integer; parallel=:distributed
3+
) where {T<:Integer}
4+
return if parallel === :threads
5+
threaded_random_greedy_color(g, reps)
6+
elseif parallel === :distributed
7+
distr_random_greedy_color(g, reps)
8+
else
9+
error(
10+
"Unsupported parallel argument '$(repr(parallel))' (supported: ':threads' or ':distributed')",
11+
)
12+
end
13+
end
14+
15+
function threaded_random_greedy_color(g::AbstractGraph{T}, reps::Integer) where {T<:Integer}
16+
local_best = Any[nothing for _ in 1:reps]
17+
Base.Threads.@threads for i in 1:reps
18+
seq = shuffle(vertices(g))
19+
local_best[i] = Graphs.perm_greedy_color(g, seq)
20+
end
21+
best = reduce(Graphs.best_color, local_best)
22+
23+
return convert(Graphs.Coloring{T}, best)
24+
end
25+
26+
function distr_random_greedy_color(g::AbstractGraph{T}, reps::Integer) where {T<:Integer}
227
best = @distributed (Graphs.best_color) for i in 1:reps
328
seq = shuffle(vertices(g))
429
Graphs.perm_greedy_color(g, seq)

0 commit comments

Comments
 (0)