diff options
10 files changed, 100 insertions, 30 deletions
diff --git a/config-model/src/main/javacc/SDParser.jj b/config-model/src/main/javacc/SDParser.jj index 6dde12f0fac..3141f7f7164 100644 --- a/config-model/src/main/javacc/SDParser.jj +++ b/config-model/src/main/javacc/SDParser.jj @@ -297,7 +297,7 @@ TOKEN : | < MUTABLE: "mutable" > | < FASTSEARCH: "fast-search" > | < HUGE: "huge" > -| < TENSOR_TYPE: "tensor(" (~["(",")"])+ ")" > +| < TENSOR_TYPE: "tensor" ("<" (~["<",">"])+ ">")? "(" (~["(",")"])+ ")" > | < TENSOR_VALUE_SL: "value" (" ")* ":" (" ")* ("{"<BRACE_SL_LEVEL_1>) ("\n")? > | < TENSOR_VALUE_ML: "value" (<SEARCHLIB_SKIP>)? "{" (["\n"," "])* ("{"<BRACE_ML_LEVEL_1>) (["\n"," "])* "}" ("\n")? > | < COMPRESSION: "compression" > diff --git a/config-model/src/test/derived/tensor/attributes.cfg b/config-model/src/test/derived/tensor/attributes.cfg index 4b54e67f8b8..f1c95da7084 100644 --- a/config-model/src/test/derived/tensor/attributes.cfg +++ b/config-model/src/test/derived/tensor/attributes.cfg @@ -61,3 +61,24 @@ attribute[].upperbound 9223372036854775807 attribute[].densepostinglistthreshold 0.4 attribute[].tensortype "tensor(x[10],y[20])" attribute[].imported false +attribute[].name "f5" +attribute[].datatype TENSOR +attribute[].collectiontype SINGLE +attribute[].removeifzero false +attribute[].createifnonexistent false +attribute[].fastsearch false +attribute[].huge false +attribute[].ismutable false +attribute[].sortascending true +attribute[].sortfunction UCA +attribute[].sortstrength PRIMARY +attribute[].sortlocale "" +attribute[].enablebitvectors false +attribute[].enableonlybitvector false +attribute[].fastaccess false +attribute[].arity 8 +attribute[].lowerbound -9223372036854775808 +attribute[].upperbound 9223372036854775807 +attribute[].densepostinglistthreshold 0.4 +attribute[].tensortype "tensor<float>(x[10])" +attribute[].imported false diff --git a/config-model/src/test/derived/tensor/documenttypes.cfg b/config-model/src/test/derived/tensor/documenttypes.cfg index 3b85e9b3a58..0b75644f4ae 100644 --- a/config-model/src/test/derived/tensor/documenttypes.cfg +++ b/config-model/src/test/derived/tensor/documenttypes.cfg @@ -40,6 +40,11 @@ documenttype[].datatype[].sstruct.field[].id 1224191509 documenttype[].datatype[].sstruct.field[].id_v6 1039544782 documenttype[].datatype[].sstruct.field[].datatype 21 documenttype[].datatype[].sstruct.field[].detailedtype "tensor(x[10],y[20])" +documenttype[].datatype[].sstruct.field[].name "f5" +documenttype[].datatype[].sstruct.field[].id 329055840 +documenttype[].datatype[].sstruct.field[].id_v6 105711688 +documenttype[].datatype[].sstruct.field[].datatype 21 +documenttype[].datatype[].sstruct.field[].detailedtype "tensor<float>(x[10])" documenttype[].datatype[].id -1903234535 documenttype[].datatype[].type STRUCT documenttype[].datatype[].array.element.id 0 @@ -59,3 +64,4 @@ documenttype[].fieldsets{[document]}.fields[] "f1" documenttype[].fieldsets{[document]}.fields[] "f2" documenttype[].fieldsets{[document]}.fields[] "f3" documenttype[].fieldsets{[document]}.fields[] "f4" +documenttype[].fieldsets{[document]}.fields[] "f5" diff --git a/config-model/src/test/derived/tensor/rank-profiles.cfg b/config-model/src/test/derived/tensor/rank-profiles.cfg index 471343da63c..87c0b6fab42 100644 --- a/config-model/src/test/derived/tensor/rank-profiles.cfg +++ b/config-model/src/test/derived/tensor/rank-profiles.cfg @@ -5,6 +5,8 @@ rankprofile[].fef.property[].name "vespa.type.attribute.f3" rankprofile[].fef.property[].value "tensor(x{})" rankprofile[].fef.property[].name "vespa.type.attribute.f4" rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].fef.property[].name "vespa.type.attribute.f5" +rankprofile[].fef.property[].value "tensor<float>(x[10])" rankprofile[].name "unranked" rankprofile[].fef.property[].name "vespa.rank.firstphase" rankprofile[].fef.property[].value "value(0)" @@ -20,6 +22,8 @@ rankprofile[].fef.property[].name "vespa.type.attribute.f3" rankprofile[].fef.property[].value "tensor(x{})" rankprofile[].fef.property[].name "vespa.type.attribute.f4" rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].fef.property[].name "vespa.type.attribute.f5" +rankprofile[].fef.property[].value "tensor<float>(x[10])" rankprofile[].name "profile1" rankprofile[].fef.property[].name "vespa.rank.firstphase" rankprofile[].fef.property[].value "rankingExpression(firstphase)" @@ -31,6 +35,8 @@ rankprofile[].fef.property[].name "vespa.type.attribute.f3" rankprofile[].fef.property[].value "tensor(x{})" rankprofile[].fef.property[].name "vespa.type.attribute.f4" rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].fef.property[].name "vespa.type.attribute.f5" +rankprofile[].fef.property[].value "tensor<float>(x[10])" rankprofile[].name "profile2" rankprofile[].fef.property[].name "vespa.rank.firstphase" rankprofile[].fef.property[].value "rankingExpression(firstphase)" @@ -42,6 +48,8 @@ rankprofile[].fef.property[].name "vespa.type.attribute.f3" rankprofile[].fef.property[].value "tensor(x{})" rankprofile[].fef.property[].name "vespa.type.attribute.f4" rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].fef.property[].name "vespa.type.attribute.f5" +rankprofile[].fef.property[].value "tensor<float>(x[10])" rankprofile[].name "profile3" rankprofile[].fef.property[].name "rankingExpression(joinedtensors).rankingScript" rankprofile[].fef.property[].value "tensor(i[10])(i) * attribute(f4)" @@ -57,3 +65,18 @@ rankprofile[].fef.property[].name "vespa.type.attribute.f3" rankprofile[].fef.property[].value "tensor(x{})" rankprofile[].fef.property[].name "vespa.type.attribute.f4" rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].fef.property[].name "vespa.type.attribute.f5" +rankprofile[].fef.property[].value "tensor<float>(x[10])" +rankprofile[].name "profile4" +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(attribute(f5), sum)" +rankprofile[].fef.property[].name "vespa.type.attribute.f2" +rankprofile[].fef.property[].value "tensor(x[2],y[])" +rankprofile[].fef.property[].name "vespa.type.attribute.f3" +rankprofile[].fef.property[].value "tensor(x{})" +rankprofile[].fef.property[].name "vespa.type.attribute.f4" +rankprofile[].fef.property[].value "tensor(x[10],y[20])" +rankprofile[].fef.property[].name "vespa.type.attribute.f5" +rankprofile[].fef.property[].value "tensor<float>(x[10])" diff --git a/config-model/src/test/derived/tensor/summary.cfg b/config-model/src/test/derived/tensor/summary.cfg index 5e5507836b0..903b6033297 100644 --- a/config-model/src/test/derived/tensor/summary.cfg +++ b/config-model/src/test/derived/tensor/summary.cfg @@ -1,5 +1,5 @@ -defaultsummaryid 289405525 -classes[].id 289405525 +defaultsummaryid 898020074 +classes[].id 898020074 classes[].name "default" classes[].fields[].name "f1" classes[].fields[].type "tensor" @@ -7,13 +7,15 @@ classes[].fields[].name "f3" classes[].fields[].type "tensor" classes[].fields[].name "f4" classes[].fields[].type "tensor" +classes[].fields[].name "f5" +classes[].fields[].type "tensor" classes[].fields[].name "rankfeatures" classes[].fields[].type "featuredata" classes[].fields[].name "summaryfeatures" classes[].fields[].type "featuredata" classes[].fields[].name "documentid" classes[].fields[].type "longstring" -classes[].id 1860420340 +classes[].id 193983608 classes[].name "attributeprefetch" classes[].fields[].name "f2" classes[].fields[].type "tensor" @@ -21,6 +23,8 @@ classes[].fields[].name "f3" classes[].fields[].type "tensor" classes[].fields[].name "f4" classes[].fields[].type "tensor" +classes[].fields[].name "f5" +classes[].fields[].type "tensor" classes[].fields[].name "rankfeatures" classes[].fields[].type "featuredata" classes[].fields[].name "summaryfeatures" diff --git a/config-model/src/test/derived/tensor/tensor.sd b/config-model/src/test/derived/tensor/tensor.sd index e3e8cf43347..622be033229 100644 --- a/config-model/src/test/derived/tensor/tensor.sd +++ b/config-model/src/test/derived/tensor/tensor.sd @@ -8,12 +8,15 @@ search tensor { field f2 type tensor(x[2],y[]) { indexing: attribute } - field f3 type tensor(x{}) { + field f3 type tensor<double>(x{}) { indexing: attribute | summary } field f4 type tensor(x[10],y[20]) { indexing: attribute | summary } + field f5 type tensor<float>(x[10]) { + indexing: attribute | summary + } } rank-profile profile1 { @@ -44,4 +47,12 @@ search tensor { } + rank-profile profile4 { + + first-phase { + expression: sum(attribute(f5)) + } + + } + } diff --git a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/onnx/TypeConverter.java b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/onnx/TypeConverter.java index 29d600fa7c6..8c9fe60e1d4 100644 --- a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/onnx/TypeConverter.java +++ b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/onnx/TypeConverter.java @@ -53,17 +53,17 @@ class TypeConverter { private static TensorType.Value toValueType(Onnx.TensorProto.DataType dataType) { switch (dataType) { - case FLOAT: return TensorType.Value.FLOAT; + case FLOAT: return TensorType.Value.DOUBLE; case DOUBLE: return TensorType.Value.DOUBLE; // Imperfect conversion, for now: - case BOOL: return TensorType.Value.FLOAT; - case INT8: return TensorType.Value.FLOAT; - case INT16: return TensorType.Value.FLOAT; - case INT32: return TensorType.Value.FLOAT; + case BOOL: return TensorType.Value.DOUBLE; + case INT8: return TensorType.Value.DOUBLE; + case INT16: return TensorType.Value.DOUBLE; + case INT32: return TensorType.Value.DOUBLE; case INT64: return TensorType.Value.DOUBLE; - case UINT8: return TensorType.Value.FLOAT; - case UINT16: return TensorType.Value.FLOAT; - case UINT32: return TensorType.Value.FLOAT; + case UINT8: return TensorType.Value.DOUBLE; + case UINT16: return TensorType.Value.DOUBLE; + case UINT32: return TensorType.Value.DOUBLE; case UINT64: return TensorType.Value.DOUBLE; default: throw new IllegalArgumentException("A ONNX tensor with data type " + dataType + " cannot be converted to a Vespa tensor type"); diff --git a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/tensorflow/TypeConverter.java b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/tensorflow/TypeConverter.java index d8ddb01b650..08c0564ed8a 100644 --- a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/tensorflow/TypeConverter.java +++ b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/tensorflow/TypeConverter.java @@ -85,19 +85,19 @@ class TypeConverter { private static TensorType.Value toValueType(DataType dataType) { switch (dataType) { - case DT_FLOAT: return TensorType.Value.FLOAT; + case DT_FLOAT: return TensorType.Value.DOUBLE; case DT_DOUBLE: return TensorType.Value.DOUBLE; // Imperfect conversion, for now: - case DT_BOOL: return TensorType.Value.FLOAT; - case DT_BFLOAT16: return TensorType.Value.FLOAT; - case DT_HALF: return TensorType.Value.FLOAT; - case DT_INT8: return TensorType.Value.FLOAT; - case DT_INT16: return TensorType.Value.FLOAT; - case DT_INT32: return TensorType.Value.FLOAT; + case DT_BOOL: return TensorType.Value.DOUBLE; + case DT_BFLOAT16: return TensorType.Value.DOUBLE; + case DT_HALF: return TensorType.Value.DOUBLE; + case DT_INT8: return TensorType.Value.DOUBLE; + case DT_INT16: return TensorType.Value.DOUBLE; + case DT_INT32: return TensorType.Value.DOUBLE; case DT_INT64: return TensorType.Value.DOUBLE; - case DT_UINT8: return TensorType.Value.FLOAT; - case DT_UINT16: return TensorType.Value.FLOAT; - case DT_UINT32: return TensorType.Value.FLOAT; + case DT_UINT8: return TensorType.Value.DOUBLE; + case DT_UINT16: return TensorType.Value.DOUBLE; + case DT_UINT32: return TensorType.Value.DOUBLE; case DT_UINT64: return TensorType.Value.DOUBLE; default: throw new IllegalArgumentException("A TensorFlow tensor with data type " + dataType + " cannot be converted to a Vespa tensor type"); @@ -106,12 +106,12 @@ class TypeConverter { private static TensorType.Value toValueType(org.tensorflow.DataType dataType) { switch (dataType) { - case FLOAT: return TensorType.Value.FLOAT; + case FLOAT: return TensorType.Value.DOUBLE; case DOUBLE: return TensorType.Value.DOUBLE; // Imperfect conversion, for now: - case BOOL: return TensorType.Value.FLOAT; - case INT32: return TensorType.Value.FLOAT; - case UINT8: return TensorType.Value.FLOAT; + case BOOL: return TensorType.Value.DOUBLE; + case INT32: return TensorType.Value.DOUBLE; + case UINT8: return TensorType.Value.DOUBLE; case INT64: return TensorType.Value.DOUBLE; default: throw new IllegalArgumentException("A TensorFlow tensor with data type " + dataType + " cannot be converted to a Vespa tensor type"); diff --git a/model-integration/src/test/java/ai/vespa/rankingexpression/importer/onnx/OnnxMnistSoftmaxImportTestCase.java b/model-integration/src/test/java/ai/vespa/rankingexpression/importer/onnx/OnnxMnistSoftmaxImportTestCase.java index 07814687dc6..424e4d6c57c 100644 --- a/model-integration/src/test/java/ai/vespa/rankingexpression/importer/onnx/OnnxMnistSoftmaxImportTestCase.java +++ b/model-integration/src/test/java/ai/vespa/rankingexpression/importer/onnx/OnnxMnistSoftmaxImportTestCase.java @@ -43,14 +43,14 @@ public class OnnxMnistSoftmaxImportTestCase { // Check inputs assertEquals(1, model.inputs().size()); assertTrue(model.inputs().containsKey("Placeholder")); - assertEquals(TensorType.fromSpec("tensor<float>(d0[],d1[784])"), model.inputs().get("Placeholder")); + assertEquals(TensorType.fromSpec("tensor(d0[],d1[784])"), model.inputs().get("Placeholder")); // Check signature ImportedMlFunction output = model.defaultSignature().outputFunction("add", "add"); assertNotNull(output); assertEquals("join(reduce(join(rename(Placeholder, (d0, d1), (d0, d2)), constant(test_Variable), f(a,b)(a * b)), sum, d2), constant(test_Variable_1), f(a,b)(a + b))", output.expression()); - assertEquals(TensorType.fromSpec("tensor<float>(d0[],d1[784])"), + assertEquals(TensorType.fromSpec("tensor(d0[],d1[784])"), model.inputs().get(model.defaultSignature().inputs().get("Placeholder"))); assertEquals("{Placeholder=tensor(d0[],d1[784])}", output.argumentTypes().toString()); } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/TensorType.java b/vespajlib/src/main/java/com/yahoo/tensor/TensorType.java index 8e566fac0b6..9869f1e908c 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/TensorType.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/TensorType.java @@ -168,7 +168,11 @@ public class TensorType { @Override public String toString() { - return "tensor(" + dimensions.stream().map(Dimension::toString).collect(Collectors.joining(",")) + ")"; + if ((rank() == 0) || (valueType == Value.DOUBLE)) { + return "tensor(" + dimensions.stream().map(Dimension::toString).collect(Collectors.joining(",")) + ")"; + } else { + return "tensor<" + valueType + ">(" + dimensions.stream().map(Dimension::toString).collect(Collectors.joining(",")) + ")"; + } } @Override @@ -177,6 +181,7 @@ public class TensorType { if (o == null || getClass() != o.getClass()) return false; TensorType other = (TensorType)o; + if ( (this.rank() == 0) && (other.rank() == 0)) return true; if ( this.valueType != other.valueType) return false; if ( ! this.dimensions.equals(other.dimensions)) return false; return true; |