Skip to content

Commit 2f1a18f

Browse files
committed
Add graphblas workflow; change def of algebraic structures to interfaces
1 parent 157f510 commit 2f1a18f

28 files changed

Lines changed: 337 additions & 314 deletions

File tree

benchmarks/GraphBLAS-sharp.Benchmarks/BenchmarksEWiseAdd.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ type EWiseAddBenchmarks4Float32() =
157157
[<Benchmark>]
158158
member this.EWiseAdditionCOOFloat32() =
159159
let (ClContext context) = this.OclContext
160-
leftCOO.EWiseAdd rightCOO None Float32Semiring.addMult
160+
leftCOO.EWiseAdd rightCOO None AddMult.float32
161161
|> context.RunSync
162162

163163
static member InputMatricesProvider =
@@ -227,7 +227,7 @@ type EWiseAddBenchmarks4Bool() =
227227
[<Benchmark>]
228228
member this.EWiseAdditionCOOBool() =
229229
let (ClContext context) = this.OclContext
230-
leftCOO.EWiseAdd rightCOO None BooleanSemiring.anyAll
230+
leftCOO.EWiseAdd rightCOO None AnyAll.bool
231231
|> context.RunSync
232232

233233
static member InputMatricesProvider =
Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,32 @@ namespace GraphBLAS.FSharp
33
open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation
44
open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic
55

