From 38ed6dd995f9c7c0e6e00d5aeff56964978ec774 Mon Sep 17 00:00:00 2001 From: margarita0303 Date: Tue, 2 Aug 2022 20:59:11 +0300 Subject: [PATCH] added benchmarks with different sizes, added check for accuracy --- .../kscience/kmath/benchmarks/SVDBenchmark.kt | 117 +++++++++++++++++- 1 file changed, 112 insertions(+), 5 deletions(-) diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/SVDBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/SVDBenchmark.kt index 6879960d7..ee581f778 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/SVDBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/SVDBenchmark.kt @@ -8,27 +8,134 @@ import kotlinx.benchmark.Benchmark import kotlinx.benchmark.Blackhole import kotlinx.benchmark.Scope import kotlinx.benchmark.State +import org.ejml.UtilEjml.assertTrue +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.diagonalEmbedding +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.eq import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.svdGolubKahan +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.transpose import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.svdPowerMethod @State(Scope.Benchmark) class SVDBenchmark { companion object { - val tensor = DoubleTensorAlgebra.randomNormal(intArrayOf(10, 10, 10), 0) + val tensorSmall = DoubleTensorAlgebra.randomNormal(intArrayOf(5, 5), 0) + val tensorMedium = DoubleTensorAlgebra.randomNormal(intArrayOf(10, 10), 0) + val tensorLarge = DoubleTensorAlgebra.randomNormal(intArrayOf(50, 50), 0) + val tensorVeryLarge = DoubleTensorAlgebra.randomNormal(intArrayOf(100, 100), 0) + val epsilon = 1e-9 } @Benchmark - fun svdPowerMethod(blackhole: Blackhole) { + fun svdPowerMethodSmall(blackhole: Blackhole) { + val svd = tensorSmall.svdPowerMethod() + val tensorSVD = svd.first + .dot( + diagonalEmbedding(svd.second) + .dot(svd.third.transpose()) + ) + assertTrue(tensorSVD.eq(tensorSmall, epsilon)) blackhole.consume( - tensor.svdPowerMethod() + tensorSmall.svdPowerMethod() ) } @Benchmark - fun svdGolubKahan(blackhole: Blackhole) { + fun svdPowerMethodMedium(blackhole: Blackhole) { + val svd = tensorMedium.svdPowerMethod() + val tensorSVD = svd.first + .dot( + diagonalEmbedding(svd.second) + .dot(svd.third.transpose()) + ) + assertTrue(tensorSVD.eq(tensorMedium, epsilon)) blackhole.consume( - tensor.svdGolubKahan() + tensorMedium.svdPowerMethod() + ) + } + + @Benchmark + fun svdPowerMethodLarge(blackhole: Blackhole) { + val svd = tensorLarge.svdPowerMethod() + val tensorSVD = svd.first + .dot( + diagonalEmbedding(svd.second) + .dot(svd.third.transpose()) + ) + assertTrue(tensorSVD.eq(tensorLarge, epsilon)) + blackhole.consume( + tensorLarge.svdPowerMethod() + ) + } + + @Benchmark + fun svdPowerMethodVeryLarge(blackhole: Blackhole) { + val svd = tensorVeryLarge.svdPowerMethod() + val tensorSVD = svd.first + .dot( + diagonalEmbedding(svd.second) + .dot(svd.third.transpose()) + ) + assertTrue(tensorSVD.eq(tensorVeryLarge, epsilon)) + blackhole.consume( + tensorVeryLarge.svdPowerMethod() + ) + } + + @Benchmark + fun svdGolubKahanSmall(blackhole: Blackhole) { + val svd = tensorSmall.svdGolubKahan() + val tensorSVD = svd.first + .dot( + diagonalEmbedding(svd.second) + .dot(svd.third.transpose()) + ) + assertTrue(tensorSVD.eq(tensorSmall, epsilon)) + blackhole.consume( + tensorSmall.svdGolubKahan() + ) + } + + @Benchmark + fun svdGolubKahanMedium(blackhole: Blackhole) { + val svd = tensorMedium.svdGolubKahan() + val tensorSVD = svd.first + .dot( + diagonalEmbedding(svd.second) + .dot(svd.third.transpose()) + ) + assertTrue(tensorSVD.eq(tensorMedium, epsilon)) + blackhole.consume( + tensorMedium.svdGolubKahan() + ) + } + + @Benchmark + fun svdGolubKahanLarge(blackhole: Blackhole) { + val svd = tensorLarge.svdGolubKahan() + val tensorSVD = svd.first + .dot( + diagonalEmbedding(svd.second) + .dot(svd.third.transpose()) + ) + assertTrue(tensorSVD.eq(tensorLarge, epsilon)) + blackhole.consume( + tensorLarge.svdGolubKahan() + ) + } + + @Benchmark + fun svdGolubKahanVeryLarge(blackhole: Blackhole) { + val svd = tensorVeryLarge.svdGolubKahan() + val tensorSVD = svd.first + .dot( + diagonalEmbedding(svd.second) + .dot(svd.third.transpose()) + ) + assertTrue(tensorSVD.eq(tensorVeryLarge, epsilon)) + blackhole.consume( + tensorVeryLarge.svdGolubKahan() ) } } \ No newline at end of file