Skip to content

Commit 65f2d22

Browse files
committed
Update interface with OpenCLEvaluation. Disable fody
1 parent d517fff commit 65f2d22

File tree

10 files changed

+205
-175
lines changed

10 files changed

+205
-175
lines changed

Directory.Build.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
<Authors>YaccConstructor</Authors>
1010
<RepositoryUrl>https://github.com/YaccConstructor/GraphBLAS-sharp</RepositoryUrl>
1111
<!-- owners is not supported in MSBuild -->
12+
<DisableFody>true</DisableFody>
1213
</PropertyGroup>
1314
</Project>

src/GraphBLAS-sharp/Abstracts.fs

Lines changed: 93 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,81 +2,114 @@ namespace GraphBLAS.FSharp
22

33
open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation
44

5+
(*
6+
везде вместо того, чтобы возвращать unit, можно возвращать измененный объект,
7+
но нужно подумать, насколько создание нового объекта лучше/хуже изменения существующего
8+
копирование большмх матриц явно хуже и зачем, а вот Clear сделать не inplace мб имеет смысл
9+
10+
везде методы, тк проперти не соответсвуют концепции отсутствия вычислений,
11+
хотя выглядеть будет оч плохо
12+
13+
можно все операции, в которых не меняется структура объекта, сделать inplace
14+
(хотя, если операция затрагивает весь объект, то все равно читать и писать,
15+
единственно, что памяти единовременно в 2 раза больше потребуется)
16+
17+
теперь есть единственный метод GetMask (без GetComplemented)
18+
тк это теперь не свойство, то требует аргумента, а значит можно передавать isComplemented
19+
20+
методы Extract и Assign, которые возвращают/присваивают подграф, семантически отличаются от тех, что в C
21+
здесь возвращаемый подграф (подматрица) всегда того же размера, что и изначальная матрица
22+
(т.е в матрице смежности вершины графа не удалаются, а только ребра)
23+
поэтому перед операцией нужно сравнивать размерности матрицы и маски, по которой мы получаем подграф
24+
чтобы удалить еще и вершины, можно потом сделать resize
25+
26+
у вектора размерность теперь называется size, а не length, потому что идейно вектор -- набор вершин
27+
+ в C API тоже size
28+
29+
метод Prune можно переименовать в Select или Filter
30+
31+
нужно выяснить, как Partitial Aplication методы интеропятся с C#
32+
33+
возможно, стоит отказаться от перегрузок Extract и Assign, чтобы сделать их PA,
34+
тем самым, избавившись от скобок при вызове
35+
36+
можно все методы сделать как методы C# (без PA), а рядом положить модуль с PA функциями
37+
это нужно, для более гибкого интерфейся и лучшего интеропа с C#
38+
*)
39+
540
[<AbstractClass>]
641
type Matrix<'a when 'a : struct and 'a : equality>(nrow: int, ncol: int) =
742
abstract RowCount: int
843
abstract ColumnCount: int
944
default this.RowCount = nrow
1045
default this.ColumnCount = ncol
1146

