From a7209cf3f8f11e916d70c4eb5db0bf13f181ef1f Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Thu, 22 Dec 2016 13:55:10 +0100 Subject: Add tensor generate functions --- .../src/test/derived/tensor/rank-profiles.cfg | 28 ++++++++++++++++++++++ config-model/src/test/derived/tensor/tensor.sd | 18 ++++++++++++++ .../derived/ExportingTestCase.java | 2 +- .../rankingexpression/rule/CompositeNode.java | 2 +- .../rankingexpression/rule/TensorFunctionNode.java | 18 +++++++++++--- .../evaluation/EvaluationTestCase.java | 2 ++ .../main/java/com/yahoo/tensor/functions/Diag.java | 2 +- .../java/com/yahoo/tensor/functions/Random.java | 2 +- .../java/com/yahoo/tensor/functions/Range.java | 2 +- .../yahoo/tensor/functions/ScalarFunctions.java | 2 +- .../com/yahoo/tensor/functions/TensorFunction.java | 2 +- .../test/java/com/yahoo/tensor/TensorTestCase.java | 4 ++-- 12 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 config-model/src/test/derived/tensor/rank-profiles.cfg diff --git a/config-model/src/test/derived/tensor/rank-profiles.cfg b/config-model/src/test/derived/tensor/rank-profiles.cfg new file mode 100644 index 00000000000..d70555c9131 --- /dev/null +++ b/config-model/src/test/derived/tensor/rank-profiles.cfg @@ -0,0 +1,28 @@ +rankprofile[].name "default" +rankprofile[].fef.property[].name "vespa.type.attribute.f4" +rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].name "unranked" +rankprofile[].fef.property[].name "vespa.rank.firstphase" +rankprofile[].fef.property[].value "value(0)" +rankprofile[].fef.property[].name "vespa.hitcollector.heapsize" +rankprofile[].fef.property[].value "0" +rankprofile[].fef.property[].name "vespa.hitcollector.arraysize" +rankprofile[].fef.property[].value "0" +rankprofile[].fef.property[].name "vespa.dump.ignoredefaultfeatures" +rankprofile[].fef.property[].value "true" +rankprofile[].fef.property[].name "vespa.type.attribute.f4" +rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].name "profile1" +rankprofile[].fef.property[].name "vespa.rank.firstphase" +rankprofile[].fef.property[].value "rankingExpression(firstphase)" +rankprofile[].fef.property[].name "rankingExpression(firstphase).rankingScript" +rankprofile[].fef.property[].value "map(attribute(f4), f(x)(x * x)) + reduce(tensor(x[2],y[3])(random), count) * rename(attribute(f4), (x, y), (y, x))" +rankprofile[].fef.property[].name "vespa.type.attribute.f4" +rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].name "profile2" +rankprofile[].fef.property[].name "vespa.rank.firstphase" +rankprofile[].fef.property[].value "rankingExpression(firstphase)" +rankprofile[].fef.property[].name "rankingExpression(firstphase).rankingScript" +rankprofile[].fef.property[].value "reduce(join(attribute(f4), tensor(x[2],y[2],z[3])((x==y)*(y==z)), f(a,b)(a * b)), sum, x)" +rankprofile[].fef.property[].name "vespa.type.attribute.f4" +rankprofile[].fef.property[].value "tensor(x[10],y[20])" diff --git a/config-model/src/test/derived/tensor/tensor.sd b/config-model/src/test/derived/tensor/tensor.sd index b89b96e253b..fab4cafddab 100644 --- a/config-model/src/test/derived/tensor/tensor.sd +++ b/config-model/src/test/derived/tensor/tensor.sd @@ -1,5 +1,6 @@ # Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. search tensor { + document tensor { field f1 type tensor { indexing: summary @@ -15,4 +16,21 @@ search tensor { attribute: tensor(x[10],y[20]) } } + + rank-profile profile1 { + + first-phase { + expression: map(attribute(f4),f(x)(x*x)) + reduce(random(x[2],y[3]), count) * rename(attribute(f4), (x, y), (y, x)) + } + + } + + rank-profile profile2 { + + first-phase { + expression: matmul(attribute(f4), diag(x[2],y[2],z[3]), x) + } + + } + } diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java index c93e07d57c1..635d9684dc9 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java @@ -135,7 +135,7 @@ public class ExportingTestCase extends AbstractExportingTestCase { } @Test - public void testTensorField() throws IOException, ParseException { + public void testTensor() throws IOException, ParseException { assertCorrectDeriving("tensor"); } diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/CompositeNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/CompositeNode.java index d181c29b516..43658fcfa59 100644 --- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/CompositeNode.java +++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/CompositeNode.java @@ -4,7 +4,7 @@ package com.yahoo.searchlib.rankingexpression.rule; import java.util.List; /** - *

