summaryrefslogtreecommitdiffstats
path: root/searchcore/src/tests/proton/verify_ranksetup
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2020-09-02 12:57:18 +0000
committerHåvard Pettersen <havardpe@oath.com>2020-09-02 13:23:05 +0000
commitece34e9b3039efe5bfc05ff8b3c566734db15320 (patch)
tree75a49f67e23f8823f87352b2dae3d6ecf461aa78 /searchcore/src/tests/proton/verify_ranksetup
parent71d07c1af54bd61a12a7636f2f30716ab49d97cc (diff)
test onnx models (plus some cleanup)
Diffstat (limited to 'searchcore/src/tests/proton/verify_ranksetup')
-rw-r--r--searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.cpp158
1 files changed, 97 insertions, 61 deletions
diff --git a/searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.cpp b/searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.cpp
index 2f5ee2f22cb..21f66735748 100644
--- a/searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.cpp
+++ b/searchcore/src/tests/proton/verify_ranksetup/verify_ranksetup_test.cpp
@@ -21,6 +21,8 @@ using namespace search::index;
using search::index::schema::CollectionType;
using search::index::schema::DataType;
+using vespalib::make_string_short::fmt;
+
struct Writer {
FILE *file;
Writer(const std::string &file_name) {
@@ -61,14 +63,15 @@ struct Attribute {
Attribute::~Attribute() {}
-struct Model {
+struct Setup {
std::map<std::string,std::pair<std::string,std::string> > indexes;
std::map<std::string,Attribute> attributes;
std::map<std::string,std::string> properties;
std::map<std::string,std::string> constants;
std::vector<bool> extra_profiles;
- Model();
- ~Model();
+ std::map<std::string,std::string> onnx_models;
+ Setup();
+ ~Setup();
void index(const std::string &name, schema::DataType data_type,
schema::CollectionType collection_type)
{
@@ -85,6 +88,9 @@ struct Model {
void property(const std::string &name, const std::string &val) {
properties[name] = val;
}
+ void rank_expr(const std::string &name, const std::string &expr) {
+ property(fmt("rankingExpression(%s).rankingScript", name.c_str()), expr);
+ }
void first_phase(const std::string &feature) {
property(rank::FirstPhase::NAME, feature);
}
@@ -146,15 +152,33 @@ struct Model {
++idx;
}
}
+ void write_onnx_models(const Writer &out) {
+ size_t idx = 0;
+ for (const auto &entry: onnx_models) {
+ out.fmt("model[%zu].name \"%s\"\n", idx, entry.first.c_str());
+ out.fmt("model[%zu].fileref \"onnx_ref_%zu\"\n", idx, idx);
+ ++idx;
+ }
+ }
+ void write_self_cfg(const Writer &out) {
+ size_t idx = 0;
+ for (const auto &entry: onnx_models) {
+ out.fmt("file[%zu].ref \"onnx_ref_%zu\"\n", idx, idx);
+ out.fmt("file[%zu].path \"%s\"\n", idx, entry.second.c_str());
+ ++idx;
+ }
+ }
void generate() {
write_attributes(Writer(gen_dir + "/attributes.cfg"));
write_indexschema(Writer(gen_dir + "/indexschema.cfg"));
write_rank_profiles(Writer(gen_dir + "/rank-profiles.cfg"));
write_ranking_constants(Writer(gen_dir + "/ranking-constants.cfg"));
+ write_onnx_models(Writer(gen_dir + "/onnx-models.cfg"));
+ write_self_cfg(Writer(gen_dir + "/verify-ranksetup.cfg"));
}
bool verify() {
generate();
- return vespalib::ChildProcess::run(vespalib::make_string("%s dir:%s", prog, gen_dir.c_str()).c_str());
+ return vespalib::ChildProcess::run(fmt("%s dir:%s", prog, gen_dir.c_str()).c_str());
}
void verify_valid(std::initializer_list<std::string> features) {
for (const std::string &f: features) {
@@ -174,7 +198,7 @@ struct Model {
}
};
-Model::Model()
+Setup::Setup()
: indexes(),
attributes(),
properties(),
@@ -182,14 +206,14 @@ Model::Model()
{
verify_dir();
}
-Model::~Model() {}
+Setup::~Setup() {}
//-----------------------------------------------------------------------------
-struct EmptyModel : Model {};
+struct EmptySetup : Setup {};
-struct SimpleModel : Model {
- SimpleModel() : Model() {
+struct SimpleSetup : Setup {
+ SimpleSetup() : Setup() {
index("title", DataType::STRING, CollectionType::SINGLE);
index("list", DataType::STRING, CollectionType::ARRAY);
index("keywords", DataType::STRING, CollectionType::WEIGHTEDSET);
@@ -199,29 +223,35 @@ struct SimpleModel : Model {
}
};
-struct ShadowModel : Model {
- ShadowModel() : Model() {
+struct OnnxSetup : Setup {
+ OnnxSetup() : Setup() {
+ onnx_models["simple"] = TEST_PATH("../../../../../eval/src/tests/tensor/onnx_wrapper/simple.onnx");
+ }
+};
+
+struct ShadowSetup : Setup {
+ ShadowSetup() : Setup() {
index("both", DataType::STRING, CollectionType::SINGLE);
attribute("both", DataType::STRING, CollectionType::SINGLE);
}
};
-TEST_F("print usage", Model()) {
- EXPECT_TRUE(!vespalib::ChildProcess::run(vespalib::make_string("%s", prog).c_str()));
+TEST_F("print usage", Setup()) {
+ EXPECT_TRUE(!vespalib::ChildProcess::run(fmt("%s", prog).c_str()));
}
-TEST_F("setup output directory", Model()) {
- ASSERT_TRUE(vespalib::ChildProcess::run(vespalib::make_string("rm -rf %s", gen_dir.c_str()).c_str()));
- ASSERT_TRUE(vespalib::ChildProcess::run(vespalib::make_string("mkdir %s", gen_dir.c_str()).c_str()));
+TEST_F("setup output directory", Setup()) {
+ ASSERT_TRUE(vespalib::ChildProcess::run(fmt("rm -rf %s", gen_dir.c_str()).c_str()));
+ ASSERT_TRUE(vespalib::ChildProcess::run(fmt("mkdir %s", gen_dir.c_str()).c_str()));
}
//-----------------------------------------------------------------------------
-TEST_F("require that empty setup passes validation", EmptyModel()) {
+TEST_F("require that empty setup passes validation", EmptySetup()) {
EXPECT_TRUE(f.verify());
}
-TEST_F("require that we can verify multiple rank profiles", SimpleModel()) {
+TEST_F("require that we can verify multiple rank profiles", SimpleSetup()) {
f.first_phase(valid_feature);
f.good_profile();
EXPECT_TRUE(f.verify());
@@ -229,95 +259,101 @@ TEST_F("require that we can verify multiple rank profiles", SimpleModel()) {
EXPECT_TRUE(!f.verify());
}
-TEST_F("require that first phase can break validation", SimpleModel()) {
+TEST_F("require that first phase can break validation", SimpleSetup()) {
f.first_phase(invalid_feature);
EXPECT_TRUE(!f.verify());
}
-TEST_F("require that second phase can break validation", SimpleModel()) {
+TEST_F("require that second phase can break validation", SimpleSetup()) {
f.second_phase(invalid_feature);
EXPECT_TRUE(!f.verify());
}
-TEST_F("require that summary features can break validation", SimpleModel()) {
+TEST_F("require that summary features can break validation", SimpleSetup()) {
f.summary_feature(invalid_feature);
EXPECT_TRUE(!f.verify());
}
-TEST_F("require that dump features can break validation", SimpleModel()) {
+TEST_F("require that dump features can break validation", SimpleSetup()) {
f.dump_feature(invalid_feature);
EXPECT_TRUE(!f.verify());
}
-TEST_F("require that fieldMatch feature requires single value field", SimpleModel()) {
- f.first_phase("fieldMatch(keywords)");
- EXPECT_TRUE(!f.verify());
- f.first_phase("fieldMatch(list)");
- EXPECT_TRUE(!f.verify());
- f.first_phase("fieldMatch(title)");
- EXPECT_TRUE(f.verify());
+//-----------------------------------------------------------------------------
+
+TEST_F("require that fieldMatch feature requires single value field", SimpleSetup()) {
+ f.verify_invalid({"fieldMatch(keywords)", "fieldMatch(list)"});
+ f.verify_valid({"fieldMatch(title)"});
}
-TEST_F("require that age feature requires attribute parameter", SimpleModel()) {
- f.first_phase("age(unknown)");
- EXPECT_TRUE(!f.verify());
- f.first_phase("age(title)");
- EXPECT_TRUE(!f.verify());
- f.first_phase("age(date)");
- EXPECT_TRUE(f.verify());
+TEST_F("require that age feature requires attribute parameter", SimpleSetup()) {
+ f.verify_invalid({"age(unknown)", "age(title)"});
+ f.verify_valid({"age(date)"});
}
-TEST_F("require that nativeRank can be used on any valid field", SimpleModel()) {
+TEST_F("require that nativeRank can be used on any valid field", SimpleSetup()) {
f.verify_invalid({"nativeRank(unknown)"});
f.verify_valid({"nativeRank", "nativeRank(title)", "nativeRank(date)", "nativeRank(title,date)"});
}
-TEST_F("require that nativeAttributeMatch requires attribute parameter", SimpleModel()) {
+TEST_F("require that nativeAttributeMatch requires attribute parameter", SimpleSetup()) {
f.verify_invalid({"nativeAttributeMatch(unknown)", "nativeAttributeMatch(title)", "nativeAttributeMatch(title,date)"});
f.verify_valid({"nativeAttributeMatch", "nativeAttributeMatch(date)"});
}
-TEST_F("require that shadowed attributes can be used", ShadowModel()) {
- f.first_phase("attribute(both)");
- EXPECT_TRUE(f.verify());
+TEST_F("require that shadowed attributes can be used", ShadowSetup()) {
+ f.verify_valid({"attribute(both)"});
}
-TEST_F("require that ranking constants can be used", SimpleModel()) {
- f.first_phase("constant(my_tensor)");
- EXPECT_TRUE(f.verify());
+TEST_F("require that ranking constants can be used", SimpleSetup()) {
+ f.verify_valid({"constant(my_tensor)"});
}
-TEST_F("require that undefined ranking constants cannot be used", SimpleModel()) {
- f.first_phase("constant(bogus_tensor)");
- EXPECT_TRUE(!f.verify());
+TEST_F("require that undefined ranking constants cannot be used", SimpleSetup()) {
+ f.verify_invalid({"constant(bogus_tensor)"});
}
-TEST_F("require that ranking expressions can be verified", SimpleModel()) {
- f.first_phase("rankingExpression(\\\"constant(my_tensor)+attribute(date)\\\")");
- EXPECT_TRUE(f.verify());
+TEST_F("require that ranking expressions can be verified", SimpleSetup()) {
+ f.rank_expr("my_expr", "constant(my_tensor)+attribute(date)");
+ f.verify_valid({"rankingExpression(my_expr)"});
}
//-----------------------------------------------------------------------------
-TEST_F("require that tensor join is supported", SimpleModel()) {
- f.first_phase("rankingExpression(\\\"join(constant(my_tensor),attribute(date),f(t,d)(t+d))\\\")");
- EXPECT_TRUE(f.verify());
+TEST_F("require that tensor join is supported", SimpleSetup()) {
+ f.rank_expr("my_expr", "join(constant(my_tensor),attribute(date),f(t,d)(t+d))");
+ f.verify_valid({"rankingExpression(my_expr)"});
}
-TEST_F("require that nested tensor join is not supported", SimpleModel()) {
- f.first_phase("rankingExpression(\\\"join(constant(my_tensor),attribute(date),f(t,d)(join(t,d,f(x,y)(x+y))))\\\")");
- EXPECT_TRUE(!f.verify());
+TEST_F("require that nested tensor join is not supported", SimpleSetup()) {
+ f.rank_expr("my_expr", "join(constant(my_tensor),attribute(date),f(t,d)(join(t,d,f(x,y)(x+y))))");
+ f.verify_invalid({"rankingExpression(my_expr)"});
}
-TEST_F("require that imported attribute field can be used by rank feature", SimpleModel()) {
- f.first_phase("attribute(imported_attr)");
- EXPECT_TRUE(f.verify());
+TEST_F("require that imported attribute field can be used by rank feature", SimpleSetup()) {
+ f.verify_valid({"attribute(imported_attr)"});
+}
+
+//-----------------------------------------------------------------------------
+
+TEST_F("require that onnx model can be verified", OnnxSetup()) {
+ f.rank_expr("query_tensor", "tensor<float>(a[1],b[4]):[[1,2,3,4]]");
+ f.rank_expr("attribute_tensor", "tensor<float>(a[4],b[1]):[[5],[6],[7],[8]]");
+ f.rank_expr("bias_tensor", "tensor<float>(a[1],b[1]):[[9]]");
+ f.verify_valid({"onnxModel(simple)"});
+}
+
+TEST_F("require that input type mismatch makes onnx model fail verification", OnnxSetup()) {
+ f.rank_expr("query_tensor", "tensor<double>(a[1],b[4]):[[1,2,3,4]]"); // <- double vs float
+ f.rank_expr("attribute_tensor", "tensor<float>(a[4],b[1]):[[5],[6],[7],[8]]");
+ f.rank_expr("bias_tensor", "tensor<float>(a[1],b[1]):[[9]]");
+ f.verify_invalid({"onnxModel(simple)"});
}
//-----------------------------------------------------------------------------
-TEST_F("cleanup files", Model()) {
- ASSERT_TRUE(vespalib::ChildProcess::run(vespalib::make_string("rm -rf %s", gen_dir.c_str()).c_str()));
+TEST_F("cleanup files", Setup()) {
+ ASSERT_TRUE(vespalib::ChildProcess::run(fmt("rm -rf %s", gen_dir.c_str()).c_str()));
}
TEST_MAIN_WITH_PROCESS_PROXY() { TEST_RUN_ALL(); }