Skip to content

Commit ff5d55c

Browse files
committed
Add RemoveDuplicates func; add some constructors
1 parent 5fe00e7 commit ff5d55c

17 files changed

Lines changed: 244 additions & 279 deletions

File tree

benchmarks/GraphBLAS-sharp.Benchmarks/BenchmarksEWiseAdd.fs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ type EWiseAddBenchmarks4Float32() =
158158
member this.EWiseAdditionCOOFloat32() =
159159
let (ClContext context) = this.OclContext
160160
(leftCOO, rightCOO) ||> Matrix.eWiseAdd AddMult.float32
161-
|> EvalGB.runWithClContext context
161+
|> EvalGB.withClContext context
162+
|> EvalGB.runSync
162163

163164
static member InputMatricesProvider =
164165
"EWiseAddBenchmarks4Float32.txt"
@@ -228,7 +229,8 @@ type EWiseAddBenchmarks4Bool() =
228229
member this.EWiseAdditionCOOBool() =
229230
let (ClContext context) = this.OclContext
230231
(leftCOO, rightCOO) ||> Matrix.eWiseAdd AnyAll.bool
231-
|> EvalGB.runWithClContext context
232+
|> EvalGB.withClContext context
233+
|> EvalGB.runSync
232234

233235
static member InputMatricesProvider =
234236
"EWiseAddBenchmarks4Bool.txt"

src/GraphBLAS-sharp/AlgebraicStructures.fs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,19 @@ type ISemiring<'a> =
2121
inherit IMonoid<'a>
2222
abstract Times: ClosedBinaryOp<'a>
2323

24-
// на самом деле должен быть "зависымым типом"
25-
// (если получает ноль, то Zero, иначе Just x)
26-
// но он будет оборачивать 'a только на стороне F#
27-
// => можно сделать специальный статик коснтруктор для инстансов
28-
// (если так делать, то уже не получится оставить его генерик типом)
29-
// (можно в конструктор передавать проверку на ноль первым параметром, тогда норм)
24+
(*
25+
мотивация:
26+
хотим, чтобы ноль был нулем (даже если он явно в матрице хранится)
27+
и все моноиды, определенные над MonoidicType 'a имели корректную семантику
28+
(если получился 0 и мы сменили моноид, то этот элемент все еще будет нулем в другом моноиде)
29+
*)
30+
3031
[<Struct>]
3132
type MonoidicType<'a> =
3233
| Just of 'a
3334
| Zero
3435

