Skip to content

MSBFS #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1cacb79
Set dataset folder to default
kirillgarbar Oct 5, 2023
2b23505
Merge pull request #87 from kirillgarbar/fix
gsvgit Oct 6, 2023
01c35d3
SSSP return vector
kirillgarbar Oct 16, 2023
83c860e
BFS sparse and push-pull on int32
kirillgarbar Oct 16, 2023
735f064
PageRank
kirillgarbar Oct 16, 2023
988672e
BFS, SSSP, PR benchmarks
kirillgarbar Oct 16, 2023
78c7964
Vector.create
kirillgarbar Oct 16, 2023
7e914f1
PageRank on ClMatrix and ClVector
kirillgarbar Oct 16, 2023
a38aa20
PageRank test case
kirillgarbar Oct 16, 2023
f1a6f24
Formatting
kirillgarbar Oct 16, 2023
edc5a73
Vector.create tests
kirillgarbar Oct 16, 2023
6f6c629
Rename
kirillgarbar Oct 24, 2023
cadb104
Pass accurasy to PR
kirillgarbar Oct 24, 2023
baa0c0b
Private functiona and constants
kirillgarbar Oct 24, 2023
15f415e
PageRank test property
kirillgarbar Oct 24, 2023
39361c4
Fix formatting bug
kirillgarbar Oct 24, 2023
e548294
Benchmark rename
kirillgarbar Oct 24, 2023
483b644
merge: kirillgarbar/dev branch into msbfs
artemiipatov Nov 7, 2023
2199287
add: matrix intersect
artemiipatov Nov 10, 2023
00bdd5a
add: msbfs levels
artemiipatov Nov 14, 2023
97281a6
add: spgemm coo->csr->coo
artemiipatov Nov 15, 2023
1538ad6
add: msbfs parents
artemiipatov Nov 15, 2023
cf10d92
fix: msbfs parents
artemiipatov Nov 15, 2023
1558c6d
add: tests
artemiipatov Nov 17, 2023
e78e50e
refactor: formatting
artemiipatov Nov 17, 2023
95941af
wip: tests and msbfs bug fix
artemiipatov Nov 20, 2023
7b21b4f
fix: msbfs levels bug
artemiipatov Nov 21, 2023
f4016eb
fix: msbfs tests
artemiipatov Nov 21, 2023
94fec78
fix: msbfs parents bug
artemiipatov Nov 22, 2023
3d9654d
fix: msbfs parents, clarray.copyto bugs
artemiipatov Nov 22, 2023
e33db1a
fix: mergeDisjoint, msbfs, intersect tests bugs
artemiipatov Nov 22, 2023
63a44e3
refactor: formatting
artemiipatov Nov 22, 2023
dacc3e1
merge dev
artemiipatov Nov 25, 2023
d6373cc
revert: kirill's changes comming with pagerank pr
artemiipatov Nov 25, 2023
9a9b7f9
revert: benchmarks changes
artemiipatov Nov 25, 2023
a94fd07
revert: benchmarks configs
artemiipatov Nov 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion benchmarks/GraphBLAS-sharp.Benchmarks/Algorithms/BFS.fs
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,3 @@ type BFSWithTransferBenchmarkInt32() =

static member InputMatrixProvider =
Benchmarks<_>.InputMatrixProviderBuilder "BFSBenchmarks.txt"

Original file line number Diff line number Diff line change
@@ -1 +1 @@
BFSBenchmark
BFSWithoutTransfer
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
7 changes: 6 additions & 1 deletion src/GraphBLAS-sharp.Backend/Algorithms/Algorithms.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@ module Algorithms =

let singleSourcePushPull = BFS.singleSourcePushPull

module MSBFS =
let runLevels = MSBFS.Levels.run

let runParents = MSBFS.Parents.run

