Skip to content

Commit 735f064

Browse files
committed
PageRank
1 parent 83c860e commit 735f064

4 files changed

Lines changed: 215 additions & 0 deletions

File tree

src/GraphBLAS-sharp.Backend/Algorithms/Algorithms.fs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ module Algorithms =
1414

1515
module SSSP =
1616
let singleSource = SSSP.run
17+
18+
module PageRank =
19+
let run = PageRank.run
20+
21+
let prepareMatrix = PageRank.prepareMatrix
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
namespace GraphBLAS.FSharp.Backend.Algorithms
2+
3+
open GraphBLAS.FSharp.Backend
4+
open Brahma.FSharp
5+
open GraphBLAS.FSharp.Objects
6+
open GraphBLAS.FSharp.Backend.Quotes
7+
open GraphBLAS.FSharp.Backend.Vector.Dense
8+
open GraphBLAS.FSharp.Objects.ClMatrix
9+
open GraphBLAS.FSharp.Objects.ClContextExtensions
10+
open GraphBLAS.FSharp.Objects.ArraysExtensions
11+
open GraphBLAS.FSharp.Objects.ClCellExtensions
12+
13+
module internal PageRank =
14+
let alpha = 0.85f
15+
let accuracy = 0.00000001f
16+
17+
let countOutDegree (clContext: ClContext) workGroupSize =
18+
19+
let one =
20+
<@ fun (x: float32 option) (_: int option) ->
21+
let mutable res = 0
22+
23+
match x with
24+
| Some _ -> res <- 1
25+
| None -> ()
26+
27+
if res = 0 then None else Some res @>
28+
29+
let spMV =
30+
Operations.SpMV.runTo ArithmeticOperations.intSumOption one clContext workGroupSize
31+
32+
let zeroCreate =
33+
GraphBLAS.FSharp.ClArray.zeroCreate clContext workGroupSize
34+
35+
fun (queue: MailboxProcessor<Msg>) (matrix: ClMatrix.CSR<float32>) ->
36+
let outDegree: ClArray<int option> =
37+
zeroCreate queue DeviceOnly matrix.ColumnCount
38+
39+
spMV queue matrix outDegree outDegree
40+
41+
outDegree
42+
43+
let prepareMatrix (clContext: ClContext) workGroupSize =
44+
45+
let alpha = 0.85f
46+
47+
let op =
48+
<@ fun (x: float32 option) y ->
49+
let mutable res = 0.0f
50+
51+
match x, y with
52+
| Some _, Some y -> res <- alpha / (float32 y)
53+
| Some _, None -> ()
54+
| None, Some _ -> ()
55+
| None, None -> ()
56+
57+
if res = 0.0f then None else Some res @>
58+
59+
//TODO: generalize to map2 Matrix x Vector
60+
let multiply =
61+
<@ fun (range: Range1D) (numberOfRows: int) (matrixRowPointers: ClArray<int>) (matrixValues: ClArray<float32>) (vectorValues: ClArray<int option>) (resultMatrixValues: ClArray<float32>) ->
62+
63+
let i = range.GlobalID0
64+
let li = range.LocalID0
65+
let group = i / workGroupSize
66+
67+
if group < numberOfRows then
68+
let rowStart = matrixRowPointers.[group]
69+
let rowEnd = matrixRowPointers.[group + 1]
70+
71+
let vectorValue = vectorValues.[group]
72+
let mutable index = rowStart + li
73+
74+
while index < rowEnd do
75+
let matrixValue = matrixValues.[index]
76+
let resultValue = (%op) (Some matrixValue) vectorValue
77+
78+
match resultValue with
79+
| Some v -> resultMatrixValues.[index] <- v
80+
| None -> () //This should not be reachable
81+
82+
index <- index + workGroupSize @>
83+
84+
let countOutDegree = countOutDegree clContext workGroupSize
85+
86+
let copy =
87+
GraphBLAS.FSharp.ClArray.copy clContext workGroupSize
88+
89+
let transpose =
90+
Matrix.CSR.Matrix.transposeInPlace clContext workGroupSize
91+
92+
let multiply = clContext.Compile multiply
93+
94+
fun (queue: MailboxProcessor<Msg>) (matrix: ClMatrix.CSR<float32>) ->
95+
96+
let outDegree = countOutDegree queue matrix
97+
98+
let resultValues =
99+
clContext.CreateClArrayWithSpecificAllocationMode(DeviceOnly, matrix.Values.Length)
100+
101+
let kernel = multiply.GetKernel()
102+
103+
let ndRange =
104+
Range1D.CreateValid(matrix.RowCount * workGroupSize, workGroupSize)
105+
106+
queue.Post(
107+
Msg.MsgSetArguments
108+
(fun () ->
109+
kernel.KernelFunc
110+
ndRange
111+
matrix.RowCount
112+
matrix.RowPointers
113+
matrix.Values
114+
outDegree
115+
resultValues)
116+
)
117+
118+
queue.Post(Msg.CreateRunMsg<_, _> kernel)
119+
120+
outDegree.Free queue
121+
122+
let newMatrix =
123+
{ Context = clContext
124+
RowCount = matrix.RowCount
125+
ColumnCount = matrix.ColumnCount
126+
RowPointers = copy queue DeviceOnly matrix.RowPointers
127+
Columns = copy queue DeviceOnly matrix.Columns
128+
Values = resultValues }
129+
130+
let transposed = transpose queue DeviceOnly newMatrix
131+
transposed
132+
133+
let run (clContext: ClContext) workGroupSize =
134+
135+
let alpha = 0.85f
136+
let accuracy = 0.00000001f
137+
138+
let minusAndSquare = ArithmeticOperations.minusAndSquare
139+
let plus = ArithmeticOperations.float32SumOption
140+
let mul = ArithmeticOperations.float32MulOption
141+
142+
let spMVTo =
143+
Operations.SpMV.runTo plus mul clContext workGroupSize
144+
145+
let addToResult =
146+
Vector.map2InPlace plus clContext workGroupSize
147+
148+
let subtractAndSquare =
149+
Vector.map2InPlace minusAndSquare clContext workGroupSize
150+
151+
let reduce =
152+
Vector.reduce <@ (+) @> clContext workGroupSize
153+
154+
let create =
155+
GraphBLAS.FSharp.ClArray.create clContext workGroupSize
156+
157+
fun (queue: MailboxProcessor<Msg>) (matrix: ClMatrix.CSR<float32>) ->
158+
159+
let vertexCount = matrix.RowCount
160+
161+
//None is 0
162+
let mutable rank = create queue DeviceOnly vertexCount None
163+
164+
let mutable prevRank =
165+
create queue DeviceOnly vertexCount (Some(1.0f / (float32 vertexCount)))
166+
167+
let mutable errors = create queue DeviceOnly vertexCount None
168+
169+
let addition =
170+
create queue DeviceOnly vertexCount (Some((1.0f - alpha) / (float32 vertexCount)))
171+
172+
let mutable error = accuracy + 0.1f
173+
174+
let mutable i = 0
175+
176+
while error > accuracy do
177+
i <- i + 1
178+
179+
// rank = matrix*rank + (1 - alpha)/N
180+
spMVTo queue matrix prevRank rank
181+
addToResult queue rank addition rank
182+
183+
// error
184+
subtractAndSquare queue rank prevRank errors
185+
error <- sqrt <| (reduce queue errors).ToHostAndFree queue
186+
187+
//Swap vectors
188+
let temp = rank
189+
rank <- prevRank
190+
prevRank <- temp
191+
192+
prevRank.Free queue
193+
errors.Free queue
194+
addition.Free queue
195+
196+
rank

src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969

7070
<Compile Include="Algorithms/BFS.fs" />
7171
<Compile Include="Algorithms/SSSP.fs" />
72+
<Compile Include="Algorithms/PageRank.fs" />
7273
<Compile Include="Algorithms/Algorithms.fs" />
7374

7475
</ItemGroup>

src/GraphBLAS-sharp.Backend/Quotes/Arithmetic.fs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,16 @@ module ArithmeticOperations =
244244
| Some x, None -> Some x
245245
| None, Some y -> Some y
246246
| _ -> None @>
247+
248+
//PageRank specific
249+
let minusAndSquare =
250+
<@ fun (x: float32 option) (y: float32 option) ->
251+
let mutable res = 0.0f
252+
253+
match x, y with
254+
| Some f, Some s -> res <- (f - s) * (f - s)
255+
| Some f, None -> res <- f * f
256+
| None, Some s -> res <- s * s
257+
| None, None -> ()
258+
259+
if res = 0.0f then None else Some res @>

0 commit comments

Comments
 (0)