6-
type MatrixTuples<'a when 'a : struct and 'a : equality> = {
7-
RowIndices: int[]
8-
ColumnIndices: int[]
9-
Values: 'a[]
10-
}
11-
with
12-
member this.ToHost() = opencl {
13-
let! rows = ToHost this.RowIndices
14-
let! cols = ToHost this.ColumnIndices
15-
let! vals = ToHost this.Values
16-
17-
return {
18-
RowIndices = rows
19-
ColumnIndices = cols
20-
Values = vals
21-
}
6+
// algebraic objects
7+
8+
type MatrixTuples<'a when 'a : struct and 'a : equality> =
9+
{
10+
RowIndices: int[]
11+
ColumnIndices: int[]
12+
Values: 'a[]
2213
}
2314

15+
member this.ToHost() =
16+
opencl {
17+
let! rows = ToHost this.RowIndices
18+
let! cols = ToHost this.ColumnIndices
19+
let! vals = ToHost this.Values
20+
21+
return {
22+
RowIndices = rows
23+
ColumnIndices = cols
24+
Values = vals
25+
}
26+
}
27+
28+
type Scalar<'a when 'a : struct and 'a : equality> = Scalar of 'a
29+
with
30+
static member op_Implicit (Scalar source) = source
31+
2432
[<AbstractClass>]
2533
type Matrix<'a when 'a : struct and 'a : equality>(nrow: int, ncol: int) =
2634
abstract RowCount: int
@@ -48,17 +56,17 @@ type Matrix<'a when 'a : struct and 'a : equality>(nrow: int, ncol: int) =
4856
abstract Assign: (Mask1D option * int) * Scalar<'a> -> OpenCLEvaluation<unit>
4957
abstract Assign: (int * Mask1D option) * Scalar<'a> -> OpenCLEvaluation<unit>
5058

51-
abstract Mxm: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation<Matrix<'a>>
52-
abstract Mxv: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation<Vector<'a>>
53-
abstract EWiseAdd: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation<Matrix<'a>>
54-
abstract EWiseMult: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation<Matrix<'a>>
59+
abstract Mxm: Matrix<'a> -> Mask2D option -> ISemiring<'a> -> OpenCLEvaluation<Matrix<'a>>
60+
abstract Mxv: Vector<'a> -> Mask1D option -> ISemiring<'a> -> OpenCLEvaluation<Vector<'a>>
61+
abstract EWiseAdd: Matrix<'a> -> Mask2D option -> ISemiring<'a> -> OpenCLEvaluation<Matrix<'a>>
62+
abstract EWiseMult: Matrix<'a> -> Mask2D option -> ISemiring<'a> -> OpenCLEvaluation<Matrix<'a>>
5563
abstract Apply: Mask2D option -> UnaryOp<'a, 'b> -> OpenCLEvaluation<Matrix<'b>>
5664
abstract Prune: Mask2D option -> UnaryOp<'a, bool> -> OpenCLEvaluation<Matrix<'a>>
57-
abstract ReduceIn: Mask1D option -> Monoid<'a> -> OpenCLEvaluation<Vector<'a>>
58-
abstract ReduceOut: Mask1D option -> Monoid<'a> -> OpenCLEvaluation<Vector<'a>>
59-
abstract Reduce: Monoid<'a> -> OpenCLEvaluation<Scalar<'a>>
65+
abstract ReduceIn: Mask1D option -> IMonoid<'a> -> OpenCLEvaluation<Vector<'a>>
66+
abstract ReduceOut: Mask1D option -> IMonoid<'a> -> OpenCLEvaluation<Vector<'a>>
67+
abstract Reduce: IMonoid<'a> -> OpenCLEvaluation<Scalar<'a>>
6068
abstract Transpose: unit -> OpenCLEvaluation<Matrix<'a>>
61-
abstract Kronecker: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation<Matrix<'a>>
69+
abstract Kronecker: Matrix<'a> -> Mask2D option -> ISemiring<'a> -> OpenCLEvaluation<Matrix<'a>>
6270

6371
and [<AbstractClass>] Vector<'a when 'a : struct and 'a : equality>(size: int) =
6472
abstract Size: int
@@ -78,12 +86,12 @@ and [<AbstractClass>] Vector<'a when 'a : struct and 'a : equality>(size: int) =
7886
abstract Assign: int * Scalar<'a> -> OpenCLEvaluation<unit>
7987
abstract Assign: Mask1D option * Scalar<'a> -> OpenCLEvaluation<unit>
8088

81-
abstract Vxm: Matrix<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation<Vector<'a>>
82-
abstract EWiseAdd: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation<Vector<'a>>
83-
abstract EWiseMult: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation<Vector<'a>>
89+
abstract Vxm: Matrix<'a> -> Mask1D option -> ISemiring<'a> -> OpenCLEvaluation<Vector<'a>>
90+
abstract EWiseAdd: Vector<'a> -> Mask1D option -> ISemiring<'a> -> OpenCLEvaluation<Vector<'a>>
91+
abstract EWiseMult: Vector<'a> -> Mask1D option -> ISemiring<'a> -> OpenCLEvaluation<Vector<'a>>
8492
abstract Apply: Mask1D option -> UnaryOp<'a, 'b> -> OpenCLEvaluation<Vector<'b>>
8593
abstract Prune: Mask1D option -> UnaryOp<'a, bool> -> OpenCLEvaluation<Vector<'a>>
86-
abstract Reduce: Monoid<'a> -> OpenCLEvaluation<Scalar<'a>>
94+
abstract Reduce: IMonoid<'a> -> OpenCLEvaluation<Scalar<'a>>
8795

8896
and Mask1D(indices: int[], size: int, isComplemented: bool) =
8997
member this.Indices = indices
@@ -97,21 +105,23 @@ and Mask2D(rowIndices: int[], columnIndices: int[], rowCount: int, columnCount:
97105
member this.ColumnCount = columnCount
98106
member this.IsComplemented = isComplemented
99107

100-
type COOFormat<'a> = {
101-
RowCount: int
102-
ColumnCount: int
103-
Rows: int[]
104-
Columns: int[]
105-
Values: 'a[]
106-
}
107-
108-
type CSRFormat<'a> = {
109-
ColumnCount: int
110-
RowPointers: int[]
111-
ColumnIndices: int[]
112-
Values: 'a[]
113-
}
114-
with
108+
type COOFormat<'a> =
109+
{
110+
RowCount: int
111+
ColumnCount: int
112+
Rows: int[]
113+
Columns: int[]
114+
Values: 'a[]
115+
}
116+
117+
type CSRFormat<'a> =
118+
{
119+
ColumnCount: int
120+
RowPointers: int[]
121+
ColumnIndices: int[]
122+
Values: 'a[]
123+
}
124+
115125
static member CreateEmpty<'a>() = {
116126
RowPointers = Array.zeroCreate<int> 0
117127
ColumnIndices = Array.zeroCreate<int> 0
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace GraphBLAS.FSharp
2+
3+
open Microsoft.FSharp.Quotations
4+
5+
type UnaryOp<'a, 'b> =
6+
| UnaryOp of Expr<'a -> 'b>
7+
static member op_Implicit (UnaryOp source) = source
8+
9+
type BinaryOp<'a, 'b, 'c> =
10+
| BinaryOp of Expr<'a -> 'b -> 'c>
11+
static member op_Implicit (BinaryOp source) = source
12+
13+
// делать отдельными классами или оставить аллиасами
14+
type ClosedUnaryOp<'a> =
15+
| ClosedUnaryOp of Expr<'a -> 'a>
16+
static member op_Implicit (UnaryOp source) = source
17+
18+
type ClosedBinaryOp<'a> =
19+
| ClosedBinaryOp of Expr<'a -> 'a -> 'a>
20+
static member op_Implicit (UnaryOp source) = source
21+
22+
// associative closed bin op (magma with associative)
23+
type ISemigroup<'a> =
24+
abstract Plus: ClosedBinaryOp<'a>
25+
26+
// semigroup with id
27+
type IMonoid<'a> =
28+
inherit ISemigroup<'a>
29+
abstract Zero: 'a
30+
31+
type ISemiring<'a> =
32+
inherit IMonoid<'a>
33+
abstract Times: ClosedBinaryOp<'a>

