Skip to content
Closed

RFC #17

Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions benchmarks/GraphBLAS-sharp.Benchmarks/BenchmarksBFS.fs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ type BFSBenchmark4CSRMatrix() =

[<GlobalSetup>]
member this.BuildMatrix() =
matrix <- CSRMatrix(this.PathToGraph)
source <- random.Next matrix.RowCount
matrix <- MatrixCSR <| CSRMatrix.FromFile this.PathToGraph
source <- random.Next <| Matrix.rowCount matrix

[<Benchmark>]
member this.LevelBFS() =
levelBFS matrix source
BFS.levelSingleSource matrix source

/// Sequence of paths to files where data for benchmarking will be taken from
static member GraphPaths = seq {
Expand Down
34 changes: 18 additions & 16 deletions benchmarks/GraphBLAS-sharp.Benchmarks/BenchmarksEWiseAdd.fs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ type EWiseAddBenchmarks4Float32() =
let mutable leftCOO = Unchecked.defaultof<Matrix<float32>>
let mutable rightCOO = Unchecked.defaultof<Matrix<float32>>

member val FirstMatrix = Unchecked.defaultof<COOFormat<float32>> with get, set
member val SecondMatrix = Unchecked.defaultof<COOFormat<float32>> with get, set
member val FirstMatrix = Unchecked.defaultof<COOMatrix<float32>> with get, set
member val SecondMatrix = Unchecked.defaultof<COOMatrix<float32>> with get, set

[<GlobalSetup>]
member this.FormInputData() =
Expand Down Expand Up @@ -130,13 +130,13 @@ type EWiseAddBenchmarks4Float32() =
Array.blit this.FirstMatrix.Values 0 leftVals 0 this.FirstMatrix.Values.Length

leftCOO <-
COOMatrix(
COOMatrix.FromTuples(
this.FirstMatrix.RowCount,
this.FirstMatrix.ColumnCount,
leftRows,
leftCols,
leftVals
) :> Matrix<float32>
) |> MatrixCOO

let rightRows = Array.zeroCreate<int> this.SecondMatrix.Rows.Length
let rightCols = Array.zeroCreate<int> this.SecondMatrix.Columns.Length
Expand All @@ -146,19 +146,20 @@ type EWiseAddBenchmarks4Float32() =
Array.blit this.SecondMatrix.Values 0 rightVals 0 this.SecondMatrix.Values.Length

rightCOO <-
COOMatrix(
COOMatrix.FromTuples(
this.SecondMatrix.RowCount,
this.SecondMatrix.ColumnCount,
rightRows,
rightCols,
rightVals
) :> Matrix<float32>
) |> MatrixCOO

[<Benchmark>]
member this.EWiseAdditionCOOFloat32() =
let (ClContext context) = this.OclContext
leftCOO.EWiseAdd rightCOO None Float32Semiring.addMult
|> context.RunSync
(leftCOO, rightCOO) ||> Matrix.eWiseAdd AddMult.float32
|> EvalGB.withClContext context
|> EvalGB.runSync

static member InputMatricesProvider =
"EWiseAddBenchmarks4Float32.txt"
Expand All @@ -176,8 +177,8 @@ type EWiseAddBenchmarks4Bool() =
let mutable leftCOO = Unchecked.defaultof<Matrix<bool>>
let mutable rightCOO = Unchecked.defaultof<Matrix<bool>>

member val FirstMatrix = Unchecked.defaultof<COOFormat<bool>> with get, set
member val SecondMatrix = Unchecked.defaultof<COOFormat<bool>> with get, set
member val FirstMatrix = Unchecked.defaultof<COOMatrix<bool>> with get, set
member val SecondMatrix = Unchecked.defaultof<COOMatrix<bool>> with get, set

[<GlobalSetup>]
member this.FormInputData() =
Expand All @@ -201,13 +202,13 @@ type EWiseAddBenchmarks4Bool() =
Array.blit this.FirstMatrix.Columns 0 leftCols 0 this.FirstMatrix.Columns.Length

leftCOO <-
COOMatrix(
COOMatrix.FromTuples(
this.FirstMatrix.RowCount,
this.FirstMatrix.ColumnCount,
leftRows,
leftCols,
leftVals
) :> Matrix<bool>
) |> MatrixCOO

let rightRows = Array.zeroCreate<int> this.SecondMatrix.Rows.Length
let rightCols = Array.zeroCreate<int> this.SecondMatrix.Columns.Length
Expand All @@ -216,19 +217,20 @@ type EWiseAddBenchmarks4Bool() =
Array.blit this.SecondMatrix.Columns 0 rightCols 0 this.SecondMatrix.Columns.Length

rightCOO <-
COOMatrix(
COOMatrix.FromTuples(
this.SecondMatrix.RowCount,
this.SecondMatrix.ColumnCount,
rightRows,
rightCols,
rightVals
) :> Matrix<bool>
) |> MatrixCOO

[<Benchmark>]
member this.EWiseAdditionCOOBool() =
let (ClContext context) = this.OclContext
leftCOO.EWiseAdd rightCOO None BooleanSemiring.anyAll
|> context.RunSync
(leftCOO, rightCOO) ||> Matrix.eWiseAdd AnyAll.bool
|> EvalGB.withClContext context
|> EvalGB.runSync

static member InputMatricesProvider =
"EWiseAddBenchmarks4Bool.txt"
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/GraphBLAS-sharp.Benchmarks/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ module Utils =
ColumnCount = mtx.Shape.ColumnCount
}

