@@ -3,6 +3,7 @@ namespace GraphBLAS.FSharp.Backend.Algorithms
33open Brahma.FSharp
44open FSharp.Quotations
55open GraphBLAS.FSharp
6+ open GraphBLAS.FSharp .Backend .Quotes
67open GraphBLAS.FSharp .Objects
78open GraphBLAS.FSharp .Objects .ClMatrix
89open GraphBLAS.FSharp .Objects .ArraysExtensions
@@ -11,35 +12,35 @@ open GraphBLAS.FSharp.Backend.Matrix.LIL
1112open GraphBLAS.FSharp .Backend .Matrix .COO
1213
1314module internal MSBFS =
14- module Levels =
15- let private updateFront ( clContext : ClContext ) workGroupSize =
15+ let private frontExclude ( clContext : ClContext ) workGroupSize =
1616
17- let excludeValues = ClArray.excludeElements clContext workGroupSize
17+ let excludeValues = ClArray.excludeElements clContext workGroupSize
1818
19- let excludeIndices = ClArray.excludeElements clContext workGroupSize
19+ let excludeIndices = ClArray.excludeElements clContext workGroupSize
2020
21- fun ( queue : MailboxProcessor < _ >) allocationMode ( front : ClMatrix.COO < _ >) ( intersection : ClArray < int >) ->
21+ fun ( queue : MailboxProcessor < _ >) allocationMode ( front : ClMatrix.COO < _ >) ( intersection : ClArray < int >) ->
2222
23- let newRows = excludeIndices queue allocationMode intersection front.Rows
23+ let newRows = excludeIndices queue allocationMode intersection front.Rows
2424
25- let newColumns = excludeIndices queue allocationMode intersection front.Columns
25+ let newColumns = excludeIndices queue allocationMode intersection front.Columns
2626
27- let newValues = excludeValues queue allocationMode intersection front.Values
27+ let newValues = excludeValues queue allocationMode intersection front.Values
2828
29- match newRows, newColumns, newValues with
30- | Some rows, Some columns, Some values ->
31- { Context = clContext
32- Rows = rows
33- Columns = columns
34- Values = values
35- RowCount = front.RowCount
36- ColumnCount = front.ColumnCount }
37- |> Some
38- | _ -> None
29+ match newRows, newColumns, newValues with
30+ | Some rows, Some columns, Some values ->
31+ { Context = clContext
32+ Rows = rows
33+ Columns = columns
34+ Values = values
35+ RowCount = front.RowCount
36+ ColumnCount = front.ColumnCount }
37+ |> Some
38+ | _ -> None
3939
40+ module Levels =
4041 let private updateFrontAndLevels ( clContext : ClContext ) workGroupSize =
4142
42- let updateFront = updateFront clContext workGroupSize
43+ let updateFront = frontExclude clContext workGroupSize
4344
4445 let mergeDisjoint = Matrix.mergeDisjoint clContext workGroupSize
4546
@@ -130,4 +131,78 @@ module internal MSBFS =
130131 |> List.map ( SSBFS queue matrix)
131132
132133 module Parents =
133- let run = 0
134+ let updateFrontAndParents ( clContext : ClContext ) workGroupSize =
135+ // update parents same as levels
136+ // every front value should be equal to its column number
137+ let frontExclude = frontExclude clContext workGroupSize
138+
139+ let mergeDisjoint = Matrix.mergeDisjoint clContext workGroupSize
140+
141+ let findIntersection = Intersect.findKeysIntersection clContext workGroupSize
142+
143+ fun ( queue : MailboxProcessor < Msg >) allocationMode ( front : ClMatrix.COO < _ >) ( parents : ClMatrix.COO < _ >) ->
144+
145+ // Find intersection of levels and front indices.
146+ let intersection = findIntersection queue DeviceOnly front parents
147+
148+ // Remove mutual elements
149+ let newFront = frontExclude queue allocationMode front intersection
150+
151+ intersection.Free queue
152+
153+ match newFront with
154+ | Some f ->
155+ // Update levels
156+ let resultFront =
157+ { f with Values = f.Columns }
158+ let newLevels = mergeDisjoint queue parents f
159+ newLevels, Some resultFront
160+ | _ -> parents, None
161+
162+ let run < 'a when 'a : struct >
163+ ( clContext : ClContext )
164+ workGroupSize
165+ =
166+
167+ let spGeMM =
168+ Operations.SpGeMM.COO.expand ( ArithmeticOperations.min 0 ) ( ArithmeticOperations.fst 0 ) clContext workGroupSize
169+
170+ let updateFrontAndLevels = updateFrontAndParents clContext workGroupSize
171+
172+ fun ( queue : MailboxProcessor < Msg >) ( matrix : ClMatrix < 'a >) ( source : int list ) ->
173+ let vertexCount = matrix.RowCount
174+ let sourceVertexCount = source.Length
175+
176+ let mutable parents =
177+ source
178+ |> List.mapi ( fun i vertex -> i, vertex, 0 )
179+ |> Matrix.ofList clContext DeviceOnly sourceVertexCount vertexCount
180+
181+ let mutable front =
182+ source
183+ |> List.mapi ( fun i vertex -> i, vertex, vertex)
184+ |> Matrix.ofList clContext DeviceOnly sourceVertexCount vertexCount
185+
186+ let mutable stop = false
187+
188+ while not stop do
189+
190+ //Getting new frontier
191+ match spGeMM queue DeviceOnly ( ClMatrix.COO front) matrix with
192+ | None ->
193+ front.Dispose queue
194+ stop <- true
195+ | Some newFrontier ->
196+ front.Dispose queue
197+ //Filtering visited vertices
198+ match updateFrontAndLevels queue DeviceOnly newFrontier parents with
199+ | l, Some f ->
200+ front <- f
201+ parents.Dispose queue
202+ parents <- l
203+ newFrontier.Dispose queue
204+ | _, None ->
205+ stop <- true
206+ newFrontier.Dispose queue
207+
208+ parents
0 commit comments