From d3861f502cb01c6fe77c16f0378c0af04fec502c Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Fri, 1 Sep 2023 17:52:34 +0200 Subject: [PATCH 01/11] Add FDSS 2023 portfolios. --- driver/portfolios/seq_opt_fdss_2023.py | 79 ++++++++++++++++++++++++++ driver/portfolios/seq_sat_fdss_2023.py | 65 +++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 driver/portfolios/seq_opt_fdss_2023.py create mode 100644 driver/portfolios/seq_sat_fdss_2023.py diff --git a/driver/portfolios/seq_opt_fdss_2023.py b/driver/portfolios/seq_opt_fdss_2023.py new file mode 100644 index 0000000000..3d0001f42f --- /dev/null +++ b/driver/portfolios/seq_opt_fdss_2023.py @@ -0,0 +1,79 @@ +""" +This is the "Fast Downward Stone Soup 2023" sequential portfolio that +participated in the IPC 2023 optimal track. + +Clemens Büchner, Remo Christen, Augusto Blaas Corrêa, Salomé Eriksson, Patrick Ferber, Jendrik Seipp and Silvan Sievers. +Fast Downward Stone Soup 2023. +In Tenth International Planning Competition (IPC 2023), Deterministic Part. 2023. +""" + +SAS_FILE = "output.sas" +OPTIMAL = True + +CONFIGS_STRIPS = [ + # ipdb-60s-por + (542, ['--search', 'astar(ipdb(max_time=60), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), + # can-cegar-10s-por + (93, ['--search', 'astar(cpdbs(multiple_cegar(max_pdb_size=1000000,max_collection_size=10000000,pattern_generation_max_time=infinity,total_max_time=10,stagnation_limit=2,blacklist_trigger_percentage=0.75,enable_blacklist_on_stagnation=true,use_wildcard_plans=true)), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), + # mas-ssc-sbmiasm-300s-por + (213, ['--search', 'astar(merge_and_shrink(shrink_strategy=shrink_bisimulation(greedy=false), merge_strategy=merge_sccs(order_of_sccs=topological, merge_selector=score_based_filtering(scoring_functions=[sf_miasm(shrink_strategy=shrink_bisimulation(greedy=false),max_states=50000,threshold_before_merge=1),total_order(atomic_ts_order=reverse_level,product_ts_order=new_to_old,atomic_before_product=false)])), label_reduction=exact(before_shrinking=true, before_merging=false), max_states=50k, threshold_before_merge=1, main_loop_max_time=300), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), + # bjolp + (206, ['--search', 'let(lmc, landmark_cost_partitioning(lm_merged([lm_rhw(), lm_hm(m=1)])), astar(lmc,lazy_evaluator=lmc))']), + # seq-lmcut-por + (105, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints()]), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), + # potential-initial-state + (83, ['--search', 'astar(initial_state_potential())']), + # cartesian-cegar-landmarks-goals-60s-por + (96, ['--search', 'astar(cegar(subtasks=[landmarks(order=random), goals(order=random)], max_states=infinity, max_transitions=infinity, max_time=60), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), + # can-sys3 + (218, ['--search', 'astar(cpdbs(patterns=systematic(3)))']), + # seq-lmcut-hplus-relaxed + (91, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints(), delete_relaxation_constraints(use_time_vars=false, use_integer_vars=false)]))']), +] + +CONFIGS_COND_EFFS = [ + # mas-ssc-dfp-60s + (1137, ['--search', 'astar(merge_and_shrink(shrink_strategy=shrink_bisimulation(greedy=false), merge_strategy=merge_sccs(order_of_sccs=topological, merge_selector=score_based_filtering(scoring_functions=[goal_relevance(), dfp(), total_order(atomic_ts_order=reverse_level,product_ts_order=new_to_old,atomic_before_product=false)])), label_reduction=exact(before_shrinking=true, before_merging=false), max_states=50k, threshold_before_merge=1, main_loop_max_time=60))']), + # mas-ssc-sbmiasm-300s + (346, ['--search', 'astar(merge_and_shrink(shrink_strategy=shrink_bisimulation(greedy=false), merge_strategy=merge_sccs(order_of_sccs=topological, merge_selector=score_based_filtering(scoring_functions=[sf_miasm(shrink_strategy=shrink_bisimulation(greedy=false),max_states=50000,threshold_before_merge=1),total_order(atomic_ts_order=reverse_level,product_ts_order=new_to_old,atomic_before_product=false)])), label_reduction=exact(before_shrinking=true, before_merging=false), max_states=50k, threshold_before_merge=1, main_loop_max_time=300))']), + # hmax + (229, ['--search', 'astar(hmax())']), +] + +CONFIGS_AXIOMS = [ + (1800, ['--search', 'astar(blind())']), +] + + +def get_pddl_features(task): + has_axioms = False + has_conditional_effects = False + with open(task) as f: + in_op = False + for line in f: + line = line.strip() + if line == "begin_rule": + has_axioms = True + + if line == "begin_operator": + in_op = True + elif line == "end_operator": + in_op = False + elif in_op: + parts = line.split() + if len(parts) >= 6 and all(p.lstrip('-').isdigit() for p in parts): + has_conditional_effects = True + return has_axioms, has_conditional_effects + + +HAS_AXIOMS, HAS_CONDITIONAL_EFFECTS = get_pddl_features(SAS_FILE) + +print(f"Task has axioms: {HAS_AXIOMS}") +print(f"Task has conditional effects: {HAS_CONDITIONAL_EFFECTS}") + +if HAS_AXIOMS: + CONFIGS = CONFIGS_AXIOMS +elif HAS_CONDITIONAL_EFFECTS: + CONFIGS = CONFIGS_COND_EFFS +else: + CONFIGS = CONFIGS_STRIPS diff --git a/driver/portfolios/seq_sat_fdss_2023.py b/driver/portfolios/seq_sat_fdss_2023.py new file mode 100644 index 0000000000..27117d2168 --- /dev/null +++ b/driver/portfolios/seq_sat_fdss_2023.py @@ -0,0 +1,65 @@ +""" +This is the "Fast Downward Stone Soup 2023" sequential portfolio that +participated in the IPC 2023 agile and satisficing tracks. + +Clemens Büchner, Remo Christen, Augusto Blaas Corrêa, Salomé Eriksson, Patrick Ferber, Jendrik Seipp and Silvan Sievers. +Fast Downward Stone Soup 2023. +In Tenth International Planning Competition (IPC 2023), Deterministic Part. 2023. +""" + +OPTIMAL = False + +CONFIGS = [ + # fdss-2018-01 + (383, ['--search', 'let(hlm, landmark_sum(lm_reasonable_orders_hps(lm_rhw()),transform=adapt_costs(one)),let(hff, ff(transform=adapt_costs(one)),lazy(alt([single(hff),single(hff,pref_only=true),single(hlm),single(hlm,pref_only=true),type_based([hff,g()])],boost=1000),preferred=[hff,hlm],cost_type=one,reopen_closed=false,randomize_successors=true,preferred_successors_first=false,bound=BOUND, verbosity=silent)))']), + # fdss-2018-03 + (57, ['--search', 'let(hlm, landmark_sum(lm_reasonable_orders_hps(lm_rhw()),transform=adapt_costs(one)),let(hff, ff(transform=adapt_costs(one)),lazy(alt([single(hff),single(hff,pref_only=true),single(hlm),single(hlm,pref_only=true)],boost=1000),preferred=[hff,hlm],cost_type=one,reopen_closed=false,randomize_successors=false,preferred_successors_first=true,bound=BOUND, verbosity=silent)))']), + # lazy_hff_hlm-epsilon-greedy_pref_ops-no-reasonable-orders + (60, ['--search', 'let(hlm, landmark_sum(lm_rhw(), pref=true, transform=adapt_costs(one)),let(hff, ff(transform=adapt_costs(one)),lazy(alt([single(hff),single(hff,pref_only=true),epsilon_greedy(hlm),single(hlm,pref_only=true)],boost=1000),preferred=[hff,hlm],cost_type=one,reopen_closed=false,randomize_successors=true, bound=BOUND, verbosity=silent)))']), + # fdss-2014-01 + (22, ['--search', 'let(hadd, add(transform=adapt_costs(one)),let(hlm, landmark_sum(lm_reasonable_orders_hps(lm_rhw()),transform=adapt_costs(plusone)),lazy_greedy([hadd,hlm],preferred=[hadd,hlm],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2018-04 + (30, ['--search', 'let(hff, ff(transform=adapt_costs(one)),let(hlm, landmark_sum(lm_reasonable_orders_hps(lm_rhw()),transform=adapt_costs(one)),eager_greedy([hff,hlm],preferred=[hff,hlm],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2014-08 + (206, ['--search', 'let(hff, ff(transform=adapt_costs(one)),let(hadd, add(transform=adapt_costs(one)),lazy_greedy([hadd,hff],preferred=[hadd,hff],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2014-03 + (30, ['--search', 'let(hadd, add(transform=adapt_costs(one)),let(hlm, landmark_sum(lm_reasonable_orders_hps(lm_rhw()),transform=adapt_costs(plusone)),eager_greedy([hadd,hlm],preferred=[hadd,hlm],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2018-07 + (21, ['--search', 'let(hcea, cea(transform=adapt_costs(one)),let(hlm, landmark_sum(lm_reasonable_orders_hps(lm_rhw()),transform=adapt_costs(one)),lazy_greedy([hcea,hlm],preferred=[hcea,hlm],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2018-09 + (59, ['--search', 'let(hff, ff(transform=adapt_costs(one)),lazy(alt([single(sum([g(),weight(hff,10)])),single(sum([g(),weight(hff,10)]),pref_only=true)],boost=2000),preferred=[hff],reopen_closed=false,cost_type=one,bound=BOUND, verbosity=silent))']), + # fdss-2014-11 + (89, ['--search', 'let(hff, ff(transform=adapt_costs(one)),let(hlm, landmark_sum(lm_reasonable_orders_hps(lm_rhw()),transform=adapt_costs(plusone)),lazy_wastar([hff,hlm],w=3,preferred=[hff,hlm],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2018-14 + (29, ['--search', 'let(hgoalcount, goalcount(transform=adapt_costs(plusone)),let(hff, ff(),lazy(alt([single(sum([g(),weight(hff,10)])),single(sum([g(),weight(hff,10)]),pref_only=true),single(sum([g(),weight(hgoalcount,10)])),single(sum([g(),weight(hgoalcount,10)]),pref_only=true)],boost=2000),preferred=[hff,hgoalcount],reopen_closed=false,cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-1-03 + (53, ['--search', 'let(hcea, cea(transform=adapt_costs(one)),let(hcg, cg(transform=adapt_costs(one)),lazy_greedy([hcea,hcg],preferred=[hcea,hcg],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2014-16 + (19, ['--search', 'let(hcg, cg(transform=adapt_costs(one)),let(hff, ff(transform=adapt_costs(one)),lazy_wastar([hcg,hff],w=3,preferred=[hcg,hff],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2018-18 + (177, ['--search', 'let(hcg, cg(transform=adapt_costs(plusone)),lazy(alt([type_based([g()]),single(hcg),single(hcg,pref_only=true)],boost=0),preferred=[hcg],reopen_closed=true,cost_type=plusone,bound=BOUND, verbosity=silent))']), + # fdss-2014-13 + (30, ['--search', 'let(hcg, cg(transform=adapt_costs(one)),let(hlm, landmark_sum(lm_reasonable_orders_hps(lm_rhw()),transform=adapt_costs(plusone)),eager_greedy([hcg,hlm],preferred=[hcg,hlm],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2014-18 + (30, ['--search', 'let(hadd, add(transform=adapt_costs(one)),eager(alt([single(sum([g(), weight(hadd, 3)])),single(sum([g(), weight(hadd,3)]),pref_only=true)]),preferred=[hadd],cost_type=one,bound=BOUND, verbosity=silent))']), + # fdss-1-11 + (26, ['--search', 'let(h, cea(transform=adapt_costs(one)),eager_greedy([h],preferred=[h],cost_type=one,bound=BOUND, verbosity=silent))']), + # fdss-2014-19 + (27, ['--search', 'let(hff, ff(transform=adapt_costs(one)),let(hcea, cea(transform=adapt_costs(one)),eager(alt([single(sum([g(),weight(hff,3)])),single(sum([g(),weight(hff,3)]),pref_only=true),single(sum([g(),weight(hcea,3)])),single(sum([g(),weight(hcea,3)]),pref_only=true)]),preferred=[hff,hcea],cost_type=one,bound=BOUND, verbosity=silent)))']), + # fdss-2018-02 + (18, ['--search', 'let(lmg, lm_rhw(only_causal_landmarks=false,disjunctive_landmarks=true,use_orders=false),let(hlm, landmark_cost_partitioning(lmg,transform=adapt_costs(one)),let(hff, ff(transform=adapt_costs(one)),lazy(alt([type_based([g()]),single(hlm),single(hlm,pref_only=true),single(hff),single(hff,pref_only=true)],boost=0),preferred=[hlm],reopen_closed=false,cost_type=plusone,bound=BOUND, verbosity=silent))))']), + # fdss-2018-16 + (29, ['--search', 'let(lmg, lm_rhw(only_causal_landmarks=false,disjunctive_landmarks=false,use_orders=true),let(hlm, landmark_sum(lmg,transform=adapt_costs(one)),let(hff, ff(transform=adapt_costs(one)),let(hblind, blind(),lazy(alt([type_based([g()]),single(sum([g(),weight(hblind,2)])),single(sum([g(),weight(hblind,2)]),pref_only=true),single(sum([g(),weight(hlm,2)])),single(sum([g(),weight(hlm,2)]),pref_only=true),single(sum([g(),weight(hff,2)])),single(sum([g(),weight(hff,2)]),pref_only=true)],boost=4419),preferred=[hlm],reopen_closed=true,cost_type=one,bound=BOUND, verbosity=silent)))))']), + # fdss-2018-29 + (90, ['--search', 'let(hadd, add(transform=adapt_costs(plusone)),let(hff, ff(),lazy(alt([tiebreaking([sum([weight(g(),4),weight(hff,5)]),hff]),tiebreaking([sum([weight(g(),4),weight(hff,5)]),hff],pref_only=true),tiebreaking([sum([weight(g(),4),weight(hadd,5)]),hadd]),tiebreaking([sum([weight(g(),4),weight(hadd,5)]),hadd],pref_only=true)],boost=2537),preferred=[hff,hadd],reopen_closed=true,bound=BOUND, verbosity=silent)))']), + # fdss-2018-31 + (28, ['--search', 'let(hff, ff(transform=adapt_costs(one)),lazy(alt([single(sum([weight(g(),2),weight(hff,3)])),single(sum([weight(g(),2),weight(hff,3)]),pref_only=true)],boost=5000),preferred=[hff],reopen_closed=true,cost_type=one,bound=BOUND, verbosity=silent))']), + # fdss-2018-28 + (29, ['--search', 'let(hblind, blind(),let(hadd, add(),let(hcg, cg(transform=adapt_costs(one)),let(hhmax, hmax(),eager(alt([tiebreaking([sum([g(),weight(hblind,7)]),hblind]),tiebreaking([sum([g(),weight(hhmax,7)]),hhmax]),tiebreaking([sum([g(),weight(hadd,7)]),hadd]),tiebreaking([sum([g(),weight(hcg,7)]),hcg])],boost=2142),preferred=[],reopen_closed=true,bound=BOUND, verbosity=silent)))))']), + # fdss-2018-35 + (85, ['--search', 'let(lmg, lm_hm(conjunctive_landmarks=false,use_orders=false,m=1),let(hcg, cg(transform=adapt_costs(one)),let(hlm, landmark_cost_partitioning(lmg),lazy(alt([single(hlm),single(hlm,pref_only=true),single(hcg),single(hcg,pref_only=true)],boost=0),preferred=[hcg],reopen_closed=false,cost_type=one,bound=BOUND, verbosity=silent))))']), + # fdss-2018-27 + (30, ['--search', 'let(lmg, lm_reasonable_orders_hps(lm_rhw(only_causal_landmarks=true,disjunctive_landmarks=true,use_orders=true)),let(hblind, blind(),let(hadd, add(),let(hlm, landmark_sum(lmg,pref=true,transform=adapt_costs(plusone)),let(hff, ff(),lazy(alt([single(sum([weight(g(),2),weight(hblind,3)])),single(sum([weight(g(),2),weight(hblind,3)]),pref_only=true),single(sum([weight(g(),2),weight(hff,3)])),single(sum([weight(g(),2),weight(hff,3)]),pref_only=true),single(sum([weight(g(),2),weight(hlm,3)])),single(sum([weight(g(),2),weight(hlm,3)]),pref_only=true),single(sum([weight(g(),2),weight(hadd,3)])),single(sum([weight(g(),2),weight(hadd,3)]),pref_only=true)],boost=2474),preferred=[hadd],reopen_closed=false,cost_type=one,bound=BOUND, verbosity=silent))))))']), + # fdss-2018-39 + (59, ['--search', 'let(lmg, lm_exhaust(only_causal_landmarks=false),let(hgoalcount, goalcount(transform=adapt_costs(plusone)),let(hlm, landmark_sum(lmg),let(hff, ff(),let(hblind, blind(),eager(alt([tiebreaking([sum([weight(g(),8),weight(hblind,9)]),hblind]),tiebreaking([sum([weight(g(),8),weight(hlm,9)]),hlm]),tiebreaking([sum([weight(g(),8),weight(hff,9)]),hff]),tiebreaking([sum([weight(g(),8),weight(hgoalcount,9)]),hgoalcount])],boost=2005),preferred=[],reopen_closed=true,bound=BOUND, verbosity=silent))))))']), +] From 576a39b72ec81c08e92bfee3d1f824d56f5544b8 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Mon, 4 Sep 2023 20:26:37 +0200 Subject: [PATCH 02/11] Skip lines with operator names. --- driver/portfolios/seq_opt_fdss_2023.py | 1 + 1 file changed, 1 insertion(+) diff --git a/driver/portfolios/seq_opt_fdss_2023.py b/driver/portfolios/seq_opt_fdss_2023.py index 3d0001f42f..f1a69a2737 100644 --- a/driver/portfolios/seq_opt_fdss_2023.py +++ b/driver/portfolios/seq_opt_fdss_2023.py @@ -57,6 +57,7 @@ def get_pddl_features(task): if line == "begin_operator": in_op = True + next(f) # Skip line with operator name. elif line == "end_operator": in_op = False elif in_op: From 0fa301d9c61a1643bfd908c540e328fd41c981bc Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Mon, 4 Sep 2023 20:34:53 +0200 Subject: [PATCH 03/11] Skip CPLEX configs on macOS. --- driver/tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/driver/tests.py b/driver/tests.py index c594d87ebc..62e5e34a06 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -103,6 +103,9 @@ def test_portfolio_configs(): configs = _get_portfolio_configs(Path(portfolio)) all_configs |= set(tuple(_convert_to_standalone_config(config)) for config in configs) for config in all_configs: + # Skip CPLEX configs on macOS because our GitHub Actions runners don't support it. + if sys.platform == "darwin" and any("operatorcounting" in part for part in config): + continue _run_search(config) From 064873734d032383ba1f941e303e8bd6516afba8 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 5 Sep 2023 09:00:49 +0200 Subject: [PATCH 04/11] Test all configs, use SoPlex. --- driver/portfolios/seq_opt_fdss_2023.py | 6 ++-- driver/tests.py | 39 ++++++++++++++++++-------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/driver/portfolios/seq_opt_fdss_2023.py b/driver/portfolios/seq_opt_fdss_2023.py index f1a69a2737..65737278ad 100644 --- a/driver/portfolios/seq_opt_fdss_2023.py +++ b/driver/portfolios/seq_opt_fdss_2023.py @@ -14,13 +14,13 @@ # ipdb-60s-por (542, ['--search', 'astar(ipdb(max_time=60), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), # can-cegar-10s-por - (93, ['--search', 'astar(cpdbs(multiple_cegar(max_pdb_size=1000000,max_collection_size=10000000,pattern_generation_max_time=infinity,total_max_time=10,stagnation_limit=2,blacklist_trigger_percentage=0.75,enable_blacklist_on_stagnation=true,use_wildcard_plans=true)), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), + (93, ['--search', 'astar(cpdbs(multiple_cegar(max_pdb_size=1000000,max_collection_size=10000000,pattern_generation_max_time=infinity,total_max_time=10,stagnation_limit=2.0,blacklist_trigger_percentage=0.75,enable_blacklist_on_stagnation=true,use_wildcard_plans=true)), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), # mas-ssc-sbmiasm-300s-por (213, ['--search', 'astar(merge_and_shrink(shrink_strategy=shrink_bisimulation(greedy=false), merge_strategy=merge_sccs(order_of_sccs=topological, merge_selector=score_based_filtering(scoring_functions=[sf_miasm(shrink_strategy=shrink_bisimulation(greedy=false),max_states=50000,threshold_before_merge=1),total_order(atomic_ts_order=reverse_level,product_ts_order=new_to_old,atomic_before_product=false)])), label_reduction=exact(before_shrinking=true, before_merging=false), max_states=50k, threshold_before_merge=1, main_loop_max_time=300), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), # bjolp (206, ['--search', 'let(lmc, landmark_cost_partitioning(lm_merged([lm_rhw(), lm_hm(m=1)])), astar(lmc,lazy_evaluator=lmc))']), # seq-lmcut-por - (105, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints()]), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), + (105, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints()], lpsolver=cplex), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), # potential-initial-state (83, ['--search', 'astar(initial_state_potential())']), # cartesian-cegar-landmarks-goals-60s-por @@ -28,7 +28,7 @@ # can-sys3 (218, ['--search', 'astar(cpdbs(patterns=systematic(3)))']), # seq-lmcut-hplus-relaxed - (91, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints(), delete_relaxation_constraints(use_time_vars=false, use_integer_vars=false)]))']), + (91, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints(), delete_relaxation_constraints(use_time_vars=false, use_integer_vars=false)], lpsolver=cplex))']), ] CONFIGS_COND_EFFS = [ diff --git a/driver/tests.py b/driver/tests.py index 62e5e34a06..621613daee 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -27,16 +27,27 @@ def translate(): "misc/tests/benchmarks/gripper/prob01.pddl"] subprocess.check_call(cmd, cwd=REPO_ROOT_DIR) +# We need to translate the example task when this module is imported to have the +# SAS+ file ready for the @pytest.parametrize function below. Translating the +# task in setup_module() does not work here, because the @pytest.parametrize +# decorator is executed before setup_module() is called. An alternative would be +# to use a conftest.py file and call translate() in a pytest_sessionstart() +# function, but that adds another file and leads to dumping the translator +# output to the terminal. +translate() + def cleanup(): subprocess.check_call([sys.executable, "fast-downward.py", "--cleanup"], cwd=REPO_ROOT_DIR) -def run_driver(parameters): +def teardown_module(module): cleanup() - translate() - cmd = [sys.executable, "fast-downward.py"] + parameters + + +def run_driver(parameters): + cmd = [sys.executable, "fast-downward.py", "--keep"] + parameters return subprocess.check_call(cmd, cwd=REPO_ROOT_DIR) @@ -72,9 +83,11 @@ def _get_portfolio_configs(portfolio: Path): traceback.print_exc() raise SyntaxError( f"The portfolio {portfolio} could not be loaded.") - if "CONFIGS" not in attributes: - raise ValueError("portfolios must define CONFIGS") - return [config for _, config in attributes["CONFIGS"]] + for key, value in attributes.items(): + # The optimal FDSS 2023 portfolio defines different configs for different PDDL subsets. + if key.startswith("CONFIGS"): + for _, config in value: + yield config def _convert_to_standalone_config(config): @@ -82,6 +95,7 @@ def _convert_to_standalone_config(config): ("H_COST_TRANSFORM", "no_transform()"), ("S_COST_TYPE", "normal"), ("BOUND", "infinity"), + ("lpsolver=cplex", "lpsolver=soplex"), # CPLEX is not available in all CI runners. ] for index, part in enumerate(config): for before, after in replacements: @@ -97,16 +111,17 @@ def _run_search(config): stdin="output.sas") -def test_portfolio_configs(): +def _get_all_portfolio_configs(): all_configs = set() for portfolio in PORTFOLIOS.values(): configs = _get_portfolio_configs(Path(portfolio)) all_configs |= set(tuple(_convert_to_standalone_config(config)) for config in configs) - for config in all_configs: - # Skip CPLEX configs on macOS because our GitHub Actions runners don't support it. - if sys.platform == "darwin" and any("operatorcounting" in part for part in config): - continue - _run_search(config) + return all_configs + + +@pytest.mark.parametrize("config", _get_all_portfolio_configs()) +def test_portfolio_config(config): + _run_search(config) @pytest.mark.skipif(not limits.can_set_time_limit(), reason="Cannot set time limits on this system") From 329d04fca6dd44a14bb4a953175cc983c3959bf1 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 5 Sep 2023 21:51:59 +0200 Subject: [PATCH 05/11] Don't substitute SoPlex for CPLEX. --- driver/portfolios/seq_opt_fdss_2023.py | 4 ++-- driver/tests.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/driver/portfolios/seq_opt_fdss_2023.py b/driver/portfolios/seq_opt_fdss_2023.py index 65737278ad..96d051de36 100644 --- a/driver/portfolios/seq_opt_fdss_2023.py +++ b/driver/portfolios/seq_opt_fdss_2023.py @@ -20,7 +20,7 @@ # bjolp (206, ['--search', 'let(lmc, landmark_cost_partitioning(lm_merged([lm_rhw(), lm_hm(m=1)])), astar(lmc,lazy_evaluator=lmc))']), # seq-lmcut-por - (105, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints()], lpsolver=cplex), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), + (105, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints()]), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), # potential-initial-state (83, ['--search', 'astar(initial_state_potential())']), # cartesian-cegar-landmarks-goals-60s-por @@ -28,7 +28,7 @@ # can-sys3 (218, ['--search', 'astar(cpdbs(patterns=systematic(3)))']), # seq-lmcut-hplus-relaxed - (91, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints(), delete_relaxation_constraints(use_time_vars=false, use_integer_vars=false)], lpsolver=cplex))']), + (91, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints(), delete_relaxation_constraints(use_time_vars=false, use_integer_vars=false)]))']), ] CONFIGS_COND_EFFS = [ diff --git a/driver/tests.py b/driver/tests.py index 621613daee..1595711338 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -95,7 +95,6 @@ def _convert_to_standalone_config(config): ("H_COST_TRANSFORM", "no_transform()"), ("S_COST_TYPE", "normal"), ("BOUND", "infinity"), - ("lpsolver=cplex", "lpsolver=soplex"), # CPLEX is not available in all CI runners. ] for index, part in enumerate(config): for before, after in replacements: @@ -121,6 +120,8 @@ def _get_all_portfolio_configs(): @pytest.mark.parametrize("config", _get_all_portfolio_configs()) def test_portfolio_config(config): + if sys.platform == "darwin" and any("operatorcounting" in part for part in config): + pytest.skip("macOS CI runners don't support LP configs.") _run_search(config) From 28ad20873ee3f27e8b56567d1d4193ae8509bf1f Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 5 Sep 2023 21:55:48 +0200 Subject: [PATCH 06/11] Only skip tests in CI. --- driver/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver/tests.py b/driver/tests.py index 1595711338..42833492ce 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -120,7 +120,7 @@ def _get_all_portfolio_configs(): @pytest.mark.parametrize("config", _get_all_portfolio_configs()) def test_portfolio_config(config): - if sys.platform == "darwin" and any("operatorcounting" in part for part in config): + if os.getenv("CI") and sys.platform == "darwin" and any("operatorcounting" in part for part in config): pytest.skip("macOS CI runners don't support LP configs.") _run_search(config) From ee85316bf0c521c85ad7a5abf1d4887ce16e939d Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 5 Sep 2023 21:57:10 +0200 Subject: [PATCH 07/11] Pass env var. --- misc/tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/tox.ini b/misc/tox.ini index 45fe839450..728d7781a0 100644 --- a/misc/tox.ini +++ b/misc/tox.ini @@ -23,6 +23,8 @@ allowlist_externals = changedir = {toxinidir}/../ deps = pytest +passenv = + CI commands = pytest driver/tests.py misc/tests/test-exitcodes.py From 039862c94b54043e637cb4d75a95b41d0a9dcdb4 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 5 Sep 2023 22:26:01 +0200 Subject: [PATCH 08/11] Skip potential heuristic on macOS. --- driver/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driver/tests.py b/driver/tests.py index 42833492ce..cd2eb85788 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -120,7 +120,8 @@ def _get_all_portfolio_configs(): @pytest.mark.parametrize("config", _get_all_portfolio_configs()) def test_portfolio_config(config): - if os.getenv("CI") and sys.platform == "darwin" and any("operatorcounting" in part for part in config): + if (os.getenv("CI") and sys.platform == "darwin" and + any("operatorcounting" in part or "initial_state_potential" in part for part in config)): pytest.skip("macOS CI runners don't support LP configs.") _run_search(config) From bef2e98931fd97d85ca32c436b733e31a109e3b1 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Wed, 6 Sep 2023 18:04:50 +0200 Subject: [PATCH 09/11] Remove optimal portfolio. --- driver/portfolios/seq_opt_fdss_2023.py | 80 -------------------------- driver/tests.py | 9 +-- 2 files changed, 1 insertion(+), 88 deletions(-) delete mode 100644 driver/portfolios/seq_opt_fdss_2023.py diff --git a/driver/portfolios/seq_opt_fdss_2023.py b/driver/portfolios/seq_opt_fdss_2023.py deleted file mode 100644 index 96d051de36..0000000000 --- a/driver/portfolios/seq_opt_fdss_2023.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -This is the "Fast Downward Stone Soup 2023" sequential portfolio that -participated in the IPC 2023 optimal track. - -Clemens Büchner, Remo Christen, Augusto Blaas Corrêa, Salomé Eriksson, Patrick Ferber, Jendrik Seipp and Silvan Sievers. -Fast Downward Stone Soup 2023. -In Tenth International Planning Competition (IPC 2023), Deterministic Part. 2023. -""" - -SAS_FILE = "output.sas" -OPTIMAL = True - -CONFIGS_STRIPS = [ - # ipdb-60s-por - (542, ['--search', 'astar(ipdb(max_time=60), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), - # can-cegar-10s-por - (93, ['--search', 'astar(cpdbs(multiple_cegar(max_pdb_size=1000000,max_collection_size=10000000,pattern_generation_max_time=infinity,total_max_time=10,stagnation_limit=2.0,blacklist_trigger_percentage=0.75,enable_blacklist_on_stagnation=true,use_wildcard_plans=true)), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), - # mas-ssc-sbmiasm-300s-por - (213, ['--search', 'astar(merge_and_shrink(shrink_strategy=shrink_bisimulation(greedy=false), merge_strategy=merge_sccs(order_of_sccs=topological, merge_selector=score_based_filtering(scoring_functions=[sf_miasm(shrink_strategy=shrink_bisimulation(greedy=false),max_states=50000,threshold_before_merge=1),total_order(atomic_ts_order=reverse_level,product_ts_order=new_to_old,atomic_before_product=false)])), label_reduction=exact(before_shrinking=true, before_merging=false), max_states=50k, threshold_before_merge=1, main_loop_max_time=300), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), - # bjolp - (206, ['--search', 'let(lmc, landmark_cost_partitioning(lm_merged([lm_rhw(), lm_hm(m=1)])), astar(lmc,lazy_evaluator=lmc))']), - # seq-lmcut-por - (105, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints()]), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), - # potential-initial-state - (83, ['--search', 'astar(initial_state_potential())']), - # cartesian-cegar-landmarks-goals-60s-por - (96, ['--search', 'astar(cegar(subtasks=[landmarks(order=random), goals(order=random)], max_states=infinity, max_transitions=infinity, max_time=60), pruning=limited_pruning(pruning=atom_centric_stubborn_sets(), min_required_pruning_ratio=0.2))']), - # can-sys3 - (218, ['--search', 'astar(cpdbs(patterns=systematic(3)))']), - # seq-lmcut-hplus-relaxed - (91, ['--search', 'astar(operatorcounting([state_equation_constraints(), lmcut_constraints(), delete_relaxation_constraints(use_time_vars=false, use_integer_vars=false)]))']), -] - -CONFIGS_COND_EFFS = [ - # mas-ssc-dfp-60s - (1137, ['--search', 'astar(merge_and_shrink(shrink_strategy=shrink_bisimulation(greedy=false), merge_strategy=merge_sccs(order_of_sccs=topological, merge_selector=score_based_filtering(scoring_functions=[goal_relevance(), dfp(), total_order(atomic_ts_order=reverse_level,product_ts_order=new_to_old,atomic_before_product=false)])), label_reduction=exact(before_shrinking=true, before_merging=false), max_states=50k, threshold_before_merge=1, main_loop_max_time=60))']), - # mas-ssc-sbmiasm-300s - (346, ['--search', 'astar(merge_and_shrink(shrink_strategy=shrink_bisimulation(greedy=false), merge_strategy=merge_sccs(order_of_sccs=topological, merge_selector=score_based_filtering(scoring_functions=[sf_miasm(shrink_strategy=shrink_bisimulation(greedy=false),max_states=50000,threshold_before_merge=1),total_order(atomic_ts_order=reverse_level,product_ts_order=new_to_old,atomic_before_product=false)])), label_reduction=exact(before_shrinking=true, before_merging=false), max_states=50k, threshold_before_merge=1, main_loop_max_time=300))']), - # hmax - (229, ['--search', 'astar(hmax())']), -] - -CONFIGS_AXIOMS = [ - (1800, ['--search', 'astar(blind())']), -] - - -def get_pddl_features(task): - has_axioms = False - has_conditional_effects = False - with open(task) as f: - in_op = False - for line in f: - line = line.strip() - if line == "begin_rule": - has_axioms = True - - if line == "begin_operator": - in_op = True - next(f) # Skip line with operator name. - elif line == "end_operator": - in_op = False - elif in_op: - parts = line.split() - if len(parts) >= 6 and all(p.lstrip('-').isdigit() for p in parts): - has_conditional_effects = True - return has_axioms, has_conditional_effects - - -HAS_AXIOMS, HAS_CONDITIONAL_EFFECTS = get_pddl_features(SAS_FILE) - -print(f"Task has axioms: {HAS_AXIOMS}") -print(f"Task has conditional effects: {HAS_CONDITIONAL_EFFECTS}") - -if HAS_AXIOMS: - CONFIGS = CONFIGS_AXIOMS -elif HAS_CONDITIONAL_EFFECTS: - CONFIGS = CONFIGS_COND_EFFS -else: - CONFIGS = CONFIGS_STRIPS diff --git a/driver/tests.py b/driver/tests.py index cd2eb85788..cacd34310a 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -83,11 +83,7 @@ def _get_portfolio_configs(portfolio: Path): traceback.print_exc() raise SyntaxError( f"The portfolio {portfolio} could not be loaded.") - for key, value in attributes.items(): - # The optimal FDSS 2023 portfolio defines different configs for different PDDL subsets. - if key.startswith("CONFIGS"): - for _, config in value: - yield config + return [config for _, config in attributes["CONFIGS"]] def _convert_to_standalone_config(config): @@ -120,9 +116,6 @@ def _get_all_portfolio_configs(): @pytest.mark.parametrize("config", _get_all_portfolio_configs()) def test_portfolio_config(config): - if (os.getenv("CI") and sys.platform == "darwin" and - any("operatorcounting" in part or "initial_state_potential" in part for part in config)): - pytest.skip("macOS CI runners don't support LP configs.") _run_search(config) From 43e7df9883b1ea596315870532bcd57609cc86f5 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Wed, 6 Sep 2023 18:07:56 +0200 Subject: [PATCH 10/11] Remove obsolete changes. --- driver/tests.py | 2 ++ misc/tox.ini | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/driver/tests.py b/driver/tests.py index cacd34310a..c9f61179d2 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -83,6 +83,8 @@ def _get_portfolio_configs(portfolio: Path): traceback.print_exc() raise SyntaxError( f"The portfolio {portfolio} could not be loaded.") + if "CONFIGS" not in attributes: + raise ValueError("portfolios must define CONFIGS") return [config for _, config in attributes["CONFIGS"]] diff --git a/misc/tox.ini b/misc/tox.ini index 728d7781a0..45fe839450 100644 --- a/misc/tox.ini +++ b/misc/tox.ini @@ -23,8 +23,6 @@ allowlist_externals = changedir = {toxinidir}/../ deps = pytest -passenv = - CI commands = pytest driver/tests.py misc/tests/test-exitcodes.py From ad2e5d30a33e593450fc59a289bf63e369a112a3 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Thu, 5 Oct 2023 15:53:33 +0200 Subject: [PATCH 11/11] Translate task in conftest.py --- driver/conftest.py | 21 +++++++++++++++++++++ driver/tests.py | 16 ---------------- 2 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 driver/conftest.py diff --git a/driver/conftest.py b/driver/conftest.py new file mode 100644 index 0000000000..1273ea1b83 --- /dev/null +++ b/driver/conftest.py @@ -0,0 +1,21 @@ +# This file is read by pytest before running the tests to set them up. We use it +# to have the SAS+ file for the example task ready for the @pytest.parametrize +# function in tests.py. Translating the task in setup_module() does not work in +# this case, because the @pytest.parametrize decorator is executed before +# setup_module() is called. + +import subprocess +import sys + +from .util import REPO_ROOT_DIR + + +def translate(): + """Create output.sas file for example task.""" + cmd = [sys.executable, "fast-downward.py", "--translate", + "misc/tests/benchmarks/gripper/prob01.pddl"] + subprocess.check_call(cmd, cwd=REPO_ROOT_DIR) + + +def pytest_sessionstart(session): + translate() diff --git a/driver/tests.py b/driver/tests.py index c9f61179d2..7b060dca8b 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -21,22 +21,6 @@ from .util import REPO_ROOT_DIR, find_domain_filename -def translate(): - """Create translated task.""" - cmd = [sys.executable, "fast-downward.py", "--translate", - "misc/tests/benchmarks/gripper/prob01.pddl"] - subprocess.check_call(cmd, cwd=REPO_ROOT_DIR) - -# We need to translate the example task when this module is imported to have the -# SAS+ file ready for the @pytest.parametrize function below. Translating the -# task in setup_module() does not work here, because the @pytest.parametrize -# decorator is executed before setup_module() is called. An alternative would be -# to use a conftest.py file and call translate() in a pytest_sessionstart() -# function, but that adds another file and leads to dumping the translator -# output to the terminal. -translate() - - def cleanup(): subprocess.check_call([sys.executable, "fast-downward.py", "--cleanup"], cwd=REPO_ROOT_DIR)