diff options
6 files changed, 28 insertions, 22 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/Presentation.java b/container-search/src/main/java/com/yahoo/search/query/Presentation.java index 31641b5c2f0..afa87eb4a06 100644 --- a/container-search/src/main/java/com/yahoo/search/query/Presentation.java +++ b/container-search/src/main/java/com/yahoo/search/query/Presentation.java @@ -75,7 +75,7 @@ public class Presentation implements Cloneable { private boolean timing = false; /** Whether to renders tensors in short form */ - private boolean tensorShortForm = false; + private boolean tensorShortForm = true; /** Set of explicitly requested summary fields, instead of summary classes */ private Set<String> summaryFields = LazySet.newHashSet(); @@ -180,7 +180,7 @@ public class Presentation implements Cloneable { * Returns whether tensors should use short form in JSON and textual representations, see * <a href="https://docs.vespa.ai/en/reference/document-json-format.html#tensor">https://docs.vespa.ai/en/reference/document-json-format.html#tensor</a> * and <a href="https://docs.vespa.ai/en/reference/tensor.html#tensor-literal-form">https://docs.vespa.ai/en/reference/tensor.html#tensor-literal-form</a>. - * Default is false. + * Default is true. */ public boolean getTensorShortForm() { return tensorShortForm; } diff --git a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java index 4a1ab693151..0a4dcb2eec1 100644 --- a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java @@ -204,14 +204,14 @@ public class JsonRendererTestCase { + " \"object\": \"thingie\"," + " \"string\": \"stuff\"," + " \"predicate\": \"a in [b]\"," - + " \"tensor1\": { \"cells\": [ { \"address\": {\"x\": \"a\"}, \"value\":2.0 } ] }," + + " \"tensor1\": { \"type\": \"tensor(x{})\", \"cells\": { \"a\":2.0 } }," + " \"tensor2\": { \"cells\": [] }," - + " \"tensor3\": { \"cells\": [ { \"address\": {\"x\": \"a\", \"y\": \"0\"}, \"value\":2.0 }, { \"address\": {\"x\": \"a\", \"y\": \"1\"}, \"value\":-1.0 } ] }," + + " \"tensor3\": { \"type\": \"tensor(x{},y{})\", \"cells\": [ { \"address\": {\"x\": \"a\", \"y\": \"0\"}, \"value\":2.0 }, { \"address\": {\"x\": \"a\", \"y\": \"1\"}, \"value\":-1.0 } ] }," + " \"summaryfeatures\": {" + " \"scalar1\":1.5," + " \"scalar2\":2.5," - + " \"tensor1\":{\"type\":\"tensor(x[3])\",\"cells\":[{\"address\":{\"x\":\"0\"},\"value\":1.5},{\"address\":{\"x\":\"1\"},\"value\":2.0},{\"address\":{\"x\":\"2\"},\"value\":2.5}]}," - + " \"tensor2\":{\"type\":\"tensor()\",\"cells\":[{\"address\":{},\"value\":0.5}]}" + + " \"tensor1\":{\"type\":\"tensor(x[3])\", \"values\":[1.5, 2.0, 2.5] }," + + " \"tensor2\":{\"type\":\"tensor()\", \"values\":[0.5] }" + " }," + " \"data\": \"Data \\\\xc3\\\\xa6 \\\\xc3\\\\xa5\"" + " }," diff --git a/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java b/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java index b0e2be26f8a..2661b9c2eb2 100644 --- a/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java +++ b/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java @@ -90,13 +90,13 @@ public class ModelsEvaluationHandler extends ThreadedHttpRequestHandler { Tensor result = evaluator.evaluate(); Optional<String> format = property(request, "format.tensors"); - if (format.isPresent() && format.get().equalsIgnoreCase("short")) { - return new Response(200, JsonFormat.encodeShortForm(result)); + if (format.isPresent() && format.get().equalsIgnoreCase("long")) { + return new Response(200, JsonFormat.encode(result)); } else if (format.isPresent() && format.get().equalsIgnoreCase("string")) { return new Response(200, result.toString().getBytes(StandardCharsets.UTF_8)); } - return new Response(200, JsonFormat.encode(result)); + return new Response(200, JsonFormat.encodeShortForm(result)); } private HttpResponse listAllModels(HttpRequest request) { diff --git a/model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java b/model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java index 3000c83b7ec..7790f8a60d0 100644 --- a/model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java +++ b/model-evaluation/src/test/java/ai/vespa/models/handler/ModelsEvaluationHandlerTest.java @@ -66,7 +66,7 @@ public class ModelsEvaluationHandlerTest { @Test public void testXgBoostEvaluationWithoutBindings() { String url = "http://localhost/model-evaluation/v1/xgboost_2_2/eval"; // only has a single function - String expected = "{\"cells\":[{\"address\":{},\"value\":-4.376589999999999}]}"; + String expected = "{\"type\":\"tensor()\",\"values\":[-4.376589999999999]}"; handler.assertResponse(url, 200, expected); } @@ -79,7 +79,7 @@ public class ModelsEvaluationHandlerTest { properties.put("f109", "0.4"); properties.put("non-existing-binding", "-1"); String url = "http://localhost/model-evaluation/v1/xgboost_2_2/eval"; - String expected = "{\"cells\":[{\"address\":{},\"value\":-7.936679999999999}]}"; + String expected = "{\"type\":\"tensor()\",\"values\":[-7.936679999999999]}"; handler.assertResponse(url, properties, 200, expected); } @@ -91,6 +91,7 @@ public class ModelsEvaluationHandlerTest { properties.put("f60", "0.3"); properties.put("f109", "0.4"); properties.put("non-existing-binding", "-1"); + properties.put("format.tensors", "long"); String url = "http://localhost/model-evaluation/v1/xgboost_2_2/eval"; String expected = "{\"cells\":[{\"address\":{},\"value\":-7.936679999999999}]}"; handler.assertResponse(url, properties, 200, expected); @@ -99,7 +100,7 @@ public class ModelsEvaluationHandlerTest { @Test public void testLightGBMEvaluationWithoutBindings() { String url = "http://localhost/model-evaluation/v1/lightgbm_regression/eval"; - String expected = "{\"cells\":[{\"address\":{},\"value\":1.9130086820218188}]}"; + String expected = "{\"type\":\"tensor()\",\"values\":[1.9130086820218188]}"; handler.assertResponse(url, 200, expected); } @@ -112,7 +113,7 @@ public class ModelsEvaluationHandlerTest { properties.put("categorical_2", "i"); properties.put("non-existing-binding", "-1"); String url = "http://localhost/model-evaluation/v1/lightgbm_regression/eval"; - String expected = "{\"cells\":[{\"address\":{},\"value\":2.054697758469921}]}"; + String expected = "{\"type\":\"tensor()\",\"values\":[2.054697758469921]}"; handler.assertResponse(url, properties, 200, expected); } @@ -125,7 +126,7 @@ public class ModelsEvaluationHandlerTest { properties.put("categorical_2", "j"); properties.put("non-existing-binding", "-1"); String url = "http://localhost/model-evaluation/v1/lightgbm_regression/eval"; - String expected = "{\"cells\":[{\"address\":{},\"value\":2.0745534018208094}]}"; + String expected = "{\"type\":\"tensor()\",\"values\":[2.0745534018208094]}"; handler.assertResponse(url, properties, 200, expected); } @@ -162,7 +163,7 @@ public class ModelsEvaluationHandlerTest { Map<String, String> properties = new HashMap<>(); properties.put("Placeholder", inputTensor()); String url = "http://localhost/model-evaluation/v1/mnist_softmax/eval"; - String expected = "{\"cells\":[{\"address\":{\"d0\":\"0\",\"d1\":\"0\"},\"value\":-0.3546536862850189},{\"address\":{\"d0\":\"0\",\"d1\":\"1\"},\"value\":0.3759574592113495},{\"address\":{\"d0\":\"0\",\"d1\":\"2\"},\"value\":0.06054411828517914},{\"address\":{\"d0\":\"0\",\"d1\":\"3\"},\"value\":-0.251544713973999},{\"address\":{\"d0\":\"0\",\"d1\":\"4\"},\"value\":0.017951013520359993},{\"address\":{\"d0\":\"0\",\"d1\":\"5\"},\"value\":1.2899067401885986},{\"address\":{\"d0\":\"0\",\"d1\":\"6\"},\"value\":-0.10389615595340729},{\"address\":{\"d0\":\"0\",\"d1\":\"7\"},\"value\":0.6367976665496826},{\"address\":{\"d0\":\"0\",\"d1\":\"8\"},\"value\":-1.4136744737625122},{\"address\":{\"d0\":\"0\",\"d1\":\"9\"},\"value\":-0.2573896050453186}]}"; + String expected = "{\"type\":\"tensor(d0[],d1[10])\",\"values\":[[-0.3546536862850189,0.3759574592113495,0.06054411828517914,-0.251544713973999,0.017951013520359993,1.2899067401885986,-0.10389615595340729,0.6367976665496826,-1.4136744737625122,-0.2573896050453186]]}"; handler.assertResponse(url, properties, 200, expected); } @@ -171,7 +172,7 @@ public class ModelsEvaluationHandlerTest { Map<String, String> properties = new HashMap<>(); properties.put("Placeholder", inputTensor()); String url = "http://localhost/model-evaluation/v1/mnist_softmax/default.add/eval"; - String expected = "{\"cells\":[{\"address\":{\"d0\":\"0\",\"d1\":\"0\"},\"value\":-0.3546536862850189},{\"address\":{\"d0\":\"0\",\"d1\":\"1\"},\"value\":0.3759574592113495},{\"address\":{\"d0\":\"0\",\"d1\":\"2\"},\"value\":0.06054411828517914},{\"address\":{\"d0\":\"0\",\"d1\":\"3\"},\"value\":-0.251544713973999},{\"address\":{\"d0\":\"0\",\"d1\":\"4\"},\"value\":0.017951013520359993},{\"address\":{\"d0\":\"0\",\"d1\":\"5\"},\"value\":1.2899067401885986},{\"address\":{\"d0\":\"0\",\"d1\":\"6\"},\"value\":-0.10389615595340729},{\"address\":{\"d0\":\"0\",\"d1\":\"7\"},\"value\":0.6367976665496826},{\"address\":{\"d0\":\"0\",\"d1\":\"8\"},\"value\":-1.4136744737625122},{\"address\":{\"d0\":\"0\",\"d1\":\"9\"},\"value\":-0.2573896050453186}]}"; + String expected = "{\"type\":\"tensor(d0[],d1[10])\",\"values\":[[-0.3546536862850189,0.3759574592113495,0.06054411828517914,-0.251544713973999,0.017951013520359993,1.2899067401885986,-0.10389615595340729,0.6367976665496826,-1.4136744737625122,-0.2573896050453186]]}"; handler.assertResponse(url, properties, 200, expected); } @@ -179,6 +180,7 @@ public class ModelsEvaluationHandlerTest { public void testMnistSoftmaxEvaluateSpecificFunctionWithBindingsShortForm() { Map<String, String> properties = new HashMap<>(); properties.put("Placeholder", inputTensorShortForm()); + properties.put("format.tensors", "long"); String url = "http://localhost/model-evaluation/v1/mnist_softmax/default.add/eval"; String expected = "{\"cells\":[{\"address\":{\"d0\":\"0\",\"d1\":\"0\"},\"value\":-0.3546536862850189},{\"address\":{\"d0\":\"0\",\"d1\":\"1\"},\"value\":0.3759574592113495},{\"address\":{\"d0\":\"0\",\"d1\":\"2\"},\"value\":0.06054411828517914},{\"address\":{\"d0\":\"0\",\"d1\":\"3\"},\"value\":-0.251544713973999},{\"address\":{\"d0\":\"0\",\"d1\":\"4\"},\"value\":0.017951013520359993},{\"address\":{\"d0\":\"0\",\"d1\":\"5\"},\"value\":1.2899067401885986},{\"address\":{\"d0\":\"0\",\"d1\":\"6\"},\"value\":-0.10389615595340729},{\"address\":{\"d0\":\"0\",\"d1\":\"7\"},\"value\":0.6367976665496826},{\"address\":{\"d0\":\"0\",\"d1\":\"8\"},\"value\":-1.4136744737625122},{\"address\":{\"d0\":\"0\",\"d1\":\"9\"},\"value\":-0.2573896050453186}]}"; handler.assertResponse(url, properties, 200, expected); diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java index 8c2e39d595e..e7b58bf083d 100644 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java @@ -716,7 +716,7 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler { synchronized void writeSingleDocument(Document document) throws IOException { boolean tensorShortForm = false; if (request != null && request.parameters().containsKey("format.tensors")) { - tensorShortForm = request.parameters().get("format.tensors").contains("short"); + tensorShortForm = !(request.parameters().get("format.tensors").contains("long")); } new JsonWriter(json, tensorShortForm).writeFields(document); } diff --git a/vespajlib/src/main/java/com/yahoo/tensor/serialization/JsonFormat.java b/vespajlib/src/main/java/com/yahoo/tensor/serialization/JsonFormat.java index d7758f309db..b683519988c 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/serialization/JsonFormat.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/serialization/JsonFormat.java @@ -109,11 +109,15 @@ public class JsonFormat { private static void encodeValues(IndexedTensor tensor, Cursor cursor, long[] indexes, int dimension) { DimensionSizes sizes = tensor.dimensionSizes(); - for (indexes[dimension] = 0; indexes[dimension] < sizes.size(dimension); ++indexes[dimension]) { - if (dimension < (sizes.dimensions() - 1)) { - encodeValues(tensor, cursor.addArray(), indexes, dimension + 1); - } else { - cursor.addDouble(tensor.get(indexes)); + if (indexes.length == 0) { + cursor.addDouble(tensor.get(0)); + } else { + for (indexes[dimension] = 0; indexes[dimension] < sizes.size(dimension); ++indexes[dimension]) { + if (dimension < (sizes.dimensions() - 1)) { + encodeValues(tensor, cursor.addArray(), indexes, dimension + 1); + } else { + cursor.addDouble(tensor.get(indexes)); + } } } } |