Skip to content

Commit

Permalink
Merge remote-tracking branch 'YaccConstructor/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
kirillgarbar committed Dec 10, 2023
2 parents b278b7a + 4a70218 commit ebdb250
Show file tree
Hide file tree
Showing 44 changed files with 1,899 additions and 253 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-and-benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
with:
name: BFS
tool: 'benchmarkdotnet'
output-file-path: BenchmarkDotNet.Artifacts/results/GraphBLAS.FSharp.Benchmarks.BFSWithoutTransferBenchmarkInt32-report-brief.json
output-file-path: BenchmarkDotNet.Artifacts/results/GraphBLAS.FSharp.Benchmarks.Algorithms.BFS.BFSWithoutTransferBenchmarkInt32-report-brief.json
# Access token to deploy GitHub Pages branch
github-token: ${{ secrets._GITHUB_TOKEN }}
# Push and deploy GitHub pages branch automatically
Expand Down
7 changes: 3 additions & 4 deletions benchmarks/GraphBLAS-sharp.Benchmarks/Algorithms/BFS.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace GraphBLAS.FSharp.Benchmarks.Algorithms.BFS
namespace GraphBLAS.FSharp.Benchmarks.Algorithms.BFS

open System.IO
open BenchmarkDotNet.Attributes
Expand All @@ -12,8 +12,8 @@ open GraphBLAS.FSharp.Objects.ArraysExtensions
open GraphBLAS.FSharp.Backend.Quotes

[<AbstractClass>]
[<IterationCount(10)>]
[<WarmupCount(3)>]
[<IterationCount(100)>]
[<WarmupCount(10)>]
[<Config(typeof<Configs.Matrix>)>]
type Benchmarks<'elem when 'elem : struct>(
buildFunToBenchmark,
Expand Down Expand Up @@ -211,4 +211,3 @@ type BFSWithTransferBenchmarkBool() =

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

4 changes: 2 additions & 2 deletions benchmarks/GraphBLAS-sharp.Benchmarks/Configs/Context.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
NVIDIA*
AMD*
Gpu
32
64
Original file line number Diff line number Diff line change
@@ -1 +1 @@
BFSBenchmark
BFSWithoutTransfer
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
<Compile Include="Matrix/Map2/MathNET.fs" />
<Compile Include="Vector/Map2.fs" />
<Compile Include="Algorithms/BFS.fs" />
<Compile Include="Algorithms/PageRank.fs" />
<Compile Include="Program.fs" />
<Folder Include="Datasets" />
</ItemGroup>
Expand Down
2 changes: 0 additions & 2 deletions benchmarks/GraphBLAS-sharp.Benchmarks/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ open BenchmarkDotNet.Running
let main argv =
let benchmarks =
BenchmarkSwitcher [| typeof<Algorithms.BFS.BFSWithoutTransferBenchmarkBool>
typeof<Algorithms.BFS.BFSPushPullWithoutTransferBenchmarkBool>
typeof<Algorithms.PageRank.PageRankWithoutTransferBenchmarkFloat32> |]

benchmarks.Run argv |> ignore
0
4 changes: 2 additions & 2 deletions benchmarks/GraphBLAS-sharp.Benchmarks/Scripts/Benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

from dataclasses import dataclass

ROOT = pathlib.Path(__file__).parent.parent.parent.parent
BENCHMARKS = pathlib.Path(__file__).parent.parent
ROOT = pathlib.Path(__file__).resolve().parent.parent.parent.parent
BENCHMARKS = pathlib.Path(__file__).resolve().parent.parent
CONFIGS = BENCHMARKS / "Configs"
BINARIES = BENCHMARKS / "bin" / "Release" / "net7.0"
RESULTS = ROOT / "BenchmarkDotNet.Artifacts" / "results"
Expand Down
10 changes: 5 additions & 5 deletions src/GraphBLAS-sharp.Backend/Algorithms/Algorithms.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ module Algorithms =

let singleSourcePushPull = BFS.singleSourcePushPull

module SSSP =
let run = SSSP.run
module MSBFS =
let runLevels = MSBFS.Levels.run

module PageRank =
let run = PageRank.run
let runParents = MSBFS.Parents.run

let prepareMatrix = PageRank.prepareMatrix
module SSSP =
let run = SSSP.run
4 changes: 2 additions & 2 deletions src/GraphBLAS-sharp.Backend/Algorithms/BFS.fs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ module internal BFS =
let fillSubVectorTo =
Vector.assignByMaskInPlace Mask.assign clContext workGroupSize

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

let levels =
Expand Down Expand Up @@ -149,7 +149,7 @@ module internal BFS =
Vector.map2Sparse Mask.complementedOp clContext workGroupSize

let fillSubVectorInPlace =
Vector.assignByMaskInPlace Mask.assign clContext workGroupSize
Vector.assignByMaskInPlace (Mask.assign) clContext workGroupSize

let toSparse = Vector.toSparse clContext workGroupSize

Expand Down
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 =
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
8 changes: 5 additions & 3 deletions src/GraphBLAS-sharp.Backend/Algorithms/SSSP.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ open GraphBLAS.FSharp.Backend.Quotes
open GraphBLAS.FSharp.Objects.ClContextExtensions
open GraphBLAS.FSharp.Objects.ClCellExtensions

module internal SSSP =
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 Expand Up @@ -76,4 +76,6 @@ module internal SSSP =
front1.Dispose queue
front2.Dispose queue

distance
match distance with
| ClVector.Dense dist -> dist
| _ -> failwith "not implemented"
Loading

0 comments on commit ebdb250

Please sign in to comment.