The parent of all node types which contains child nodes.

+ * The parent of all node types which contains child nodes. * * @author bratseth */ diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java index 15ad6ba647a..1947b00ac16 100644 --- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java +++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/TensorFunctionNode.java @@ -46,7 +46,7 @@ public class TensorFunctionNode extends CompositeNode { } @Override - public String toString(SerializationContext context, Deque path, CompositeNode parent) { + public String toString(SerializationContext context, Deque path, CompositeNode parent) { // Serialize as primitive return function.toPrimitive().toString(new ExpressionNodeToStringContext(context, path, this)); } @@ -104,10 +104,20 @@ public class TensorFunctionNode extends CompositeNode { return ((TensorValue)result).asTensor(); } + @Override + public String toString() { + return toString(ExpressionNodeToStringContext.empty); + } + @Override public String toString(ToStringContext c) { - ExpressionNodeToStringContext context = (ExpressionNodeToStringContext)c; - return expression.toString(context.context, context.path, context.parent); + if (c instanceof ExpressionNodeToStringContext) { + ExpressionNodeToStringContext context = (ExpressionNodeToStringContext) c; + return expression.toString(context.context, context.path, context.parent); + } + else { + return expression.toString(); + } } } @@ -119,6 +129,8 @@ public class TensorFunctionNode extends CompositeNode { final Deque path; final CompositeNode parent; + public static final ExpressionNodeToStringContext empty = new ExpressionNodeToStringContext(null, null, null); + public ExpressionNodeToStringContext(SerializationContext context, Deque path, CompositeNode parent) { this.context = context; this.path = path; diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java index dc451b1dc5c..26d19bcec37 100644 --- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java +++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java @@ -250,6 +250,8 @@ public class EvaluationTestCase { tester.assertEvaluates("{ {x:0,y:0}:81.0, {x:1,y:0}:88.0 }", "xw_plus_b(tensor0, tensor1, tensor2, x)", "{ {x:0}:15, {x:1}:12 }", "{ {y:0}:3 }", "{ {x:0}:0, {x:1}:7 }"); // expressions combining functions + tester.assertEvaluates("tensor(y{}):{{y:6}:0}}", "matmul(tensor0, diag(x[5],y[7]), x)", "tensor(x{},y{}):{{x:4,y:6}:1})"); + tester.assertEvaluates("tensor(y{}):{{y:6}:10}}", "matmul(tensor0, range(x[5],y[7]), x)", "tensor(x{},y{}):{{x:4,y:6}:1})"); tester.assertEvaluates(String.valueOf(7.5 + 45 + 1.7), "sum( " + // model computation: " tensor0 * tensor1 * tensor2 " + // - feature combinations diff --git a/vespajlib/src/main/java/com/yahoo/tensor/functions/Diag.java b/vespajlib/src/main/java/com/yahoo/tensor/functions/Diag.java index d22619de58d..007baa4fa70 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/functions/Diag.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/functions/Diag.java @@ -34,7 +34,7 @@ public class Diag extends CompositeTensorFunction { @Override public TensorFunction replaceArguments(List arguments) { - if ( arguments.size() != 1) + if ( arguments.size() != 0) throw new IllegalArgumentException("Diag must have 0 arguments, got " + arguments.size()); return this; } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/functions/Random.java b/vespajlib/src/main/java/com/yahoo/tensor/functions/Random.java index ba34c0d9748..5903ca7c8b8 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/functions/Random.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/functions/Random.java @@ -31,7 +31,7 @@ public class Random extends CompositeTensorFunction { @Override public TensorFunction replaceArguments(List arguments) { - if ( arguments.size() != 1) + if ( arguments.size() != 0) throw new IllegalArgumentException("Random must have 0 arguments, got " + arguments.size()); return this; } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/functions/Range.java b/vespajlib/src/main/java/com/yahoo/tensor/functions/Range.java index e18edd48127..7565cd5b44a 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/functions/Range.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/functions/Range.java @@ -29,7 +29,7 @@ public class Range extends CompositeTensorFunction { @Override public TensorFunction replaceArguments(List arguments) { - if ( arguments.size() != 1) + if ( arguments.size() != 0) throw new IllegalArgumentException("Range must have 0 arguments, got " + arguments.size()); return this; } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/functions/ScalarFunctions.java b/vespajlib/src/main/java/com/yahoo/tensor/functions/ScalarFunctions.java index eb21cdf6bfc..801baab0b46 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/functions/ScalarFunctions.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/functions/ScalarFunctions.java @@ -102,7 +102,7 @@ public class ScalarFunctions { } @Override - public String toString() { return "random()"; } + public String toString() { return "random"; } } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/functions/TensorFunction.java b/vespajlib/src/main/java/com/yahoo/tensor/functions/TensorFunction.java index 02a300fabdd..39b677e22ff 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/functions/TensorFunction.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/functions/TensorFunction.java @@ -53,6 +53,6 @@ public abstract class TensorFunction { public abstract String toString(ToStringContext context); @Override - public final String toString() { return toString(ToStringContext.empty()); } + public String toString() { return toString(ToStringContext.empty()); } } diff --git a/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java b/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java index ba50a68f1f2..e973fe00238 100644 --- a/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java @@ -78,10 +78,10 @@ public class TensorTestCase { (List indexes) -> (double)indexes.get(0)*indexes.get(1))); assertEquals(Tensor.from("{ {x:0,y:0,z:0}:0, {x:0,y:1,z:0}:1, {x:1,y:0,z:0}:1, {x:1,y:1,z:0}:2, {x:2,y:0,z:0}:2, {x:2,y:1,z:0}:3, "+ " {x:0,y:0,z:1}:1, {x:0,y:1,z:1}:2, {x:1,y:0,z:1}:2, {x:1,y:1,z:1}:3, {x:2,y:0,z:1}:3, {x:2,y:1,z:1}:4 }"), - Tensor.range(new TensorType.Builder().indexed("x", 3).indexed("y", 2).indexed("y", 2).build())); + Tensor.range(new TensorType.Builder().indexed("x", 3).indexed("y", 2).indexed("z", 2).build())); assertEquals(Tensor.from("{ {x:0,y:0,z:0}:1, {x:0,y:1,z:0}:0, {x:1,y:0,z:0}:0, {x:1,y:1,z:0}:0, {x:2,y:0,z:0}:0, {x:2,y:1,z:0}:0, "+ " {x:0,y:0,z:1}:0, {x:0,y:1,z:1}:0, {x:1,y:0,z:1}:0, {x:1,y:1,z:1}:1, {x:2,y:0,z:1}:0, {x:2,y:1,z:1}:00 }"), - Tensor.diag(new TensorType.Builder().indexed("x", 3).indexed("y", 2).indexed("y", 2).build())); + Tensor.diag(new TensorType.Builder().indexed("x", 3).indexed("y", 2).indexed("z", 2).build())); } /** Test the same computation made in various ways which are implemented with special-case optimizations */ -- cgit v1.2.3