2020#include < warthog/util/pqueue.h>
2121#include < warthog/util/scenario_manager.h>
2222#include < warthog/util/timer.h>
23+ #ifdef WARTHOG_POSTHOC
24+ #include < warthog/io/grid_trace.h>
25+ #endif
2326
2427#include " cfg.h"
2528#include < getopt.h>
3033#include < fstream>
3134#include < functional>
3235#include < iomanip>
36+ #include < iostream>
3337#include < memory>
3438#include < sstream>
3539#include < unordered_map>
@@ -44,6 +48,16 @@ int checkopt = 0;
4448int verbose = 0 ;
4549// display program help on startup
4650int print_help = 0 ;
51+ // run only this query, or -1 for all
52+ int filter_id = -1 ;
53+ #ifdef WARTHOG_POSTHOC
54+ // write trace to file, empty string to disable
55+ std::string trace_file;
56+ using listener_grid = ::warthog::io::grid_trace;
57+ using listener_type = std::tuple<listener_grid>;
58+ #else
59+ using listener_type = std::tuple<>;
60+ #endif
4761
4862void
4963help (std::ostream& out)
@@ -66,6 +80,11 @@ help(std::ostream& out)
6680 " values in the scen file)\n "
6781 << " \t --verbose (optional; prints debugging info when compiled "
6882 " with debug symbols)\n "
83+ << " \t --filter [id] (optional; run only query [id])\n "
84+ #ifdef WARTHOG_POSTHOC
85+ << " \t --trace [.trace.yaml file] (optional; write posthoc trace for "
86+ " first query to [file])\n "
87+ #endif
6988 << " Invoking the program this way solves all instances in [scen "
7089 " file] with algorithm [alg]\n "
7190 << " Currently recognised values for [alg]:\n "
@@ -104,21 +123,49 @@ check_optimality(
104123 return true ;
105124}
106125
126+ #ifdef WARTHOG_POSTHOC
127+ #define WARTHOG_POSTHOC_DO (f ) f
128+ #else
129+ #define WARTHOG_POSTHOC_DO (f )
130+ #endif
131+
107132template <typename Search>
108133int
109134run_experiments (
110135 Search& algo, std::string alg_name,
111136 warthog::util::scenario_manager& scenmgr, bool verbose, bool checkopt,
112137 std::ostream& out)
113138{
139+ WARTHOG_GINFO_FMT (" start search with algorithm {}" , alg_name);
114140 warthog::search::search_parameters par;
115141 warthog::search::solution sol;
116142 auto * expander = algo.get_expander ();
117143 if (expander == nullptr ) return 1 ;
144+
118145 out << " id\t alg\t expanded\t generated\t reopen\t surplus\t heapops"
119146 << " \t nanos\t plen\t pcost\t scost\t map\n " ;
120- for (unsigned int i = 0 ; i < scenmgr.num_experiments (); i++)
147+ for (uint32_t i = filter_id >= 0 ? static_cast <uint32_t >(filter_id) : 0 ,
148+ ie = filter_id >= 0
149+ ? i + 1
150+ : static_cast <uint32_t >(scenmgr.num_experiments ());
151+ i < ie; i++)
121152 {
153+ #ifdef WARTHOG_POSTHOC
154+ std::optional<std::ofstream>
155+ trace_stream; // open and pass to trace if used
156+ if constexpr (std::same_as<
157+ listener_type,
158+ std::remove_cvref_t <decltype (algo.get_listeners ())>>)
159+ {
160+ if (i == filter_id && !trace_file.empty ())
161+ {
162+ listener_grid& l
163+ = std::get<listener_grid>(algo.get_listeners ());
164+ trace_stream.emplace (trace_file);
165+ l.open (*trace_stream);
166+ }
167+ }
168+ #endif
122169 warthog::util::experiment* exp = scenmgr.get_experiment (i);
123170
124171 warthog::pack_id startid
@@ -130,21 +177,40 @@ run_experiments(
130177
131178 algo.get_path (&pi, &par, &sol);
132179
180+ #ifdef WARTHOG_POSTHOC
181+ if constexpr (std::same_as<
182+ listener_type,
183+ std::remove_cvref_t <decltype (algo.get_listeners ())>>)
184+ {
185+ if (trace_stream.has_value ())
186+ {
187+ // close
188+ std::get<listener_grid>(algo.get_listeners ()).close ();
189+ }
190+ }
191+ #endif
192+
133193 out << i << " \t " << alg_name << " \t " << sol.met_ .nodes_expanded_
134194 << " \t " << sol.met_ .nodes_generated_ << " \t "
135195 << sol.met_ .nodes_reopen_ << " \t " << sol.met_ .nodes_surplus_
136196 << " \t " << sol.met_ .heap_ops_ << " \t "
137197 << sol.met_ .time_elapsed_nano_ .count () << " \t "
138- << (sol.path_ .size () - 1 ) << " \t " << sol. sum_of_edge_costs_ << " \t "
139- << exp-> distance () << " \t " << scenmgr. last_file_loaded ()
140- << std::endl;
198+ << (! sol.path_ .empty () ? sol. path_ . size () - 1 : 0 ) << " \t "
199+ << sol. sum_of_edge_costs_ << " \t " << exp-> distance () << " \t "
200+ << scenmgr. last_file_loaded () << std::endl;
141201
142202 if (checkopt)
143203 {
144- if (!check_optimality (sol, exp)) return 4 ;
204+ if (!check_optimality (sol, exp))
205+ {
206+ WARTHOG_GCRIT (" search error: failed suboptimal 4" );
207+ return 4 ;
208+ }
145209 }
146210 }
147211
212+ WARTHOG_GINFO_FMT (
213+ " search complete; total memory: {}" , algo.mem () + scenmgr.mem ());
148214 return 0 ;
149215}
150216
@@ -158,17 +224,12 @@ run_astar(
158224 warthog::heuristic::octile_heuristic heuristic (map.width (), map.height ());
159225 warthog::util::pqueue_min open;
160226
161- warthog::search::unidirectional_search astar (&heuristic, &expander, &open);
227+ warthog::search::unidirectional_search astar (
228+ &heuristic, &expander, &open, listener_type (WARTHOG_POSTHOC_DO (&map)));
162229
163230 int ret = run_experiments (
164231 astar, alg_name, scenmgr, verbose, checkopt, std::cout);
165- if (ret != 0 )
166- {
167- std::cerr << " run_experiments error code " << ret << std::endl;
168- return ret;
169- }
170- std::cerr << " done. total memory: " << astar.mem () + scenmgr.mem () << " \n " ;
171- return 0 ;
232+ return ret;
172233}
173234
174235int
@@ -182,17 +243,12 @@ run_astar4c(
182243 map.width (), map.height ());
183244 warthog::util::pqueue_min open;
184245
185- warthog::search::unidirectional_search astar (&heuristic, &expander, &open);
246+ warthog::search::unidirectional_search astar (
247+ &heuristic, &expander, &open, listener_type (WARTHOG_POSTHOC_DO (&map)));
186248
187249 int ret = run_experiments (
188250 astar, alg_name, scenmgr, verbose, checkopt, std::cout);
189- if (ret != 0 )
190- {
191- std::cerr << " run_experiments error code " << ret << std::endl;
192- return ret;
193- }
194- std::cerr << " done. total memory: " << astar.mem () + scenmgr.mem () << " \n " ;
195- return 0 ;
251+ return ret;
196252}
197253
198254int
@@ -205,17 +261,12 @@ run_dijkstra(
205261 warthog::heuristic::zero_heuristic heuristic;
206262 warthog::util::pqueue_min open;
207263
208- warthog::search::unidirectional_search astar (&heuristic, &expander, &open);
264+ warthog::search::unidirectional_search astar (
265+ &heuristic, &expander, &open, listener_type (WARTHOG_POSTHOC_DO (&map)));
209266
210267 int ret = run_experiments (
211268 astar, alg_name, scenmgr, verbose, checkopt, std::cout);
212- if (ret != 0 )
213- {
214- std::cerr << " run_experiments error code " << ret << std::endl;
215- return ret;
216- }
217- std::cerr << " done. total memory: " << astar.mem () + scenmgr.mem () << " \n " ;
218- return 0 ;
269+ return ret;
219270}
220271
221272int
@@ -242,13 +293,7 @@ run_wgm_astar(
242293
243294 int ret = run_experiments (
244295 astar, alg_name, scenmgr, verbose, checkopt, std::cout);
245- if (ret != 0 )
246- {
247- std::cerr << " run_experiments error code " << ret << std::endl;
248- return ret;
249- }
250- std::cerr << " done. total memory: " << astar.mem () + scenmgr.mem () << " \n " ;
251- return 0 ;
296+ return ret;
252297}
253298
254299} // namespace
@@ -258,13 +303,17 @@ main(int argc, char** argv)
258303{
259304 // parse arguments
260305 warthog::util::param valid_args[]
261- = {{" alg" , required_argument, 0 , 1 },
306+ = {{" alg" , required_argument, 0 , 0 },
262307 {" scen" , required_argument, 0 , 0 },
263- {" map" , required_argument, 0 , 1 },
308+ {" map" , required_argument, 0 , 0 },
264309 // {"gen", required_argument, 0, 3},
265310 {" help" , no_argument, &print_help, 1 },
266311 {" checkopt" , no_argument, &checkopt, 1 },
267312 {" verbose" , no_argument, &verbose, 1 },
313+ {" filter" , required_argument, &filter_id, 1 },
314+ #ifdef WARTHOG_POSTHOC
315+ {" trace" , required_argument, 0 , 0 },
316+ #endif
268317 {" costs" , required_argument, 0 , 1 },
269318 {0 , 0 , 0 , 0 }};
270319
@@ -283,6 +332,14 @@ main(int argc, char** argv)
283332 std::string mapfile = cfg.get_param_value (" map" );
284333 std::string costfile = cfg.get_param_value (" costs" );
285334
335+ if (filter_id == 1 )
336+ {
337+ filter_id = std::stoi (cfg.get_param_value (" filter" ));
338+ }
339+ #ifdef WARTHOG_POSTHOC
340+ trace_file = cfg.get_param_value (" trace" );
341+ #endif
342+
286343 // if(gen != "")
287344 // {
288345 // warthog::util::scenario_manager sm;
0 commit comments