summaryrefslogtreecommitdiffstats
path: root/vespajlib
diff options
context:
space:
mode:
Diffstat (limited to 'vespajlib')
-rw-r--r--vespajlib/src/test/java/com/yahoo/tensor/MatrixDotProductBenchmark.java90
-rw-r--r--vespajlib/src/test/java/com/yahoo/tensor/TensorFunctionBenchmark.java18
2 files changed, 99 insertions, 9 deletions
diff --git a/vespajlib/src/test/java/com/yahoo/tensor/MatrixDotProductBenchmark.java b/vespajlib/src/test/java/com/yahoo/tensor/MatrixDotProductBenchmark.java
new file mode 100644
index 00000000000..439aac5578a
--- /dev/null
+++ b/vespajlib/src/test/java/com/yahoo/tensor/MatrixDotProductBenchmark.java
@@ -0,0 +1,90 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.tensor;
+
+import com.yahoo.tensor.evaluation.MapEvaluationContext;
+import com.yahoo.tensor.evaluation.VariableTensor;
+import com.yahoo.tensor.functions.ConstantTensor;
+import com.yahoo.tensor.functions.Join;
+import com.yahoo.tensor.functions.Reduce;
+import com.yahoo.tensor.functions.TensorFunction;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+/**
+ * Microbenchmark of a "dot product" of two mapped rank 2 tensors
+ *
+ * @author bratseth
+ */
+public class MatrixDotProductBenchmark {
+
+ private final static Random random = new Random();
+
+ public double benchmark(int iterations, List<Tensor> modelMatrixes, TensorType.Dimension.Type dimensionType) {
+ Tensor queryMatrix = matrix(1, 20, dimensionType).get(0);
+ dotProduct(queryMatrix, modelMatrixes, Math.max(iterations/10, 10)); // warmup
+ System.gc();
+ long startTime = System.currentTimeMillis();
+ dotProduct(queryMatrix, modelMatrixes, iterations);
+ long totalTime = System.currentTimeMillis() - startTime;
+ return (double)totalTime / (double)iterations;
+ }
+
+ private double dotProduct(Tensor tensor, List<Tensor> tensors, int iterations) {
+ double result = 0;
+ for (int i = 0 ; i < iterations; i++)
+ result = dotProduct(tensor, tensors);
+ return result;
+ }
+
+ private double dotProduct(Tensor tensor, List<Tensor> tensors) {
+ double largest = Double.MIN_VALUE;
+ TensorFunction dotProductFunction = new Reduce(new Join(new ConstantTensor(tensor),
+ new VariableTensor("argument"), (a, b) -> a * b),
+ Reduce.Aggregator.sum).toPrimitive();
+ MapEvaluationContext context = new MapEvaluationContext();
+
+ for (Tensor tensorElement : tensors) { // tensors.size() = 1 for larger tensor
+ context.put("argument", tensorElement);
+ double dotProduct = dotProductFunction.evaluate(context).asDouble();
+ if (dotProduct > largest) {
+ largest = dotProduct;
+ }
+ }
+ return largest;
+ }
+
+ private static List<Tensor> matrix(int dimension1Size, int dimension2Size, TensorType.Dimension.Type dimensionType) {
+ TensorType.Builder typeBuilder = new TensorType.Builder();
+ addDimension(typeBuilder, "i", dimensionType, dimension1Size);
+ addDimension(typeBuilder, "j", dimensionType, dimension2Size);
+ Tensor.Builder builder = Tensor.Builder.of(typeBuilder.build());
+ for (int i = 0; i < dimension1Size; i++) {
+ for (int j = 0; j < dimension2Size; j++) {
+ builder.cell()
+ .label("i", String.valueOf("label" + i))
+ .label("j", String.valueOf("label" + j))
+ .value(random.nextDouble());
+ }
+ }
+ return Collections.singletonList(builder.build());
+ }
+
+ private static void addDimension(TensorType.Builder builder, String name, TensorType.Dimension.Type type, int size) {
+ switch (type) {
+ case mapped: builder.mapped(name); break;
+ case indexedUnbound: builder.indexed(name); break;
+ case indexedBound: builder.indexed(name, size); break;
+ default: throw new IllegalArgumentException("Dimension type " + type + " not supported");
+ }
+ }
+
+ public static void main(String[] args) {
+ double time = new MatrixDotProductBenchmark().benchmark(10000, matrix(10, 55, TensorType.Dimension.Type.mapped), TensorType.Dimension.Type.mapped);
+ System.out.printf("Matrixes, 10*55 size matrixes. Time per sum(join): %1$8.3f ms\n", time);
+ }
+
+}
diff --git a/vespajlib/src/test/java/com/yahoo/tensor/TensorFunctionBenchmark.java b/vespajlib/src/test/java/com/yahoo/tensor/TensorFunctionBenchmark.java
index abdb3071bf7..7b856dde2d5 100644
--- a/vespajlib/src/test/java/com/yahoo/tensor/TensorFunctionBenchmark.java
+++ b/vespajlib/src/test/java/com/yahoo/tensor/TensorFunctionBenchmark.java
@@ -107,26 +107,26 @@ public class TensorFunctionBenchmark {
double time = 0;
// ---------------- Mapped with extra space (sidesteps current special-case optimizations):
- // 9.9 ms
+ // 7.8 ms
time = new TensorFunctionBenchmark().benchmark(1000, vectors(100, 300, TensorType.Dimension.Type.mapped), TensorType.Dimension.Type.mapped, true);
System.out.printf("Mapped vectors, x space time per join: %1$8.3f ms\n", time);
- // 10.5 ms
+ // 7.7 ms
time = new TensorFunctionBenchmark().benchmark(1000, matrix(100, 300, TensorType.Dimension.Type.mapped), TensorType.Dimension.Type.mapped, true);
System.out.printf("Mapped matrix, x space time per join: %1$8.3f ms\n", time);
// ---------------- Mapped:
- // 2.6 ms
+ // 2.1 ms
time = new TensorFunctionBenchmark().benchmark(5000, vectors(100, 300, TensorType.Dimension.Type.mapped), TensorType.Dimension.Type.mapped, false);
System.out.printf("Mapped vectors, time per join: %1$8.3f ms\n", time);
- // 6.8 ms
+ // 7.0 ms
time = new TensorFunctionBenchmark().benchmark(1000, matrix(100, 300, TensorType.Dimension.Type.mapped), TensorType.Dimension.Type.mapped, false);
System.out.printf("Mapped matrix, time per join: %1$8.3f ms\n", time);
// ---------------- Indexed (unbound) with extra space (sidesteps current special-case optimizations):
- // 30 ms
+ // 14.5 ms
time = new TensorFunctionBenchmark().benchmark(500, vectors(100, 300, TensorType.Dimension.Type.indexedUnbound), TensorType.Dimension.Type.indexedUnbound, true);
System.out.printf("Indexed vectors, x space time per join: %1$8.3f ms\n", time);
- // 27 ms
+ // 8.9 ms
time = new TensorFunctionBenchmark().benchmark(500, matrix(100, 300, TensorType.Dimension.Type.indexedUnbound), TensorType.Dimension.Type.indexedUnbound, true);
System.out.printf("Indexed matrix, x space time per join: %1$8.3f ms\n", time);
@@ -134,15 +134,15 @@ public class TensorFunctionBenchmark {
// 0.14 ms
time = new TensorFunctionBenchmark().benchmark(50000, vectors(100, 300, TensorType.Dimension.Type.indexedUnbound), TensorType.Dimension.Type.indexedUnbound, false);
System.out.printf("Indexed unbound vectors, time per join: %1$8.3f ms\n", time);
- // 0.14 ms
+ // 0.44 ms
time = new TensorFunctionBenchmark().benchmark(50000, matrix(100, 300, TensorType.Dimension.Type.indexedUnbound), TensorType.Dimension.Type.indexedUnbound, false);
System.out.printf("Indexed unbound matrix, time per join: %1$8.3f ms\n", time);
// ---------------- Indexed bound:
- // 0.14 ms
+ // 0.32 ms
time = new TensorFunctionBenchmark().benchmark(50000, vectors(100, 300, TensorType.Dimension.Type.indexedBound), TensorType.Dimension.Type.indexedBound, false);
System.out.printf("Indexed bound vectors, time per join: %1$8.3f ms\n", time);
- // 0.14 ms
+ // 0.44 ms
time = new TensorFunctionBenchmark().benchmark(50000, matrix(100, 300, TensorType.Dimension.Type.indexedBound), TensorType.Dimension.Type.indexedBound, false);
System.out.printf("Indexed bound matrix, time per join: %1$8.3f ms\n", time);
}