Skip to content

Commit b30a9f8

Browse files
committed
add: ClArray.chunk* tests
1 parent babe90e commit b30a9f8

9 files changed

Lines changed: 339 additions & 102 deletions

File tree

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,9 @@ module ClArray =
346346
let kernel = clContext.Compile kernel
347347

348348
fun (processor: MailboxProcessor<_>) allocationMode (sourceArray: ClArray<'a>) startIndex endIndex ->
349-
if startIndex < 0 then failwith ""
350-
if startIndex >= endIndex then failwith "" // empty array
351-
if endIndex > sourceArray.Length then failwith "" // TODO()
349+
if startIndex < 0 then failwith "startIndex is less than zero"
350+
if startIndex >= endIndex then failwith "startIndex is greater than or equal to the endIndex"
351+
if endIndex > sourceArray.Length then failwith "endIndex is larger than the size of the array"
352352

353353
let resultLength = endIndex - startIndex
354354

@@ -382,20 +382,19 @@ module ClArray =
382382
let getChunk =
383383
getChunk clContext workGroupSize
384384

385-
// TODO(immutable array)
386385
fun (processor: MailboxProcessor<_>) allocationMode chunkSize (sourceArray: ClArray<'a>) ->
387-
if chunkSize <= 0 then failwith ""
386+
if chunkSize <= 0 then failwith "The size of the piece cannot be less than 1"
388387

389-
let chunkCount = (sourceArray.Length - 1) / chunkSize + 1
388+
let chunkCount = (sourceArray.Length - 1) / chunkSize
390389

391390
let getChunk = getChunk processor allocationMode sourceArray
392391

393392
seq {
394393
for i in 0 .. chunkCount do
395394
let startIndex = i * chunkSize
396-
let endIndex = max (startIndex + chunkSize) sourceArray.Length
395+
let endIndex = min (startIndex + chunkSize) sourceArray.Length
397396

398-
yield lazy ( getChunk startIndex endIndex )
397+
yield lazy getChunk startIndex endIndex
399398
}
400399

401400
/// <summary>

src/GraphBLAS-sharp.Backend/GraphBLAS-sharp.Backend.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
<Compile Include="Common/Sum.fs" />
3737
<!--Compile Include="Matrices.fs" /-->
3838
<Compile Include="Matrix/Common.fs" />
39-
<Compile Include="Matrix\Split.fs" />
4039
<Compile Include="Matrix/COOMatrix/Map2.fs" />
4140
<Compile Include="Matrix/COOMatrix/Map2AtLeastOne.fs" />
4241
<Compile Include="Matrix/COOMatrix/Map.fs" />
@@ -46,6 +45,7 @@
4645
<Compile Include="Matrix/CSRMatrix/SpGEMM.fs" />
4746
<Compile Include="Matrix/CSRMatrix/Map.fs" />
4847
<Compile Include="Matrix/CSRMatrix/Matrix.fs" />
48+
<Compile Include="Matrix\Split.fs" />
4949
<Compile Include="Matrix/Matrix.fs" />
5050
<Compile Include="Vector/SparseVector/Common.fs" />
5151
<Compile Include="Vector/SparseVector/Map2.fs" />

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

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
module GraphBLAS.FSharp.Backend.Matrix
1+
namespace GraphBLAS.FSharp.Backend.Matrix
22

33
open Brahma.FSharp
44
open GraphBLAS.FSharp.Backend.Common
55
open GraphBLAS.FSharp.Backend.Objects
66
open GraphBLAS.FSharp.Backend.Objects.ClMatrix
77
open GraphBLAS.FSharp.Backend.Objects.ArraysExtensions
8+
open GraphBLAS.FSharp.Backend.Objects.ClVector
89

910
// type lazy matrix ???
1011

@@ -42,7 +43,21 @@ module Split =
4243
|> Seq.map (fun lazyMatrix -> lazyMatrix.Value)
4344
|> Seq.toArray
4445

46+
// let run (clContext: ClContext) workGroupSize =
47+
//
48+
// let run = runCOOLazy clContext workGroupSize
49+
//
50+
// let runCOO = runCOO clContext workGroupSize
51+
//
52+
// let COOToCSR = COO.Matrix.toCSR clCOntext workGroupSize
53+
//
54+
// fun (processor: MailboxProcessor<_>) allocationMode chunkSize (matrix: ClMatrix<'a>) ->
55+
// match matrix with
56+
// | ClMatrix.COO matrix -> runCOO processor allocationMode chunkSize matrix
57+
// | ClMatrix.COO matrix ->
58+
// ()
4559
module ByRow =
60+
// MB We can split CSR to chunks without COO representation
4661
let runCSRLazy (clContext: ClContext) workGroupSize =
4762

4863
let getChunkValues = ClArray.getChunk clContext workGroupSize
@@ -54,6 +69,12 @@ module Split =
5469
let getChunkValues = getChunkValues processor allocationMode matrix.Values
5570
let getChunkIndices = getChunkIndices processor allocationMode matrix.Columns
5671

72+
let creatSparseVector values columns =
73+
{ Context = clContext
74+
Indices = columns
75+
Values = values
76+
Size = matrix.ColumnCount }
77+
5778
matrix.RowPointers.ToHost processor
5879
|> Seq.pairwise
5980
|> Seq.map (fun (first, second) ->
@@ -62,7 +83,7 @@ module Split =
6283
let values = getChunkValues first second
6384
let columns = getChunkIndices first second
6485

65-
Some (values, columns)
86+
Some <| creatSparseVector values columns
6687
else None)
6788

6889
let runCSR (clContext: ClContext) workGroupSize =
@@ -73,3 +94,43 @@ module Split =
7394
runLazy processor allocationMode matrix
7495
|> Seq.map (fun lazyValue -> lazyValue.Value)
7596
|> Seq.toArray
97+
98+
module ByColumn =
99+
let runCSRLazy (clContext: ClContext) workGroupSize =
100+
101+
let getChunkValues = ClArray.getChunk clContext workGroupSize
102+
103+
let getChunkIndices = ClArray.getChunk clContext workGroupSize
104+
105+
fun (processor: MailboxProcessor<_>) allocationMode (matrix: ClMatrix.CSC<'a>) ->
106+
107+
let getChunkValues = getChunkValues processor allocationMode matrix.Values
108+
let getChunkIndices = getChunkIndices processor allocationMode matrix.Rows
109+
110+
let creatSparseVector values columns =
111+
{ Context = clContext
112+
Indices = columns
113+
Values = values
114+
Size = matrix.RowCount }
115+
116+
matrix.ColumnPointers.ToHost processor
117+
|> Seq.pairwise
118+
|> Seq.map (fun (first, second) ->
119+
lazy
120+
if second - first > 0 then
121+
let values = getChunkValues first second
122+
let rows = getChunkIndices first second
123+
124+
Some <| creatSparseVector values rows
125+
else None)
126+
127+
let runCSR (clContext: ClContext) workGroupSize =
128+
129+
let runLazy = runCSRLazy clContext workGroupSize
130+
131+
fun (processor: MailboxProcessor<_>) allocationMode (matrix: ClMatrix.CSC<'a>) ->
132+
runLazy processor allocationMode matrix
133+
|> Seq.map (fun lazyValue -> lazyValue.Value)
134+
|> Seq.toArray
135+
136+
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
module GraphBLAS.FSharp.Tests.Backend.Common.ClArray.chunkBySize
2+
3+
open Expecto
4+
open Brahma.FSharp
5+
open GraphBLAS.FSharp.Backend.Common
6+
open GraphBLAS.FSharp.Test
7+
open GraphBLAS.FSharp.Tests
8+
open GraphBLAS.FSharp.Backend.Objects.ClContext
9+
open GraphBLAS.FSharp.Backend.Objects.ArraysExtensions
10+
11+
let context = Context.defaultContext.ClContext
12+
13+
let processor = Context.defaultContext.Queue
14+
15+
let config = { Utils.defaultConfig with arbitrary = [ typeof<Generators.ArrayAndChunkPositions> ] }
16+
17+
let makeTestGetChunk<'a when 'a : equality> testFun (array: 'a [], startPosition: int, endPosition: int) =
18+
19+
if array.Length > 0 then
20+
21+
let clArray = context.CreateClArray array
22+
23+
let (clActual: ClArray<'a>) =
24+
testFun processor HostInterop clArray startPosition endPosition
25+
26+
clArray.Free processor
27+
let actual = clActual.ToHostAndFree processor
28+
29+
"Results must be the same"
30+
|> Expect.sequenceEqual actual array.[startPosition .. endPosition - 1]
31+
32+
let creatTestGetChunk<'a when 'a : equality> =
33+
ClArray.getChunk context Utils.defaultWorkGroupSize
34+
|> makeTestGetChunk<'a>
35+
|> testPropertyWithConfig config $"test on %A{typeof<'a>}"
36+
37+
let getChunkTests =
38+
[ creatTestGetChunk<int>
39+
40+
if Utils.isFloat64Available context.ClDevice then
41+
creatTestGetChunk<float>
42+
43+
creatTestGetChunk<float32>
44+
creatTestGetChunk<bool>
45+
creatTestGetChunk<byte> ]
46+
|> testList "getChunk"
47+
48+
let makeTestChunkBySize<'a when 'a : equality> isEqual testFun (array: 'a [], chunkSize: uint) =
49+
50+
let chunkSize = int chunkSize
51+
52+
if chunkSize > 0 && array.Length > 0 then
53+
54+
let clArray = context.CreateClArray array
55+
56+
let clActual: ClArray<'a>[] =
57+
(testFun processor HostInterop chunkSize clArray)
58+
59+
clArray.Free processor
60+
61+
let actual =
62+
clActual
63+
|> Array.map (fun clArray -> clArray.ToHostAndFree processor)
64+
65+
let expected =
66+
Array.chunkBySize chunkSize array
67+
68+
"Results must be the same"
69+
|> Utils.compareChunksArrays isEqual actual expected
70+
71+
let creatTestChunkBySize<'a when 'a : equality> isEqual =
72+
ClArray.chunkBySize context Utils.defaultWorkGroupSize
73+
|> makeTestChunkBySize<'a> isEqual
74+
|> testPropertyWithConfig config $"test on %A{typeof<'a>}"
75+
76+
let chunkBySizeTests =
77+
[ creatTestChunkBySize<int> (=)
78+
79+
if Utils.isFloat64Available context.ClDevice then
80+
creatTestChunkBySize<float> Utils.floatIsEqual
81+
82+
creatTestChunkBySize<float32> Utils.float32IsEqual
83+
creatTestChunkBySize<bool> (=)
84+
creatTestChunkBySize<byte> (=) ]
85+
|> testList "chanBySize"
86+
87+
let creatTestChunkBySizeLazy<'a when 'a : equality> isEqual =
88+
(fun processor allocationMode chunkSize array ->
89+
ClArray.lazyChunkBySize context Utils.defaultWorkGroupSize processor allocationMode chunkSize array
90+
|> Seq.map (fun lazyValue -> lazyValue.Value)
91+
|> Seq.toArray)
92+
|> makeTestChunkBySize<'a> isEqual
93+
|> testPropertyWithConfig config $"test on %A{typeof<'a>}"
94+
95+
let lazyChunkBySizeTests =
96+
[ creatTestChunkBySizeLazy<int> (=)
97+
98+
if Utils.isFloat64Available context.ClDevice then
99+
creatTestChunkBySizeLazy<float> Utils.floatIsEqual
100+
101+
creatTestChunkBySizeLazy<float32> Utils.float32IsEqual
102+
creatTestChunkBySizeLazy<bool> (=)
103+
creatTestChunkBySizeLazy<byte> (=) ]
104+
|> testList "chunkBySize lazy"
105+
106+
let allTests =
107+
testList "chunk" [ getChunkTests; chunkBySizeTests; lazyChunkBySizeTests ]

tests/GraphBLAS-sharp.Tests/Generators.fs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,3 +820,60 @@ module Generators =
820820
static member BoolType() =
821821
pairOfVectorsOfEqualSize <| Arb.generate<bool>
822822
|> Arb.fromGen
823+
824+
type ArrayAndChunkPositions() =
825+
static let arrayAndChunkPosition (valuesGenerator: Gen<'a>) =
826+
gen {
827+
let! length = Gen.sized <| fun size -> Gen.choose (1, size)
828+
829+
let! array = Gen.arrayOfLength length valuesGenerator
830+
831+
let! endPosition = Gen.choose (1, length - 1)
832+
let! startPosition = Gen.choose (0, endPosition - 1)
833+
834+
return (array, startPosition, endPosition)
835+
}
836+
837+
static member IntType() =
838+
arrayAndChunkPosition <| Arb.generate<int>
839+
|> Arb.fromGen
840+
841+
static member FloatType() =
842+
arrayAndChunkPosition
843+
<| (Arb.Default.NormalFloat()
844+
|> Arb.toGen
845+
|> Gen.map float)
846+
|> Arb.fromGen
847+
848+
static member Float32Type() =
849+
arrayAndChunkPosition
850+
<| (normalFloat32Generator <| System.Random())
851+
|> Arb.fromGen
852+
853+
static member SByteType() =
854+
arrayAndChunkPosition <| Arb.generate<sbyte>
855+
|> Arb.fromGen
856+
857+
static member ByteType() =
858+
arrayAndChunkPosition <| Arb.generate<byte>
859+
|> Arb.fromGen
860+
861+
static member Int16Type() =
862+
arrayAndChunkPosition <| Arb.generate<int16>
863+
|> Arb.fromGen
864+
865+
static member UInt16Type() =
866+
arrayAndChunkPosition <| Arb.generate<uint16>
867+
|> Arb.fromGen
868+
869+
static member Int32Type() =
870+
arrayAndChunkPosition <| Arb.generate<int32>
871+
|> Arb.fromGen
872+
873+
static member UInt32Type() =
874+
arrayAndChunkPosition <| Arb.generate<uint32>
875+
|> Arb.fromGen
876+
877+
static member BoolType() =
878+
arrayAndChunkPosition <| Arb.generate<bool>
879+
|> Arb.fromGen

tests/GraphBLAS-sharp.Tests/GraphBLAS-sharp.Tests.fsproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<Compile Include="Common/ClArray/RemoveDuplicates.fs" />
2525
<Compile Include="Common/ClArray/Copy.fs" />
2626
<Compile Include="Common/ClArray/Replicate.fs" />
27+
<Compile Include="Common\ClArray\chunkBySize.fs" />
2728
<Compile Include="Common/Sort/Bitonic.fs" />
2829
<Compile Include="Common/Sort/Radix.fs" />
2930
<Compile Include="Common/Reduce/Sum.fs" />
@@ -49,6 +50,7 @@
4950
<Compile Include="Matrix/Mxm.fs" />
5051
<Compile Include="Matrix/Transpose.fs" />
5152
<Compile Include="Matrix/Map.fs" />
53+
<Compile Include="Matrix\Split.fs" />
5254
<Compile Include="Program.fs" />
5355
</ItemGroup>
5456
<Import Project="..\..\.paket\Paket.Restore.targets" />

tests/GraphBLAS-sharp.Tests/Helpers.fs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ module Utils =
9999
Actual value is %A{actual.[i]}, expected %A{expected.[i]}, \n actual: %A{actual} \n expected: %A{expected}"
100100
|> failtestf "%s"
101101

102+
let compareChunksArrays areEqual (actual: 'a [][]) (expected: 'a [][]) message =
103+
$"%s{message}. Lengths should be equal. Actual is %A{actual}, expected %A{expected}"
104+
|> Expect.equal actual.Length expected.Length
105+
106+
for i in 0 .. actual.Length - 1 do
107+
compareArrays areEqual actual.[i] expected.[i] message
108+
102109
let compare2DArrays areEqual (actual: 'a [,]) (expected: 'a [,]) message =
103110
$"%s{message}. Lengths should be equal. Actual is %A{actual}, expected %A{expected}"
104111
|> Expect.equal actual.Length expected.Length
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module GraphBLAS.FSharp.Tests.Backend.Matrix.Split
2+
3+
let makeTest testFun =
4+

0 commit comments

Comments
 (0)