Skip to content

Commit c0d5141

Browse files
committed
Parallel and sequential CPU versions for benchmarking
1 parent be4d4c4 commit c0d5141

2 files changed

Lines changed: 116 additions & 101 deletions

File tree

src/MatrixMultiplication/Main.fs

Lines changed: 110 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ type ImageProcessingArguments =
3535
| Semiring _ -> "Semiring to operate with matrices."
3636

3737
module Main =
38-
let optZero = <@None@>
38+
let optIntZero = <@None@>
39+
3940
[<EntryPoint>]
4041
let main (argv: string array) =
4142
let parser = ArgumentParser.Create<ImageProcessingArguments>(programName = "MatrixMultiplication")
@@ -50,18 +51,25 @@ module Main =
5051
let semiring = results.GetResult(Semiring, defaultValue = Semirings.Arithmetic)
5152

5253

53-
let bench mXm checker m1 m2 =
54+
let time mXm checker m1 m2 =
5455
let start = System.DateTime.Now
5556
let res = mXm m1 m2
5657
printfn $"Processing time: {(System.DateTime.Now - start).TotalMilliseconds} ms"
5758
if check then checker res
5859

59-
let benchCpu () =
60-
let mXm = Matrices.cpuParallelMxM
61-
let checker = 1
62-
()
60+
let cpuParallelKernel (opAdd:Quotations.Expr<_>) (opMult:Quotations.Expr<_>) zero =
61+
Matrices.cpuParallelMxM
62+
(opAdd.Compile())
63+
(opMult.Compile())
64+
(FSharp.Quotations.Evaluator.QuotationEvaluator.Evaluate zero)
65+
66+
let cpuKernel (opAdd:Quotations.Expr<_>) (opMult:Quotations.Expr<_>) zero =
67+
Matrices.cpuMxM
68+
(opAdd.Compile())
69+
(opMult.Compile())
70+
(FSharp.Quotations.Evaluator.QuotationEvaluator.Evaluate zero)
6371

64-
let benchGpu () =
72+
let gpuKernel opAdd opMult zero =
6573

6674
let device =
6775
match platform with
@@ -78,95 +86,100 @@ module Main =
7886

7987
let context = ClContext(device)
8088

81-
let inline mXmKernel opAdd opMult zero = Matrices.applyMultiplyGPU kernel context workGroupSize workPerThread opAdd opMult zero
89+
Matrices.applyMultiplyGPU kernel context workGroupSize workPerThread opAdd opMult zero
90+
91+
let inline mXmKernel opAdd opMult zero =
92+
match platform with
93+
| Platforms.CPUParallel -> cpuParallelKernel opAdd opMult zero
94+
| Platforms.CPU -> cpuKernel opAdd opMult zero
95+
| _ -> gpuKernel opAdd opMult zero
96+
97+
match matrixType with
98+
| MatrixTypes.MT_byte ->
99+
let m1 = Matrices.getRandomByteMatrix matrixSize
100+
let m2 = Matrices.getRandomByteMatrix matrixSize
101+
let mXm, checker =
102+
match semiring with
103+
| Semirings.Arithmetic ->
104+
mXmKernel <@(+)@> <@( * )@> <@0uy@>
105+
, Matrices.check (+) ( * ) 0uy m1 m2
106+
| Semirings.MinPlus ->
107+
mXmKernel <@min@> <@(+)@> <@255uy@>
108+
, Matrices.check min (+) 255uy m1 m2
109+
| x -> failwithf $"Unexpected semiring {x}."
82110