src/GraphBLAS-sharp/Algorithms/BFS.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module BFS =
1919
let! frontierMask = frontier.GetMask()
2020
do! levels.Assign(frontierMask, Scalar currentLevel)
2121
let! levelsComplemented = levels.GetMask(isComplemented = true)
22-
let! frontier = frontier.Vxm matrix levelsComplemented BooleanSemiring.anyAll
22+
let! frontier = frontier.Vxm matrix levelsComplemented AnyAll.bool
2323
currentLevel <- currentLevel + 1
2424

2525
return levels

src/GraphBLAS-sharp/Algorithms/SSSP.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module SSSP =
1313

1414
opencl {
1515
for _ in 1 .. vertexCount - 1 do
16-
let! step = distance.Vxm matrix None FloatSemiring.minAdd
16+
let! step = distance.Vxm matrix None MinAdd.float
1717
do! distance.Assign(None, step)
1818

1919
return distance

src/GraphBLAS-sharp/Algorithms/TriangleCounting.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ module TriangleCounting =
1717
let! convertedMatrix = lowerTriangular.Apply None (UnaryOp <@ bool2int @>)
1818
let! convertedTransposed = convertedMatrix.Transpose()
1919
let! lowerTriangularMask = lowerTriangular.GetMask()
20-
let! result = convertedMatrix.Mxm convertedTransposed lowerTriangularMask IntegerSemiring.addMult
21-
return! result.Reduce IntegerMonoid.add
20+
let! result = convertedMatrix.Mxm convertedTransposed lowerTriangularMask AddMult.int
21+
return! result.Reduce Add.int
2222
}

src/GraphBLAS-sharp/Backend/Common/Scan.fs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic
55
open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation
66
open Utils
77

8-
// functions in mudule could be named run\get\if\it\t
8+
// functions in mudule could be named run\get\of\it\t
99
// like mentioned here https://www.reddit.com/r/fsharp/comments/5kvsyk/modules_or_namespaces/dbt0zf7?utm_source=share&utm_medium=web2x&context=3
1010
module internal Scan =
1111
let rec v1 (inputArray: int[]) =
@@ -93,10 +93,8 @@ module internal Scan =
9393
return outputArray
9494
}
9595

