Skip to content

Commit dffcb5f

Browse files
committed
refactor: Matrix.map*, ClArray.choose
1 parent ecb4eb5 commit dffcb5f

File tree

7 files changed

+64
-75
lines changed

7 files changed

+64
-75
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ GraphBLAS# is a GPGPU-based [GraphBLAS](https://graphblas.org/)-like API impleme
1919
| Left of 't1
2020
| Right of 't2
2121
```
22-
So, type of matrix-matrix elementwise oertion is ```Matrix<Option<'t1>> -> Matrix<Option<'t2>> -> (AtLeastOne<'t1,'t2> -> Option<'t3>) -> Matrix<Option<'t3>>```.
23-
- No semirings. Just functions. Ofcourse one can implement semirings on the top of provided API.
22+
So, type of matrix-matrix elementwise operation is ```Matrix<Option<'t1>> -> Matrix<Option<'t2>> -> (AtLeastOne<'t1,'t2> -> Option<'t3>) -> Matrix<Option<'t3>>```.
23+
- No semirings. Just functions. Of course one can implement semirings on the top of provided API.
2424
- Minimal core: high-order functions allows us to minimaze core by functions unification. For example, such functions as matrix-matrix addition, matrix-matrix element-wise multiplication, masking all are partial case of `map2` function.
2525

2626
### Operations

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,12 +390,19 @@ module ClArray =
390390
(prefixSum processor positions)
391391
.ToHostAndFree(processor)
392392

393-
let result =
394-
clContext.CreateClArrayWithSpecificAllocationMode(allocationMode, resultLength)
393+
if resultLength = 0 then
394+
positions.Free processor
395+
396+
None
397+
else
398+
let result =
399+
clContext.CreateClArrayWithSpecificAllocationMode(allocationMode, resultLength)
395400

396-
assignValues processor sourceValues positions result
401+
assignValues processor sourceValues positions result
397402

398-
result
403+
positions.Free processor
404+
405+
Some result
399406

400407
let assignOption2 (op: Expr<'a -> 'b -> 'c option>) (clContext: ClContext) workGroupSize =
401408

src/GraphBLAS-sharp.Backend/Matrix/CSR/Map2.fs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ module internal Map2 =
9494
///<param name="clContext">.</param>
9595
///<param name="opAdd">.</param>
9696
///<param name="workGroupSize">Should be a power of 2 and greater than 1.</param>
97-
let runToCOO<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality>
97+
let run<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality>
9898
(opAdd: Expr<'a option -> 'b option -> 'c option>)
9999
(clContext: ClContext)
100100
workGroupSize
@@ -135,22 +135,6 @@ module internal Map2 =
135135
Columns = resultColumns
136136
Values = resultValues }
137137

138-
let run<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality>
139-
(opAdd: Expr<'a option -> 'b option -> 'c option>)
140-
(clContext: ClContext)
141-
workGroupSize
142-
=
143-
144-
let map2ToCOO = runToCOO opAdd clContext workGroupSize
145-
146-
let toCSRInPlace =
147-
Matrix.toCSRInPlace clContext workGroupSize
148-
149-
fun (queue: MailboxProcessor<_>) allocationMode (matrixLeft: ClMatrix.CSR<'a>) (matrixRight: ClMatrix.CSR<'b>) ->
150-
map2ToCOO queue allocationMode matrixLeft matrixRight
151-
|> toCSRInPlace queue allocationMode
152-
153-
154138
module AtLeastOne =
155139
let preparePositions<'a, 'b, 'c when 'a: struct and 'b: struct and 'c: struct and 'c: equality>
156140
(opAdd: Expr<'a option -> 'b option -> 'c option>)

src/GraphBLAS-sharp.Backend/Matrix/CSR/Matrix.fs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ open GraphBLAS.FSharp.Backend.Objects.ClMatrix
1010
open GraphBLAS.FSharp.Backend.Objects.ClContext
1111
open GraphBLAS.FSharp.Backend.Objects.ClVector
1212
open GraphBLAS.FSharp.Backend.Objects.ArraysExtensions
13-
open GraphBLAS.FSharp.Backend.Objects.ArraysExtensions
14-
open GraphBLAS.FSharp.Backend.Objects.ClCell
1513

1614

1715
module Matrix =

src/GraphBLAS-sharp.Backend/Matrix/Matrix.fs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,16 @@ module Matrix =
261261
let mapCSR =
262262
CSR.Matrix.map opAdd clContext workGroupSize
263263

264+
let transposeCOO =
265+
COO.Matrix.transposeInPlace clContext workGroupSize
266+
264267
fun (processor: MailboxProcessor<_>) allocationMode matrix ->
265268
match matrix with
266269
| ClMatrix.COO m -> mapCOO processor allocationMode m |> ClMatrix.COO
267270
| ClMatrix.CSR m -> mapCSR processor allocationMode m |> ClMatrix.COO
268271
| ClMatrix.CSC m ->
269272
(mapCSR processor allocationMode m.ToCSR)
273+
|> transposeCOO processor
270274
|> ClMatrix.COO
271275
| _ -> failwith "Not yet implemented"
272276

@@ -277,18 +281,21 @@ module Matrix =
277281
let map2CSR =
278282
CSR.Matrix.map2 opAdd clContext workGroupSize
279283

284+
let transposeCOO =
285+
COO.Matrix.transposeInPlace clContext workGroupSize
286+
280287
fun (processor: MailboxProcessor<_>) allocationMode matrix1 matrix2 ->
281288
match matrix1, matrix2 with
282289
| ClMatrix.COO m1, ClMatrix.COO m2 ->
283290
map2COO processor allocationMode m1 m2
284291
|> ClMatrix.COO
285292
| ClMatrix.CSR m1, ClMatrix.CSR m2 ->
286293
map2CSR processor allocationMode m1 m2
287-
|> ClMatrix.CSR
294+
|> ClMatrix.COO
288295
| ClMatrix.CSC m1, ClMatrix.CSC m2 ->
289296
(map2CSR processor allocationMode m1.ToCSR m2.ToCSR)
290-
.ToCSC
291-
|> ClMatrix.CSC
297+
|> transposeCOO processor
298+
|> ClMatrix.COO
292299
| _ -> failwith "Matrix formats are not matching"
293300

294301
let map2AtLeastOne (opAdd: Expr<AtLeastOne<'a, 'b> -> 'c option>) (clContext: ClContext) workGroupSize =

src/GraphBLAS-sharp.Backend/Vector/Dense/Vector.fs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -156,18 +156,12 @@ module Vector =
156156

157157
fun (processor: MailboxProcessor<_>) (vector: ClArray<'a option>) ->
158158

159-
let notEmpty =
160-
(containsNonZero processor vector)
161-
.ToHostAndFree processor
159+
choose processor DeviceOnly vector
160+
|> function
161+
| Some values ->
162+
let result = reduce processor values
162163

163-
if notEmpty then
164-
let values = choose processor DeviceOnly vector
164+
processor.Post(Msg.CreateFreeMsg<_>(values))
165165

166-
let result = reduce processor values
167-
168-
processor.Post(Msg.CreateFreeMsg<_>(values))
169-
170-
result
171-
172-
else
173-
clContext.CreateClCell Unchecked.defaultof<'a>
166+
result
167+
| None -> clContext.CreateClCell Unchecked.defaultof<'a>

tests/GraphBLAS-sharp.Tests/Backend/Common/ClArray/Choose.fs

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,31 @@ let workGroupSize = Utils.defaultWorkGroupSize
1313

1414
let config = Utils.defaultConfig
1515

16-
let context = Context.defaultContext.ClContext
17-
18-
let processor = defaultContext.Queue
16+
let makeTest<'a, 'b> testContext mapFun isEqual choose (array: 'a []) =
17+
let context = testContext.ClContext
18+
let q = testContext.Queue
1919

20-
let makeTest<'a, 'b> testContext choose mapFun isEqual (array: 'a []) =
2120
if array.Length > 0 then
22-
let context = testContext.ClContext
23-
let q = testContext.Queue
24-
25-
let clArray =
26-
context.CreateClArrayWithSpecificAllocationMode(DeviceOnly, array)
27-
28-
let (clResult: ClArray<'b>) = choose q HostInterop clArray
2921

30-
let hostResult = Array.zeroCreate clResult.Length
22+
let clArray = context.CreateClArray array
3123

32-
q.PostAndReply(fun ch -> Msg.CreateToHostMsg(clResult, hostResult, ch))
33-
|> ignore
24+
let (clResult: ClArray<'b> option) = choose q HostInterop clArray
3425

3526
let expectedResult = Array.choose mapFun array
3627

37-
"Result should be the same"
38-
|> Utils.compareArrays isEqual hostResult expectedResult
28+
match clResult with
29+
| Some clResult ->
30+
let hostResult = clResult.ToHostAndFree testContext.Queue
3931

40-
let createTest<'a, 'b> testContext mapFun mapFunQ isEqual =
41-
let context = testContext.ClContext
32+
"Result should be the same"
33+
|> Utils.compareArrays isEqual hostResult expectedResult
34+
| None ->
35+
"Result must be empty"
36+
|> Expect.isTrue (expectedResult.Length = 0)
4237

43-
let choose =
44-
ClArray.choose mapFunQ context workGroupSize
45-
46-
makeTest<'a, 'b> testContext choose mapFun isEqual
38+
let createTest<'a, 'b> testContext mapFun mapFunQ isEqual =
39+
ClArray.choose mapFunQ testContext.ClContext workGroupSize
40+
|> makeTest<'a, 'b> testContext mapFun isEqual
4741
|> testPropertyWithConfig config $"test on %A{typeof<'a>} -> %A{typeof<'b>}"
4842

4943
let testFixtures testContext =
@@ -61,7 +55,10 @@ let testFixtures testContext =
6155
let tests =
6256
TestCases.gpuTests "choose id" testFixtures
6357

64-
let makeTest2 isEqual opMap testFun (firstArray: 'a [], secondArray: 'a []) =
58+
let makeTest2 testContext isEqual opMap testFun (firstArray: 'a [], secondArray: 'a []) =
59+
let context = testContext.ClContext
60+
let processor = testContext.Queue
61+
6562
if firstArray.Length > 0 && secondArray.Length > 0 then
6663

6764
let expected =
@@ -81,21 +78,23 @@ let makeTest2 isEqual opMap testFun (firstArray: 'a [], secondArray: 'a []) =
8178
"Results must be the same"
8279
|> Utils.compareArrays isEqual actual expected
8380

84-
let createTest2 (isEqual: 'a -> 'a -> bool) (opMapQ, opMap) testFun =
85-
let testFun =
86-
testFun opMapQ context Utils.defaultWorkGroupSize
87-
88-
makeTest2 isEqual opMap testFun
81+
let createTest2 testsContext (isEqual: 'a -> 'a -> bool) (opMapQ, opMap) testFun =
82+
testFun opMapQ testsContext.ClContext Utils.defaultWorkGroupSize
83+
|> makeTest2 testsContext isEqual opMap
8984
|> testPropertyWithConfig config $"test on %A{typeof<'a>}"
9085

91-
let tests2 =
92-
[ createTest2 (=) ArithmeticOperations.intAdd ClArray.choose2
86+
let testsFixtures2 testContext =
87+
let context = testContext.ClContext
88+
89+
[ createTest2 testContext (=) ArithmeticOperations.intAdd ClArray.choose2
9390

9491
if Utils.isFloat64Available context.ClDevice then
95-
createTest2 (=) ArithmeticOperations.floatAdd ClArray.choose2
92+
createTest2 testContext (=) ArithmeticOperations.floatAdd ClArray.choose2
9693

97-
createTest2 (=) ArithmeticOperations.float32Add ClArray.choose2
98-
createTest2 (=) ArithmeticOperations.boolAdd ClArray.choose2 ]
99-
|> testList "choose2 add"
94+
createTest2 testContext (=) ArithmeticOperations.float32Add ClArray.choose2
95+
createTest2 testContext (=) ArithmeticOperations.boolAdd ClArray.choose2 ]
96+
97+
let tests2 =
98+
TestCases.gpuTests "choose2 add" testsFixtures2
10099

101100
let allTests = testList "Choose" [ tests; tests2 ]

0 commit comments

Comments
 (0)