83-
match matrixType with
84-
| MatrixTypes.MT_byte ->
85-
let m1 = Matrices.getRandomByteMatrix matrixSize
86-
let m2 = Matrices.getRandomByteMatrix matrixSize
87-
let mXm, checker =
88-
match semiring with
89-
| Semirings.Arithmetic ->
90-
mXmKernel <@(+)@> <@( * )@> <@0uy@>
91-
, Matrices.check (+) ( * ) 0uy m1 m2
92-
| Semirings.MinPlus ->
93-
mXmKernel <@min@> <@(+)@> <@255uy@>
94-
, Matrices.check min (+) 255uy m1 m2
95-
| x -> failwithf $"Unexpected semiring {x}."
96-
97-
bench mXm checker m1 m2
98-
99-
| MatrixTypes.MT_int ->
100-
let m1 = Matrices.getRandomIntMatrix matrixSize
101-
let m2 = Matrices.getRandomIntMatrix matrixSize
102-
let mXm, checker =
103-
match semiring with
104-
| Semirings.Arithmetic ->
105-
mXmKernel <@(+)@> <@( * )@> <@0@>
106-
, Matrices.check (+) ( * ) 0 m1 m2
107-
| Semirings.MinPlus ->
108-
mXmKernel <@min@> <@(+)@> <@System.Int32.MaxValue@>
109-
, Matrices.check min (+) System.Int32.MaxValue m1 m2
110-
| x -> failwithf $"Unexpected semiring {x}."
111-
112-
bench mXm checker m1 m2
113-
114-
| MatrixTypes.MT_OptInt ->
115-
let m1 = Matrices.getRandomOptionIntMatrix matrixSize
116-
let m2 = Matrices.getRandomOptionIntMatrix matrixSize
117-
let mXm, checker =
118-
match semiring with
119-
| Semirings.Arithmetic ->
120-
let opAdd =
121-
<@fun a b ->
122-
match a, b with
123-
| Some x, Some y -> Some (x + y)
124-
| _ -> None
125-
@>
126-
let opMult =
127-
<@fun a b ->
128-
match a, b with
129-
| Some x, Some y -> Some (x * y)
130-
| _ -> None
131-
@>
132-
mXmKernel opAdd opMult optZero
133-
, Matrices.check (opAdd.Compile()) (opMult.Compile()) None m1 m2
134-
| Semirings.MinPlus ->
135-
let opAdd =
136-
<@fun a b ->
137-
match a, b with
138-
| Some x, Some y -> Some (min x y)
139-
| None, Some x
140-
| Some x, None -> Some x
141-
| None, None -> None
142-
@>
143-
let opMult =
144-
<@fun a b ->
145-
match a, b with
146-
| Some x, Some y -> Some (x + y)
147-
| _ -> None
148-
@>
149-
mXmKernel opAdd opMult optZero
150-
, Matrices.check (opAdd.Compile()) (opMult.Compile()) None m1 m2
151-
| x -> failwithf $"Unexpected semiring {x}."
152-
153-
bench mXm checker m1 m2
154-
155-
| MatrixTypes.MT_float32 ->
156-
let m1 = Matrices.getRandomFloat32Matrix matrixSize
157-
let m2 = Matrices.getRandomFloat32Matrix matrixSize
158-
let mXm, checker =
159-
match semiring with
160-
| Semirings.Arithmetic ->
161-
mXmKernel <@(+)@> <@( * )@> <@0f@>
162-
, Matrices.check (+) ( * ) 0f m1 m2
163-
| Semirings.MinPlus ->
164-
mXmKernel <@min@> <@(+)@> <@System.Single.MaxValue@>
165-
, Matrices.check min (+) System.Single.PositiveInfinity m1 m2
166-
| x -> failwithf $"Unexpected semiring {x}."
167-
168-
bench mXm checker m1 m2
169-
170-
benchGpu()
171-
111+
time mXm checker m1 m2
112+
113+
| MatrixTypes.MT_int ->
114+
let m1 = Matrices.getRandomIntMatrix matrixSize
115+
let m2 = Matrices.getRandomIntMatrix matrixSize
116+
let mXm, checker =
117+
match semiring with
118+
| Semirings.Arithmetic ->
119+
mXmKernel <@(+)@> <@( * )@> <@0@>
120+
, Matrices.check (+) ( * ) 0 m1 m2
121+
| Semirings.MinPlus ->
122+
mXmKernel <@min@> <@(+)@> <@System.Int32.MaxValue@>
123+
, Matrices.check min (+) System.Int32.MaxValue m1 m2
124+
| x -> failwithf $"Unexpected semiring {x}."
125+
126+
time mXm checker m1 m2
127+
128+
| MatrixTypes.MT_OptInt ->
129+
let m1 = Matrices.getRandomOptionIntMatrix matrixSize
130+
let m2 = Matrices.getRandomOptionIntMatrix matrixSize
131+
let mXm, checker =
132+
match semiring with
133+
| Semirings.Arithmetic ->
134+
let opAdd =
135+
<@fun a b ->
136+
match a, b with
137+
| Some x, Some y -> Some (x + y)
138+
| _ -> None
139+
@>
140+
let opMult =
141+
<@fun a b ->
142+
match a, b with
143+
| Some x, Some y -> Some (x * y)
144+
| _ -> None
145+
@>
146+
mXmKernel opAdd opMult optIntZero
147+
, Matrices.check (opAdd.Compile()) (opMult.Compile()) None m1 m2
148+
| Semirings.MinPlus ->
149+
let opAdd =
150+
<@fun a b ->
151+
match a, b with
152+
| Some x, Some y -> Some (min x y)
153+
| None, Some x
154+
| Some x, None -> Some x
155+
| None, None -> None
156+
@>
157+
let opMult =
158+
<@fun a b ->
159+
match a, b with
160+
| Some x, Some y -> Some (x + y)
161+
| _ -> None
162+
@>
163+
mXmKernel opAdd opMult optIntZero
164+
, Matrices.check (opAdd.Compile()) (opMult.Compile()) None m1 m2
165+
| x -> failwithf $"Unexpected semiring {x}."
166+
167+
time mXm checker m1 m2
168+
169+
| MatrixTypes.MT_float32 ->
170+
let m1 = Matrices.getRandomFloat32Matrix matrixSize
171+
let m2 = Matrices.getRandomFloat32Matrix matrixSize
172+
let mXm, checker =
173+
match semiring with
174+
| Semirings.Arithmetic ->
175+
mXmKernel <@(+)@> <@( * )@> <@0f@>
176+
, Matrices.check (+) ( * ) 0f m1 m2
177+
| Semirings.MinPlus ->
178+
mXmKernel <@min@> <@(+)@> <@System.Single.MaxValue@>
179+
, Matrices.check min (+) System.Single.PositiveInfinity m1 m2
180+
| x -> failwithf $"Unexpected semiring {x}."
181+
182+
time mXm checker m1 m2
183+
184+
172185
0

