diff options
author | HÃ¥vard Pettersen <3535158+havardpe@users.noreply.github.com> | 2022-01-27 10:49:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-27 10:49:00 +0100 |
commit | 941d3a6d4d8c1a710669d7dfe0609300833fe6e6 (patch) | |
tree | 9437510bcad8000ad14029ee82f71f13dbc61579 /eval | |
parent | c790fe3631168f68efcc8c9e8fe5a30e414517d2 (diff) | |
parent | 59c6f9191059039abad80e3c406ec14a0b56686c (diff) |
Merge pull request #20941 from vespa-engine/havardpe/handle-nan-in-tensor-spec-to-expr
handle nan cells when converting tensor spec to expression
Diffstat (limited to 'eval')
-rw-r--r-- | eval/src/tests/eval/tensor_spec/tensor_spec_test.cpp | 15 | ||||
-rw-r--r-- | eval/src/vespa/eval/eval/tensor_spec.cpp | 18 |
2 files changed, 31 insertions, 2 deletions
diff --git a/eval/src/tests/eval/tensor_spec/tensor_spec_test.cpp b/eval/src/tests/eval/tensor_spec/tensor_spec_test.cpp index 4c5b847abc1..6023d472d13 100644 --- a/eval/src/tests/eval/tensor_spec/tensor_spec_test.cpp +++ b/eval/src/tests/eval/tensor_spec/tensor_spec_test.cpp @@ -7,6 +7,10 @@ using vespalib::Slime; using vespalib::eval::TensorSpec; +auto my_nan = std::numeric_limits<double>::quiet_NaN(); +auto my_neg_inf = (-1.0/0.0); +auto my_inf = (1.0/0.0); + TEST("require that a tensor spec can be converted to and from slime") { TensorSpec spec("tensor(x[2],y{})"); spec.add({{"x", 0}, {"y", "xxx"}}, 1.0) @@ -30,6 +34,17 @@ TEST("require that a tensor spec can be converted to and from an expression") { EXPECT_EQUAL(TensorSpec::from_expr(expr), spec); } +TEST("require that nan/inf/-inf cells get converted to valid expressions") { + TensorSpec spec("tensor<float>(x[2],y{})"); + spec.add({{"x", 0}, {"y", "xxx"}}, my_nan) + .add({{"x", 0}, {"y", "yyy"}}, my_nan) + .add({{"x", 1}, {"y", "xxx"}}, my_neg_inf) + .add({{"x", 1}, {"y", "yyy"}}, my_inf); + vespalib::string expr = spec.to_expr(); + fprintf(stderr, "expr: \n%s\n", expr.c_str()); + EXPECT_EQUAL(TensorSpec::from_expr(expr), spec); +} + TEST("require that tensor specs can be diffed") { TensorSpec expect("tensor(x[2],y{})"); expect.add({{"x", 0}, {"y", "xxx"}}, 1.5) diff --git a/eval/src/vespa/eval/eval/tensor_spec.cpp b/eval/src/vespa/eval/eval/tensor_spec.cpp index 025f3e8c0a3..223e32ce04f 100644 --- a/eval/src/vespa/eval/eval/tensor_spec.cpp +++ b/eval/src/vespa/eval/eval/tensor_spec.cpp @@ -19,6 +19,20 @@ namespace eval { namespace { +vespalib::string number_to_expr(double value) { + if (std::isfinite(value)) { + return make_string("%g", value); + } else if (std::isnan(value)) { + return {"(0/0)"}; + } else { // -inf or inf + if (value < 0) { + return {"(-1/0)"}; + } else { + return {"(1/0)"}; + } + } +} + TensorSpec::Address extract_address(const slime::Inspector &address) { struct Extractor : slime::ObjectTraverser { TensorSpec::Address address; @@ -288,14 +302,14 @@ vespalib::string TensorSpec::to_expr() const { if (_type == "double") { - return make_string("%g", as_double()); + return number_to_expr(as_double()); } vespalib::string out = _type; out.append(":{"); CommaTracker cell_list; for (const auto &cell: _cells) { cell_list.maybe_add_comma(out); - out.append(make_string("%s:%g", as_string(cell.first).c_str(), cell.second.value)); + out.append(make_string("%s:%s", as_string(cell.first).c_str(), number_to_expr(cell.second.value).c_str())); } out.append("}"); return out; |