module SSSP =
let singleSource = SSSP.run
let run = SSSP.run
265 changes: 265 additions & 0 deletions src/GraphBLAS-sharp.Backend/Algorithms/MSBFS.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
namespace GraphBLAS.FSharp.Backend.Algorithms

open Brahma.FSharp
open FSharp.Quotations
open GraphBLAS.FSharp
open GraphBLAS.FSharp.Objects
open GraphBLAS.FSharp.Common
open GraphBLAS.FSharp.Objects.ClMatrix
open GraphBLAS.FSharp.Objects.ArraysExtensions
open GraphBLAS.FSharp.Objects.ClContextExtensions
open GraphBLAS.FSharp.Objects.ClCellExtensions
open GraphBLAS.FSharp.Backend.Quotes
open GraphBLAS.FSharp.Backend.Matrix.LIL
open GraphBLAS.FSharp.Backend.Matrix.COO

module internal MSBFS =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can BFS also be Parents and Leveles? Can unified interface be created?

let private frontExclude (clContext: ClContext) workGroupSize =

let invert =
ClArray.mapInPlace ArithmeticOperations.intNotQ clContext workGroupSize

let prefixSum =
PrefixSum.standardExcludeInPlace clContext workGroupSize

let scatterIndices =
Scatter.lastOccurrence clContext workGroupSize

let scatterValues =
Scatter.lastOccurrence clContext workGroupSize

fun (queue: MailboxProcessor<_>) allocationMode (front: ClMatrix.COO<_>) (intersection: ClArray<int>) ->

invert queue intersection

let length =
(prefixSum queue intersection).ToHostAndFree queue

if length = 0 then
None
else
let rows =
clContext.CreateClArrayWithSpecificAllocationMode(allocationMode, length)

let columns =
clContext.CreateClArrayWithSpecificAllocationMode(allocationMode, length)

let values =
clContext.CreateClArrayWithSpecificAllocationMode(allocationMode, length)

scatterIndices queue intersection front.Rows rows
scatterIndices queue intersection front.Columns columns
scatterValues queue intersection front.Values values

{ Context = clContext
Rows = rows
Columns = columns
Values = values
RowCount = front.RowCount
ColumnCount = front.ColumnCount }
|> Some

module Levels =
let private updateFrontAndLevels (clContext: ClContext) workGroupSize =

let updateFront = frontExclude clContext workGroupSize

let mergeDisjoint =
Matrix.mergeDisjoint clContext workGroupSize

let setLevel = ClArray.fill clContext workGroupSize

let findIntersection =
Intersect.findKeysIntersection clContext workGroupSize

fun (queue: MailboxProcessor<_>) allocationMode (level: int) (front: ClMatrix.COO<_>) (levels: ClMatrix.COO<_>) ->

// Find intersection of levels and front indices.
let intersection =
findIntersection queue DeviceOnly front levels

// Remove mutual elements
let newFront =
updateFront queue allocationMode front intersection

intersection.Free queue

match newFront with
| Some f ->
let levelClCell = clContext.CreateClCell level

// Set current level value to all remaining front positions
setLevel queue levelClCell 0 f.Values.Length f.Values

levelClCell.Free queue

// Update levels
let newLevels = mergeDisjoint queue levels f

newLevels, newFront
| _ -> levels, None

