diff options
Diffstat (limited to 'eval/src/apps/make_tensor_binary_format_test_spec')
4 files changed, 664 insertions, 0 deletions
diff --git a/eval/src/apps/make_tensor_binary_format_test_spec/.gitignore b/eval/src/apps/make_tensor_binary_format_test_spec/.gitignore new file mode 100644 index 00000000000..aff1914d6bf --- /dev/null +++ b/eval/src/apps/make_tensor_binary_format_test_spec/.gitignore @@ -0,0 +1 @@ +/eval_make_tensor_binary_format_test_spec_app diff --git a/eval/src/apps/make_tensor_binary_format_test_spec/CMakeLists.txt b/eval/src/apps/make_tensor_binary_format_test_spec/CMakeLists.txt new file mode 100644 index 00000000000..b12bd919124 --- /dev/null +++ b/eval/src/apps/make_tensor_binary_format_test_spec/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(eval_make_tensor_binary_format_test_spec_app + SOURCES + make_tensor_binary_format_test_spec.cpp + DEPENDS + vespaeval +) diff --git a/eval/src/apps/make_tensor_binary_format_test_spec/make_tensor_binary_format_test_spec.cpp b/eval/src/apps/make_tensor_binary_format_test_spec/make_tensor_binary_format_test_spec.cpp new file mode 100644 index 00000000000..4e274aa513d --- /dev/null +++ b/eval/src/apps/make_tensor_binary_format_test_spec/make_tensor_binary_format_test_spec.cpp @@ -0,0 +1,320 @@ +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/vespalib/data/slime/slime.h> +#include <vespa/vespalib/objects/nbostream.h> +#include <vespa/vespalib/util/stringfmt.h> +#include <vespa/eval/eval/tensor_spec.h> +#include <vespa/eval/eval/value_type.h> +#include <iostream> + +using namespace vespalib; +using namespace vespalib::eval; +using namespace vespalib::slime::convenience; + +using Opts = std::initializer_list<std::reference_wrapper<const nbostream>>; +using Dict = std::vector<vespalib::string>; + +//----------------------------------------------------------------------------- + +nbostream make_sparse() { + nbostream data; + data << uint8_t(0x1); + return data; +} + +nbostream make_dense() { + nbostream data; + data << uint8_t(0x2); + return data; +} + +nbostream make_mixed() { + nbostream data; + data << uint8_t(0x3); + return data; +} + +void set_tensor(Cursor &test, const TensorSpec &spec) { + const Inspector &old_tensor = test["tensor"]; + if (old_tensor.valid()) { + TensorSpec old_spec = TensorSpec::from_slime(old_tensor); + if (!(old_spec == spec)) { + fprintf(stderr, "inconsistent specs\n"); + std::cerr << old_spec; + std::cerr << spec; + abort(); // inconsistent specs across binary permutations + } + } else { + Cursor &tensor = test.setObject("tensor"); + spec.to_slime(tensor); + } +} + +void add_binary(Cursor &test, const nbostream &data) { + if (!test["binary"].valid()) { + test.setArray("binary"); + } + test["binary"].addData(Memory(data.peek(), data.size())); +} + +void add_binary(Cursor &test, Opts opts) { + for (const nbostream &opt: opts) { + add_binary(test, opt); + } +} + +std::vector<Dict> perm(const Dict &dict) { + std::vector<Dict> list; + if (dict.empty()) { + } else if (dict.size() == 1) { + list.push_back(dict); + } else if (dict.size() == 2) { + list.push_back({dict[0], dict[1]}); + list.push_back({dict[1], dict[0]}); + } else if (dict.size() == 3) { + list.push_back({dict[0], dict[1], dict[2]}); + list.push_back({dict[0], dict[2], dict[1]}); + list.push_back({dict[1], dict[0], dict[2]}); + list.push_back({dict[1], dict[2], dict[0]}); + list.push_back({dict[2], dict[0], dict[1]}); + list.push_back({dict[2], dict[1], dict[0]}); + } else { + fprintf(stderr, "unsupported permutation size: %zu\n", dict.size()); + abort(); // perm only implemented for sizes (0,1,2,3) + } + return list; +}; + +const std::map<std::string, double> val_map{ + {"a", 1.0}, + {"b", 2.0}, + {"c", 3.0}, + {"foo", 1.0}, + {"bar", 2.0}}; + +double val(size_t idx) { return double(idx + 1); } +double val(const vespalib::string &label) { + auto res = val_map.find(label); + if (res == val_map.end()) { + fprintf(stderr, "unsupported label: '%s'\n", label.c_str()); + abort(); // unsupported label + } + return res->second; +} +double mix(std::initializer_list<double> vals) { + double value = 0.0; + for (double val: vals) { + value = ((value * 10) + val); + } + return value; +} + +//----------------------------------------------------------------------------- + +void make_number_test(Cursor &test, double value) { + TensorSpec spec("double"); + spec.add({{}}, value); + nbostream sparse = make_sparse(); + sparse.putInt1_4Bytes(0); + sparse.putInt1_4Bytes(1); + sparse << value; + nbostream dense = make_dense(); + dense.putInt1_4Bytes(0); + dense << value; + nbostream mixed = make_mixed(); + mixed.putInt1_4Bytes(0); + mixed.putInt1_4Bytes(0); + mixed << value; + set_tensor(test, spec); + add_binary(test, {sparse, dense, mixed}); + if (value == 0.0) { + nbostream empty = make_sparse(); + empty.putInt1_4Bytes(0); + empty.putInt1_4Bytes(0); + add_binary(test, empty); + } +} + +//----------------------------------------------------------------------------- + +void make_vector_test(Cursor &test, size_t x_size) { + TensorSpec spec(vespalib::make_string("tensor(x[%zu])", x_size)); + nbostream dense = make_dense(); + dense.putInt1_4Bytes(1); + dense.writeSmallString("x"); + dense.putInt1_4Bytes(x_size); + nbostream mixed = make_mixed(); + mixed.putInt1_4Bytes(0); + mixed.putInt1_4Bytes(1); + mixed.writeSmallString("x"); + mixed.putInt1_4Bytes(x_size); + for (size_t x = 0; x < x_size; ++x) { + double value = val(x); + spec.add({{"x", x}}, value); + dense << value; + mixed << value; + } + set_tensor(test, spec); + add_binary(test, {dense, mixed}); +} + +void make_matrix_test(Cursor &test, size_t x_size, size_t y_size) { + TensorSpec spec(vespalib::make_string("tensor(x[%zu],y[%zu])", x_size, y_size)); + nbostream dense = make_dense(); + dense.putInt1_4Bytes(2); + dense.writeSmallString("x"); + dense.putInt1_4Bytes(x_size); + dense.writeSmallString("y"); + dense.putInt1_4Bytes(y_size); + nbostream mixed = make_mixed(); + mixed.putInt1_4Bytes(0); + mixed.putInt1_4Bytes(2); + mixed.writeSmallString("x"); + mixed.putInt1_4Bytes(x_size); + mixed.writeSmallString("y"); + mixed.putInt1_4Bytes(y_size); + for (size_t x = 0; x < x_size; ++x) { + for (size_t y = 0; y < y_size; ++y) { + double value = mix({val(x), val(y)}); + spec.add({{"x", x}, {"y", y}}, value); + dense << value; + mixed << value; + } + } + set_tensor(test, spec); + add_binary(test, {dense, mixed}); +} + +//----------------------------------------------------------------------------- + +void make_map_test(Cursor &test, const Dict &x_dict_in) { + TensorSpec spec("tensor(x{})"); + nbostream sparse_base = make_sparse(); + sparse_base.putInt1_4Bytes(1); + sparse_base.writeSmallString("x"); + sparse_base.putInt1_4Bytes(x_dict_in.size()); + nbostream mixed_base = make_mixed(); + mixed_base.putInt1_4Bytes(1); + mixed_base.writeSmallString("x"); + mixed_base.putInt1_4Bytes(0); + mixed_base.putInt1_4Bytes(x_dict_in.size()); + auto x_perm = perm(x_dict_in); + for (const Dict &x_dict: x_perm) { + nbostream sparse = sparse_base; + nbostream mixed = mixed_base; + for (vespalib::string x: x_dict) { + double value = val(x); + spec.add({{"x", x}}, value); + sparse.writeSmallString(x); + mixed.writeSmallString(x); + sparse << value; + mixed << value; + } + set_tensor(test, spec); + add_binary(test, {sparse, mixed}); + } + if (x_dict_in.empty()) { + set_tensor(test, spec); + add_binary(test, {sparse_base, mixed_base}); + } +} + +void make_mesh_test(Cursor &test, const Dict &x_dict_in, const vespalib::string &y) { + TensorSpec spec("tensor(x{},y{})"); + nbostream sparse_base = make_sparse(); + sparse_base.putInt1_4Bytes(2); + sparse_base.writeSmallString("x"); + sparse_base.writeSmallString("y"); + sparse_base.putInt1_4Bytes(x_dict_in.size() * 1); + nbostream mixed_base = make_mixed(); + mixed_base.putInt1_4Bytes(2); + mixed_base.writeSmallString("x"); + mixed_base.writeSmallString("y"); + mixed_base.putInt1_4Bytes(0); + mixed_base.putInt1_4Bytes(x_dict_in.size() * 1); + auto x_perm = perm(x_dict_in); + for (const Dict &x_dict: x_perm) { + nbostream sparse = sparse_base; + nbostream mixed = mixed_base; + for (vespalib::string x: x_dict) { + double value = mix({val(x), val(y)}); + spec.add({{"x", x}, {"y", y}}, value); + sparse.writeSmallString(x); + sparse.writeSmallString(y); + mixed.writeSmallString(x); + mixed.writeSmallString(y); + sparse << value; + mixed << value; + } + set_tensor(test, spec); + add_binary(test, {sparse, mixed}); + } + if (x_dict_in.empty()) { + set_tensor(test, spec); + add_binary(test, {sparse_base, mixed_base}); + } +} + +//----------------------------------------------------------------------------- + +void make_vector_map_test(Cursor &test, + const vespalib::string &mapped_name, const Dict &mapped_dict, + const vespalib::string &indexed_name, size_t indexed_size) +{ + auto type_str = vespalib::make_string("tensor(%s{},%s[%zu])", + mapped_name.c_str(), indexed_name.c_str(), indexed_size); + ValueType type = ValueType::from_spec(type_str); + TensorSpec spec(type.to_spec()); // ensures type string is normalized + nbostream mixed_base = make_mixed(); + mixed_base.putInt1_4Bytes(1); + mixed_base.writeSmallString(mapped_name); + mixed_base.putInt1_4Bytes(1); + mixed_base.writeSmallString(indexed_name); + mixed_base.putInt1_4Bytes(indexed_size); + mixed_base.putInt1_4Bytes(mapped_dict.size()); + auto mapped_perm = perm(mapped_dict); + for (const Dict &dict: mapped_perm) { + nbostream mixed = mixed_base; + for (vespalib::string label: dict) { + mixed.writeSmallString(label); + for (size_t idx = 0; idx < indexed_size; ++idx) { + double value = mix({val(label), val(idx)}); + spec.add({{mapped_name, label}, {indexed_name, idx}}, value); + mixed << value; + } + } + set_tensor(test, spec); + add_binary(test, mixed); + } + if (mapped_dict.empty()) { + set_tensor(test, spec); + add_binary(test, mixed_base); + } +} + +//----------------------------------------------------------------------------- + +void make_tests(Cursor &tests) { + make_number_test(tests.addObject(), 0.0); + make_number_test(tests.addObject(), 42.0); + make_vector_test(tests.addObject(), 3); + make_matrix_test(tests.addObject(), 2, 3); + make_map_test(tests.addObject(), {}); + make_map_test(tests.addObject(), {"a", "b", "c"}); + make_mesh_test(tests.addObject(), {}, "a"); + make_mesh_test(tests.addObject(), {"foo", "bar"}, "a"); + make_vector_map_test(tests.addObject(), "x", {}, "y", 10); + make_vector_map_test(tests.addObject(), "y", {}, "x", 10); + make_vector_map_test(tests.addObject(), "x", {"a", "b"}, "y", 3); + make_vector_map_test(tests.addObject(), "y", {"a", "b"}, "x", 3); +} + +int main(int, char **) { + Slime slime; + Cursor &top = slime.setObject(); + Cursor &tests = top.setArray("tests"); + make_tests(tests); + top.setLong("num_tests", tests.entries()); + fprintf(stdout, "%s", slime.toString().c_str()); + return 0; +} diff --git a/eval/src/apps/make_tensor_binary_format_test_spec/test_spec.json b/eval/src/apps/make_tensor_binary_format_test_spec/test_spec.json new file mode 100644 index 00000000000..1b74b4b8838 --- /dev/null +++ b/eval/src/apps/make_tensor_binary_format_test_spec/test_spec.json @@ -0,0 +1,336 @@ +{ + "tests": [ + { + "tensor": { + "type": "double", + "cells": [ + { + "address": { + }, + "value": 0 + } + ] + }, + "binary": [ + "0x0100010000000000000000", + "0x02000000000000000000", + "0x0300000000000000000000", + "0x010000" + ] + }, + { + "tensor": { + "type": "double", + "cells": [ + { + "address": { + }, + "value": 42 + } + ] + }, + "binary": [ + "0x0100014045000000000000", + "0x02004045000000000000", + "0x0300004045000000000000" + ] + }, + { + "tensor": { + "type": "tensor(x[3])", + "cells": [ + { + "address": { + "x": 0 + }, + "value": 1 + }, + { + "address": { + "x": 1 + }, + "value": 2 + }, + { + "address": { + "x": 2 + }, + "value": 3 + } + ] + }, + "binary": [ + "0x02010178033FF000000000000040000000000000004008000000000000", + "0x0300010178033FF000000000000040000000000000004008000000000000" + ] + }, + { + "tensor": { + "type": "tensor(x[2],y[3])", + "cells": [ + { + "address": { + "x": 0, + "y": 0 + }, + "value": 11 + }, + { + "address": { + "x": 0, + "y": 1 + }, + "value": 12 + }, + { + "address": { + "x": 0, + "y": 2 + }, + "value": 13 + }, + { + "address": { + "x": 1, + "y": 0 + }, + "value": 21 + }, + { + "address": { + "x": 1, + "y": 1 + }, + "value": 22 + }, + { + "address": { + "x": 1, + "y": 2 + }, + "value": 23 + } + ] + }, + "binary": [ + "0x020201780201790340260000000000004028000000000000402A000000000000403500000000000040360000000000004037000000000000", + "0x03000201780201790340260000000000004028000000000000402A000000000000403500000000000040360000000000004037000000000000" + ] + }, + { + "tensor": { + "type": "tensor(x{})", + "cells": [ + ] + }, + "binary": [ + "0x0101017800", + "0x030101780000" + ] + }, + { + "tensor": { + "type": "tensor(x{})", + "cells": [ + { + "address": { + "x": "a" + }, + "value": 1 + }, + { + "address": { + "x": "b" + }, + "value": 2 + }, + { + "address": { + "x": "c" + }, + "value": 3 + } + ] + }, + "binary": [ + "0x010101780301613FF00000000000000162400000000000000001634008000000000000", + "0x03010178000301613FF00000000000000162400000000000000001634008000000000000", + "0x010101780301613FF00000000000000163400800000000000001624000000000000000", + "0x03010178000301613FF00000000000000163400800000000000001624000000000000000", + "0x01010178030162400000000000000001613FF000000000000001634008000000000000", + "0x0301017800030162400000000000000001613FF000000000000001634008000000000000", + "0x0101017803016240000000000000000163400800000000000001613FF0000000000000", + "0x030101780003016240000000000000000163400800000000000001613FF0000000000000", + "0x01010178030163400800000000000001613FF000000000000001624000000000000000", + "0x0301017800030163400800000000000001613FF000000000000001624000000000000000", + "0x0101017803016340080000000000000162400000000000000001613FF0000000000000", + "0x030101780003016340080000000000000162400000000000000001613FF0000000000000" + ] + }, + { + "tensor": { + "type": "tensor(x{},y{})", + "cells": [ + ] + }, + "binary": [ + "0x01020178017900", + "0x0302017801790000" + ] + }, + { + "tensor": { + "type": "tensor(x{},y{})", + "cells": [ + { + "address": { + "x": "bar", + "y": "a" + }, + "value": 21 + }, + { + "address": { + "x": "foo", + "y": "a" + }, + "value": 11 + } + ] + }, + "binary": [ + "0x0102017801790203666F6F016140260000000000000362617201614035000000000000", + "0x030201780179000203666F6F016140260000000000000362617201614035000000000000", + "0x01020178017902036261720161403500000000000003666F6F01614026000000000000", + "0x0302017801790002036261720161403500000000000003666F6F01614026000000000000" + ] + }, + { + "tensor": { + "type": "tensor(x{},y[10])", + "cells": [ + ] + }, + "binary": [ + "0x030101780101790A00" + ] + }, + { + "tensor": { + "type": "tensor(x[10],y{})", + "cells": [ + ] + }, + "binary": [ + "0x030101790101780A00" + ] + }, + { + "tensor": { + "type": "tensor(x{},y[3])", + "cells": [ + { + "address": { + "x": "a", + "y": 0 + }, + "value": 11 + }, + { + "address": { + "x": "a", + "y": 1 + }, + "value": 12 + }, + { + "address": { + "x": "a", + "y": 2 + }, + "value": 13 + }, + { + "address": { + "x": "b", + "y": 0 + }, + "value": 21 + }, + { + "address": { + "x": "b", + "y": 1 + }, + "value": 22 + }, + { + "address": { + "x": "b", + "y": 2 + }, + "value": 23 + } + ] + }, + "binary": [ + "0x030101780101790302016140260000000000004028000000000000402A0000000000000162403500000000000040360000000000004037000000000000", + "0x0301017801017903020162403500000000000040360000000000004037000000000000016140260000000000004028000000000000402A000000000000" + ] + }, + { + "tensor": { + "type": "tensor(x[3],y{})", + "cells": [ + { + "address": { + "x": 0, + "y": "a" + }, + "value": 11 + }, + { + "address": { + "x": 0, + "y": "b" + }, + "value": 21 + }, + { + "address": { + "x": 1, + "y": "a" + }, + "value": 12 + }, + { + "address": { + "x": 1, + "y": "b" + }, + "value": 22 + }, + { + "address": { + "x": 2, + "y": "a" + }, + "value": 13 + }, + { + "address": { + "x": 2, + "y": "b" + }, + "value": 23 + } + ] + }, + "binary": [ + "0x030101790101780302016140260000000000004028000000000000402A0000000000000162403500000000000040360000000000004037000000000000", + "0x0301017901017803020162403500000000000040360000000000004037000000000000016140260000000000004028000000000000402A000000000000" + ] + } + ], + "num_tests": 12 +} |