src/MatrixMultiplication/Matrices.fs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,13 @@ let getRandomMatrix (n: uint) init =
1111
for i in 0 .. int n - 1 -> Array.init (int n) init
1212
|]
1313

14-
let check opAdd opMult zero (m1 : array<array<_>>) (m2: array<array<_>>) (m3:array<_>) =
14+
let cpuMxM opAdd opMult zero (m1 : array<array<_>>) (m2: array<array<_>>) =
1515
let res = Array.init (m1.Length * m1.Length) (fun _ -> zero)
1616
for i in 0..m1.Length - 1 do
1717
for j in 0..m1.Length - 1 do
1818
for k in 0..m1.Length - 1 do
1919
res.[i*m1.Length + j] <- opAdd res.[i * m1.Length + j] (opMult m1.[i].[k] m2.[k].[j])
20-
21-
Array.iteri2 (fun i r1 r2 -> if r1 <> r2 then printfn $"Expected {r1}, got {r2}") res m3
22-
20+
res
2321

2422
let cpuParallelMxM opAdd opMult zero (m1 : array<array<_>>) (m2: array<array<_>>) =
2523
let res = Array.init (m1.Length * m1.Length) (fun _ -> zero)
@@ -31,6 +29,10 @@ let cpuParallelMxM opAdd opMult zero (m1 : array<array<_>>) (m2: array<array<_>>
3129
)
3230
res
3331

32+
let check opAdd opMult zero (m1 : array<array<_>>) (m2: array<array<_>>) (m3:array<_>) =
33+
let res = cpuMxM opAdd opMult zero (m1 : array<array<_>>) (m2: array<array<_>>)
34+
Array.iteri2 (fun i r1 r2 -> if r1 <> r2 then printfn $"Expected {r1}, got {r2}") res m3
35+
3436

3537
let getRandomIntMatrix n = getRandomMatrix n (fun i -> rand.Next(-10,10))
3638
let getRandomByteMatrix n = getRandomMatrix n (fun i -> rand.Next() |> byte)

0 commit comments

Comments
 (0)