12-
abstract Extract: Mask2D option -> Matrix<'a>
13-
abstract Extract: (Mask1D option * int) -> Vector<'a>
14-
abstract Extract: (int * Mask1D option) -> Vector<'a>
15-
abstract Extract: (int * int) -> Scalar<'a>
16-
// Размерности должны совпадать
17-
abstract Assign: Mask2D option * Matrix<'a> -> unit
18-
abstract Assign: (Mask1D option * int) * Vector<'a> -> unit
19-
abstract Assign: (int * Mask1D option) * Vector<'a> -> unit
20-
abstract Assign: (int * int) * Scalar<'a> -> unit
21-
abstract Assign: Mask2D option * Scalar<'a> -> unit
22-
abstract Assign: (Mask1D option * int) * Scalar<'a> -> unit
23-
abstract Assign: (int * Mask1D option) * Scalar<'a> -> unit
24-
// abstract Resize
25-
// abstract Dup
26-
// abstract Clear
27-
// abstract NNZ
28-
// abstract Tuples: OpenCLEvaluation<{| Rows: int[]; Columns: int[]; Values: 'a[] |}>
29-
30-
abstract Mxm: Matrix<'a> -> Mask2D option -> Semiring<'a> -> Matrix<'a>
31-
abstract Mxv: Vector<'a> -> Mask1D option -> Semiring<'a> -> Vector<'a>
32-
abstract EWiseAdd: Matrix<'a> -> Mask2D option -> Monoid<'a> -> Matrix<'a>
33-
abstract EWiseMult: Matrix<'a> -> Mask2D option -> Monoid<'a> -> Matrix<'a>
34-
abstract Apply: Mask2D option -> UnaryOp<'a, 'b> -> Matrix<'b>
35-
abstract Prune: Mask2D option -> UnaryOp<'a, bool> -> Matrix<'a>
36-
abstract ReduceIn: Mask1D option -> Monoid<'a> -> Vector<'a>
37-
abstract ReduceOut: Mask1D option -> Monoid<'a> -> Vector<'a>
38-
abstract Reduce: Monoid<'a> -> Scalar<'a>
39-
abstract T: Matrix<'a>
40-
// abstract Kronecker
41-
42-
abstract Mask: Mask2D option
43-
abstract Complemented: Mask2D option
47+
abstract Clear: unit -> OpenCLEvaluation<unit>
48+
abstract Copy: unit -> OpenCLEvaluation<Matrix<'a>>
49+
abstract Resize: int -> int -> OpenCLEvaluation<Matrix<'a>>
50+
abstract GetNNZ: unit -> OpenCLEvaluation<int>
51+
abstract GetTuples: unit -> OpenCLEvaluation<{| Rows: int[]; Columns: int[]; Values: 'a[] |}>
52+
abstract GetMask: bool -> OpenCLEvaluation<Mask2D option>
53+
54+
abstract Extract: Mask2D option -> OpenCLEvaluation<Matrix<'a>>
55+
abstract Extract: (Mask1D option * int) -> OpenCLEvaluation<Vector<'a>>
56+
abstract Extract: (int * Mask1D option) -> OpenCLEvaluation<Vector<'a>>
57+
abstract Extract: (int * int) -> OpenCLEvaluation<Scalar<'a>>
58+
abstract Assign: Mask2D option * Matrix<'a> -> OpenCLEvaluation<unit>
59+
abstract Assign: (Mask1D option * int) * Vector<'a> -> OpenCLEvaluation<unit>
60+
abstract Assign: (int * Mask1D option) * Vector<'a> -> OpenCLEvaluation<unit>
61+
abstract Assign: (int * int) * Scalar<'a> -> OpenCLEvaluation<unit>
62+
abstract Assign: Mask2D option * Scalar<'a> -> OpenCLEvaluation<unit>
63+
abstract Assign: (Mask1D option * int) * Scalar<'a> -> OpenCLEvaluation<unit>
64+
abstract Assign: (int * Mask1D option) * Scalar<'a> -> OpenCLEvaluation<unit>
65+
66+
abstract Mxm: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation<Matrix<'a>>
67+
abstract Mxv: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation<Vector<'a>>
68+
abstract EWiseAdd: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation<Matrix<'a>>
69+
abstract EWiseMult: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation<Matrix<'a>>
70+
abstract Apply: Mask2D option -> UnaryOp<'a, 'b> -> OpenCLEvaluation<Matrix<'b>>
71+
abstract Prune: Mask2D option -> UnaryOp<'a, bool> -> OpenCLEvaluation<Matrix<'a>>
72+
abstract ReduceIn: Mask1D option -> Monoid<'a> -> OpenCLEvaluation<Vector<'a>>
73+
abstract ReduceOut: Mask1D option -> Monoid<'a> -> OpenCLEvaluation<Vector<'a>>
74+
abstract Reduce: Monoid<'a> -> OpenCLEvaluation<Scalar<'a>>
75+
abstract Transpose: unit -> OpenCLEvaluation<Matrix<'a>>
76+
abstract Kronecker: Matrix<'a> -> Mask2D option -> Semiring<'a> -> OpenCLEvaluation<Matrix<'a>>
4477

4578
static member inline (+) (x: Matrix<'a>, y: Matrix<'a>) = x.EWiseAdd y
4679
static member inline (*) (x: Matrix<'a>, y: Matrix<'a>) = x.EWiseMult y
4780
static member inline (@.) (x: Matrix<'a>, y: Matrix<'a>) = x.Mxm y
4881
static member inline (@.) (x: Matrix<'a>, y: Vector<'a>) = x.Mxv y
4982

50-
and [<AbstractClass>] Vector<'a when 'a : struct and 'a : equality>(length: int) =
51-
abstract Length: int
52-
default this.Length = length
53-
54-
abstract Clear: unit -> unit
55-
abstract Extract: Mask1D option -> Vector<'a>
56-
abstract Extract: int -> Scalar<'a>
57-
abstract Assign: Mask1D option * Vector<'a> -> unit
58-
abstract Assign: int * Scalar<'a> -> unit
59-
abstract Assign: Mask1D option * Scalar<'a> -> unit
60-
// abstract Dup
61-
// abstract Resize
62-
// abstrct Clear
63-
// abstract NNZ
64-
// abstract Tuples: {| Indices: int[]; Values: 'a[] |}
65-
66-
abstract Vxm: Matrix<'a> -> Mask1D option -> Semiring<'a> -> Vector<'a>
67-
abstract EWiseAdd: Vector<'a> -> Mask1D option -> Monoid<'a> -> Vector<'a>
68-
abstract EWiseMult: Vector<'a> -> Mask1D option -> Monoid<'a> -> Vector<'a>
69-
abstract Apply: Mask1D option -> UnaryOp<'a, 'b> -> Vector<'b>
70-
abstract Prune: Mask1D option -> UnaryOp<'a, bool> -> Vector<'a>
71-
abstract Reduce: Monoid<'a> -> Scalar<'a>
72-
73-
abstract Mask: Mask1D option
74-
abstract Complemented: Mask1D option
83+
84+
and [<AbstractClass>] Vector<'a when 'a : struct and 'a : equality>(size: int) =
85+
abstract Size: int
86+
default this.Size = size
87+
88+
abstract Clear: unit -> OpenCLEvaluation<unit>
89+
abstract Copy: unit -> OpenCLEvaluation<Vector<'a>>
90+
abstract Resize: int -> OpenCLEvaluation<Vector<'a>>
91+
abstract GetNNZ: unit -> OpenCLEvaluation<int>
92+
abstract GetTuples: unit -> OpenCLEvaluation<{| Indices: int[]; Values: 'a[] |}>
93+
abstract GetMask: bool -> OpenCLEvaluation<Mask1D option>
94+
95+
abstract Extract: Mask1D option -> OpenCLEvaluation<Vector<'a>>
96+
abstract Extract: int -> OpenCLEvaluation<Scalar<'a>>
97+
abstract Assign: Mask1D option * Vector<'a> -> OpenCLEvaluation<unit>
98+
abstract Assign: int * Scalar<'a> -> OpenCLEvaluation<unit>
99+
abstract Assign: Mask1D option * Scalar<'a> -> OpenCLEvaluation<unit>
100+
101+
abstract Vxm: Matrix<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation<Vector<'a>>
102+
abstract EWiseAdd: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation<Vector<'a>>
103+
abstract EWiseMult: Vector<'a> -> Mask1D option -> Semiring<'a> -> OpenCLEvaluation<Vector<'a>>
104+
abstract Apply: Mask1D option -> UnaryOp<'a, 'b> -> OpenCLEvaluation<Vector<'b>>
105+
abstract Prune: Mask1D option -> UnaryOp<'a, bool> -> OpenCLEvaluation<Vector<'a>>
106+
abstract Reduce: Monoid<'a> -> OpenCLEvaluation<Scalar<'a>>
75107

76108
static member inline (+) (x: Vector<'a>, y: Vector<'a>) = x.EWiseAdd y
77109
static member inline (*) (x: Vector<'a>, y: Vector<'a>) = x.EWiseMult y
78110
static member inline (@.) (x: Vector<'a>, y: Matrix<'a>) = x.Vxm y
79111

112+
80113
and Mask1D(indices: int[], length: int, isComplemented: bool) =
81114
member this.Indices = indices
82115
member this.Length = length
@@ -85,9 +118,10 @@ and Mask1D(indices: int[], length: int, isComplemented: bool) =
85118
member this.Item
86119
with get (idx: int) : bool =
87120
this.Indices
88-
|> Array.exists ((=) idx)
121+
|> Array.contains idx
89122
|> (<>) this.IsComplemented
90123

124+
91125
and Mask2D(indices: (int * int)[], rowCount: int, columnCount: int, isComplemented: bool) =
92126
member this.Rows = indices |> Array.unzip |> fst
93127
member this.Columns = indices |> Array.unzip |> snd
@@ -99,5 +133,5 @@ and Mask2D(indices: (int * int)[], rowCount: int, columnCount: int, isComplement
99133
with get (rowIdx: int, colIdx: int) : bool =
100134
(this.Rows, this.Columns)
101135
||> Array.zip
102-
|> Array.exists ((=) (rowIdx, colIdx))
136+
|> Array.contains (rowIdx, colIdx)
103137
|> (<>) this.IsComplemented

src/GraphBLAS-sharp/Algorithms/BFS.fs

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,69 @@ namespace GraphBLAS.FSharp.Algorithms
33
open GraphBLAS.FSharp.Predefined
44
open GraphBLAS.FSharp.Helpers
55
open GraphBLAS.FSharp
6+
open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic
7+
open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation
8+
9+
[<AutoOpen>]
10+
module Ext =
11+
type OpenCLEvaluationBuilder with
12+
member this.While(guard, body) =
13+
if not <| guard ()
14+
then this.Zero()
15+
else this.Bind(body, fun () -> this.While(guard, body))
16+
17+
member this.Delay(f) = f ()
18+
19+
member this.Zero() = this.Return()
20+
21+
member this.Combine(a, b) = this.Bind(a, fun () -> b)
622

723
[<AutoOpen>]
824
module BFS =
9-
let levelBFS (matrix: Matrix<bool>) (source: int) : Vector<int> =
25+
let levelBFS (matrix: Matrix<bool>) (source: int) : OpenCLEvaluation<Vector<int>> =
1026
let vertexCount = matrix.RowCount
11-
let levels = DenseVector(Array.zeroCreate vertexCount, IntegerMonoid.add)
27+
let levels = Vector.Dense(Array.zeroCreate vertexCount, IntegerMonoid.add)
1228

13-
let frontier = SparseVector(vertexCount, [source, true])
29+
let frontier = Vector.Sparse(vertexCount, [source, true])
1430
let mutable currentLevel = 1
1531

16-
while !> (frontier.Reduce BooleanMonoid.any) && currentLevel < vertexCount do
17-
levels.Assign(frontier.Mask, Scalar currentLevel)
18-
frontier.Clear()
19-
frontier.Assign(levels.Complemented, (frontier @. matrix) levels.Complemented BooleanSemiring.anyAll)
20-
currentLevel <- currentLevel + 1
32+
// let inline ($) (a: Mask1D option -> 'a) (b: Mask1D option) = a <| b
33+
let inline (?<-) (a: Vector<'a>) (b: Mask1D option) (c: Scalar<'a>) = a.Assign(b, c)
34+
let inline (<@@>) (a: Vector<'a>) (b: Mask1D option) (c: Scalar<'a>) = ()
35+
36+
37+
38+
// let frontier = (@.) frontier
39+
40+
// let a = levels.AssignE <| frontier.Mask
41+
// let a = levels $ frontier.Mask <| Scalar currentLevel
42+
let a = levels ? frontier.Mask <- Scalar currentLevel
43+
44+
45+
46+
47+
// opencl {
48+
// while currentLevel < vertexCount do
49+
// do! levels.Assign(frontier.Mask, Scalar currentLevel)
50+
// // let! frontier = frontier @. matrix <|| (levels.Complemented, BooleanSemiring.anyAll)
51+
// let! frontier = frontier @. matrix <| {| Mask = levels.Complemented; SR = BooleanSemiring.anyAll |}
52+
// currentLevel <- currentLevel + 1
53+
// // let! a = frontier.Reduce BooleanMonoid.any
54+
// // let s = !> a
55+
// let a = levels.Assign $ frontier.Mask
56+
57+
// return levels
58+
// }
59+
60+
// while !> (frontier.Reduce BooleanMonoid.any) && currentLevel < vertexCount do
61+
// levels.Assign(frontier.Mask, Scalar currentLevel)
62+
// frontier.Clear()
63+
// frontier.Assign(levels.Complemented, (frontier @. matrix) levels.Complemented BooleanSemiring.anyAll)
64+
// currentLevel <- currentLevel + 1
65+
66+
// upcast levels
67+
2168

22-
upcast levels
2369

2470
// let parentBFS (matrix: Matrix<bool>) (source: int) : Vector<int> =
2571
// let vertexCount = matrix.RowCount

src/GraphBLAS-sharp/FodyWeavers.xml

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/GraphBLAS-sharp/FodyWeavers.xsd

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)