let transposeCOO (matrix: COOFormat<'a>) =
let transposeCOO (matrix: COOMatrix<'a>) =
printfn "Start transpose COO"

(matrix.Columns, matrix.Rows, matrix.Values)
Expand Down
120 changes: 0 additions & 120 deletions src/GraphBLAS-sharp/Abstracts.fs

This file was deleted.

78 changes: 78 additions & 0 deletions src/GraphBLAS-sharp/AlgebraicStructures.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
namespace GraphBLAS.FSharp

open Microsoft.FSharp.Quotations

type UnaryOp<'a, 'b> = UnaryOp of Expr<'a -> 'b>
type BinaryOp<'a, 'b, 'c> = BinaryOp of Expr<'a -> 'b -> 'c>

type ClosedUnaryOp<'a> = ClosedUnaryOp of Expr<'a -> 'a>
type ClosedBinaryOp<'a> = ClosedBinaryOp of Expr<'a -> 'a -> 'a>

/// Magma with associative (magma is set with closed binary operator)
type ISemigroup<'a> =
abstract Op: ClosedBinaryOp<'a>

/// Semigroup with identity
type IMonoid<'a> =
abstract Plus: ClosedBinaryOp<'a>
abstract Zero: 'a

/// Monoid with associative binary operator,
/// for wich Zero is annihilator
type ISemiring<'a> =
abstract Zero: 'a
abstract Plus: ClosedBinaryOp<'a>
abstract Times: ClosedBinaryOp<'a>

type Semigroup<'a> =
{
AssociativeOp: ClosedBinaryOp<'a>
}

interface ISemigroup<'a> with
member this.Op = this.AssociativeOp

type Monoid<'a> =
{
AssociativeOp: ClosedBinaryOp<'a>
Identity: 'a
}

interface ISemigroup<'a> with
member this.Op = this.AssociativeOp

interface IMonoid<'a> with
member this.Plus = this.AssociativeOp
member this.Zero = this.Identity

type Semiring<'a> =
{
PlusMonoid: Monoid<'a>
TimesSemigroup: Semigroup<'a>
}

interface IMonoid<'a> with
member this.Zero = this.PlusMonoid.Identity
member this.Plus = this.PlusMonoid.AssociativeOp

interface ISemiring<'a> with
member this.Times = this.TimesSemigroup.AssociativeOp
member this.Zero = this.PlusMonoid.Identity
member this.Plus = this.PlusMonoid.AssociativeOp

(*
мотивация:
хотим, чтобы ноль был нулем (даже если он явно в матрице хранится)
и все моноиды, определенные над MonoidicType 'a имели корректную семантику
(если получился 0 и мы сменили моноид, то этот элемент все еще будет нулем в другом моноиде)
*)

[<Struct>]
type MonoidicType<'a> =
| Just of 'a
| Zero

module MonoidicType =
let wrap (isZero: 'a -> bool) x =
if isZero x then Zero
else Just x
43 changes: 13 additions & 30 deletions src/GraphBLAS-sharp/Algorithms/BFS.fs
Original file line number Diff line number Diff line change
@@ -1,40 +1,23 @@
namespace GraphBLAS.FSharp.Algorithms

open GraphBLAS.FSharp.Predefined
open GraphBLAS.FSharp.Helpers
open GraphBLAS.FSharp
open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic
open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation

[<AutoOpen>]
module BFS =
let levelBFS (matrix: Matrix<bool>) (source: int) : OpenCLEvaluation<Vector<int>> =
let vertexCount = matrix.RowCount
let levels = Vector.ofArray <| Array.zeroCreate vertexCount <| (=) 0
let frontier = Vector.ofTuples vertexCount [source, true]
let levelSingleSource (matrix: Matrix<bool>) (source: int) = graphblas {
let vertexCount = Matrix.rowCount matrix
let! levels = Vector.zeroCreate vertexCount
let! frontier = Vector.ofList vertexCount [source, true]

opencl {
let mutable currentLevel = 1
while currentLevel < vertexCount do
let! frontierMask = frontier.GetMask()
do! levels.Assign(frontierMask, Scalar currentLevel)
let! levelsComplemented = levels.GetMask(isComplemented = true)
let! frontier = frontier.Vxm matrix levelsComplemented BooleanSemiring.anyAll
currentLevel <- currentLevel + 1
let mutable currentLevel = 1
while currentLevel < vertexCount do
let! frontierMask = Vector.mask frontier
do! levels |> Vector.fillSubVector frontierMask (Scalar currentLevel)

return levels
}
let! levelsComplemented = Vector.complemented levels
let! frontier = (frontier, matrix) ||> Vector.vxmWithMask AnyAll.bool levelsComplemented

// let parentBFS (matrix: Matrix<bool>) (source: int) : Vector<int> =
// let vertexCount = matrix.RowCount
// let parents = SparseVector(vertexCount, [source, -1])
currentLevel <- currentLevel + 1

// let id = DenseVector(Array.init vertexCount id, IntegerMonoid.add)
// let frontier = SparseVector(vertexCount, [source, source])

// for _ in 1 .. vertexCount - 1 do
// frontier.[parents.Complemented] <- (frontier @. matrix) parents.Complemented IntegerSemiring.minFirst
// parents.[frontier.Mask] <- frontier
// frontier.[frontier.Mask] <- id

// upcast parents
return levels
}
Loading