From 89c0d863d2ddc7ae71f60c7b6d4b28cb30b7a660 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 29 Nov 2020 22:26:05 +0300 Subject: [PATCH] Benchmark refactoring --- examples/build.gradle.kts | 2 +- .../ArrayBenchmark.kt | 2 +- .../BufferBenchmark.kt | 4 +- .../benchmarks/LinearAlgebraBenchmark.kt | 50 ++++++++++++++++++ .../MultiplicationBenchmark.kt | 13 ++++- .../NDFieldBenchmark.kt | 3 +- .../ViktorBenchmark.kt | 7 ++- .../kotlin/kscience/kmath/utils/utils.kt | 11 ---- .../kmath/linear/LinearAlgebraBenchmark.kt | 52 ------------------- .../kscience/kmath/linear/FeaturedMatrix.kt | 2 +- 10 files changed, 74 insertions(+), 72 deletions(-) rename examples/src/benchmarks/kotlin/kscience/kmath/{structures => benchmarks}/ArrayBenchmark.kt (96%) rename examples/src/benchmarks/kotlin/kscience/kmath/{structures => benchmarks}/BufferBenchmark.kt (85%) create mode 100644 examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/LinearAlgebraBenchmark.kt rename examples/src/benchmarks/kotlin/kscience/kmath/{structures => benchmarks}/MultiplicationBenchmark.kt (81%) rename examples/src/benchmarks/kotlin/kscience/kmath/{structures => benchmarks}/NDFieldBenchmark.kt (94%) rename examples/src/benchmarks/kotlin/kscience/kmath/{structures => benchmarks}/ViktorBenchmark.kt (86%) delete mode 100644 examples/src/benchmarks/kotlin/kscience/kmath/utils/utils.kt delete mode 100644 examples/src/main/kotlin/kscience/kmath/linear/LinearAlgebraBenchmark.kt diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index eead68a9d..c079eaa84 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -69,7 +69,7 @@ benchmark { // This one matches sourceSet name above configurations.register("fast") { - warmups = 5 // number of warmup iterations + warmups = 1 // number of warmup iterations iterations = 3 // number of iterations iterationTime = 500 // time in seconds per iteration iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/ArrayBenchmark.kt similarity index 96% rename from examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt rename to examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/ArrayBenchmark.kt index a91d02253..8c44135fb 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/ArrayBenchmark.kt @@ -1,4 +1,4 @@ -package kscience.kmath.structures +package kscience.kmath.benchmarks import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Scope diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/BufferBenchmark.kt similarity index 85% rename from examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt rename to examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/BufferBenchmark.kt index 8b6fd4a51..4c64517f1 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/BufferBenchmark.kt @@ -1,7 +1,9 @@ -package kscience.kmath.structures +package kscience.kmath.benchmarks import kscience.kmath.operations.Complex import kscience.kmath.operations.complex +import kscience.kmath.structures.MutableBuffer +import kscience.kmath.structures.RealBuffer import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.State diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/LinearAlgebraBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/LinearAlgebraBenchmark.kt new file mode 100644 index 000000000..0ac6ea5f0 --- /dev/null +++ b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/LinearAlgebraBenchmark.kt @@ -0,0 +1,50 @@ +package kscience.kmath.linear + + +import kotlinx.benchmark.Benchmark +import kscience.kmath.commons.linear.CMMatrixContext +import kscience.kmath.commons.linear.CMMatrixContext.dot +import kscience.kmath.commons.linear.inverse +import kscience.kmath.commons.linear.toCM +import kscience.kmath.ejml.EjmlMatrixContext +import kscience.kmath.ejml.inverse +import kscience.kmath.ejml.toEjml +import kscience.kmath.operations.invoke +import kscience.kmath.structures.Matrix +import org.openjdk.jmh.annotations.Scope +import org.openjdk.jmh.annotations.State +import kotlin.random.Random + +@State(Scope.Benchmark) +class LinearAlgebraBenchmark { + companion object { + val random = Random(1224) + val dim = 100 + + //creating invertible matrix + val u = Matrix.real(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } + val l = Matrix.real(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 } + val matrix = l dot u + } + + @Benchmark + fun kmathLUPInversion() { + MatrixContext.real.inverse(matrix) + } + + @Benchmark + fun cmLUPInversion() { + CMMatrixContext { + val cm = matrix.toCM() //avoid overhead on conversion + inverse(cm) + } + } + + @Benchmark + fun ejmlInverse() { + EjmlMatrixContext { + val km = matrix.toEjml() //avoid overhead on conversion + inverse(km) + } + } +} \ No newline at end of file diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/MultiplicationBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/MultiplicationBenchmark.kt similarity index 81% rename from examples/src/benchmarks/kotlin/kscience/kmath/structures/MultiplicationBenchmark.kt rename to examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/MultiplicationBenchmark.kt index 3c2c12c0b..9d2b02245 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/MultiplicationBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/MultiplicationBenchmark.kt @@ -1,4 +1,4 @@ -package kscience.kmath.structures +package kscience.kmath.benchmarks import kotlinx.benchmark.Benchmark import kscience.kmath.commons.linear.CMMatrixContext @@ -7,8 +7,8 @@ import kscience.kmath.commons.linear.toCM import kscience.kmath.ejml.EjmlMatrixContext import kscience.kmath.ejml.toEjml import kscience.kmath.linear.real -import kscience.kmath.operations.RealField import kscience.kmath.operations.invoke +import kscience.kmath.structures.Matrix import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.State import kotlin.random.Random @@ -44,6 +44,15 @@ class MultiplicationBenchmark { } } + @Benchmark + fun ejmlMultiplicationwithConversion() { + val ejmlMatrix1 = matrix1.toEjml() + val ejmlMatrix2 = matrix2.toEjml() + EjmlMatrixContext.invoke { + ejmlMatrix1 dot ejmlMatrix2 + } + } + @Benchmark fun bufferedMultiplication() { matrix1 dot matrix2 diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/NDFieldBenchmark.kt similarity index 94% rename from examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt rename to examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/NDFieldBenchmark.kt index 8ec47ae81..1be8e7236 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/NDFieldBenchmark.kt @@ -1,7 +1,8 @@ -package kscience.kmath.structures +package kscience.kmath.benchmarks import kscience.kmath.operations.RealField import kscience.kmath.operations.invoke +import kscience.kmath.structures.* import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.State diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/ViktorBenchmark.kt similarity index 86% rename from examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt rename to examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/ViktorBenchmark.kt index 464925ca0..8663e353c 100644 --- a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt +++ b/examples/src/benchmarks/kotlin/kscience/kmath/benchmarks/ViktorBenchmark.kt @@ -1,7 +1,10 @@ -package kscience.kmath.structures +package kscience.kmath.benchmarks import kscience.kmath.operations.RealField import kscience.kmath.operations.invoke +import kscience.kmath.structures.BufferedNDField +import kscience.kmath.structures.NDField +import kscience.kmath.structures.RealNDField import kscience.kmath.viktor.ViktorNDField import org.jetbrains.bio.viktor.F64Array import org.openjdk.jmh.annotations.Benchmark @@ -36,7 +39,7 @@ internal class ViktorBenchmark { @Benchmark fun rawViktor() { - val one = F64Array.full(init = 1.0, shape = *intArrayOf(dim, dim)) + val one = F64Array.full(init = 1.0, shape = intArrayOf(dim, dim)) var res = one repeat(n) { res = res + one } } diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/utils/utils.kt b/examples/src/benchmarks/kotlin/kscience/kmath/utils/utils.kt deleted file mode 100644 index 329b7b17b..000000000 --- a/examples/src/benchmarks/kotlin/kscience/kmath/utils/utils.kt +++ /dev/null @@ -1,11 +0,0 @@ -package kscience.kmath.utils - -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract -import kotlin.system.measureTimeMillis - -internal inline fun measureAndPrint(title: String, block: () -> Unit) { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - val time = measureTimeMillis(block) - println("$title completed in $time millis") -} diff --git a/examples/src/main/kotlin/kscience/kmath/linear/LinearAlgebraBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/linear/LinearAlgebraBenchmark.kt deleted file mode 100644 index 5b1fc9bc7..000000000 --- a/examples/src/main/kotlin/kscience/kmath/linear/LinearAlgebraBenchmark.kt +++ /dev/null @@ -1,52 +0,0 @@ -package kscience.kmath.linear - -import kscience.kmath.commons.linear.CMMatrixContext -import kscience.kmath.commons.linear.CMMatrixContext.dot -import kscience.kmath.commons.linear.inverse -import kscience.kmath.commons.linear.toCM -import kscience.kmath.ejml.EjmlMatrixContext -import kscience.kmath.ejml.inverse -import kscience.kmath.ejml.toEjml -import kscience.kmath.operations.RealField -import kscience.kmath.operations.invoke -import kscience.kmath.structures.Matrix -import kotlin.random.Random -import kotlin.system.measureTimeMillis - -fun main() { - val random = Random(1224) - val dim = 100 - //creating invertible matrix - val u = Matrix.real(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } - val l = Matrix.real(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 } - val matrix = l dot u - - val n = 5000 // iterations - - MatrixContext.real { - repeat(50) { inverse(matrix) } - val inverseTime = measureTimeMillis { repeat(n) { inverse(matrix) } } - println("[kmath] Inversion of $n matrices $dim x $dim finished in $inverseTime millis") - } - - //commons-math - - val commonsTime = measureTimeMillis { - CMMatrixContext { - val cm = matrix.toCM() //avoid overhead on conversion - repeat(n) { inverse(cm) } - } - } - - - println("[commons-math] Inversion of $n matrices $dim x $dim finished in $commonsTime millis") - - val ejmlTime = measureTimeMillis { - EjmlMatrixContext { - val km = matrix.toEjml() //avoid overhead on conversion - repeat(n) { inverse(km) } - } - } - - println("[ejml] Inversion of $n matrices $dim x $dim finished in $ejmlTime millis") -} diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt index 003741979..350379717 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt @@ -80,4 +80,4 @@ public fun Matrix.transpose(): Matrix { rowNum, setOf(TransposedFeature(this)) ) { i, j -> get(j, i) } -} +} \ No newline at end of file