1
1
function bfs_distances (
2
2
A_T:: TM ,
3
- source:: Ti ,
3
+ source:: Ti ;
4
+ use_mask= true ,
4
5
) where {Tv,Ti<: Integer ,TM<: AbstractSparseGPUMatrix{Tv,Ti} }
5
6
backend = get_backend (A_T)
6
7
7
8
# Tv is typically Bool
8
9
curr = KernelAbstractions. zeros (backend, Tv, size (A_T, 1 ))
9
10
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 ))
11
12
12
13
13
14
# Ti is typically Int32, and is guaranteed to be able to hold the size of the matrix
@@ -16,7 +17,13 @@ function bfs_distances(
16
17
17
18
dist .= typemax (Ti)
18
19
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
20
27
21
28
return dist
22
29
end
@@ -27,7 +34,7 @@ function bfs_distances!(
27
34
dist:: TVi ,
28
35
curr:: TVv ,
29
36
next:: TVv ,
30
- explored :: TVv ,
37
+ to_explore :: TVv
31
38
) where {
32
39
Tv,
33
40
Ti<: Integer ,
@@ -37,27 +44,62 @@ function bfs_distances!(
37
44
}
38
45
@allowscalar curr[source] = one (Tv)
39
46
@allowscalar dist[source] = zero (Ti)
40
- @allowscalar explored [source] = one (Tv)
47
+ @allowscalar to_explore [source] = zero (Tv)
41
48
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)
45
50
46
51
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
48
64
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)
49
88
89
+ while true
90
+ iter += one (Ti)
50
91
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
53
93
if reduce (| , curr) == zero (Tv)
54
94
return nothing
55
95
end
56
96
# Update the dist array where curr is not zero and dist is zero
57
97
dist .= ifelse .(curr .== one (Tv), iter, dist)
58
98
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)
61
103
end
62
104
return nothing
63
- end
105
+ end
0 commit comments