let run<'a when 'a: struct>
(add: Expr<int -> int -> int option>)
(mul: Expr<int -> 'a -> int option>)
(clContext: ClContext)
workGroupSize
=

let spGeMM =
Operations.SpGeMM.COO.expand add mul clContext workGroupSize

let copy = Matrix.copy clContext workGroupSize

let updateFrontAndLevels =
updateFrontAndLevels clContext workGroupSize

fun (queue: MailboxProcessor<Msg>) (matrix: ClMatrix<'a>) (source: int list) ->
let vertexCount = matrix.RowCount
let sourceVertexCount = source.Length

let source = source |> List.sort

let startMatrix =
source |> List.mapi (fun i vertex -> i, vertex, 1)

let mutable levels =
startMatrix
|> Matrix.ofList clContext DeviceOnly sourceVertexCount vertexCount

let mutable front = copy queue DeviceOnly levels

let mutable level = 1
let mutable stop = false

while not stop do
level <- level + 1

//Getting new frontier
match spGeMM queue DeviceOnly (ClMatrix.COO front) matrix with
| None ->
front.Dispose queue
stop <- true

| Some newFrontier ->
front.Dispose queue

//Filtering visited vertices
match updateFrontAndLevels queue DeviceOnly level newFrontier levels with
| l, Some f ->
front <- f

levels.Dispose queue

levels <- l

newFrontier.Dispose queue

| _, None ->
stop <- true
newFrontier.Dispose queue

ClMatrix.COO levels

module Parents =
let private updateFrontAndParents (clContext: ClContext) workGroupSize =
let frontExclude = frontExclude clContext workGroupSize

let mergeDisjoint =
Matrix.mergeDisjoint clContext workGroupSize

let findIntersection =
Intersect.findKeysIntersection clContext workGroupSize

let copyIndices = ClArray.copyTo clContext workGroupSize

fun (queue: MailboxProcessor<Msg>) allocationMode (front: ClMatrix.COO<_>) (parents: ClMatrix.COO<_>) ->

// Find intersection of levels and front indices.
let intersection =
findIntersection queue DeviceOnly front parents

// Remove mutual elements
let newFront =
frontExclude queue allocationMode front intersection

intersection.Free queue

match newFront with
| Some f ->
// Update parents
let newParents = mergeDisjoint queue parents f

copyIndices queue f.Columns f.Values

newParents, Some f

| _ -> parents, None

let run<'a when 'a: struct> (clContext: ClContext) workGroupSize =

let spGeMM =
Operations.SpGeMM.COO.expand
(ArithmeticOperations.min)
(ArithmeticOperations.fst)
clContext
workGroupSize

let updateFrontAndParents =
updateFrontAndParents clContext workGroupSize

fun (queue: MailboxProcessor<Msg>) (inputMatrix: ClMatrix<'a>) (source: int list) ->
let vertexCount = inputMatrix.RowCount
let sourceVertexCount = source.Length

let source = source |> List.sort

let matrix =
match inputMatrix with
| ClMatrix.CSR m ->
{ Context = clContext
RowPointers = m.RowPointers
Columns = m.Columns
Values = m.Columns
RowCount = m.RowCount
ColumnCount = m.ColumnCount }
|> ClMatrix.CSR
| _ -> failwith "Incorrect format"

let mutable parents =
source
|> List.mapi (fun i vertex -> i, vertex, -1)
|> Matrix.ofList clContext DeviceOnly sourceVertexCount vertexCount

let mutable front =
source
|> List.mapi (fun i vertex -> i, vertex, vertex)
|> Matrix.ofList clContext DeviceOnly sourceVertexCount vertexCount

let mutable stop = false

while not stop do
//Getting new frontier
match spGeMM queue DeviceOnly (ClMatrix.COO front) matrix with
| None ->
front.Dispose queue
stop <- true

| Some newFrontier ->
front.Dispose queue

//Filtering visited vertices
match updateFrontAndParents queue DeviceOnly newFrontier parents with
| p, Some f ->
front <- f

parents.Dispose queue
parents <- p

newFrontier.Dispose queue

| _, None ->
stop <- true
newFrontier.Dispose queue

ClMatrix.COO parents
2 changes: 1 addition & 1 deletion src/GraphBLAS-sharp.Backend/Algorithms/SSSP.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module SSSP =
let run (clContext: ClContext) workGroupSize =

let less = ArithmeticOperations.less<int>
let min = ArithmeticOperations.min<int>
let min = ArithmeticOperations.minOption<int>
let plus = ArithmeticOperations.intSumAsMul

let spMVInPlace =
Expand Down
Loading