Skip to content

Commit d9e17c4

Browse files
committed
Adapted BFS to use masking feature
about 2x speedup
1 parent b89ce8b commit d9e17c4

File tree

1 file changed

+56
-14
lines changed

1 file changed

+56
-14
lines changed

src/algorithms/bfs.jl

+56-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
function bfs_distances(
22
A_T::TM,
3-
source::Ti,
3+
source::Ti;
4+
use_mask=true,
45
) where {Tv,Ti<:Integer,TM<:AbstractSparseGPUMatrix{Tv,Ti}}
56
backend = get_backend(A_T)
67

78
# Tv is typically Bool
89
curr = KernelAbstractions.zeros(backend, Tv, size(A_T, 1))
910
next = KernelAbstractions.zeros(backend, Tv, size(A_T, 1))
10-
explored = KernelAbstractions.zeros(backend, Tv, size(A_T, 1))
11+
to_explore = KernelAbstractions.ones(backend, Tv, size(A_T, 1))
1112

1213

1314
# Ti is typically Int32, and is guaranteed to be able to hold the size of the matrix
@@ -16,7 +17,13 @@ function bfs_distances(
1617

1718
dist .= typemax(Ti)
1819

19-
bfs_distances!(A_T, source, dist, curr, next, explored)
20+
if use_mask
21+
# BFS with mask
22+
bfs_distances!(A_T, source, dist, curr, next, to_explore)
23+
else
24+
# BFS without mask
25+
no_mask_bfs_distances!(A_T, source, dist, curr, next, to_explore)
26+
end
2027

2128
return dist
2229
end
@@ -27,7 +34,7 @@ function bfs_distances!(
2734
dist::TVi,
2835
curr::TVv,
2936
next::TVv,
30-
explored::TVv,
37+
to_explore::TVv
3138
) where {
3239
Tv,
3340
Ti<:Integer,
@@ -37,27 +44,62 @@ function bfs_distances!(
3744
}
3845
@allowscalar curr[source] = one(Tv)
3946
@allowscalar dist[source] = zero(Ti)
40-
@allowscalar explored[source] = one(Tv)
47+
@allowscalar to_explore[source] = zero(Tv)
4148
iter = zero(Ti)
42-
#mask = KernelAbstractions.zeros(get_backend(A_T), Ti, size(A_T, 1))
43-
#copyto!(mask, 1:size(A_T, 1))
44-
#@allowscalar
49+
next .= zero(Tv)
4550

4651
while true
47-
iter += one(Ti)
52+
iter += one(Ti)
53+
gpu_spmv!(next, A_T, curr, mul=GPUGraphs_band, add=GPUGraphs_bor, mask=to_explore)
54+
if reduce(|, next) == zero(Tv)
55+
return nothing
56+
end
57+
# Update the dist array where curr is not zero and dist is zero
58+
dist .= ifelse.(next .== one(Tv), iter, dist)
59+
60+
# set to_explore to false for the newly explored nodes
61+
to_explore .= to_explore .& (next .== zero(Tv))
62+
# set curr to next
63+
curr .= next
4864
next .= zero(Tv)
65+
end
66+
return nothing
67+
end
68+
69+
function no_mask_bfs_distances!(
70+
A_T::TM,
71+
source::Ti,
72+
dist::TVi,
73+
curr::TVv,
74+
next::TVv,
75+
to_explore::TVv
76+
) where {
77+
Tv,
78+
Ti<:Integer,
79+
TVv<:AbstractVector{Tv},
80+
TVi<:AbstractVector{Ti},
81+
TM<:AbstractSparseGPUMatrix{Tv,Ti},
82+
}
83+
@allowscalar curr[source] = one(Tv)
84+
@allowscalar dist[source] = zero(Ti)
85+
@allowscalar to_explore[source] = zero(Tv)
86+
iter = zero(Ti)
87+
next .= zero(Tv)
4988

89+
while true
90+
iter += one(Ti)
5091
gpu_spmv!(next, A_T, curr, mul=GPUGraphs_band, add=GPUGraphs_bor)
51-
# set curr to next on newly explored nodes
52-
curr .= next .& .~(explored)
92+
curr .= next .& to_explore
5393
if reduce(|, curr) == zero(Tv)
5494
return nothing
5595
end
5696
# Update the dist array where curr is not zero and dist is zero
5797
dist .= ifelse.(curr .== one(Tv), iter, dist)
5898

59-
# set explored to true for the newly explored nodes
60-
explored .= explored .| (curr .== one(Tv))
99+
# set to_explore to false for the newly explored nodes
100+
to_explore .= to_explore .& (curr .== zero(Tv))
101+
# set curr to next
102+
next .= zero(Tv)
61103
end
62104
return nothing
63-
end
105+
end

0 commit comments

Comments
 (0)