aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2020-06-08 14:22:25 +0200
committerJon Bratseth <bratseth@gmail.com>2020-06-08 14:22:25 +0200
commite060beabc75b7db1424d168ee3513f5a5692a101 (patch)
tree4c5c98be642085e1cfa978f584402765216415e5
parent66dfc4bbfbce4e492ffd459d199a183067b1cfb1 (diff)
Disallow unbound tensor dimensions in document fields
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java74
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/TemporarySDField.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/ml/ConvertedModel.java2
-rw-r--r--config-model/src/test/cfg/application/ml_models/searchdefinitions/test.sd2
-rw-r--r--config-model/src/test/derived/tensor/documenttypes.cfg2
-rw-r--r--config-model/src/test/derived/tensor/tensor.sd2
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java21
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/processing/FastAccessValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java2
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java22
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithOnnxTestCase.java17
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java13
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java4
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java12
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java2
-rw-r--r--indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java2
-rw-r--r--indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TrimExpression.java1
17 files changed, 97 insertions, 85 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java
index 30ce142d503..e36635ba6b8 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/SDField.java
@@ -7,12 +7,14 @@ import com.yahoo.document.DocumentType;
import com.yahoo.document.Field;
import com.yahoo.document.MapDataType;
import com.yahoo.document.StructDataType;
+import com.yahoo.document.TensorDataType;
import com.yahoo.language.Linguistics;
import com.yahoo.language.simple.SimpleLinguistics;
import com.yahoo.searchdefinition.Index;
import com.yahoo.searchdefinition.Search;
import com.yahoo.searchdefinition.fieldoperation.FieldOperation;
import com.yahoo.searchdefinition.fieldoperation.FieldOperationContainer;
+import com.yahoo.tensor.TensorType;
import com.yahoo.vespa.documentmodel.SummaryField;
import com.yahoo.vespa.indexinglanguage.ExpressionSearcher;
import com.yahoo.vespa.indexinglanguage.ExpressionVisitor;
@@ -116,9 +118,10 @@ public class SDField extends Field implements TypedKey, FieldOperationContainer,
private boolean isExtraField = false;
/**
- * Creates a new field. This method is only used to create reserved fields
- * @param name The name of the field
- * @param dataType The datatype of the field
+ * Creates a new field. This method is only used to create reserved fields.
+ *
+ * @param name the name of the field
+ * @param dataType the datatype of the field
*/
protected SDField(SDDocumentType repo, String name, int id, DataType dataType, boolean populate) {
super(name, id, dataType);
@@ -129,64 +132,36 @@ public class SDField extends Field implements TypedKey, FieldOperationContainer,
this(repo, name, id, dataType, true);
}
- /**
- Creates a new field.
-
- @param name The name of the field
- @param dataType The datatype of the field
- */
+ /** Creates a new field */
public SDField(SDDocumentType repo, String name, DataType dataType, boolean populate) {
- super(name,dataType);
+ super(name, dataType);
populate(populate, repo, name, dataType);
}
- private void populate(boolean populate, SDDocumentType repo, String name, DataType dataType) {
- populate(populate,repo, name, dataType, null, 0);
- }
-
- private void populate(boolean populate, SDDocumentType repo, String name, DataType dataType, Matching fieldMatching, int recursion) {
- if (populate || (dataType instanceof MapDataType)) {
- populateWithStructFields(repo, name, dataType, recursion);
- populateWithStructMatching(repo, name, dataType, fieldMatching);
- }
- }
-
-
- /**
- * Creates a new field.
- *
- * @param name The name of the field
- * @param dataType The datatype of the field
- * @param owner the owning document (used to check for id collisions)
- */
+ /** Creates a new field */
protected SDField(SDDocumentType repo, String name, DataType dataType, SDDocumentType owner, boolean populate) {
super(name, dataType, owner == null ? null : owner.getDocumentType());
- this.ownerDocType=owner;
+ this.ownerDocType = owner;
populate(populate, repo, name, dataType);
}
/**
- * Creates a new field.
+ * Creates a new field
*
- * @param name The name of the field
- * @param dataType The datatype of the field
- * @param owner The owning document (used to check for id collisions)
- * @param fieldMatching The matching object to set for the field
+ * @param name the name of the field
+ * @param dataType the datatype of the field
+ * @param owner the owning document (used to check for id collisions)
+ * @param fieldMatching the matching object to set for the field
*/
protected SDField(SDDocumentType repo, String name, DataType dataType, SDDocumentType owner,
Matching fieldMatching, boolean populate, int recursion) {
super(name, dataType, owner == null ? null : owner.getDocumentType());
- this.ownerDocType=owner;
+ this.ownerDocType = owner;
if (fieldMatching != null)
this.setMatching(fieldMatching);
populate(populate, repo, name, dataType, fieldMatching, recursion);
}
- /**
- *
- * @param name The name of the field
- * @param dataType The datatype of the field
- */
public SDField(SDDocumentType repo, String name, DataType dataType) {
this(repo, name,dataType, true);
}
@@ -194,6 +169,23 @@ public class SDField extends Field implements TypedKey, FieldOperationContainer,
this(null, name,dataType);
}
+ private void populate(boolean populate, SDDocumentType repo, String name, DataType dataType) {
+ populate(populate, repo, name, dataType, null, 0);
+ }
+
+ private void populate(boolean populate, SDDocumentType repo, String name, DataType dataType, Matching fieldMatching, int recursion) {
+ if (dataType instanceof TensorDataType) {
+ TensorType type = ((TensorDataType)dataType).getTensorType();
+ if (type.dimensions().stream().anyMatch(d -> d.isIndexed() && d.size().isEmpty()))
+ throw new IllegalArgumentException("Illegal type in field " + name + " type " + type +
+ ": Dense tensor dimensions must have a size");
+ }
+ if (populate || (dataType instanceof MapDataType)) {
+ populateWithStructFields(repo, name, dataType, recursion);
+ populateWithStructMatching(repo, name, dataType, fieldMatching);
+ }
+ }
+
public void setIsExtraField(boolean isExtra) {
isExtraField = isExtra;
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporarySDField.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporarySDField.java
index 04d11792379..2921253461d 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporarySDField.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/TemporarySDField.java
@@ -4,7 +4,7 @@ package com.yahoo.searchdefinition.document;
import com.yahoo.document.DataType;
/**
- * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a>
+ * @author Einar M R Rosenvinge
*/
public class TemporarySDField extends SDField {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/ml/ConvertedModel.java b/config-model/src/main/java/com/yahoo/vespa/model/ml/ConvertedModel.java
index c3d6f457ce8..f8b48da291d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/ml/ConvertedModel.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/ml/ConvertedModel.java
@@ -448,7 +448,7 @@ public class ConvertedModel {
int i = rename.fromDimensions().indexOf(dimension.name());
if (i < 0) {
throw new IllegalArgumentException("Rename does not contain dimension '" +
- dimension + "' in child expression type: " + childType);
+ dimension + "' in child expression type: " + childType);
}
from.add((String)rename.fromDimensions().get(i));
to.add((String)rename.toDimensions().get(i));
diff --git a/config-model/src/test/cfg/application/ml_models/searchdefinitions/test.sd b/config-model/src/test/cfg/application/ml_models/searchdefinitions/test.sd
index 247df8a0241..6d10c50e80a 100644
--- a/config-model/src/test/cfg/application/ml_models/searchdefinitions/test.sd
+++ b/config-model/src/test/cfg/application/ml_models/searchdefinitions/test.sd
@@ -2,7 +2,7 @@
search test {
document test {
- field argument type tensor<float>(d0[],d1[784]) {
+ field argument type tensor<float>(d0[1],d1[784]) {
indexing: attribute
}
}
diff --git a/config-model/src/test/derived/tensor/documenttypes.cfg b/config-model/src/test/derived/tensor/documenttypes.cfg
index 68bd394c9d6..bbf9759659b 100644
--- a/config-model/src/test/derived/tensor/documenttypes.cfg
+++ b/config-model/src/test/derived/tensor/documenttypes.cfg
@@ -23,7 +23,7 @@ documenttype[].datatype[].sstruct.compression.minsize 200
documenttype[].datatype[].sstruct.field[].name "f1"
documenttype[].datatype[].sstruct.field[].id 26661415
documenttype[].datatype[].sstruct.field[].datatype 21
-documenttype[].datatype[].sstruct.field[].detailedtype "tensor(x[])"
+documenttype[].datatype[].sstruct.field[].detailedtype "tensor(x[3])"
documenttype[].datatype[].sstruct.field[].name "f2"
documenttype[].datatype[].sstruct.field[].id 2080644671
documenttype[].datatype[].sstruct.field[].datatype 21
diff --git a/config-model/src/test/derived/tensor/tensor.sd b/config-model/src/test/derived/tensor/tensor.sd
index a7248fe3200..44a84a3cbb3 100644
--- a/config-model/src/test/derived/tensor/tensor.sd
+++ b/config-model/src/test/derived/tensor/tensor.sd
@@ -2,7 +2,7 @@
search tensor {
document tensor {
- field f1 type tensor(x[]) {
+ field f1 type tensor(x[3]) {
indexing: summary
}
field f2 type tensor<float>(x[2],y[1]) {
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java
index e2f2c1fd407..0f83a4db98f 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java
@@ -125,7 +125,7 @@ public class RankProfileTestCase extends SchemaTestCase {
" document test { \n" +
" field a type tensor(x[10]) { indexing: attribute }\n" +
" field b type tensor(y{}) { indexing: attribute }\n" +
- " field c type tensor(x[]) { indexing: attribute }\n" +
+ " field c type tensor(x[5]) { indexing: attribute }\n" +
" }\n" +
" rank-profile p1 {}\n" +
" rank-profile p2 {}\n" +
@@ -140,11 +140,28 @@ public class RankProfileTestCase extends SchemaTestCase {
assertAttributeTypeSettings(registry.get(search, "p2"), search);
}
+ @Test
+ public void requireThatDenseDimensionsMustBeBound() throws ParseException {
+ try {
+ SearchBuilder builder = new SearchBuilder(new RankProfileRegistry());
+ builder.importString("search test {\n" +
+ " document test { \n" +
+ " field a type tensor(x[]) { indexing: attribute }\n" +
+ " }\n" +
+ "}");
+ builder.build();
+ }
+ catch (IllegalArgumentException e) {
+ assertEquals("Illegal type in field a type tensor(x[]): Dense tensor dimensions must have a size",
+ e.getMessage());
+ }
+ }
+
private static void assertAttributeTypeSettings(RankProfile profile, Search search) {
RawRankProfile rawProfile = new RawRankProfile(profile, new QueryProfileRegistry(), new ImportedMlModels(), new AttributeFields(search));
assertEquals("tensor(x[10])", findProperty(rawProfile.configProperties(), "vespa.type.attribute.a").get());
assertEquals("tensor(y{})", findProperty(rawProfile.configProperties(), "vespa.type.attribute.b").get());
- assertEquals("tensor(x[])", findProperty(rawProfile.configProperties(), "vespa.type.attribute.c").get());
+ assertEquals("tensor(x[5])", findProperty(rawProfile.configProperties(), "vespa.type.attribute.c").get());
}
@Test
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/FastAccessValidatorTest.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/FastAccessValidatorTest.java
index 994538deed6..71277f136f8 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/FastAccessValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/FastAccessValidatorTest.java
@@ -39,7 +39,7 @@ public class FastAccessValidatorTest {
" indexing: attribute ",
" attribute: fast-access",
" }",
- " field tensor_attribute type tensor(x[]) {",
+ " field tensor_attribute type tensor(x[5]) {",
" indexing: attribute ",
" attribute: fast-access",
" }",
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java
index c679bb7e61f..b7db9134b88 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsResolverTestCase.java
@@ -114,7 +114,7 @@ public class ImportedFieldsResolverTestCase {
parentSearch.getDocument().addField(createField("attribute_field", DataType.INT, "{ attribute }"));
parentSearch.getDocument().addField(createField("attribute_and_index", DataType.INT, "{ attribute | index }"));
parentSearch.getDocument().addField(new TemporarySDField("not_attribute", DataType.INT));
- parentSearch.getDocument().addField(createField("tensor_field", new TensorDataType(TensorType.fromSpec("tensor(x[])")), "{ attribute }"));
+ parentSearch.getDocument().addField(createField("tensor_field", new TensorDataType(TensorType.fromSpec("tensor(x[5])")), "{ attribute }"));
parentSearch.getDocument().addField(createField("predicate_field", DataType.PREDICATE, "{ attribute }"));
addRefField(parentSearch, grandParentSearch, "ref");
addImportedField(parentSearch, "ancient_field", "ref", "ancient_field");
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java
index a306e0f2c90..96f12a47a2f 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java
@@ -37,7 +37,7 @@ public class RankingExpressionTypeResolverTestCase {
builder.importString(joinLines(
"search test {",
" document test { ",
- " field a type tensor(x[],y[]) {",
+ " field a type tensor(x[10],y[3]) {",
" indexing: attribute",
" }",
" }",
@@ -52,7 +52,7 @@ public class RankingExpressionTypeResolverTestCase {
fail("Expected exception");
}
catch (IllegalArgumentException expected) {
- assertEquals("In search definition 'test', rank profile 'my_rank_profile': The first-phase expression must produce a double (a tensor with no dimensions), but produces tensor(x[],y[])",
+ assertEquals("In search definition 'test', rank profile 'my_rank_profile': The first-phase expression must produce a double (a tensor with no dimensions), but produces tensor(x[10],y[3])",
Exceptions.toMessageString(expected));
}
}
@@ -64,7 +64,7 @@ public class RankingExpressionTypeResolverTestCase {
builder.importString(joinLines(
"search test {",
" document test { ",
- " field a type tensor(x[],y[]) {",
+ " field a type tensor(x[10],y[3]) {",
" indexing: attribute",
" }",
" }",
@@ -82,7 +82,7 @@ public class RankingExpressionTypeResolverTestCase {
fail("Expected exception");
}
catch (IllegalArgumentException expected) {
- assertEquals("In search definition 'test', rank profile 'my_rank_profile': The second-phase expression must produce a double (a tensor with no dimensions), but produces tensor(x[],y[])",
+ assertEquals("In search definition 'test', rank profile 'my_rank_profile': The second-phase expression must produce a double (a tensor with no dimensions), but produces tensor(x[10],y[3])",
Exceptions.toMessageString(expected));
}
}
@@ -94,7 +94,7 @@ public class RankingExpressionTypeResolverTestCase {
searchBuilder.importString(joinLines(
"search test {",
" document test { ",
- " field a type tensor(x[],y[]) {",
+ " field a type tensor(x[10],y[5]) {",
" indexing: attribute",
" }",
" field b type tensor(z[10]) {",
@@ -112,7 +112,7 @@ public class RankingExpressionTypeResolverTestCase {
fail("Expected exception");
}
catch (IllegalArgumentException expected) {
- assertEquals("In search definition 'test', rank profile 'my_rank_profile': The first-phase expression is invalid: An if expression must produce compatible types in both alternatives, but the 'true' type is tensor(x[],y[]) while the 'false' type is tensor(z[10])" +
+ assertEquals("In search definition 'test', rank profile 'my_rank_profile': The first-phase expression is invalid: An if expression must produce compatible types in both alternatives, but the 'true' type is tensor(x[10],y[5]) while the 'false' type is tensor(z[10])" +
"\n'true' branch: attribute(a)" +
"\n'false' branch: attribute(b)",
Exceptions.toMessageString(expected));
@@ -126,7 +126,7 @@ public class RankingExpressionTypeResolverTestCase {
builder.importString(joinLines(
"search test {",
" document test { ",
- " field a type tensor(x[],y[]) {",
+ " field a type tensor(x[10],y[3]) {",
" indexing: attribute",
" }",
" field b type tensor(z[10]) {",
@@ -147,7 +147,7 @@ public class RankingExpressionTypeResolverTestCase {
builder.build();
RankProfile profile =
builder.getRankProfileRegistry().get(builder.getSearch(), "my_rank_profile");
- assertEquals(TensorType.fromSpec("tensor(x[],y[])"),
+ assertEquals(TensorType.fromSpec("tensor(x[10],y[3])"),
summaryFeatures(profile).get("macro1(a)").type(profile.typeContext(builder.getQueryProfileRegistry())));
assertEquals(TensorType.fromSpec("tensor(z[10])"),
summaryFeatures(profile).get("macro1(b)").type(profile.typeContext(builder.getQueryProfileRegistry())));
@@ -159,7 +159,7 @@ public class RankingExpressionTypeResolverTestCase {
builder.importString(joinLines(
"search test {",
" document test { ",
- " field a type tensor(x[],y[]) {",
+ " field a type tensor(x[10],y[1]) {",
" indexing: attribute",
" }",
" field b type tensor(z[10]) {",
@@ -189,7 +189,7 @@ public class RankingExpressionTypeResolverTestCase {
builder.build();
RankProfile profile =
builder.getRankProfileRegistry().get(builder.getSearch(), "my_rank_profile");
- assertEquals(TensorType.fromSpec("tensor(x[],y[])"),
+ assertEquals(TensorType.fromSpec("tensor(x[10],y[1])"),
summaryFeatures(profile).get("return_a").type(profile.typeContext(builder.getQueryProfileRegistry())));
assertEquals(TensorType.fromSpec("tensor(z[10])"),
summaryFeatures(profile).get("return_b").type(profile.typeContext(builder.getQueryProfileRegistry())));
@@ -201,7 +201,7 @@ public class RankingExpressionTypeResolverTestCase {
builder.importString(joinLines(
"search parent {",
" document parent {",
- " field a type tensor(x[],y[]) {",
+ " field a type tensor(x[5],y[1000]) {",
" indexing: attribute",
" }",
" }",
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithOnnxTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithOnnxTestCase.java
index 4387d19c474..1fe1ebf2bb3 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithOnnxTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithOnnxTestCase.java
@@ -29,6 +29,7 @@ public class RankingExpressionWithOnnxTestCase {
private final static String name = "mnist_softmax";
private final static String vespaExpression = "join(reduce(join(rename(Placeholder, (d0, d1), (d0, d2)), constant(" + name + "_Variable), f(a,b)(a * b)), sum, d2), constant(" + name + "_Variable_1), f(a,b)(a + b))";
+ private final static String vespaExpressionWithBatchReduce = "join(join(reduce(join(reduce(rename(Placeholder, (d0, d1), (d0, d2)), sum, d0), constant(mnist_softmax_Variable), f(a,b)(a * b)), sum, d2), constant(mnist_softmax_Variable_1), f(a,b)(a + b)), tensor<float>(d0[1])(1.0), f(a,b)(a * b))";
@After
public void removeGeneratedModelFiles() {
@@ -93,10 +94,10 @@ public class RankingExpressionWithOnnxTestCase {
RankProfileSearchFixture search = fixtureWith("attribute(mytensor)",
"onnx('mnist_softmax.onnx')",
null,
- "field mytensor type tensor<float>(d0[],d1[784]) { indexing: attribute }",
+ "field mytensor type tensor<float>(d0[1],d1[784]) { indexing: attribute }",
"Placeholder",
application);
- search.assertFirstPhaseExpression(vespaExpression, "my_profile");
+ search.assertFirstPhaseExpression(vespaExpressionWithBatchReduce, "my_profile");
}
@@ -105,18 +106,16 @@ public class RankingExpressionWithOnnxTestCase {
String queryProfile = "<query-profile id='default' type='root'/>";
String queryProfileType =
"<query-profile-type id='root'>" +
- " <field name='query(mytensor)' type='tensor&lt;float&gt;(d0[3],d1[784],d2[10])'/>" +
+ " <field name='query(mytensor)' type='tensor&lt;float&gt;(d0[1],d1[784],d2[10])'/>" +
"</query-profile-type>";
- StoringApplicationPackage application = new StoringApplicationPackage(applicationDir,
- queryProfile,
- queryProfileType);
+ StoringApplicationPackage application = new StoringApplicationPackage(applicationDir, queryProfile, queryProfileType);
RankProfileSearchFixture search = fixtureWith("sum(query(mytensor) * attribute(mytensor) * constant(mytensor),d2)",
"onnx('mnist_softmax.onnx')",
- "constant mytensor { file: ignored\ntype: tensor<float>(d0[7],d1[784]) }",
- "field mytensor type tensor<float>(d0[],d1[784]) { indexing: attribute }",
+ "constant mytensor { file: ignored\ntype: tensor<float>(d0[1],d1[784]) }",
+ "field mytensor type tensor<float>(d0[1],d1[784]) { indexing: attribute }",
"Placeholder",
application);
- search.assertFirstPhaseExpression(vespaExpression, "my_profile");
+ search.assertFirstPhaseExpression(vespaExpressionWithBatchReduce, "my_profile");
}
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java
index 680f2dd9659..126a41e14ad 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionWithTensorFlowTestCase.java
@@ -44,6 +44,7 @@ public class RankingExpressionWithTensorFlowTestCase {
private final String name = "mnist_softmax_saved";
private final String vespaExpression = "join(reduce(join(rename(Placeholder, (d0, d1), (d0, d2)), constant(" + name + "_layer_Variable_read), f(a,b)(a * b)), sum, d2), constant(" + name + "_layer_Variable_1_read), f(a,b)(a + b))";
+ private final static String vespaExpressionWithBatchReduce = "join(join(reduce(join(reduce(rename(Placeholder, (d0, d1), (d0, d2)), sum, d0), constant(mnist_softmax_saved_layer_Variable_read), f(a,b)(a * b)), sum, d2), constant(mnist_softmax_saved_layer_Variable_1_read), f(a,b)(a + b)), tensor(d0[1])(1.0), f(a,b)(a * b))";
@After
public void removeGeneratedModelFiles() {
@@ -114,28 +115,28 @@ public class RankingExpressionWithTensorFlowTestCase {
RankProfileSearchFixture search = fixtureWith("attribute(mytensor)",
"tensorflow('mnist_softmax/saved')",
null,
- "field mytensor type tensor(d0[],d1[784]) { indexing: attribute }",
+ "field mytensor type tensor(d0[1],d1[784]) { indexing: attribute }",
"Placeholder",
application);
- search.assertFirstPhaseExpression(vespaExpression, "my_profile");
+ search.assertFirstPhaseExpression(vespaExpressionWithBatchReduce, "my_profile");
}
@Test
public void testTensorFlowReferenceWithFeatureCombination() {
String queryProfile = "<query-profile id='default' type='root'/>";
String queryProfileType = "<query-profile-type id='root'>" +
- " <field name='query(mytensor)' type='tensor(d0[3],d1[784],d2[10])'/>" +
+ " <field name='query(mytensor)' type='tensor(d0[1],d1[784],d2[10])'/>" +
"</query-profile-type>";
StoringApplicationPackage application = new StoringApplicationPackage(applicationDir,
queryProfile,
queryProfileType);
RankProfileSearchFixture search = fixtureWith("sum(query(mytensor) * attribute(mytensor) * constant(mytensor),d2)",
"tensorflow('mnist_softmax/saved')",
- "constant mytensor { file: ignored\ntype: tensor(d0[7],d1[784]) }",
- "field mytensor type tensor(d0[],d1[784]) { indexing: attribute }",
+ "constant mytensor { file: ignored\ntype: tensor(d0[1],d1[784]) }",
+ "field mytensor type tensor(d0[1],d1[784]) { indexing: attribute }",
"Placeholder",
application);
- search.assertFirstPhaseExpression(vespaExpression, "my_profile");
+ search.assertFirstPhaseExpression(vespaExpressionWithBatchReduce, "my_profile");
}
@Test
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
index e32bd09bc08..5da36d82a62 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
@@ -119,12 +119,12 @@ public class AttributeChangeValidatorTest {
"Field 'f1' changed: tensor type: 'tensor(x[2])' -> 'tensor(x[3])'", Instant.now()));
new Fixture(
- "field f1 type tensor(x[]) { indexing: attribute }",
+ "field f1 type tensor(x[5]) { indexing: attribute }",
"field f1 type tensor(x[3]) { indexing: attribute }")
.assertValidation(newRefeedAction(
"tensor-type-change",
ValidationOverrides.empty,
- "Field 'f1' changed: tensor type: 'tensor(x[])' -> 'tensor(x[3])'", Instant.now()));
+ "Field 'f1' changed: tensor type: 'tensor(x[5])' -> 'tensor(x[3])'", Instant.now()));
}
@Test
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java b/config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java
index 57dbf132883..5b38e09537d 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/ml/MlModelsTest.java
@@ -63,17 +63,17 @@ public class MlModelsTest {
private final String testProfile =
"rankingExpression(input).rankingScript: attribute(argument)\n" +
- "rankingExpression(input).type: tensor<float>(d0[],d1[784])\n" +
- "rankingExpression(imported_ml_function_mnist_saved_dnn_hidden1_add).rankingScript: join(reduce(join(rename(rankingExpression(input), (d0, d1), (d0, d4)), constant(mnist_saved_dnn_hidden1_weights_read), f(a,b)(a * b)), sum, d4), constant(mnist_saved_dnn_hidden1_bias_read), f(a,b)(a + b))\n" +
+ "rankingExpression(input).type: tensor<float>(d0[1],d1[784])\n" +
+ "rankingExpression(imported_ml_function_mnist_saved_dnn_hidden1_add).rankingScript: join(reduce(join(reduce(rename(rankingExpression(input), (d0, d1), (d0, d4)), sum, d0), constant(mnist_saved_dnn_hidden1_weights_read), f(a,b)(a * b)), sum, d4), constant(mnist_saved_dnn_hidden1_bias_read), f(a,b)(a + b))\n" +
"rankingExpression(mnist_tensorflow).rankingScript: join(reduce(join(map(join(reduce(join(join(join(0.009999999776482582, rankingExpression(imported_ml_function_mnist_saved_dnn_hidden1_add), f(a,b)(a * b)), rankingExpression(imported_ml_function_mnist_saved_dnn_hidden1_add), f(a,b)(max(a,b))), constant(mnist_saved_dnn_hidden2_weights_read), f(a,b)(a * b)), sum, d3), constant(mnist_saved_dnn_hidden2_bias_read), f(a,b)(a + b)), f(a)(1.0507009873554805 * if (a >= 0, a, 1.6732632423543772 * (exp(a) - 1)))), constant(mnist_saved_dnn_outputs_weights_read), f(a,b)(a * b)), sum, d2), constant(mnist_saved_dnn_outputs_bias_read), f(a,b)(a + b))\n" +
"rankingExpression(Placeholder).rankingScript: attribute(argument)\n" +
- "rankingExpression(Placeholder).type: tensor<float>(d0[],d1[784])\n" +
- "rankingExpression(mnist_softmax_tensorflow).rankingScript: join(reduce(join(rename(rankingExpression(Placeholder), (d0, d1), (d0, d2)), constant(mnist_softmax_saved_layer_Variable_read), f(a,b)(a * b)), sum, d2), constant(mnist_softmax_saved_layer_Variable_1_read), f(a,b)(a + b))\n" +
- "rankingExpression(mnist_softmax_onnx).rankingScript: join(reduce(join(rename(rankingExpression(Placeholder), (d0, d1), (d0, d2)), constant(mnist_softmax_Variable), f(a,b)(a * b)), sum, d2), constant(mnist_softmax_Variable_1), f(a,b)(a + b))\n" +
+ "rankingExpression(Placeholder).type: tensor<float>(d0[1],d1[784])\n" +
+ "rankingExpression(mnist_softmax_tensorflow).rankingScript: join(join(reduce(join(reduce(rename(rankingExpression(Placeholder), (d0, d1), (d0, d2)), sum, d0), constant(mnist_softmax_saved_layer_Variable_read), f(a,b)(a * b)), sum, d2), constant(mnist_softmax_saved_layer_Variable_1_read), f(a,b)(a + b)), tensor(d0[1])(1.0), f(a,b)(a * b))\n" +
+ "rankingExpression(mnist_softmax_onnx).rankingScript: join(join(reduce(join(reduce(rename(rankingExpression(Placeholder), (d0, d1), (d0, d2)), sum, d0), constant(mnist_softmax_Variable), f(a,b)(a * b)), sum, d2), constant(mnist_softmax_Variable_1), f(a,b)(a + b)), tensor<float>(d0[1])(1.0), f(a,b)(a * b))\n" +
"rankingExpression(my_xgboost).rankingScript: if (f29 < -0.1234567, if (!(f56 >= -0.242398), 1.71218, -1.70044), if (f109 < 0.8723473, -1.94071, 1.85965)) + if (!(f60 >= -0.482947), if (f29 < -4.2387498, 0.784718, -0.96853), -6.23624)\n" +
"rankingExpression(my_lightgbm).rankingScript: if (!(numerical_2 >= 0.46643291586559305), 2.1594397038037663, if (categorical_2 in [\"k\", \"l\", \"m\"], 2.235297305276056, 2.1792953471546546)) + if (categorical_1 in [\"d\", \"e\"], 0.03070842919354316, if (!(numerical_1 >= 0.5102250691730842), -0.04439151147520909, 0.005117411709368601)) + if (!(numerical_2 >= 0.668665477622446), if (!(numerical_2 >= 0.008118820676863816), -0.15361238490967524, -0.01192330846157292), 0.03499044894987518) + if (!(numerical_1 >= 0.5201391072644542), -0.02141000620783247, if (categorical_1 in [\"a\", \"b\"], -0.004121485787596721, 0.04534090904886873)) + if (categorical_2 in [\"k\", \"l\", \"m\"], if (!(numerical_2 >= 0.27283279016959255), -0.01924803254356527, 0.03643772842347651), -0.02701711918923075)\n" +
"vespa.rank.firstphase: rankingExpression(firstphase)\n" +
"rankingExpression(firstphase).rankingScript: rankingExpression(mnist_tensorflow) + rankingExpression(mnist_softmax_tensorflow) + rankingExpression(mnist_softmax_onnx) + rankingExpression(my_xgboost) + rankingExpression(my_lightgbm)\n" +
- "vespa.type.attribute.argument: tensor<float>(d0[],d1[784])\n";
+ "vespa.type.attribute.argument: tensor<float>(d0[1],d1[784])\n";
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java
index e8fa70afd1b..52ef6c40a6a 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java
@@ -82,7 +82,7 @@ public class NearestNeighborItem extends SimpleTaggableItem {
buffer.append("{field=").append(field);
buffer.append(",queryTensorName=").append(queryTensorName);
buffer.append(",hnsw.exploreAdditionalHits=").append(hnswExploreAdditionalHits);
- buffer.append(",approximate=").append(String.valueOf(approximate));
+ buffer.append(",approximate=").append(approximate);
buffer.append(",targetNumHits=").append(targetNumHits).append("}");
}
diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java
index 6056a9b0ca5..14b5af53b5a 100644
--- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java
+++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java
@@ -23,6 +23,7 @@ public final class ExactExpression extends Expression {
public ExactExpression() {
super(DataType.STRING);
}
+
@Override
protected void doExecute(ExecutionContext ctx) {
StringFieldValue input = (StringFieldValue)ctx.getValue();
@@ -70,4 +71,5 @@ public final class ExactExpression extends Expression {
public int hashCode() {
return getClass().hashCode();
}
+
}
diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TrimExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TrimExpression.java
index 14a6c8f9b04..8dcf360a6ee 100644
--- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TrimExpression.java
+++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TrimExpression.java
@@ -9,6 +9,7 @@ import com.yahoo.document.datatypes.StringFieldValue;
* @author Simon Thoresen Hult
*/
public final class TrimExpression extends Expression {
+
public TrimExpression() {
super(DataType.STRING);
}