diff --git a/build.py b/build.py index c85f776cfe..d2dcd94013 100755 --- a/build.py +++ b/build.py @@ -98,7 +98,7 @@ def build(config_name, configure_parameters, build_parameters): print(f"Building configuration {config_name}.") build_path = get_build_path(config_name) - generator_cmd = [CMAKE, "-S", get_src_path(), "-B", build_path] + generator_cmd = [CMAKE, "-S", get_src_path(), "-B", build_path, "-DCMAKE_EXPORT_COMPILE_COMMANDS=1"] if CMAKE_GENERATOR: generator_cmd += ["-G", CMAKE_GENERATOR] generator_cmd += configure_parameters diff --git a/driver/arguments.py b/driver/arguments.py index 9800d1e795..53e7e3174b 100644 --- a/driver/arguments.py +++ b/driver/arguments.py @@ -440,7 +440,12 @@ def parse_args(): driver_other.add_argument( "--cleanup", action="store_true", help="clean up temporary files (translator output and plan files) and exit") - + + driver_other.add_argument( + "--profile", choices=["none", "time", "memory"], + default="none", + help="profile the time or memory usage of the search component using valgrind tools") + parser.add_argument( "planner_args", nargs=argparse.REMAINDER, help="file names and options passed on to planner components") diff --git a/driver/run_components.py b/driver/run_components.py index 3c2cc2ff0a..16f61cf805 100644 --- a/driver/run_components.py +++ b/driver/run_components.py @@ -124,6 +124,15 @@ def run_search(args): portfolio_bound=args.portfolio_bound, single_plan=args.portfolio_single_plan) plan_manager.delete_existing_plans() + # Add profiling options + + profile = [] + if "time" == args.profile: + # args.search_options = '--tool=callgrind --dump-instr=yes --collect-jumps=yes --callgrind-out-file=callgrind.out'.split(' ') + args.search_options + profile = "valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes --callgrind-out-file=callgrind.out".split(' ') + elif "memory" == args.profile: + # args.search_options = '--leak-check=full --track-origins=yes --log-file=memory-info.out'.split(' ') + args.search_options + profile = "valgrind --leak-check=full --track-origins=yes --log-file=memory-info.out".split(' ') if args.portfolio: assert not args.search_options @@ -140,6 +149,7 @@ def run_search(args): try: call.check_call( "search", + profile + [executable] + args.search_options, stdin=args.search_input, time_limit=time_limit, diff --git a/src/search/search_algorithm.cc b/src/search/search_algorithm.cc index 0fe0b536a1..e7ecc06113 100644 --- a/src/search/search_algorithm.cc +++ b/src/search/search_algorithm.cc @@ -14,6 +14,8 @@ #include "utils/timer.h" #include "pr2/pr2.h" +#include "pr2/policy.h" +#include "pr2/deadend.h" #include #include @@ -151,6 +153,12 @@ void SearchAlgorithm::set_plan(const Plan &p) { } void SearchAlgorithm::search() { + if (PR2.deadend.record_online) { + PR2.deadend.found_online.clear(); + delete PR2.deadend.online_policy; + PR2.deadend.online_policy = new Policy(); + } + initialize(); utils::CountdownTimer timer(max_time); while (status == IN_PROGRESS) { @@ -161,6 +169,12 @@ void SearchAlgorithm::search() { break; } } + + if (PR2.deadend.record_online && + !PR2.weaksearch.limit_states && + PR2.deadend.found_online.size() > 0) + update_deadends(PR2.deadend.found_online); + // TODO: Revise when and which search times are logged. if (PR2.logging.verbose) log << "Actual search time: " << timer.get_elapsed_time() << endl; diff --git a/src/search/search_algorithms/lazy_search.cc b/src/search/search_algorithms/lazy_search.cc index acd2271974..2e6d52ddb4 100644 --- a/src/search/search_algorithms/lazy_search.cc +++ b/src/search/search_algorithms/lazy_search.cc @@ -87,6 +87,12 @@ void LazySearch::initialize() { if (PR2.logging.verbose) log << "Conducting lazy best first search, (real) bound = " << bound << endl; + // Only set up the heuristics on the first go + if (was_initialized) + return; + else + was_initialized = true; + assert(open_list); set evals; open_list->get_path_dependent_evaluators(evals); @@ -214,6 +220,13 @@ SearchStatus LazySearch::step() { !node.is_dead_end() && (current_g < node.get_g()); if (node.is_new() || reopen) { + if (PR2.weaksearch.limit_states) { + if (state_count > PR2.weaksearch.max_states) + return FAILED; + else + state_count++; + } + if (current_operator_id != OperatorID::no_operator) { assert(current_predecessor_id != StateID::no_state); if (!path_dependent_evaluators.empty()) { diff --git a/src/search/search_algorithms/lazy_search.h b/src/search/search_algorithms/lazy_search.h index 218d237f21..3406ce43cd 100644 --- a/src/search/search_algorithms/lazy_search.h +++ b/src/search/search_algorithms/lazy_search.h @@ -44,6 +44,9 @@ class LazySearch : public SearchAlgorithm { int current_real_g; EvaluationContext current_eval_context; + int state_count; // Used to limit the search when replanning for a local goal + bool was_initialized; + virtual void initialize() override; virtual SearchStatus step() override; diff --git a/src/search/state_registry.cc b/src/search/state_registry.cc index 9a74f22ed3..d8f8ad383c 100644 --- a/src/search/state_registry.cc +++ b/src/search/state_registry.cc @@ -63,13 +63,6 @@ const State &StateRegistry::get_initial_state() { StateID id = insert_id_or_pop_state(); cached_initial_state = make_unique(lookup_state(id)); } - int x = 1 + 1; - x = 1 + 1; - x = 1 + 1; - x = 1 + 1; - x = 1 + 1; - x = 1 + 1; - x = 1 + 1; // I think this return is broken return *cached_initial_state; }