35-
(*
36-
мотивация
37-
хотим, чтобы ноль был нулем (даже если он в матрице будет хранится)
38-
и все моноиды, определенные над MonoidicType 'a имели корректную семантику
39-
(если получился 0 и мы сменили моноид, то этот элемент все еще будет нудем в другом моноиде)
40-
то избавимся от кастов
41-
*)
36+
module MonoidicType =
37+
let wrap (isZero: 'a -> bool) x =
38+
if isZero x then Zero
39+
else Just x

src/GraphBLAS-sharp/Algorithms/BFS.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ open GraphBLAS.FSharp
66
module BFS =
77
let levelSingleSource (matrix: Matrix<bool>) (source: int) = graphblas {
88
let vertexCount = Matrix.rowCount matrix
9-
let levels = Vector.zeroCreate vertexCount 0
10-
let frontier = Vector.ofList vertexCount [source, true]
9+
let! levels = Vector.zeroCreate vertexCount
10+
let! frontier = Vector.ofList vertexCount [source, true]
1111

1212
let mutable currentLevel = 1
1313
while currentLevel < vertexCount do

src/GraphBLAS-sharp/Algorithms/ShortestPath.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation
88
module ShortestPath =
99
let singleSource (matrix: Matrix<float>) (source: int) = graphblas {
1010
let vertexCount = Matrix.rowCount matrix
11-
let distance = Vector.ofList vertexCount [source, 0.]
11+
let! distance = Vector.ofList vertexCount [source, 0.]
1212

1313
for _ = 1 to vertexCount - 1 do
1414
let! step = (distance, matrix) ||> Vector.vxm MinAdd.float

src/GraphBLAS-sharp/Backend/COOMatrix/EWiseAdd.fs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ module internal EWiseAdd =
1111

1212
let (ClosedBinaryOp plus) = semiring.Plus
1313
let! rawPositions = preparePositions allRows allColumns allValues plus
14-
1514
let! resultRows, resultColumns, resultValues = setPositions allRows allColumns allValues rawPositions
1615

1716
return {

src/GraphBLAS-sharp/Backend/COOMatrix/Utilities/PreparePositions.fs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ open Microsoft.FSharp.Quotations
88

99
[<AutoOpen>]
1010
module internal PreparePositions =
11-
let preparePositions (allRows: int[]) (allColumns: int[]) (allValues: 'a[]) (plus: Expr<'a -> 'a -> 'a>) : OpenCLEvaluation<int[]> = opencl {
11+
let preparePositions (allRows: int[]) (allColumns: int[]) (allValues: 'a[]) (plus: Expr<'a -> 'a -> 'a>) = opencl {
1212
let length = allValues.Length
1313

1414
let preparePositions =
@@ -21,10 +21,11 @@ module internal PreparePositions =
2121

2222
let i = ndRange.GlobalID0
2323

24-
if i < length - 1 && allRowsBuffer.[i] = allRowsBuffer.[i + 1] && allColumnsBuffer.[i] = allColumnsBuffer.[i + 1] then
24+
if i < length - 1
25+
&& allRowsBuffer.[i] = allRowsBuffer.[i + 1]
26+
&& allColumnsBuffer.[i] = allColumnsBuffer.[i + 1]
27+
then
2528
rawPositionsBuffer.[i] <- 0
26-
27-
//Do not drop explicit zeroes
2829
allValuesBuffer.[i + 1] <- (%plus) allValuesBuffer.[i] allValuesBuffer.[i + 1]
2930

3031
//Drop explicit zeroes

src/GraphBLAS-sharp/Backend/COOMatrix/Utilities/SetPositions.fs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ open GraphBLAS.FSharp.Backend.Common
77

88
[<AutoOpen>]
99
module internal SetPositions =
10-
let setPositions (allRows: int[]) (allColumns: int[]) (allValues: 'a[]) (positions: int[]) : OpenCLEvaluation<int[] * int[] * 'a[]> = opencl {
10+
let setPositions (allRows: int[]) (allColumns: int[]) (allValues: 'a[]) (positions: int[]) = opencl {
1111
let prefixSumArrayLength = positions.Length
1212

1313
let setPositions =
@@ -23,7 +23,10 @@ module internal SetPositions =
2323

2424
let i = ndRange.GlobalID0
2525

26-
if i = prefixSumArrayLength - 1 || i < prefixSumArrayLength && prefixSumArrayBuffer.[i] <> prefixSumArrayBuffer.[i + 1] then
26+
if i = prefixSumArrayLength - 1
27+
|| i < prefixSumArrayLength
28+
&& prefixSumArrayBuffer.[i] <> prefixSumArrayBuffer.[i + 1]
29+
then
2730
let index = prefixSumArrayBuffer.[i]
2831

2932
resultRowsBuffer.[index] <- allRowsBuffer.[i]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace GraphBLAS.FSharp.Backend.CSRMatrix
2+
3+
open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic
4+
open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation
5+
open GraphBLAS.FSharp
6+
open GraphBLAS.FSharp.Backend.Common
7+
8+
module internal Mxv =
9+
()

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

Lines changed: 4 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ open Brahma.FSharp.OpenCL.WorkflowBuilder.Evaluation
77
// functions in mudule could be named run\get\if\it\t
88
// like mentioned here https://www.reddit.com/r/fsharp/comments/5kvsyk/modules_or_namespaces/dbt0zf7?utm_source=share&utm_medium=web2x&context=3
99
module internal PrefixSum =
10-
let scan (inputArray: int[]) (inputArrayLength: int) (vertices: int[]) (verticesLength: int) (totalSum: int[]) : OpenCLEvaluation<unit> = opencl {
10+
let scan (inputArray: int[]) (inputArrayLength: int) (vertices: int[]) (verticesLength: int) (totalSum: int[]) = opencl {
1111
let workGroupSize = Utils.workGroupSize
1212

1313
let scan =
@@ -62,7 +62,7 @@ module internal PrefixSum =
6262
totalSum
6363
}
6464

65-
let update (inputArray: int[]) (inputArrayLength: int) (vertices: int[]) (bunchLength: int) : OpenCLEvaluation<unit> = opencl {
65+
let update (inputArray: int[]) (inputArrayLength: int) (vertices: int[]) (bunchLength: int) = opencl {
6666
let workGroupSize = Utils.workGroupSize
6767

6868
let update =
@@ -108,126 +108,5 @@ module internal PrefixSum =
108108
verticesLength <- (verticesLength - 1) / workGroupSize + 1
109109
}
110110

111-
// let rec v1 (inputArray: int[]) =
112-
// let outputArray = Array.zeroCreate inputArray.Length
113-
114-
// if inputArray.Length = 1 then
115-
// let fillOutputArray =
116-
// <@
117-
// fun (ndRange: _1D)
118-
// (inputArrayBuffer: int[])
119-
// (outputArrayBuffer: int[]) ->
120-
121-
// let i = ndRange.GlobalID0
122-
// outputArrayBuffer.[i] <- inputArrayBuffer.[i]
123-
// @>
124-
125-
// opencl {
126-
// let binder kernelP =
127-
// let ndRange = _1D(outputArray.Length)
128-
// kernelP
129-
// ndRange
130-
// inputArray
131-
// outputArray
132-
// do! RunCommand fillOutputArray binder
133-
// return outputArray
134-
// }
135-
// else
136-
// let intermediateArray = Array.zeroCreate ((inputArray.Length + 1) / 2)
137-
// let inputArrayLength = inputArray.Length
138-
// let intermediateArrayLength = intermediateArray.Length
139-
140-
// let fillIntermediateArray =
141-
// <@
142-
// fun (ndRange: _1D)
143-
// (inputArrayBuffer: int[])
144-
// (intermediateArrayBuffer: int[]) ->
145-
146-
// let i = ndRange.GlobalID0
147-
// if i < intermediateArrayLength then
148-
// if 2 * i + 1 < inputArrayLength then
149-
// intermediateArrayBuffer.[i] <- inputArrayBuffer.[2 * i] + inputArrayBuffer.[2 * i + 1]
150-
// else intermediateArrayBuffer.[i] <- inputArrayBuffer.[2 * i]
151-
// @>
152-
153-
// let fillIntermediateArray =
154-
// opencl {
155-
// let binder kernelP =
156-
// let ndRange = _1D(workSize intermediateArray.Length, workGroupSize)
157-
// kernelP
158-
// ndRange
159-
// inputArray
160-
// intermediateArray
161-
// do! RunCommand fillIntermediateArray binder
162-
// }
163-
164-
// let fillOutputArray =
165-
// <@
166-
// fun (ndRange: _1D)
167-
// (auxiliaryPrefixSumArrayBuffer: int[])
168-
// (inputArrayBuffer: int[])
169-
// (outputArrayBuffer: int[]) ->
170-
171-
// let i = ndRange.GlobalID0
172-
// if i < inputArrayLength then
173-
// let j = (i - 1) / 2
174-
// if i % 2 = 0 then
175-
// if i = 0 then outputArrayBuffer.[i] <- inputArrayBuffer.[i]
176-
// else outputArrayBuffer.[i] <- auxiliaryPrefixSumArrayBuffer.[j] + inputArrayBuffer.[i]
177-
// else outputArrayBuffer.[i] <- auxiliaryPrefixSumArrayBuffer.[j]
178-
// @>
179-
180-
// opencl {
181-
// do! fillIntermediateArray
182-
// let! auxiliaryPrefixSumArray = v1 intermediateArray
183-
184-
// let binder kernelP =
185-
// let ndRange = _1D(workSize inputArray.Length, workGroupSize)
186-
// kernelP
187-
// ndRange
188-
// auxiliaryPrefixSumArray
189-
// inputArray
190-
// outputArray
191-
// do! RunCommand fillOutputArray binder
192-
193-
// return outputArray
194-
// }
195-
196-
// let v2 (inputArray: int[]) =
197-
// let firstIntermediateArray = Array.copy inputArray
198-
// let secondIntermediateArray = Array.copy inputArray
199-
// let outputArrayLength = firstIntermediateArray.Length
200-
201-
// let updateResult =
202-
// <@
203-
// fun (ndRange: _1D)
204-
// (offset: int)
205-
// (firstIntermediateArrayBuffer: int[])
206-
// (secondIntermediateArrayBuffer: int[]) ->
207-
208-
// let i = ndRange.GlobalID0
209-
// if i < outputArrayLength then
210-
// if i < offset then firstIntermediateArrayBuffer.[i] <- secondIntermediateArrayBuffer.[i]
211-
// else firstIntermediateArrayBuffer.[i] <- secondIntermediateArrayBuffer.[i] + secondIntermediateArrayBuffer.[i - offset]
212-
// @>
213-
214-
// let binder offset firstIntermediateArray secondIntermediateArray kernelP =
215-
// let ndRange = _1D(workSize outputArrayLength, workGroupSize)
216-
// kernelP
217-
// ndRange
218-
// offset
219-
// firstIntermediateArray
220-
// secondIntermediateArray
221-
222-
// let swap (a, b) = (b, a)
223-
// let mutable arrays = firstIntermediateArray, secondIntermediateArray
224-
225-
// opencl {
226-
// let mutable offset = 1
227-
// while offset < outputArrayLength do
228-
// arrays <- swap arrays
229-
// do! RunCommand updateResult <| (binder offset <|| arrays)
230-
// offset <- offset * 2
231-
232-
// return (fst arrays)
233-
// }
111+
// сделать не inplace prefixSum
112+
// если функции вспомогательные, то лучше сделат их private
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
namespace GraphBLAS.FSharp.Backend.Common
2+
3+
open Brahma.OpenCL
4+
open Brahma.FSharp.OpenCL.WorkflowBuilder.Basic
5+
6+
module internal RemoveDuplicates =
7+
let run (array: 'a[]) = opencl {
8+
let inputLength = array.Length
9+
10+
let isUniqueBitmap =
11+
<@
12+
fun (ndRange: _1D)
13+
(inputArray: 'a[])
14+
(isUniqueBitmap: int[]) ->
15+
16+
let i = ndRange.GlobalID0
17+
if i < inputLength - 1 && inputArray.[i] = inputArray.[i + 1] then
18+
isUniqueBitmap.[i] <- 0
19+
@>
20+
21+
let setPositions =
22+
<@
23+
fun (ndRange: _1D)
24+
(inputArray: 'a[])
25+
(positions: int[])
26+
(ouputArray: 'a[]) ->
27+
28+
let i = ndRange.GlobalID0
29+
if i < inputLength then
30+
let position = positions.[i] - 1
31+
ouputArray.[position] <- inputArray.[i]
32+
@>
33+
34+
let bitmap = Array.create inputLength 1
35+
do! RunCommand isUniqueBitmap <| fun kernelPrepare ->
36+
let ndRange = _1D(Utils.workSize inputLength, Utils.workGroupSize)
37+
kernelPrepare ndRange array bitmap
38+
39+
let resultLength = Array.zeroCreate 1
40+
do! PrefixSum.run bitmap resultLength
41+
let! _ = ToHost resultLength
42+
let resultLength = resultLength.[0]
43+
44+
let outputArray = Array.zeroCreate resultLength
45+
do! RunCommand setPositions <| fun kernelPrepare ->
46+
let ndRange = _1D(Utils.workSize inputLength, Utils.workGroupSize)
47+
kernelPrepare ndRange array bitmap outputArray
48+
49+
return outputArray
50+
}

0 commit comments

Comments
 (0)