96-
let v2 (inputArray: int[]) =
97-
let firstIntermediateArray = Array.copy inputArray
98-
let secondIntermediateArray = Array.copy inputArray
99-
let outputArrayLength = firstIntermediateArray.Length
96+
let v2 (inputArray: int[]) = opencl {
97+
let outputArrayLength = inputArray.Length
10098

10199
let updateResult =
102100
<@
@@ -111,23 +109,24 @@ module internal Scan =
111109
else firstIntermediateArrayBuffer.[i] <- secondIntermediateArrayBuffer.[i] + secondIntermediateArrayBuffer.[i - offset]
112110
@>
113111

114-
let binder offset firstIntermediateArray secondIntermediateArray kernelP =
115-
let ndRange = _1D(workSize outputArrayLength, workGroupSize)
116-
kernelP
117-
ndRange
118-
offset
119-
firstIntermediateArray
120-
secondIntermediateArray
121-
112+
let firstIntermediateArray = Array.copy inputArray
113+
let secondIntermediateArray = Array.copy inputArray
122114
let swap (a, b) = (b, a)
123-
let mutable arrays = firstIntermediateArray, secondIntermediateArray
124115

125-
opencl {
126-
let mutable offset = 1
127-
while offset < outputArrayLength do
128-
arrays <- swap arrays
129-
do! RunCommand updateResult <| (binder offset <|| arrays)
130-
offset <- offset * 2
131-
132-
return (fst arrays)
133-
}
116+
let mutable arrays = firstIntermediateArray, secondIntermediateArray
117+
let mutable offset = 1
118+
119+
while offset < outputArrayLength do
120+
arrays <- swap arrays
121+
do! RunCommand updateResult <| fun kernelPrepare ->
122+
let ndRange = _1D(workSize outputArrayLength, workGroupSize)
123+
kernelPrepare
124+
ndRange
125+
offset
126+
(fst arrays)
127+
(snd arrays)
128+
129+
offset <- offset * 2
130+
131+
return (fst arrays)
132+
}

src/GraphBLAS-sharp/Backend/EWiseAdd.fs renamed to src/GraphBLAS-sharp/Backend/MatrixCOO/EWiseAdd.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace GraphBLAS.FSharp.Backend
1+
namespace GraphBLAS.FSharp.Backend.MatrixCOO
22

33
open Brahma.OpenCL
44
open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic
@@ -7,10 +7,10 @@ open GraphBLAS.FSharp
77
open GraphBLAS.FSharp.Backend.Common
88

