aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2020-03-24 14:16:54 +0000
committerHåvard Pettersen <havardpe@oath.com>2020-03-24 14:16:54 +0000
commit8deefd127ebb7e6797d57ee2f6bf327222bffbe8 (patch)
treeb480d12fb75226b0eb610bf01584f6c5246a0e9c /searchlib
parent0b3704a8e43472b66f0a79ae251ccfc6bcecbfe5 (diff)
rank setup stack usage
With large models comes large stack usage. - compile in separate thread for deterministic stack size (verify rank setup vs. proton config setup) - warn about stack usage when over 128K (note that recursive decent parsing of rank expressions comes on top of the usage reported by the blueprint resolver)
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp44
1 files changed, 35 insertions, 9 deletions
diff --git a/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp b/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
index 6b4a61e1c0f..d229a735f11 100644
--- a/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
+++ b/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
@@ -7,6 +7,7 @@
#include <stack>
#include <cassert>
#include <set>
+#include <thread>
#include <vespa/log/log.h>
LOG_SETUP(".fef.blueprintresolver");
@@ -70,6 +71,8 @@ struct Compiler : public Blueprint::DependencyHandler {
FeatureMap &feature_map;
std::set<vespalib::string> setup_set;
std::set<vespalib::string> failed_set;
+ const char *min_stack;
+ const char *max_stack;
Compiler(const BlueprintFactory &factory_in,
const IIndexEnvironment &index_env_in,
@@ -81,9 +84,21 @@ struct Compiler : public Blueprint::DependencyHandler {
spec_list(spec_list_out),
feature_map(feature_map_out),
setup_set(),
- failed_set() {}
+ failed_set(),
+ min_stack(nullptr),
+ max_stack(nullptr) {}
~Compiler();
+ void probe_stack() {
+ const char c = 'X';
+ min_stack = (min_stack == nullptr) ? &c : std::min(min_stack, &c);
+ max_stack = (max_stack == nullptr) ? &c : std::max(max_stack, &c);
+ }
+
+ int stack_usage() const {
+ return (max_stack - min_stack);
+ }
+
Frame &self() { return resolve_stack.back(); }
bool failed() const { return !failed_set.empty(); }
@@ -120,6 +135,7 @@ struct Compiler : public Blueprint::DependencyHandler {
LOG(warning, "invalid rank feature '%s': %s\n%s", feature_name.c_str(), reason.c_str(), trace.c_str());
}
}
+ probe_stack();
return FeatureRef();
}
@@ -135,6 +151,7 @@ struct Compiler : public Blueprint::DependencyHandler {
fmt("output '%s' has wrong type: was %s, expected %s",
parser.output().c_str(), type_str(is_object), accept_type_str(accept_type)));
}
+ probe_stack();
return ref;
}
@@ -165,7 +182,7 @@ struct Compiler : public Blueprint::DependencyHandler {
return fail(feature_name, "malformed name");
}
if (failed_set.count(parser.featureName()) > 0) {
- return FeatureRef();
+ return fail(parser.featureName(), "already failed");
}
auto old_feature = feature_map.find(parser.featureName());
if (old_feature != feature_map.end()) {
@@ -253,14 +270,23 @@ BlueprintResolver::compile()
{
assert(_executorSpecs.empty()); // only one compilation allowed
Compiler compiler(_factory, _indexEnv, _executorSpecs, _featureMap);
- for (const auto &seed: _seeds) {
- auto ref = compiler.resolve_feature(seed, Blueprint::AcceptInput::ANY);
- if (compiler.failed()) {
- return false;
- }
- _seedMap.emplace(FeatureNameParser(seed).featureName(), ref);
+ std::thread compile_thread([&]()
+ {
+ compiler.probe_stack();
+ for (const auto &seed: _seeds) {
+ auto ref = compiler.resolve_feature(seed, Blueprint::AcceptInput::ANY);
+ if (compiler.failed()) {
+ return;
+ }
+ _seedMap.emplace(FeatureNameParser(seed).featureName(), ref);
+ }
+ });
+ compile_thread.join();
+ int stack_usage = compiler.stack_usage();
+ if (stack_usage > (128 * 1024)) {
+ LOG(warning, "high stack usage: %d bytes", stack_usage);
}
- return true;
+ return !compiler.failed();
}
const BlueprintResolver::ExecutorSpecList &