summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2019-06-13 16:19:28 +0000
committerHåvard Pettersen <havardpe@oath.com>2019-06-13 16:19:28 +0000
commitbec261866af1a690e9f0ed43bc4f4bd42dc08d3a (patch)
tree81efc9957ee2990f59a2f7dd05bab9b35f60d479 /searchcore
parent534cf911ca025f17961979f1d52259b823749d62 (diff)
populate feature sets with serialized tensors
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/tests/proton/matching/matching_test.cpp26
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_master.cpp18
2 files changed, 29 insertions, 15 deletions
diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp
index 2a29847a634..b34a8c84237 100644
--- a/searchcore/src/tests/proton/matching/matching_test.cpp
+++ b/searchcore/src/tests/proton/matching/matching_test.cpp
@@ -630,21 +630,21 @@ TEST("require that summary features are filled") {
world.basicResults();
DocsumRequest::SP req = world.createSimpleDocsumRequest("f1", "foo");
FeatureSet::SP fs = world.getSummaryFeatures(req);
- const feature_t * f = NULL;
+ const FeatureSet::Value * f = NULL;
EXPECT_EQUAL(2u, fs->numFeatures());
EXPECT_EQUAL("attribute(a1)", fs->getNames()[0]);
EXPECT_EQUAL("value(100)", fs->getNames()[1]);
EXPECT_EQUAL(2u, fs->numDocs());
f = fs->getFeaturesByDocId(10);
EXPECT_TRUE(f != NULL);
- EXPECT_EQUAL(10, f[0]);
- EXPECT_EQUAL(100, f[1]);
+ EXPECT_EQUAL(10, f[0].as_double());
+ EXPECT_EQUAL(100, f[1].as_double());
f = fs->getFeaturesByDocId(15);
EXPECT_TRUE(f == NULL);
f = fs->getFeaturesByDocId(30);
EXPECT_TRUE(f != NULL);
- EXPECT_EQUAL(30, f[0]);
- EXPECT_EQUAL(100, f[1]);
+ EXPECT_EQUAL(30, f[0].as_double());
+ EXPECT_EQUAL(100, f[1].as_double());
}
TEST("require that rank features are filled") {
@@ -653,18 +653,18 @@ TEST("require that rank features are filled") {
world.basicResults();
DocsumRequest::SP req = world.createSimpleDocsumRequest("f1", "foo");
FeatureSet::SP fs = world.getRankFeatures(req);
- const feature_t * f = NULL;
+ const FeatureSet::Value * f = NULL;
EXPECT_EQUAL(1u, fs->numFeatures());
EXPECT_EQUAL("attribute(a2)", fs->getNames()[0]);
EXPECT_EQUAL(2u, fs->numDocs());
f = fs->getFeaturesByDocId(10);
EXPECT_TRUE(f != NULL);
- EXPECT_EQUAL(20, f[0]);
+ EXPECT_EQUAL(20, f[0].as_double());
f = fs->getFeaturesByDocId(15);
EXPECT_TRUE(f == NULL);
f = fs->getFeaturesByDocId(30);
EXPECT_TRUE(f != NULL);
- EXPECT_EQUAL(60, f[0]);
+ EXPECT_EQUAL(60, f[0].as_double());
}
TEST("require that search session can be cached") {
@@ -703,10 +703,10 @@ TEST("require that getSummaryFeatures can use cached query setup") {
EXPECT_EQUAL("attribute(a1)", fs->getNames()[0]);
EXPECT_EQUAL("value(100)", fs->getNames()[1]);
ASSERT_EQUAL(1u, fs->numDocs());
- const feature_t *f = fs->getFeaturesByDocId(30);
+ const auto *f = fs->getFeaturesByDocId(30);
ASSERT_TRUE(f);
- EXPECT_EQUAL(30, f[0]);
- EXPECT_EQUAL(100, f[1]);
+ EXPECT_EQUAL(30, f[0].as_double());
+ EXPECT_EQUAL(100, f[1].as_double());
// getSummaryFeatures can be called multiple times.
fs = world.getSummaryFeatures(docsum_request);
@@ -716,8 +716,8 @@ TEST("require that getSummaryFeatures can use cached query setup") {
ASSERT_EQUAL(1u, fs->numDocs());
f = fs->getFeaturesByDocId(30);
ASSERT_TRUE(f);
- EXPECT_EQUAL(30, f[0]);
- EXPECT_EQUAL(100, f[1]);
+ EXPECT_EQUAL(30, f[0].as_double());
+ EXPECT_EQUAL(100, f[1].as_double());
}
TEST("require that getSummaryFeatures prefers cached query setup") {
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
index ca159228f25..b86ccc22bcf 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
@@ -11,6 +11,9 @@
#include <vespa/vespalib/data/slime/inserter.h>
#include <vespa/vespalib/data/slime/inject.h>
#include <vespa/vespalib/data/slime/cursor.h>
+#include <vespa/eval/eval/tensor.h>
+#include <vespa/eval/eval/tensor_engine.h>
+#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/log/log.h>
LOG_SETUP(".proton.matching.match_master");
@@ -144,9 +147,20 @@ MatchMaster::getFeatureSet(const MatchToolsFactory &mtf,
if (search.seek(docs[i])) {
uint32_t docId = search.getDocId();
search.unpack(docId);
- search::feature_t * f = fs.getFeaturesByIndex(fs.addDocId(docId));
+ auto * f = fs.getFeaturesByIndex(fs.addDocId(docId));
for (uint32_t j = 0; j < featureNames.size(); ++j) {
- f[j] = resolver.resolve(j).as_number(docId);
+ if (resolver.is_object(j)) {
+ auto obj = resolver.resolve(j).as_object(docId);
+ if (const auto *tensor = obj.get().as_tensor()) {
+ vespalib::nbostream buf;
+ tensor->engine().encode(*tensor, buf);
+ f[j].set_data(vespalib::Memory(buf.peek(), buf.size()));
+ } else {
+ f[j].set_double(obj.get().as_double());
+ }
+ } else {
+ f[j].set_double(resolver.resolve(j).as_number(docId));
+ }
}
} else {
LOG(debug, "getFeatureSet: Did not find hit for docid '%u'. Skipping hit", docs[i]);