99
module internal EWiseAdd =
10-
let coo (matrixLeft: COOFormat<'a>) (matrixRight: COOFormat<'a>) (mask: Mask2D option) (semiring: Semiring<'a>) : OpenCLEvaluation<COOFormat<'a>> =
10+
let run (matrixLeft: COOFormat<'a>) (matrixRight: COOFormat<'a>) (mask: Mask2D option) (semiring: ISemiring<'a>) : OpenCLEvaluation<COOFormat<'a>> =
1111
let workGroupSize = Utils.workGroupSize
12-
let (BinaryOp append) = semiring.PlusMonoid.Append
13-
let zero = semiring.PlusMonoid.Zero
12+
let (ClosedBinaryOp append) = semiring.Plus
13+
let zero = semiring.Zero
1414

1515
//It is useful to consider that the first array is longer than the second one
1616
let firstRows, firstColumns, firstValues, secondRows, secondColumns, secondValues, plus =
Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation
66
open GraphBLAS.FSharp.Backend.Common
77
open GraphBLAS.FSharp.Backend
88

9+
// storageFormats (concrete implementation)
10+
911
type CSRMatrix<'a when 'a : struct and 'a : equality>(csrTuples: CSRFormat<'a>) =
1012
inherit Matrix<'a>(csrTuples.RowPointers.Length - 1, csrTuples.ColumnCount)
1113

@@ -137,7 +139,7 @@ and COOMatrix<'a when 'a : struct and 'a : equality>(cooFormat: COOFormat<'a>) =
137139
override this.EWiseAdd
138140
(matrix: Matrix<'a>)
139141
(mask: Mask2D option)
140-
(semiring: Semiring<'a>) =
142+
(semiring: ISemiring<'a>) =
141143

142144
if (this.RowCount, this.ColumnCount) <> (matrix.RowCount, matrix.ColumnCount) then
143145
invalidArg
@@ -157,7 +159,7 @@ and COOMatrix<'a when 'a : struct and 'a : equality>(cooFormat: COOFormat<'a>) =
157159
match matrix with
158160
| :? COOMatrix<'a> as coo ->
159161
opencl {
160-
let! cooFormat = EWiseAdd.coo cooFormat coo.Storage mask semiring
162+
let! cooFormat = MatrixCOO.EWiseAdd.run cooFormat coo.Storage mask semiring
161163
return upcast COOMatrix(cooFormat)
162164
}
163165
| _ -> failwith "Not Implemented"
@@ -207,15 +209,15 @@ and SparseVector<'a when 'a : struct and 'a : equality>(size: int, indices: int[
207209
override this.Assign (idx: int, Scalar (value: 'a)) : OpenCLEvaluation<unit> = failwith "Not Implemented"
208210
override this.Assign (mask: Mask1D option, Scalar (value: 'a)) : OpenCLEvaluation<unit> = failwith "Not Implemented"
209211

210-
override this.Vxm (matrix: Matrix<'a>) (mask: Mask1D option) (semiring: Semiring<'a>) : OpenCLEvaluation<Vector<'a>> = failwith "Not Implemented"
212+
override this.Vxm (matrix: Matrix<'a>) (mask: Mask1D option) (semiring: ISemiring<'a>) : OpenCLEvaluation<Vector<'a>> = failwith "Not Implemented"
211213

212214
member internal this.EWiseAddSparse
213215
(vector: SparseVector<'a>)
214216
(mask: Mask1D option)
215-
(semiring: Semiring<'a>) : OpenCLEvaluation<Vector<'a>> =
217+
(semiring: ISemiring<'a>) : OpenCLEvaluation<Vector<'a>> =
216218

217-
let (BinaryOp append) = semiring.PlusMonoid.Append
218-
let zero = semiring.PlusMonoid.Zero
219+
let (ClosedBinaryOp append) = semiring.Plus
220+
let zero = semiring.Zero
219221

220222
//It is useful to consider that the first array is longer than the second one
221223
let firstIndices, firstValues, secondIndices, secondValues, plus =
@@ -375,7 +377,7 @@ and SparseVector<'a when 'a : struct and 'a : equality>(size: int, indices: int[
375377
override this.EWiseAdd
376378
(vector: Vector<'a>)
377379
(mask: Mask1D option)
378-
(semiring: Semiring<'a>) =
380+
(semiring: ISemiring<'a>) =
379381

380382
if vector.Size <> this.Size then
381383
invalidArg
@@ -399,4 +401,4 @@ and SparseVector<'a when 'a : struct and 'a : equality>(size: int, indices: int[
399401
override this.EWiseMult a b c = failwith "Not Implemented"
400402
override this.Apply a b = failwith "Not Implemented"
401403
override this.Prune a b = failwith "Not Implemented"
402-
override this.Reduce (monoid: Monoid<'a>) = failwith "Not Implemented"
404+
override this.Reduce (monoid: IMonoid<'a>) = failwith "Not Implemented"

src/GraphBLAS-sharp/GraphBLAS-sharp.fsproj

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project Sdk="Microsoft.NET.Sdk">
33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.1;net461</TargetFrameworks>
@@ -11,15 +11,13 @@
1111
<Compile Include="AssemblyInfo.fs" />
1212
<Compile Include="Helpers.fs" />
1313
<Compile Include="Exceptions.fs" />
14-
<Compile Include="Operators.fs" />
15-
<Compile Include="Monoid.fs" />
16-
<Compile Include="Semiring.fs" />
17-
<Compile Include="Scalar.fs" />
18-
<Compile Include="Abstracts.fs" />
14+
<Compile Include="AlgebraicStructures.fs" />
15+
<Compile Include="Abstract.fs" />
1916
<Compile Include="Backend/Common/Utils.fs" />
2017
<Compile Include="Backend/Common/Scan.fs" />
21-
<Compile Include="Backend//EWiseAdd.fs" />
22-
<Compile Include="Implementations.fs" />
18+
<Compile Include="Backend/MatrixCOO/EWiseAdd.fs" />
19+
<Compile Include="Concrete.fs" />
20+
<Compile Include="GraphblasEvaluation.fs" />
2321
<Compile Include="Matrix.fs" />
2422
<Compile Include="Vector.fs" />
2523
<Compile Include="Predefined/Monoids/Any.fs" />
@@ -28,10 +26,6 @@
2826
<Compile Include="Predefined/Semirings/AnyAll.fs" />
2927
<Compile Include="Predefined/Semirings/AddMult.fs" />
3028
<Compile Include="Predefined/Semirings/MinAdd.fs" />
31-
<Compile Include="Predefined/Float.fs" />
32-
<Compile Include="Predefined/Float32.fs" />
33-
<Compile Include="Predefined/Integer.fs" />
34-
<Compile Include="Predefined/Boolean.fs" />
3529
<Compile Include="Algorithms/BFS.fs" />
3630
<Compile Include="Algorithms/SSSP.fs" />
3731
<Compile Include="Algorithms/TriangleCounting.fs" />

0 commit comments

Comments
 (0)