more perf counters
This commit is contained in:
parent
725980e694
commit
e77fd6e69f
15 changed files with 643 additions and 54 deletions
1
DOCS.md
1
DOCS.md
|
|
@ -186,6 +186,7 @@ Use `RoutingProblem.initial_paths` to provide semantic per-net seeds. Seeds are
|
||||||
Lower-level search and collision modules are semi-private implementation details. They remain accessible through deep imports for advanced use, but they are unstable and may change without notice. The stable supported entrypoint is `route(problem, options=...)`.
|
Lower-level search and collision modules are semi-private implementation details. They remain accessible through deep imports for advanced use, but they are unstable and may change without notice. The stable supported entrypoint is `route(problem, options=...)`.
|
||||||
|
|
||||||
The current implementation structure is summarized in **[docs/architecture.md](docs/architecture.md)**. The committed example-corpus counter baseline is tracked in **[docs/performance.md](docs/performance.md)**.
|
The current implementation structure is summarized in **[docs/architecture.md](docs/architecture.md)**. The committed example-corpus counter baseline is tracked in **[docs/performance.md](docs/performance.md)**.
|
||||||
|
Use `scripts/diff_performance_baseline.py` to compare a fresh local run against that baseline. The counter baseline is currently observational and is not enforced as a CI gate.
|
||||||
|
|
||||||
## 9. Tuning Notes
|
## 9. Tuning Notes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,23 +3,25 @@
|
||||||
Generated on 2026-03-31 by `scripts/record_performance_baseline.py`.
|
Generated on 2026-03-31 by `scripts/record_performance_baseline.py`.
|
||||||
|
|
||||||
The full machine-readable snapshot lives in `docs/performance_baseline.json`.
|
The full machine-readable snapshot lives in `docs/performance_baseline.json`.
|
||||||
|
Use `scripts/diff_performance_baseline.py` to compare a fresh run against that snapshot.
|
||||||
|
|
||||||
| Scenario | Duration (s) | Total | Valid | Reached | Iter | Nets Routed | Nodes | Ray Casts | Moves Gen | Moves Added | Dyn Tree | Visibility Builds | Congestion Checks | Verify Calls |
|
| Scenario | Duration (s) | Total | Valid | Reached | Iter | Nets Routed | Nodes | Ray Casts | Moves Gen | Moves Added | Dyn Tree | Visibility Builds | Congestion Checks | Verify Calls |
|
||||||
| :-- | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: |
|
| :-- | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: |
|
||||||
| example_01_simple_route | 0.0042 | 1 | 1 | 1 | 1 | 1 | 2 | 22 | 11 | 7 | 2 | 2 | 0 | 3 |
|
| example_01_simple_route | 0.0042 | 1 | 1 | 1 | 1 | 1 | 2 | 22 | 11 | 7 | 2 | 2 | 0 | 3 |
|
||||||
| example_02_congestion_resolution | 0.3335 | 3 | 3 | 3 | 1 | 3 | 366 | 1176 | 1413 | 668 | 8 | 4 | 0 | 35 |
|
| example_02_congestion_resolution | 0.3418 | 3 | 3 | 3 | 1 | 3 | 366 | 1176 | 1413 | 668 | 8 | 4 | 0 | 35 |
|
||||||
| example_03_locked_paths | 0.1810 | 2 | 2 | 2 | 2 | 2 | 191 | 681 | 904 | 307 | 5 | 4 | 0 | 14 |
|
| example_03_locked_paths | 0.1827 | 2 | 2 | 2 | 2 | 2 | 191 | 681 | 904 | 307 | 5 | 4 | 0 | 14 |
|
||||||
| example_04_sbends_and_radii | 2.0151 | 2 | 2 | 2 | 1 | 2 | 15 | 18218 | 123 | 65 | 4 | 3 | 0 | 6 |
|
| example_04_sbends_and_radii | 1.9938 | 2 | 2 | 2 | 1 | 2 | 15 | 18218 | 123 | 65 | 4 | 3 | 0 | 6 |
|
||||||
| example_05_orientation_stress | 0.2438 | 3 | 3 | 3 | 2 | 6 | 286 | 1243 | 1624 | 681 | 12 | 3 | 412 | 12 |
|
| example_05_orientation_stress | 0.2458 | 3 | 3 | 3 | 2 | 6 | 286 | 1243 | 1624 | 681 | 12 | 3 | 412 | 12 |
|
||||||
| example_06_bend_collision_models | 4.1636 | 3 | 3 | 3 | 3 | 3 | 240 | 40530 | 1026 | 629 | 6 | 6 | 0 | 9 |
|
| example_06_bend_collision_models | 4.1186 | 3 | 3 | 3 | 3 | 3 | 240 | 40530 | 1026 | 629 | 6 | 6 | 0 | 9 |
|
||||||
| example_07_large_scale_routing | 1.3759 | 10 | 10 | 10 | 1 | 10 | 78 | 11151 | 372 | 227 | 20 | 11 | 0 | 30 |
|
| example_07_large_scale_routing | 1.3734 | 10 | 10 | 10 | 1 | 10 | 78 | 11151 | 372 | 227 | 20 | 11 | 0 | 30 |
|
||||||
| example_08_custom_bend_geometry | 0.2437 | 2 | 2 | 2 | 2 | 2 | 18 | 2308 | 78 | 56 | 4 | 4 | 0 | 6 |
|
| example_08_custom_bend_geometry | 0.2410 | 2 | 2 | 2 | 2 | 2 | 18 | 2308 | 78 | 56 | 4 | 4 | 0 | 6 |
|
||||||
| example_09_unroutable_best_effort | 0.0052 | 1 | 0 | 0 | 1 | 1 | 3 | 13 | 16 | 10 | 1 | 0 | 0 | 1 |
|
| example_09_unroutable_best_effort | 0.0052 | 1 | 0 | 0 | 1 | 1 | 3 | 13 | 16 | 10 | 1 | 0 | 0 | 1 |
|
||||||
|
|
||||||
## Full Counter Set
|
## Full Counter Set
|
||||||
|
|
||||||
Each scenario entry in `docs/performance_baseline.json` records the full `RouteMetrics` snapshot, including cache, index, congestion, and verification counters.
|
Each scenario entry in `docs/performance_baseline.json` records the full `RouteMetrics` snapshot, including cache, index, congestion, and verification counters.
|
||||||
|
These counters are currently observational only and are not enforced as CI regression gates.
|
||||||
|
|
||||||
Tracked metric keys:
|
Tracked metric keys:
|
||||||
|
|
||||||
nodes_expanded, moves_generated, moves_added, pruned_closed_set, pruned_hard_collision, pruned_cost, route_iterations, nets_routed, nets_reached_target, warm_start_paths_built, warm_start_paths_used, refine_path_calls, timeout_events, move_cache_abs_hits, move_cache_abs_misses, move_cache_rel_hits, move_cache_rel_misses, static_safe_cache_hits, hard_collision_cache_hits, congestion_cache_hits, congestion_cache_misses, dynamic_path_objects_added, dynamic_path_objects_removed, dynamic_tree_rebuilds, dynamic_grid_rebuilds, static_tree_rebuilds, static_raw_tree_rebuilds, static_net_tree_rebuilds, visibility_builds, visibility_corner_pairs_checked, visibility_corner_queries, visibility_corner_hits, visibility_point_queries, visibility_point_cache_hits, visibility_point_cache_misses, ray_cast_calls, ray_cast_candidate_bounds, ray_cast_exact_geometry_checks, congestion_check_calls, congestion_exact_pair_checks, verify_path_report_calls, verify_static_buffer_ops, verify_dynamic_exact_pair_checks
|
nodes_expanded, moves_generated, moves_added, pruned_closed_set, pruned_hard_collision, pruned_cost, route_iterations, nets_routed, nets_reached_target, warm_start_paths_built, warm_start_paths_used, refine_path_calls, timeout_events, score_component_calls, score_component_total_ns, path_cost_calls, danger_map_lookup_calls, danger_map_cache_hits, danger_map_cache_misses, danger_map_query_calls, danger_map_total_ns, move_cache_abs_hits, move_cache_abs_misses, move_cache_rel_hits, move_cache_rel_misses, static_safe_cache_hits, hard_collision_cache_hits, congestion_cache_hits, congestion_cache_misses, dynamic_path_objects_added, dynamic_path_objects_removed, dynamic_tree_rebuilds, dynamic_grid_rebuilds, static_tree_rebuilds, static_raw_tree_rebuilds, static_net_tree_rebuilds, visibility_builds, visibility_corner_pairs_checked, visibility_corner_queries_exact, visibility_corner_hits_exact, visibility_point_queries, visibility_point_cache_hits, visibility_point_cache_misses, visibility_tangent_candidate_scans, visibility_tangent_candidate_corner_checks, visibility_tangent_candidate_ray_tests, ray_cast_calls, ray_cast_calls_straight_static, ray_cast_calls_expand_snap, ray_cast_calls_expand_forward, ray_cast_calls_visibility_build, ray_cast_calls_visibility_query, ray_cast_calls_visibility_tangent, ray_cast_calls_other, ray_cast_candidate_bounds, ray_cast_exact_geometry_checks, congestion_check_calls, congestion_exact_pair_checks, verify_path_report_calls, verify_static_buffer_ops, verify_dynamic_exact_pair_checks, refinement_windows_considered, refinement_static_bounds_checked, refinement_dynamic_bounds_checked, refinement_candidate_side_extents, refinement_candidates_built, refinement_candidates_verified, refinement_candidates_accepted
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,17 @@
|
||||||
"generator": "scripts/record_performance_baseline.py",
|
"generator": "scripts/record_performance_baseline.py",
|
||||||
"scenarios": [
|
"scenarios": [
|
||||||
{
|
{
|
||||||
"duration_s": 0.0041740520391613245,
|
"duration_s": 0.00415895797777921,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 0,
|
"congestion_cache_hits": 0,
|
||||||
"congestion_cache_misses": 0,
|
"congestion_cache_misses": 0,
|
||||||
"congestion_check_calls": 0,
|
"congestion_check_calls": 0,
|
||||||
"congestion_exact_pair_checks": 0,
|
"congestion_exact_pair_checks": 0,
|
||||||
|
"danger_map_cache_hits": 8,
|
||||||
|
"danger_map_cache_misses": 13,
|
||||||
|
"danger_map_lookup_calls": 21,
|
||||||
|
"danger_map_query_calls": 0,
|
||||||
|
"danger_map_total_ns": 27079,
|
||||||
"dynamic_grid_rebuilds": 0,
|
"dynamic_grid_rebuilds": 0,
|
||||||
"dynamic_path_objects_added": 2,
|
"dynamic_path_objects_added": 2,
|
||||||
"dynamic_path_objects_removed": 1,
|
"dynamic_path_objects_removed": 1,
|
||||||
|
|
@ -23,14 +28,31 @@
|
||||||
"nets_reached_target": 1,
|
"nets_reached_target": 1,
|
||||||
"nets_routed": 1,
|
"nets_routed": 1,
|
||||||
"nodes_expanded": 2,
|
"nodes_expanded": 2,
|
||||||
|
"path_cost_calls": 0,
|
||||||
"pruned_closed_set": 0,
|
"pruned_closed_set": 0,
|
||||||
"pruned_cost": 4,
|
"pruned_cost": 4,
|
||||||
"pruned_hard_collision": 0,
|
"pruned_hard_collision": 0,
|
||||||
"ray_cast_calls": 22,
|
"ray_cast_calls": 22,
|
||||||
|
"ray_cast_calls_expand_forward": 1,
|
||||||
|
"ray_cast_calls_expand_snap": 1,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 8,
|
||||||
|
"ray_cast_calls_visibility_build": 12,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 0,
|
||||||
"ray_cast_candidate_bounds": 12,
|
"ray_cast_candidate_bounds": 12,
|
||||||
"ray_cast_exact_geometry_checks": 0,
|
"ray_cast_exact_geometry_checks": 0,
|
||||||
"refine_path_calls": 1,
|
"refine_path_calls": 1,
|
||||||
|
"refinement_candidate_side_extents": 0,
|
||||||
|
"refinement_candidates_accepted": 0,
|
||||||
|
"refinement_candidates_built": 0,
|
||||||
|
"refinement_candidates_verified": 0,
|
||||||
|
"refinement_dynamic_bounds_checked": 0,
|
||||||
|
"refinement_static_bounds_checked": 0,
|
||||||
|
"refinement_windows_considered": 0,
|
||||||
"route_iterations": 1,
|
"route_iterations": 1,
|
||||||
|
"score_component_calls": 11,
|
||||||
|
"score_component_total_ns": 59404,
|
||||||
"static_net_tree_rebuilds": 1,
|
"static_net_tree_rebuilds": 1,
|
||||||
"static_raw_tree_rebuilds": 0,
|
"static_raw_tree_rebuilds": 0,
|
||||||
"static_safe_cache_hits": 1,
|
"static_safe_cache_hits": 1,
|
||||||
|
|
@ -40,12 +62,15 @@
|
||||||
"verify_path_report_calls": 3,
|
"verify_path_report_calls": 3,
|
||||||
"verify_static_buffer_ops": 0,
|
"verify_static_buffer_ops": 0,
|
||||||
"visibility_builds": 2,
|
"visibility_builds": 2,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 12,
|
"visibility_corner_pairs_checked": 12,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 0,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 0,
|
||||||
|
"visibility_tangent_candidate_scans": 1,
|
||||||
"warm_start_paths_built": 1,
|
"warm_start_paths_built": 1,
|
||||||
"warm_start_paths_used": 1
|
"warm_start_paths_used": 1
|
||||||
},
|
},
|
||||||
|
|
@ -55,12 +80,17 @@
|
||||||
"valid_results": 1
|
"valid_results": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"duration_s": 0.3335385399404913,
|
"duration_s": 0.34182924893684685,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 0,
|
"congestion_cache_hits": 0,
|
||||||
"congestion_cache_misses": 0,
|
"congestion_cache_misses": 0,
|
||||||
"congestion_check_calls": 0,
|
"congestion_check_calls": 0,
|
||||||
"congestion_exact_pair_checks": 0,
|
"congestion_exact_pair_checks": 0,
|
||||||
|
"danger_map_cache_hits": 1433,
|
||||||
|
"danger_map_cache_misses": 775,
|
||||||
|
"danger_map_lookup_calls": 2208,
|
||||||
|
"danger_map_query_calls": 0,
|
||||||
|
"danger_map_total_ns": 2165333,
|
||||||
"dynamic_grid_rebuilds": 0,
|
"dynamic_grid_rebuilds": 0,
|
||||||
"dynamic_path_objects_added": 32,
|
"dynamic_path_objects_added": 32,
|
||||||
"dynamic_path_objects_removed": 17,
|
"dynamic_path_objects_removed": 17,
|
||||||
|
|
@ -75,14 +105,31 @@
|
||||||
"nets_reached_target": 3,
|
"nets_reached_target": 3,
|
||||||
"nets_routed": 3,
|
"nets_routed": 3,
|
||||||
"nodes_expanded": 366,
|
"nodes_expanded": 366,
|
||||||
|
"path_cost_calls": 14,
|
||||||
"pruned_closed_set": 157,
|
"pruned_closed_set": 157,
|
||||||
"pruned_cost": 208,
|
"pruned_cost": 208,
|
||||||
"pruned_hard_collision": 380,
|
"pruned_hard_collision": 380,
|
||||||
"ray_cast_calls": 1176,
|
"ray_cast_calls": 1176,
|
||||||
|
"ray_cast_calls_expand_forward": 363,
|
||||||
|
"ray_cast_calls_expand_snap": 19,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 529,
|
||||||
|
"ray_cast_calls_visibility_build": 12,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 253,
|
||||||
"ray_cast_candidate_bounds": 925,
|
"ray_cast_candidate_bounds": 925,
|
||||||
"ray_cast_exact_geometry_checks": 136,
|
"ray_cast_exact_geometry_checks": 136,
|
||||||
"refine_path_calls": 3,
|
"refine_path_calls": 3,
|
||||||
|
"refinement_candidate_side_extents": 26,
|
||||||
|
"refinement_candidates_accepted": 2,
|
||||||
|
"refinement_candidates_built": 26,
|
||||||
|
"refinement_candidates_verified": 26,
|
||||||
|
"refinement_dynamic_bounds_checked": 20,
|
||||||
|
"refinement_static_bounds_checked": 0,
|
||||||
|
"refinement_windows_considered": 10,
|
||||||
"route_iterations": 1,
|
"route_iterations": 1,
|
||||||
|
"score_component_calls": 976,
|
||||||
|
"score_component_total_ns": 4650167,
|
||||||
"static_net_tree_rebuilds": 3,
|
"static_net_tree_rebuilds": 3,
|
||||||
"static_raw_tree_rebuilds": 0,
|
"static_raw_tree_rebuilds": 0,
|
||||||
"static_safe_cache_hits": 1,
|
"static_safe_cache_hits": 1,
|
||||||
|
|
@ -92,12 +139,15 @@
|
||||||
"verify_path_report_calls": 35,
|
"verify_path_report_calls": 35,
|
||||||
"verify_static_buffer_ops": 0,
|
"verify_static_buffer_ops": 0,
|
||||||
"visibility_builds": 4,
|
"visibility_builds": 4,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 12,
|
"visibility_corner_pairs_checked": 12,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 18991,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 253,
|
||||||
|
"visibility_tangent_candidate_scans": 363,
|
||||||
"warm_start_paths_built": 3,
|
"warm_start_paths_built": 3,
|
||||||
"warm_start_paths_used": 3
|
"warm_start_paths_used": 3
|
||||||
},
|
},
|
||||||
|
|
@ -107,12 +157,17 @@
|
||||||
"valid_results": 3
|
"valid_results": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"duration_s": 0.1809853739105165,
|
"duration_s": 0.18274989898782223,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 0,
|
"congestion_cache_hits": 0,
|
||||||
"congestion_cache_misses": 0,
|
"congestion_cache_misses": 0,
|
||||||
"congestion_check_calls": 0,
|
"congestion_check_calls": 0,
|
||||||
"congestion_exact_pair_checks": 0,
|
"congestion_exact_pair_checks": 0,
|
||||||
|
"danger_map_cache_hits": 624,
|
||||||
|
"danger_map_cache_misses": 414,
|
||||||
|
"danger_map_lookup_calls": 1038,
|
||||||
|
"danger_map_query_calls": 0,
|
||||||
|
"danger_map_total_ns": 1001517,
|
||||||
"dynamic_grid_rebuilds": 0,
|
"dynamic_grid_rebuilds": 0,
|
||||||
"dynamic_path_objects_added": 17,
|
"dynamic_path_objects_added": 17,
|
||||||
"dynamic_path_objects_removed": 10,
|
"dynamic_path_objects_removed": 10,
|
||||||
|
|
@ -127,14 +182,31 @@
|
||||||
"nets_reached_target": 2,
|
"nets_reached_target": 2,
|
||||||
"nets_routed": 2,
|
"nets_routed": 2,
|
||||||
"nodes_expanded": 191,
|
"nodes_expanded": 191,
|
||||||
|
"path_cost_calls": 9,
|
||||||
"pruned_closed_set": 97,
|
"pruned_closed_set": 97,
|
||||||
"pruned_cost": 140,
|
"pruned_cost": 140,
|
||||||
"pruned_hard_collision": 181,
|
"pruned_hard_collision": 181,
|
||||||
"ray_cast_calls": 681,
|
"ray_cast_calls": 681,
|
||||||
|
"ray_cast_calls_expand_forward": 189,
|
||||||
|
"ray_cast_calls_expand_snap": 8,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 407,
|
||||||
|
"ray_cast_calls_visibility_build": 24,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 53,
|
||||||
"ray_cast_candidate_bounds": 179,
|
"ray_cast_candidate_bounds": 179,
|
||||||
"ray_cast_exact_geometry_checks": 0,
|
"ray_cast_exact_geometry_checks": 0,
|
||||||
"refine_path_calls": 2,
|
"refine_path_calls": 2,
|
||||||
|
"refinement_candidate_side_extents": 8,
|
||||||
|
"refinement_candidates_accepted": 1,
|
||||||
|
"refinement_candidates_built": 8,
|
||||||
|
"refinement_candidates_verified": 8,
|
||||||
|
"refinement_dynamic_bounds_checked": 2,
|
||||||
|
"refinement_static_bounds_checked": 2,
|
||||||
|
"refinement_windows_considered": 2,
|
||||||
"route_iterations": 2,
|
"route_iterations": 2,
|
||||||
|
"score_component_calls": 504,
|
||||||
|
"score_component_total_ns": 2184569,
|
||||||
"static_net_tree_rebuilds": 2,
|
"static_net_tree_rebuilds": 2,
|
||||||
"static_raw_tree_rebuilds": 1,
|
"static_raw_tree_rebuilds": 1,
|
||||||
"static_safe_cache_hits": 1,
|
"static_safe_cache_hits": 1,
|
||||||
|
|
@ -144,12 +216,15 @@
|
||||||
"verify_path_report_calls": 14,
|
"verify_path_report_calls": 14,
|
||||||
"verify_static_buffer_ops": 69,
|
"verify_static_buffer_ops": 69,
|
||||||
"visibility_builds": 4,
|
"visibility_builds": 4,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 24,
|
"visibility_corner_pairs_checked": 24,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 476,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 53,
|
||||||
|
"visibility_tangent_candidate_scans": 189,
|
||||||
"warm_start_paths_built": 2,
|
"warm_start_paths_built": 2,
|
||||||
"warm_start_paths_used": 2
|
"warm_start_paths_used": 2
|
||||||
},
|
},
|
||||||
|
|
@ -159,12 +234,17 @@
|
||||||
"valid_results": 2
|
"valid_results": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"duration_s": 2.0151148419827223,
|
"duration_s": 1.993830946041271,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 0,
|
"congestion_cache_hits": 0,
|
||||||
"congestion_cache_misses": 0,
|
"congestion_cache_misses": 0,
|
||||||
"congestion_check_calls": 0,
|
"congestion_check_calls": 0,
|
||||||
"congestion_exact_pair_checks": 0,
|
"congestion_exact_pair_checks": 0,
|
||||||
|
"danger_map_cache_hits": 75,
|
||||||
|
"danger_map_cache_misses": 120,
|
||||||
|
"danger_map_lookup_calls": 195,
|
||||||
|
"danger_map_query_calls": 0,
|
||||||
|
"danger_map_total_ns": 207556,
|
||||||
"dynamic_grid_rebuilds": 0,
|
"dynamic_grid_rebuilds": 0,
|
||||||
"dynamic_path_objects_added": 14,
|
"dynamic_path_objects_added": 14,
|
||||||
"dynamic_path_objects_removed": 7,
|
"dynamic_path_objects_removed": 7,
|
||||||
|
|
@ -179,14 +259,31 @@
|
||||||
"nets_reached_target": 2,
|
"nets_reached_target": 2,
|
||||||
"nets_routed": 2,
|
"nets_routed": 2,
|
||||||
"nodes_expanded": 15,
|
"nodes_expanded": 15,
|
||||||
|
"path_cost_calls": 0,
|
||||||
"pruned_closed_set": 2,
|
"pruned_closed_set": 2,
|
||||||
"pruned_cost": 25,
|
"pruned_cost": 25,
|
||||||
"pruned_hard_collision": 16,
|
"pruned_hard_collision": 16,
|
||||||
"ray_cast_calls": 18218,
|
"ray_cast_calls": 18218,
|
||||||
|
"ray_cast_calls_expand_forward": 13,
|
||||||
|
"ray_cast_calls_expand_snap": 1,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 56,
|
||||||
|
"ray_cast_calls_visibility_build": 18148,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 0,
|
||||||
"ray_cast_candidate_bounds": 50717,
|
"ray_cast_candidate_bounds": 50717,
|
||||||
"ray_cast_exact_geometry_checks": 21265,
|
"ray_cast_exact_geometry_checks": 21265,
|
||||||
"refine_path_calls": 2,
|
"refine_path_calls": 2,
|
||||||
|
"refinement_candidate_side_extents": 0,
|
||||||
|
"refinement_candidates_accepted": 0,
|
||||||
|
"refinement_candidates_built": 0,
|
||||||
|
"refinement_candidates_verified": 0,
|
||||||
|
"refinement_dynamic_bounds_checked": 0,
|
||||||
|
"refinement_static_bounds_checked": 0,
|
||||||
|
"refinement_windows_considered": 0,
|
||||||
"route_iterations": 1,
|
"route_iterations": 1,
|
||||||
|
"score_component_calls": 90,
|
||||||
|
"score_component_total_ns": 410130,
|
||||||
"static_net_tree_rebuilds": 2,
|
"static_net_tree_rebuilds": 2,
|
||||||
"static_raw_tree_rebuilds": 0,
|
"static_raw_tree_rebuilds": 0,
|
||||||
"static_safe_cache_hits": 1,
|
"static_safe_cache_hits": 1,
|
||||||
|
|
@ -196,12 +293,15 @@
|
||||||
"verify_path_report_calls": 6,
|
"verify_path_report_calls": 6,
|
||||||
"verify_static_buffer_ops": 0,
|
"verify_static_buffer_ops": 0,
|
||||||
"visibility_builds": 3,
|
"visibility_builds": 3,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 18148,
|
"visibility_corner_pairs_checked": 18148,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 394,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 0,
|
||||||
|
"visibility_tangent_candidate_scans": 13,
|
||||||
"warm_start_paths_built": 2,
|
"warm_start_paths_built": 2,
|
||||||
"warm_start_paths_used": 2
|
"warm_start_paths_used": 2
|
||||||
},
|
},
|
||||||
|
|
@ -211,12 +311,17 @@
|
||||||
"valid_results": 2
|
"valid_results": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"duration_s": 0.2437819039914757,
|
"duration_s": 0.24581307696644217,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 2,
|
"congestion_cache_hits": 2,
|
||||||
"congestion_cache_misses": 412,
|
"congestion_cache_misses": 412,
|
||||||
"congestion_check_calls": 412,
|
"congestion_check_calls": 412,
|
||||||
"congestion_exact_pair_checks": 66,
|
"congestion_exact_pair_checks": 66,
|
||||||
|
"danger_map_cache_hits": 1386,
|
||||||
|
"danger_map_cache_misses": 693,
|
||||||
|
"danger_map_lookup_calls": 2079,
|
||||||
|
"danger_map_query_calls": 0,
|
||||||
|
"danger_map_total_ns": 1805113,
|
||||||
"dynamic_grid_rebuilds": 3,
|
"dynamic_grid_rebuilds": 3,
|
||||||
"dynamic_path_objects_added": 37,
|
"dynamic_path_objects_added": 37,
|
||||||
"dynamic_path_objects_removed": 25,
|
"dynamic_path_objects_removed": 25,
|
||||||
|
|
@ -231,14 +336,31 @@
|
||||||
"nets_reached_target": 6,
|
"nets_reached_target": 6,
|
||||||
"nets_routed": 6,
|
"nets_routed": 6,
|
||||||
"nodes_expanded": 286,
|
"nodes_expanded": 286,
|
||||||
|
"path_cost_calls": 2,
|
||||||
"pruned_closed_set": 139,
|
"pruned_closed_set": 139,
|
||||||
"pruned_cost": 505,
|
"pruned_cost": 505,
|
||||||
"pruned_hard_collision": 14,
|
"pruned_hard_collision": 14,
|
||||||
"ray_cast_calls": 1243,
|
"ray_cast_calls": 1243,
|
||||||
|
"ray_cast_calls_expand_forward": 280,
|
||||||
|
"ray_cast_calls_expand_snap": 3,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 951,
|
||||||
|
"ray_cast_calls_visibility_build": 0,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 9,
|
||||||
"ray_cast_candidate_bounds": 45,
|
"ray_cast_candidate_bounds": 45,
|
||||||
"ray_cast_exact_geometry_checks": 43,
|
"ray_cast_exact_geometry_checks": 43,
|
||||||
"refine_path_calls": 3,
|
"refine_path_calls": 3,
|
||||||
|
"refinement_candidate_side_extents": 0,
|
||||||
|
"refinement_candidates_accepted": 0,
|
||||||
|
"refinement_candidates_built": 0,
|
||||||
|
"refinement_candidates_verified": 0,
|
||||||
|
"refinement_dynamic_bounds_checked": 0,
|
||||||
|
"refinement_static_bounds_checked": 0,
|
||||||
|
"refinement_windows_considered": 0,
|
||||||
"route_iterations": 2,
|
"route_iterations": 2,
|
||||||
|
"score_component_calls": 1198,
|
||||||
|
"score_component_total_ns": 4292875,
|
||||||
"static_net_tree_rebuilds": 3,
|
"static_net_tree_rebuilds": 3,
|
||||||
"static_raw_tree_rebuilds": 0,
|
"static_raw_tree_rebuilds": 0,
|
||||||
"static_safe_cache_hits": 3,
|
"static_safe_cache_hits": 3,
|
||||||
|
|
@ -248,12 +370,15 @@
|
||||||
"verify_path_report_calls": 12,
|
"verify_path_report_calls": 12,
|
||||||
"verify_static_buffer_ops": 0,
|
"verify_static_buffer_ops": 0,
|
||||||
"visibility_builds": 3,
|
"visibility_builds": 3,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 0,
|
"visibility_corner_pairs_checked": 0,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 1483,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 9,
|
||||||
|
"visibility_tangent_candidate_scans": 280,
|
||||||
"warm_start_paths_built": 2,
|
"warm_start_paths_built": 2,
|
||||||
"warm_start_paths_used": 2
|
"warm_start_paths_used": 2
|
||||||
},
|
},
|
||||||
|
|
@ -263,12 +388,17 @@
|
||||||
"valid_results": 3
|
"valid_results": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"duration_s": 4.163613382959738,
|
"duration_s": 4.1186372829834,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 0,
|
"congestion_cache_hits": 0,
|
||||||
"congestion_cache_misses": 0,
|
"congestion_cache_misses": 0,
|
||||||
"congestion_check_calls": 0,
|
"congestion_check_calls": 0,
|
||||||
"congestion_exact_pair_checks": 0,
|
"congestion_exact_pair_checks": 0,
|
||||||
|
"danger_map_cache_hits": 1183,
|
||||||
|
"danger_map_cache_misses": 731,
|
||||||
|
"danger_map_lookup_calls": 1914,
|
||||||
|
"danger_map_query_calls": 731,
|
||||||
|
"danger_map_total_ns": 18374289,
|
||||||
"dynamic_grid_rebuilds": 0,
|
"dynamic_grid_rebuilds": 0,
|
||||||
"dynamic_path_objects_added": 36,
|
"dynamic_path_objects_added": 36,
|
||||||
"dynamic_path_objects_removed": 18,
|
"dynamic_path_objects_removed": 18,
|
||||||
|
|
@ -283,14 +413,31 @@
|
||||||
"nets_reached_target": 3,
|
"nets_reached_target": 3,
|
||||||
"nets_routed": 3,
|
"nets_routed": 3,
|
||||||
"nodes_expanded": 240,
|
"nodes_expanded": 240,
|
||||||
|
"path_cost_calls": 0,
|
||||||
"pruned_closed_set": 108,
|
"pruned_closed_set": 108,
|
||||||
"pruned_cost": 204,
|
"pruned_cost": 204,
|
||||||
"pruned_hard_collision": 85,
|
"pruned_hard_collision": 85,
|
||||||
"ray_cast_calls": 40530,
|
"ray_cast_calls": 40530,
|
||||||
|
"ray_cast_calls_expand_forward": 237,
|
||||||
|
"ray_cast_calls_expand_snap": 3,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 408,
|
||||||
|
"ray_cast_calls_visibility_build": 39848,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 34,
|
||||||
"ray_cast_candidate_bounds": 121732,
|
"ray_cast_candidate_bounds": 121732,
|
||||||
"ray_cast_exact_geometry_checks": 36858,
|
"ray_cast_exact_geometry_checks": 36858,
|
||||||
"refine_path_calls": 3,
|
"refine_path_calls": 3,
|
||||||
|
"refinement_candidate_side_extents": 0,
|
||||||
|
"refinement_candidates_accepted": 0,
|
||||||
|
"refinement_candidates_built": 0,
|
||||||
|
"refinement_candidates_verified": 0,
|
||||||
|
"refinement_dynamic_bounds_checked": 0,
|
||||||
|
"refinement_static_bounds_checked": 0,
|
||||||
|
"refinement_windows_considered": 0,
|
||||||
"route_iterations": 3,
|
"route_iterations": 3,
|
||||||
|
"score_component_calls": 842,
|
||||||
|
"score_component_total_ns": 20652599,
|
||||||
"static_net_tree_rebuilds": 3,
|
"static_net_tree_rebuilds": 3,
|
||||||
"static_raw_tree_rebuilds": 3,
|
"static_raw_tree_rebuilds": 3,
|
||||||
"static_safe_cache_hits": 141,
|
"static_safe_cache_hits": 141,
|
||||||
|
|
@ -300,12 +447,15 @@
|
||||||
"verify_path_report_calls": 9,
|
"verify_path_report_calls": 9,
|
||||||
"verify_static_buffer_ops": 54,
|
"verify_static_buffer_ops": 54,
|
||||||
"visibility_builds": 6,
|
"visibility_builds": 6,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 39848,
|
"visibility_corner_pairs_checked": 39848,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 2400,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 34,
|
||||||
|
"visibility_tangent_candidate_scans": 237,
|
||||||
"warm_start_paths_built": 3,
|
"warm_start_paths_built": 3,
|
||||||
"warm_start_paths_used": 3
|
"warm_start_paths_used": 3
|
||||||
},
|
},
|
||||||
|
|
@ -315,12 +465,17 @@
|
||||||
"valid_results": 3
|
"valid_results": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"duration_s": 1.375933071016334,
|
"duration_s": 1.373430646955967,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 0,
|
"congestion_cache_hits": 0,
|
||||||
"congestion_cache_misses": 0,
|
"congestion_cache_misses": 0,
|
||||||
"congestion_check_calls": 0,
|
"congestion_check_calls": 0,
|
||||||
"congestion_exact_pair_checks": 0,
|
"congestion_exact_pair_checks": 0,
|
||||||
|
"danger_map_cache_hits": 233,
|
||||||
|
"danger_map_cache_misses": 448,
|
||||||
|
"danger_map_lookup_calls": 681,
|
||||||
|
"danger_map_query_calls": 448,
|
||||||
|
"danger_map_total_ns": 10728422,
|
||||||
"dynamic_grid_rebuilds": 0,
|
"dynamic_grid_rebuilds": 0,
|
||||||
"dynamic_path_objects_added": 88,
|
"dynamic_path_objects_added": 88,
|
||||||
"dynamic_path_objects_removed": 44,
|
"dynamic_path_objects_removed": 44,
|
||||||
|
|
@ -335,14 +490,31 @@
|
||||||
"nets_reached_target": 10,
|
"nets_reached_target": 10,
|
||||||
"nets_routed": 10,
|
"nets_routed": 10,
|
||||||
"nodes_expanded": 78,
|
"nodes_expanded": 78,
|
||||||
|
"path_cost_calls": 0,
|
||||||
"pruned_closed_set": 20,
|
"pruned_closed_set": 20,
|
||||||
"pruned_cost": 64,
|
"pruned_cost": 64,
|
||||||
"pruned_hard_collision": 61,
|
"pruned_hard_collision": 61,
|
||||||
"ray_cast_calls": 11151,
|
"ray_cast_calls": 11151,
|
||||||
|
"ray_cast_calls_expand_forward": 68,
|
||||||
|
"ray_cast_calls_expand_snap": 6,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 232,
|
||||||
|
"ray_cast_calls_visibility_build": 10768,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 77,
|
||||||
"ray_cast_candidate_bounds": 21198,
|
"ray_cast_candidate_bounds": 21198,
|
||||||
"ray_cast_exact_geometry_checks": 11651,
|
"ray_cast_exact_geometry_checks": 11651,
|
||||||
"refine_path_calls": 10,
|
"refine_path_calls": 10,
|
||||||
|
"refinement_candidate_side_extents": 0,
|
||||||
|
"refinement_candidates_accepted": 0,
|
||||||
|
"refinement_candidates_built": 0,
|
||||||
|
"refinement_candidates_verified": 0,
|
||||||
|
"refinement_dynamic_bounds_checked": 0,
|
||||||
|
"refinement_static_bounds_checked": 0,
|
||||||
|
"refinement_windows_considered": 0,
|
||||||
"route_iterations": 1,
|
"route_iterations": 1,
|
||||||
|
"score_component_calls": 291,
|
||||||
|
"score_component_total_ns": 11574800,
|
||||||
"static_net_tree_rebuilds": 10,
|
"static_net_tree_rebuilds": 10,
|
||||||
"static_raw_tree_rebuilds": 1,
|
"static_raw_tree_rebuilds": 1,
|
||||||
"static_safe_cache_hits": 6,
|
"static_safe_cache_hits": 6,
|
||||||
|
|
@ -352,12 +524,15 @@
|
||||||
"verify_path_report_calls": 30,
|
"verify_path_report_calls": 30,
|
||||||
"verify_static_buffer_ops": 132,
|
"verify_static_buffer_ops": 132,
|
||||||
"visibility_builds": 11,
|
"visibility_builds": 11,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 10768,
|
"visibility_corner_pairs_checked": 10768,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 34735,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 77,
|
||||||
|
"visibility_tangent_candidate_scans": 68,
|
||||||
"warm_start_paths_built": 10,
|
"warm_start_paths_built": 10,
|
||||||
"warm_start_paths_used": 10
|
"warm_start_paths_used": 10
|
||||||
},
|
},
|
||||||
|
|
@ -367,12 +542,17 @@
|
||||||
"valid_results": 10
|
"valid_results": 10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"duration_s": 0.2436628290452063,
|
"duration_s": 0.2410298540489748,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 0,
|
"congestion_cache_hits": 0,
|
||||||
"congestion_cache_misses": 0,
|
"congestion_cache_misses": 0,
|
||||||
"congestion_check_calls": 0,
|
"congestion_check_calls": 0,
|
||||||
"congestion_exact_pair_checks": 0,
|
"congestion_exact_pair_checks": 0,
|
||||||
|
"danger_map_cache_hits": 58,
|
||||||
|
"danger_map_cache_misses": 110,
|
||||||
|
"danger_map_lookup_calls": 168,
|
||||||
|
"danger_map_query_calls": 0,
|
||||||
|
"danger_map_total_ns": 178104,
|
||||||
"dynamic_grid_rebuilds": 0,
|
"dynamic_grid_rebuilds": 0,
|
||||||
"dynamic_path_objects_added": 12,
|
"dynamic_path_objects_added": 12,
|
||||||
"dynamic_path_objects_removed": 6,
|
"dynamic_path_objects_removed": 6,
|
||||||
|
|
@ -387,14 +567,31 @@
|
||||||
"nets_reached_target": 2,
|
"nets_reached_target": 2,
|
||||||
"nets_routed": 2,
|
"nets_routed": 2,
|
||||||
"nodes_expanded": 18,
|
"nodes_expanded": 18,
|
||||||
|
"path_cost_calls": 0,
|
||||||
"pruned_closed_set": 6,
|
"pruned_closed_set": 6,
|
||||||
"pruned_cost": 16,
|
"pruned_cost": 16,
|
||||||
"pruned_hard_collision": 0,
|
"pruned_hard_collision": 0,
|
||||||
"ray_cast_calls": 2308,
|
"ray_cast_calls": 2308,
|
||||||
|
"ray_cast_calls_expand_forward": 16,
|
||||||
|
"ray_cast_calls_expand_snap": 2,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 38,
|
||||||
|
"ray_cast_calls_visibility_build": 2252,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 0,
|
||||||
"ray_cast_candidate_bounds": 3802,
|
"ray_cast_candidate_bounds": 3802,
|
||||||
"ray_cast_exact_geometry_checks": 1904,
|
"ray_cast_exact_geometry_checks": 1904,
|
||||||
"refine_path_calls": 2,
|
"refine_path_calls": 2,
|
||||||
|
"refinement_candidate_side_extents": 0,
|
||||||
|
"refinement_candidates_accepted": 0,
|
||||||
|
"refinement_candidates_built": 0,
|
||||||
|
"refinement_candidates_verified": 0,
|
||||||
|
"refinement_dynamic_bounds_checked": 0,
|
||||||
|
"refinement_static_bounds_checked": 0,
|
||||||
|
"refinement_windows_considered": 0,
|
||||||
"route_iterations": 2,
|
"route_iterations": 2,
|
||||||
|
"score_component_calls": 72,
|
||||||
|
"score_component_total_ns": 352865,
|
||||||
"static_net_tree_rebuilds": 2,
|
"static_net_tree_rebuilds": 2,
|
||||||
"static_raw_tree_rebuilds": 0,
|
"static_raw_tree_rebuilds": 0,
|
||||||
"static_safe_cache_hits": 2,
|
"static_safe_cache_hits": 2,
|
||||||
|
|
@ -404,12 +601,15 @@
|
||||||
"verify_path_report_calls": 6,
|
"verify_path_report_calls": 6,
|
||||||
"verify_static_buffer_ops": 0,
|
"verify_static_buffer_ops": 0,
|
||||||
"visibility_builds": 4,
|
"visibility_builds": 4,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 2252,
|
"visibility_corner_pairs_checked": 2252,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 0,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 0,
|
||||||
|
"visibility_tangent_candidate_scans": 16,
|
||||||
"warm_start_paths_built": 2,
|
"warm_start_paths_built": 2,
|
||||||
"warm_start_paths_used": 2
|
"warm_start_paths_used": 2
|
||||||
},
|
},
|
||||||
|
|
@ -419,12 +619,17 @@
|
||||||
"valid_results": 2
|
"valid_results": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"duration_s": 0.0052433289820328355,
|
"duration_s": 0.0052388140466064215,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"congestion_cache_hits": 0,
|
"congestion_cache_hits": 0,
|
||||||
"congestion_cache_misses": 0,
|
"congestion_cache_misses": 0,
|
||||||
"congestion_check_calls": 0,
|
"congestion_check_calls": 0,
|
||||||
"congestion_exact_pair_checks": 0,
|
"congestion_exact_pair_checks": 0,
|
||||||
|
"danger_map_cache_hits": 10,
|
||||||
|
"danger_map_cache_misses": 20,
|
||||||
|
"danger_map_lookup_calls": 30,
|
||||||
|
"danger_map_query_calls": 20,
|
||||||
|
"danger_map_total_ns": 502052,
|
||||||
"dynamic_grid_rebuilds": 0,
|
"dynamic_grid_rebuilds": 0,
|
||||||
"dynamic_path_objects_added": 1,
|
"dynamic_path_objects_added": 1,
|
||||||
"dynamic_path_objects_removed": 0,
|
"dynamic_path_objects_removed": 0,
|
||||||
|
|
@ -439,14 +644,31 @@
|
||||||
"nets_reached_target": 0,
|
"nets_reached_target": 0,
|
||||||
"nets_routed": 1,
|
"nets_routed": 1,
|
||||||
"nodes_expanded": 3,
|
"nodes_expanded": 3,
|
||||||
|
"path_cost_calls": 0,
|
||||||
"pruned_closed_set": 0,
|
"pruned_closed_set": 0,
|
||||||
"pruned_cost": 4,
|
"pruned_cost": 4,
|
||||||
"pruned_hard_collision": 2,
|
"pruned_hard_collision": 2,
|
||||||
"ray_cast_calls": 13,
|
"ray_cast_calls": 13,
|
||||||
|
"ray_cast_calls_expand_forward": 3,
|
||||||
|
"ray_cast_calls_expand_snap": 0,
|
||||||
|
"ray_cast_calls_other": 0,
|
||||||
|
"ray_cast_calls_straight_static": 10,
|
||||||
|
"ray_cast_calls_visibility_build": 0,
|
||||||
|
"ray_cast_calls_visibility_query": 0,
|
||||||
|
"ray_cast_calls_visibility_tangent": 0,
|
||||||
"ray_cast_candidate_bounds": 5,
|
"ray_cast_candidate_bounds": 5,
|
||||||
"ray_cast_exact_geometry_checks": 0,
|
"ray_cast_exact_geometry_checks": 0,
|
||||||
"refine_path_calls": 0,
|
"refine_path_calls": 0,
|
||||||
|
"refinement_candidate_side_extents": 0,
|
||||||
|
"refinement_candidates_accepted": 0,
|
||||||
|
"refinement_candidates_built": 0,
|
||||||
|
"refinement_candidates_verified": 0,
|
||||||
|
"refinement_dynamic_bounds_checked": 0,
|
||||||
|
"refinement_static_bounds_checked": 0,
|
||||||
|
"refinement_windows_considered": 0,
|
||||||
"route_iterations": 1,
|
"route_iterations": 1,
|
||||||
|
"score_component_calls": 14,
|
||||||
|
"score_component_total_ns": 538947,
|
||||||
"static_net_tree_rebuilds": 1,
|
"static_net_tree_rebuilds": 1,
|
||||||
"static_raw_tree_rebuilds": 1,
|
"static_raw_tree_rebuilds": 1,
|
||||||
"static_safe_cache_hits": 0,
|
"static_safe_cache_hits": 0,
|
||||||
|
|
@ -456,12 +678,15 @@
|
||||||
"verify_path_report_calls": 1,
|
"verify_path_report_calls": 1,
|
||||||
"verify_static_buffer_ops": 1,
|
"verify_static_buffer_ops": 1,
|
||||||
"visibility_builds": 0,
|
"visibility_builds": 0,
|
||||||
"visibility_corner_hits": 0,
|
"visibility_corner_hits_exact": 0,
|
||||||
"visibility_corner_pairs_checked": 0,
|
"visibility_corner_pairs_checked": 0,
|
||||||
"visibility_corner_queries": 0,
|
"visibility_corner_queries_exact": 0,
|
||||||
"visibility_point_cache_hits": 0,
|
"visibility_point_cache_hits": 0,
|
||||||
"visibility_point_cache_misses": 0,
|
"visibility_point_cache_misses": 0,
|
||||||
"visibility_point_queries": 0,
|
"visibility_point_queries": 0,
|
||||||
|
"visibility_tangent_candidate_corner_checks": 10,
|
||||||
|
"visibility_tangent_candidate_ray_tests": 0,
|
||||||
|
"visibility_tangent_candidate_scans": 3,
|
||||||
"warm_start_paths_built": 0,
|
"warm_start_paths_built": 0,
|
||||||
"warm_start_paths_used": 0
|
"warm_start_paths_used": 0
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,13 @@ class RoutingWorld:
|
||||||
self._dynamic_paths.remove_path(net_id)
|
self._dynamic_paths.remove_path(net_id)
|
||||||
|
|
||||||
def check_move_straight_static(self, start_port: Port, length: float, net_width: float) -> bool:
|
def check_move_straight_static(self, start_port: Port, length: float, net_width: float) -> bool:
|
||||||
reach = self.ray_cast(start_port, start_port.r, max_dist=length + 0.01, net_width=net_width)
|
reach = self.ray_cast(
|
||||||
|
start_port,
|
||||||
|
start_port.r,
|
||||||
|
max_dist=length + 0.01,
|
||||||
|
net_width=net_width,
|
||||||
|
caller="straight_static",
|
||||||
|
)
|
||||||
return reach < length - 0.001
|
return reach < length - 0.001
|
||||||
|
|
||||||
def _is_in_safety_zone_fast(self, idx: int, start_port: Port | None, end_port: Port | None) -> bool:
|
def _is_in_safety_zone_fast(self, idx: int, start_port: Port | None, end_port: Port | None) -> bool:
|
||||||
|
|
@ -393,9 +399,24 @@ class RoutingWorld:
|
||||||
angle_deg: float,
|
angle_deg: float,
|
||||||
max_dist: float = 2000.0,
|
max_dist: float = 2000.0,
|
||||||
net_width: float | None = None,
|
net_width: float | None = None,
|
||||||
|
caller: str = "other",
|
||||||
) -> float:
|
) -> float:
|
||||||
if self.metrics is not None:
|
if self.metrics is not None:
|
||||||
self.metrics.total_ray_cast_calls += 1
|
self.metrics.total_ray_cast_calls += 1
|
||||||
|
if caller == "straight_static":
|
||||||
|
self.metrics.total_ray_cast_calls_straight_static += 1
|
||||||
|
elif caller == "expand_snap":
|
||||||
|
self.metrics.total_ray_cast_calls_expand_snap += 1
|
||||||
|
elif caller == "expand_forward":
|
||||||
|
self.metrics.total_ray_cast_calls_expand_forward += 1
|
||||||
|
elif caller == "visibility_build":
|
||||||
|
self.metrics.total_ray_cast_calls_visibility_build += 1
|
||||||
|
elif caller == "visibility_query":
|
||||||
|
self.metrics.total_ray_cast_calls_visibility_query += 1
|
||||||
|
elif caller == "visibility_tangent":
|
||||||
|
self.metrics.total_ray_cast_calls_visibility_tangent += 1
|
||||||
|
else:
|
||||||
|
self.metrics.total_ray_cast_calls_other += 1
|
||||||
static_obstacles = self._static_obstacles
|
static_obstacles = self._static_obstacles
|
||||||
tree: STRtree | None
|
tree: STRtree | None
|
||||||
is_rect_array: numpy.ndarray | None
|
is_rect_array: numpy.ndarray | None
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,14 @@ class RouteMetrics:
|
||||||
warm_start_paths_used: int
|
warm_start_paths_used: int
|
||||||
refine_path_calls: int
|
refine_path_calls: int
|
||||||
timeout_events: int
|
timeout_events: int
|
||||||
|
score_component_calls: int
|
||||||
|
score_component_total_ns: int
|
||||||
|
path_cost_calls: int
|
||||||
|
danger_map_lookup_calls: int
|
||||||
|
danger_map_cache_hits: int
|
||||||
|
danger_map_cache_misses: int
|
||||||
|
danger_map_query_calls: int
|
||||||
|
danger_map_total_ns: int
|
||||||
move_cache_abs_hits: int
|
move_cache_abs_hits: int
|
||||||
move_cache_abs_misses: int
|
move_cache_abs_misses: int
|
||||||
move_cache_rel_hits: int
|
move_cache_rel_hits: int
|
||||||
|
|
@ -62,12 +70,22 @@ class RouteMetrics:
|
||||||
static_net_tree_rebuilds: int
|
static_net_tree_rebuilds: int
|
||||||
visibility_builds: int
|
visibility_builds: int
|
||||||
visibility_corner_pairs_checked: int
|
visibility_corner_pairs_checked: int
|
||||||
visibility_corner_queries: int
|
visibility_corner_queries_exact: int
|
||||||
visibility_corner_hits: int
|
visibility_corner_hits_exact: int
|
||||||
visibility_point_queries: int
|
visibility_point_queries: int
|
||||||
visibility_point_cache_hits: int
|
visibility_point_cache_hits: int
|
||||||
visibility_point_cache_misses: int
|
visibility_point_cache_misses: int
|
||||||
|
visibility_tangent_candidate_scans: int
|
||||||
|
visibility_tangent_candidate_corner_checks: int
|
||||||
|
visibility_tangent_candidate_ray_tests: int
|
||||||
ray_cast_calls: int
|
ray_cast_calls: int
|
||||||
|
ray_cast_calls_straight_static: int
|
||||||
|
ray_cast_calls_expand_snap: int
|
||||||
|
ray_cast_calls_expand_forward: int
|
||||||
|
ray_cast_calls_visibility_build: int
|
||||||
|
ray_cast_calls_visibility_query: int
|
||||||
|
ray_cast_calls_visibility_tangent: int
|
||||||
|
ray_cast_calls_other: int
|
||||||
ray_cast_candidate_bounds: int
|
ray_cast_candidate_bounds: int
|
||||||
ray_cast_exact_geometry_checks: int
|
ray_cast_exact_geometry_checks: int
|
||||||
congestion_check_calls: int
|
congestion_check_calls: int
|
||||||
|
|
@ -75,6 +93,13 @@ class RouteMetrics:
|
||||||
verify_path_report_calls: int
|
verify_path_report_calls: int
|
||||||
verify_static_buffer_ops: int
|
verify_static_buffer_ops: int
|
||||||
verify_dynamic_exact_pair_checks: int
|
verify_dynamic_exact_pair_checks: int
|
||||||
|
refinement_windows_considered: int
|
||||||
|
refinement_static_bounds_checked: int
|
||||||
|
refinement_dynamic_bounds_checked: int
|
||||||
|
refinement_candidate_side_extents: int
|
||||||
|
refinement_candidates_built: int
|
||||||
|
refinement_candidates_verified: int
|
||||||
|
refinement_candidates_accepted: int
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, slots=True)
|
@dataclass(frozen=True, slots=True)
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ def _visible_straight_candidates(
|
||||||
|
|
||||||
visibility_manager = context.visibility_manager
|
visibility_manager = context.visibility_manager
|
||||||
visibility_manager._ensure_current()
|
visibility_manager._ensure_current()
|
||||||
|
context.metrics.total_visibility_tangent_candidate_scans += 1
|
||||||
max_bend_radius = max(search_options.bend_radii, default=0.0)
|
max_bend_radius = max(search_options.bend_radii, default=0.0)
|
||||||
if max_bend_radius <= 0 or not visibility_manager.corners:
|
if max_bend_radius <= 0 or not visibility_manager.corners:
|
||||||
return []
|
return []
|
||||||
|
|
@ -76,6 +77,7 @@ def _visible_straight_candidates(
|
||||||
|
|
||||||
scored: list[tuple[float, float, float, float, float]] = []
|
scored: list[tuple[float, float, float, float, float]] = []
|
||||||
for idx in candidate_ids:
|
for idx in candidate_ids:
|
||||||
|
context.metrics.total_visibility_tangent_candidate_corner_checks += 1
|
||||||
cx, cy = visibility_manager.corners[idx]
|
cx, cy = visibility_manager.corners[idx]
|
||||||
dx = cx - current.x
|
dx = cx - current.x
|
||||||
dy = cy - current.y
|
dy = cy - current.y
|
||||||
|
|
@ -101,8 +103,15 @@ def _visible_straight_candidates(
|
||||||
collision_engine = context.cost_evaluator.collision_engine
|
collision_engine = context.cost_evaluator.collision_engine
|
||||||
tangent_candidates: set[int] = set()
|
tangent_candidates: set[int] = set()
|
||||||
for _, dist, length, dx, dy in sorted(scored)[:4]:
|
for _, dist, length, dx, dy in sorted(scored)[:4]:
|
||||||
|
context.metrics.total_visibility_tangent_candidate_ray_tests += 1
|
||||||
angle = math.degrees(math.atan2(dy, dx))
|
angle = math.degrees(math.atan2(dy, dx))
|
||||||
corner_reach = collision_engine.ray_cast(current, angle, max_dist=dist + 0.05, net_width=net_width)
|
corner_reach = collision_engine.ray_cast(
|
||||||
|
current,
|
||||||
|
angle,
|
||||||
|
max_dist=dist + 0.05,
|
||||||
|
net_width=net_width,
|
||||||
|
caller="visibility_tangent",
|
||||||
|
)
|
||||||
if corner_reach < dist - 0.01:
|
if corner_reach < dist - 0.01:
|
||||||
continue
|
continue
|
||||||
qlen = int(round(length))
|
qlen = int(round(length))
|
||||||
|
|
@ -156,7 +165,13 @@ def expand_moves(
|
||||||
dy_local = perp_t
|
dy_local = perp_t
|
||||||
|
|
||||||
if proj_t > 0 and abs(perp_t) < 1e-6 and cp.r == target.r:
|
if proj_t > 0 and abs(perp_t) < 1e-6 and cp.r == target.r:
|
||||||
max_reach = context.cost_evaluator.collision_engine.ray_cast(cp, cp.r, proj_t + 1.0, net_width=net_width)
|
max_reach = context.cost_evaluator.collision_engine.ray_cast(
|
||||||
|
cp,
|
||||||
|
cp.r,
|
||||||
|
proj_t + 1.0,
|
||||||
|
net_width=net_width,
|
||||||
|
caller="expand_snap",
|
||||||
|
)
|
||||||
if max_reach >= proj_t - 0.01 and (
|
if max_reach >= proj_t - 0.01 and (
|
||||||
prev_straight_length is None or proj_t < prev_straight_length - TOLERANCE_LINEAR
|
prev_straight_length is None or proj_t < prev_straight_length - TOLERANCE_LINEAR
|
||||||
):
|
):
|
||||||
|
|
@ -175,7 +190,13 @@ def expand_moves(
|
||||||
(int(round(proj_t)),),
|
(int(round(proj_t)),),
|
||||||
)
|
)
|
||||||
|
|
||||||
max_reach = context.cost_evaluator.collision_engine.ray_cast(cp, cp.r, search_options.max_straight_length, net_width=net_width)
|
max_reach = context.cost_evaluator.collision_engine.ray_cast(
|
||||||
|
cp,
|
||||||
|
cp.r,
|
||||||
|
search_options.max_straight_length,
|
||||||
|
net_width=net_width,
|
||||||
|
caller="expand_forward",
|
||||||
|
)
|
||||||
candidate_lengths = [
|
candidate_lengths = [
|
||||||
search_options.min_straight_length,
|
search_options.min_straight_length,
|
||||||
max_reach,
|
max_reach,
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,14 @@ class AStarMetrics:
|
||||||
"total_warm_start_paths_used",
|
"total_warm_start_paths_used",
|
||||||
"total_refine_path_calls",
|
"total_refine_path_calls",
|
||||||
"total_timeout_events",
|
"total_timeout_events",
|
||||||
|
"total_score_component_calls",
|
||||||
|
"total_score_component_total_ns",
|
||||||
|
"total_path_cost_calls",
|
||||||
|
"total_danger_map_lookup_calls",
|
||||||
|
"total_danger_map_cache_hits",
|
||||||
|
"total_danger_map_cache_misses",
|
||||||
|
"total_danger_map_query_calls",
|
||||||
|
"total_danger_map_total_ns",
|
||||||
"total_move_cache_abs_hits",
|
"total_move_cache_abs_hits",
|
||||||
"total_move_cache_abs_misses",
|
"total_move_cache_abs_misses",
|
||||||
"total_move_cache_rel_hits",
|
"total_move_cache_rel_hits",
|
||||||
|
|
@ -111,12 +119,22 @@ class AStarMetrics:
|
||||||
"total_static_net_tree_rebuilds",
|
"total_static_net_tree_rebuilds",
|
||||||
"total_visibility_builds",
|
"total_visibility_builds",
|
||||||
"total_visibility_corner_pairs_checked",
|
"total_visibility_corner_pairs_checked",
|
||||||
"total_visibility_corner_queries",
|
"total_visibility_corner_queries_exact",
|
||||||
"total_visibility_corner_hits",
|
"total_visibility_corner_hits_exact",
|
||||||
"total_visibility_point_queries",
|
"total_visibility_point_queries",
|
||||||
"total_visibility_point_cache_hits",
|
"total_visibility_point_cache_hits",
|
||||||
"total_visibility_point_cache_misses",
|
"total_visibility_point_cache_misses",
|
||||||
|
"total_visibility_tangent_candidate_scans",
|
||||||
|
"total_visibility_tangent_candidate_corner_checks",
|
||||||
|
"total_visibility_tangent_candidate_ray_tests",
|
||||||
"total_ray_cast_calls",
|
"total_ray_cast_calls",
|
||||||
|
"total_ray_cast_calls_straight_static",
|
||||||
|
"total_ray_cast_calls_expand_snap",
|
||||||
|
"total_ray_cast_calls_expand_forward",
|
||||||
|
"total_ray_cast_calls_visibility_build",
|
||||||
|
"total_ray_cast_calls_visibility_query",
|
||||||
|
"total_ray_cast_calls_visibility_tangent",
|
||||||
|
"total_ray_cast_calls_other",
|
||||||
"total_ray_cast_candidate_bounds",
|
"total_ray_cast_candidate_bounds",
|
||||||
"total_ray_cast_exact_geometry_checks",
|
"total_ray_cast_exact_geometry_checks",
|
||||||
"total_congestion_check_calls",
|
"total_congestion_check_calls",
|
||||||
|
|
@ -124,6 +142,13 @@ class AStarMetrics:
|
||||||
"total_verify_path_report_calls",
|
"total_verify_path_report_calls",
|
||||||
"total_verify_static_buffer_ops",
|
"total_verify_static_buffer_ops",
|
||||||
"total_verify_dynamic_exact_pair_checks",
|
"total_verify_dynamic_exact_pair_checks",
|
||||||
|
"total_refinement_windows_considered",
|
||||||
|
"total_refinement_static_bounds_checked",
|
||||||
|
"total_refinement_dynamic_bounds_checked",
|
||||||
|
"total_refinement_candidate_side_extents",
|
||||||
|
"total_refinement_candidates_built",
|
||||||
|
"total_refinement_candidates_verified",
|
||||||
|
"total_refinement_candidates_accepted",
|
||||||
"last_expanded_nodes",
|
"last_expanded_nodes",
|
||||||
"nodes_expanded",
|
"nodes_expanded",
|
||||||
"moves_generated",
|
"moves_generated",
|
||||||
|
|
@ -147,6 +172,14 @@ class AStarMetrics:
|
||||||
self.total_warm_start_paths_used = 0
|
self.total_warm_start_paths_used = 0
|
||||||
self.total_refine_path_calls = 0
|
self.total_refine_path_calls = 0
|
||||||
self.total_timeout_events = 0
|
self.total_timeout_events = 0
|
||||||
|
self.total_score_component_calls = 0
|
||||||
|
self.total_score_component_total_ns = 0
|
||||||
|
self.total_path_cost_calls = 0
|
||||||
|
self.total_danger_map_lookup_calls = 0
|
||||||
|
self.total_danger_map_cache_hits = 0
|
||||||
|
self.total_danger_map_cache_misses = 0
|
||||||
|
self.total_danger_map_query_calls = 0
|
||||||
|
self.total_danger_map_total_ns = 0
|
||||||
self.total_move_cache_abs_hits = 0
|
self.total_move_cache_abs_hits = 0
|
||||||
self.total_move_cache_abs_misses = 0
|
self.total_move_cache_abs_misses = 0
|
||||||
self.total_move_cache_rel_hits = 0
|
self.total_move_cache_rel_hits = 0
|
||||||
|
|
@ -164,12 +197,22 @@ class AStarMetrics:
|
||||||
self.total_static_net_tree_rebuilds = 0
|
self.total_static_net_tree_rebuilds = 0
|
||||||
self.total_visibility_builds = 0
|
self.total_visibility_builds = 0
|
||||||
self.total_visibility_corner_pairs_checked = 0
|
self.total_visibility_corner_pairs_checked = 0
|
||||||
self.total_visibility_corner_queries = 0
|
self.total_visibility_corner_queries_exact = 0
|
||||||
self.total_visibility_corner_hits = 0
|
self.total_visibility_corner_hits_exact = 0
|
||||||
self.total_visibility_point_queries = 0
|
self.total_visibility_point_queries = 0
|
||||||
self.total_visibility_point_cache_hits = 0
|
self.total_visibility_point_cache_hits = 0
|
||||||
self.total_visibility_point_cache_misses = 0
|
self.total_visibility_point_cache_misses = 0
|
||||||
|
self.total_visibility_tangent_candidate_scans = 0
|
||||||
|
self.total_visibility_tangent_candidate_corner_checks = 0
|
||||||
|
self.total_visibility_tangent_candidate_ray_tests = 0
|
||||||
self.total_ray_cast_calls = 0
|
self.total_ray_cast_calls = 0
|
||||||
|
self.total_ray_cast_calls_straight_static = 0
|
||||||
|
self.total_ray_cast_calls_expand_snap = 0
|
||||||
|
self.total_ray_cast_calls_expand_forward = 0
|
||||||
|
self.total_ray_cast_calls_visibility_build = 0
|
||||||
|
self.total_ray_cast_calls_visibility_query = 0
|
||||||
|
self.total_ray_cast_calls_visibility_tangent = 0
|
||||||
|
self.total_ray_cast_calls_other = 0
|
||||||
self.total_ray_cast_candidate_bounds = 0
|
self.total_ray_cast_candidate_bounds = 0
|
||||||
self.total_ray_cast_exact_geometry_checks = 0
|
self.total_ray_cast_exact_geometry_checks = 0
|
||||||
self.total_congestion_check_calls = 0
|
self.total_congestion_check_calls = 0
|
||||||
|
|
@ -177,6 +220,13 @@ class AStarMetrics:
|
||||||
self.total_verify_path_report_calls = 0
|
self.total_verify_path_report_calls = 0
|
||||||
self.total_verify_static_buffer_ops = 0
|
self.total_verify_static_buffer_ops = 0
|
||||||
self.total_verify_dynamic_exact_pair_checks = 0
|
self.total_verify_dynamic_exact_pair_checks = 0
|
||||||
|
self.total_refinement_windows_considered = 0
|
||||||
|
self.total_refinement_static_bounds_checked = 0
|
||||||
|
self.total_refinement_dynamic_bounds_checked = 0
|
||||||
|
self.total_refinement_candidate_side_extents = 0
|
||||||
|
self.total_refinement_candidates_built = 0
|
||||||
|
self.total_refinement_candidates_verified = 0
|
||||||
|
self.total_refinement_candidates_accepted = 0
|
||||||
self.last_expanded_nodes: list[tuple[int, int, int]] = []
|
self.last_expanded_nodes: list[tuple[int, int, int]] = []
|
||||||
self.nodes_expanded = 0
|
self.nodes_expanded = 0
|
||||||
self.moves_generated = 0
|
self.moves_generated = 0
|
||||||
|
|
@ -199,6 +249,14 @@ class AStarMetrics:
|
||||||
self.total_warm_start_paths_used = 0
|
self.total_warm_start_paths_used = 0
|
||||||
self.total_refine_path_calls = 0
|
self.total_refine_path_calls = 0
|
||||||
self.total_timeout_events = 0
|
self.total_timeout_events = 0
|
||||||
|
self.total_score_component_calls = 0
|
||||||
|
self.total_score_component_total_ns = 0
|
||||||
|
self.total_path_cost_calls = 0
|
||||||
|
self.total_danger_map_lookup_calls = 0
|
||||||
|
self.total_danger_map_cache_hits = 0
|
||||||
|
self.total_danger_map_cache_misses = 0
|
||||||
|
self.total_danger_map_query_calls = 0
|
||||||
|
self.total_danger_map_total_ns = 0
|
||||||
self.total_move_cache_abs_hits = 0
|
self.total_move_cache_abs_hits = 0
|
||||||
self.total_move_cache_abs_misses = 0
|
self.total_move_cache_abs_misses = 0
|
||||||
self.total_move_cache_rel_hits = 0
|
self.total_move_cache_rel_hits = 0
|
||||||
|
|
@ -216,12 +274,22 @@ class AStarMetrics:
|
||||||
self.total_static_net_tree_rebuilds = 0
|
self.total_static_net_tree_rebuilds = 0
|
||||||
self.total_visibility_builds = 0
|
self.total_visibility_builds = 0
|
||||||
self.total_visibility_corner_pairs_checked = 0
|
self.total_visibility_corner_pairs_checked = 0
|
||||||
self.total_visibility_corner_queries = 0
|
self.total_visibility_corner_queries_exact = 0
|
||||||
self.total_visibility_corner_hits = 0
|
self.total_visibility_corner_hits_exact = 0
|
||||||
self.total_visibility_point_queries = 0
|
self.total_visibility_point_queries = 0
|
||||||
self.total_visibility_point_cache_hits = 0
|
self.total_visibility_point_cache_hits = 0
|
||||||
self.total_visibility_point_cache_misses = 0
|
self.total_visibility_point_cache_misses = 0
|
||||||
|
self.total_visibility_tangent_candidate_scans = 0
|
||||||
|
self.total_visibility_tangent_candidate_corner_checks = 0
|
||||||
|
self.total_visibility_tangent_candidate_ray_tests = 0
|
||||||
self.total_ray_cast_calls = 0
|
self.total_ray_cast_calls = 0
|
||||||
|
self.total_ray_cast_calls_straight_static = 0
|
||||||
|
self.total_ray_cast_calls_expand_snap = 0
|
||||||
|
self.total_ray_cast_calls_expand_forward = 0
|
||||||
|
self.total_ray_cast_calls_visibility_build = 0
|
||||||
|
self.total_ray_cast_calls_visibility_query = 0
|
||||||
|
self.total_ray_cast_calls_visibility_tangent = 0
|
||||||
|
self.total_ray_cast_calls_other = 0
|
||||||
self.total_ray_cast_candidate_bounds = 0
|
self.total_ray_cast_candidate_bounds = 0
|
||||||
self.total_ray_cast_exact_geometry_checks = 0
|
self.total_ray_cast_exact_geometry_checks = 0
|
||||||
self.total_congestion_check_calls = 0
|
self.total_congestion_check_calls = 0
|
||||||
|
|
@ -229,6 +297,13 @@ class AStarMetrics:
|
||||||
self.total_verify_path_report_calls = 0
|
self.total_verify_path_report_calls = 0
|
||||||
self.total_verify_static_buffer_ops = 0
|
self.total_verify_static_buffer_ops = 0
|
||||||
self.total_verify_dynamic_exact_pair_checks = 0
|
self.total_verify_dynamic_exact_pair_checks = 0
|
||||||
|
self.total_refinement_windows_considered = 0
|
||||||
|
self.total_refinement_static_bounds_checked = 0
|
||||||
|
self.total_refinement_dynamic_bounds_checked = 0
|
||||||
|
self.total_refinement_candidate_side_extents = 0
|
||||||
|
self.total_refinement_candidates_built = 0
|
||||||
|
self.total_refinement_candidates_verified = 0
|
||||||
|
self.total_refinement_candidates_accepted = 0
|
||||||
|
|
||||||
def reset_per_route(self) -> None:
|
def reset_per_route(self) -> None:
|
||||||
self.nodes_expanded = 0
|
self.nodes_expanded = 0
|
||||||
|
|
@ -254,6 +329,14 @@ class AStarMetrics:
|
||||||
warm_start_paths_used=self.total_warm_start_paths_used,
|
warm_start_paths_used=self.total_warm_start_paths_used,
|
||||||
refine_path_calls=self.total_refine_path_calls,
|
refine_path_calls=self.total_refine_path_calls,
|
||||||
timeout_events=self.total_timeout_events,
|
timeout_events=self.total_timeout_events,
|
||||||
|
score_component_calls=self.total_score_component_calls,
|
||||||
|
score_component_total_ns=self.total_score_component_total_ns,
|
||||||
|
path_cost_calls=self.total_path_cost_calls,
|
||||||
|
danger_map_lookup_calls=self.total_danger_map_lookup_calls,
|
||||||
|
danger_map_cache_hits=self.total_danger_map_cache_hits,
|
||||||
|
danger_map_cache_misses=self.total_danger_map_cache_misses,
|
||||||
|
danger_map_query_calls=self.total_danger_map_query_calls,
|
||||||
|
danger_map_total_ns=self.total_danger_map_total_ns,
|
||||||
move_cache_abs_hits=self.total_move_cache_abs_hits,
|
move_cache_abs_hits=self.total_move_cache_abs_hits,
|
||||||
move_cache_abs_misses=self.total_move_cache_abs_misses,
|
move_cache_abs_misses=self.total_move_cache_abs_misses,
|
||||||
move_cache_rel_hits=self.total_move_cache_rel_hits,
|
move_cache_rel_hits=self.total_move_cache_rel_hits,
|
||||||
|
|
@ -271,12 +354,22 @@ class AStarMetrics:
|
||||||
static_net_tree_rebuilds=self.total_static_net_tree_rebuilds,
|
static_net_tree_rebuilds=self.total_static_net_tree_rebuilds,
|
||||||
visibility_builds=self.total_visibility_builds,
|
visibility_builds=self.total_visibility_builds,
|
||||||
visibility_corner_pairs_checked=self.total_visibility_corner_pairs_checked,
|
visibility_corner_pairs_checked=self.total_visibility_corner_pairs_checked,
|
||||||
visibility_corner_queries=self.total_visibility_corner_queries,
|
visibility_corner_queries_exact=self.total_visibility_corner_queries_exact,
|
||||||
visibility_corner_hits=self.total_visibility_corner_hits,
|
visibility_corner_hits_exact=self.total_visibility_corner_hits_exact,
|
||||||
visibility_point_queries=self.total_visibility_point_queries,
|
visibility_point_queries=self.total_visibility_point_queries,
|
||||||
visibility_point_cache_hits=self.total_visibility_point_cache_hits,
|
visibility_point_cache_hits=self.total_visibility_point_cache_hits,
|
||||||
visibility_point_cache_misses=self.total_visibility_point_cache_misses,
|
visibility_point_cache_misses=self.total_visibility_point_cache_misses,
|
||||||
|
visibility_tangent_candidate_scans=self.total_visibility_tangent_candidate_scans,
|
||||||
|
visibility_tangent_candidate_corner_checks=self.total_visibility_tangent_candidate_corner_checks,
|
||||||
|
visibility_tangent_candidate_ray_tests=self.total_visibility_tangent_candidate_ray_tests,
|
||||||
ray_cast_calls=self.total_ray_cast_calls,
|
ray_cast_calls=self.total_ray_cast_calls,
|
||||||
|
ray_cast_calls_straight_static=self.total_ray_cast_calls_straight_static,
|
||||||
|
ray_cast_calls_expand_snap=self.total_ray_cast_calls_expand_snap,
|
||||||
|
ray_cast_calls_expand_forward=self.total_ray_cast_calls_expand_forward,
|
||||||
|
ray_cast_calls_visibility_build=self.total_ray_cast_calls_visibility_build,
|
||||||
|
ray_cast_calls_visibility_query=self.total_ray_cast_calls_visibility_query,
|
||||||
|
ray_cast_calls_visibility_tangent=self.total_ray_cast_calls_visibility_tangent,
|
||||||
|
ray_cast_calls_other=self.total_ray_cast_calls_other,
|
||||||
ray_cast_candidate_bounds=self.total_ray_cast_candidate_bounds,
|
ray_cast_candidate_bounds=self.total_ray_cast_candidate_bounds,
|
||||||
ray_cast_exact_geometry_checks=self.total_ray_cast_exact_geometry_checks,
|
ray_cast_exact_geometry_checks=self.total_ray_cast_exact_geometry_checks,
|
||||||
congestion_check_calls=self.total_congestion_check_calls,
|
congestion_check_calls=self.total_congestion_check_calls,
|
||||||
|
|
@ -284,6 +377,13 @@ class AStarMetrics:
|
||||||
verify_path_report_calls=self.total_verify_path_report_calls,
|
verify_path_report_calls=self.total_verify_path_report_calls,
|
||||||
verify_static_buffer_ops=self.total_verify_static_buffer_ops,
|
verify_static_buffer_ops=self.total_verify_static_buffer_ops,
|
||||||
verify_dynamic_exact_pair_checks=self.total_verify_dynamic_exact_pair_checks,
|
verify_dynamic_exact_pair_checks=self.total_verify_dynamic_exact_pair_checks,
|
||||||
|
refinement_windows_considered=self.total_refinement_windows_considered,
|
||||||
|
refinement_static_bounds_checked=self.total_refinement_static_bounds_checked,
|
||||||
|
refinement_dynamic_bounds_checked=self.total_refinement_dynamic_bounds_checked,
|
||||||
|
refinement_candidate_side_extents=self.total_refinement_candidate_side_extents,
|
||||||
|
refinement_candidates_built=self.total_refinement_candidates_built,
|
||||||
|
refinement_candidates_verified=self.total_refinement_candidates_verified,
|
||||||
|
refinement_candidates_accepted=self.total_refinement_candidates_accepted,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ class PathFinder:
|
||||||
self.metrics = self.context.metrics if metrics is None else metrics
|
self.metrics = self.context.metrics if metrics is None else metrics
|
||||||
self.context.metrics = self.metrics
|
self.context.metrics = self.metrics
|
||||||
self.context.cost_evaluator.collision_engine.metrics = self.metrics
|
self.context.cost_evaluator.collision_engine.metrics = self.metrics
|
||||||
|
if self.context.cost_evaluator.danger_map is not None:
|
||||||
|
self.context.cost_evaluator.danger_map.metrics = self.metrics
|
||||||
self.refiner = PathRefiner(self.context)
|
self.refiner = PathRefiner(self.context)
|
||||||
self.accumulated_expanded_nodes: list[tuple[int, int, int]] = []
|
self.accumulated_expanded_nodes: list[tuple[int, int, int]] = []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from time import perf_counter_ns
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
@ -130,10 +131,16 @@ class CostEvaluator:
|
||||||
start_port: Port | None = None,
|
start_port: Port | None = None,
|
||||||
weights: ObjectiveWeights | None = None,
|
weights: ObjectiveWeights | None = None,
|
||||||
) -> float:
|
) -> float:
|
||||||
|
metrics = self.collision_engine.metrics
|
||||||
|
if metrics is not None:
|
||||||
|
metrics.total_score_component_calls += 1
|
||||||
|
start_ns = perf_counter_ns()
|
||||||
active_weights = self._resolve_weights(weights)
|
active_weights = self._resolve_weights(weights)
|
||||||
danger_map = self.danger_map
|
danger_map = self.danger_map
|
||||||
end_port = component.end_port
|
end_port = component.end_port
|
||||||
if danger_map is not None and not danger_map.is_within_bounds(end_port.x, end_port.y):
|
if danger_map is not None and not danger_map.is_within_bounds(end_port.x, end_port.y):
|
||||||
|
if metrics is not None:
|
||||||
|
metrics.total_score_component_total_ns += perf_counter_ns() - start_ns
|
||||||
return 1e15
|
return 1e15
|
||||||
|
|
||||||
move_radius = None
|
move_radius = None
|
||||||
|
|
@ -155,6 +162,8 @@ class CostEvaluator:
|
||||||
total_cost += component.length * active_weights.danger_weight * (cost_s + cost_m + cost_e) / 3.0
|
total_cost += component.length * active_weights.danger_weight * (cost_s + cost_m + cost_e) / 3.0
|
||||||
else:
|
else:
|
||||||
total_cost += component.length * active_weights.danger_weight * cost_e
|
total_cost += component.length * active_weights.danger_weight * cost_e
|
||||||
|
if metrics is not None:
|
||||||
|
metrics.total_score_component_total_ns += perf_counter_ns() - start_ns
|
||||||
return total_cost
|
return total_cost
|
||||||
|
|
||||||
def component_penalty(
|
def component_penalty(
|
||||||
|
|
@ -181,6 +190,9 @@ class CostEvaluator:
|
||||||
*,
|
*,
|
||||||
weights: ObjectiveWeights | None = None,
|
weights: ObjectiveWeights | None = None,
|
||||||
) -> float:
|
) -> float:
|
||||||
|
metrics = self.collision_engine.metrics
|
||||||
|
if metrics is not None:
|
||||||
|
metrics.total_path_cost_calls += 1
|
||||||
active_weights = self._resolve_weights(weights)
|
active_weights = self._resolve_weights(weights)
|
||||||
total = 0.0
|
total = 0.0
|
||||||
current_port = start_port
|
current_port = start_port
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from time import perf_counter_ns
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
|
@ -8,6 +9,7 @@ from scipy.spatial import cKDTree
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from shapely.geometry import Polygon
|
from shapely.geometry import Polygon
|
||||||
|
from inire.router._astar_types import AStarMetrics
|
||||||
|
|
||||||
|
|
||||||
_COST_CACHE_SIZE = 100000
|
_COST_CACHE_SIZE = 100000
|
||||||
|
|
@ -18,7 +20,7 @@ class DangerMap:
|
||||||
A proximity cost evaluator using a KD-Tree of obstacle boundary points.
|
A proximity cost evaluator using a KD-Tree of obstacle boundary points.
|
||||||
Scales with obstacle perimeter rather than design area.
|
Scales with obstacle perimeter rather than design area.
|
||||||
"""
|
"""
|
||||||
__slots__ = ('minx', 'miny', 'maxx', 'maxy', 'resolution', 'safety_threshold', 'k', 'tree', '_cost_cache')
|
__slots__ = ('minx', 'miny', 'maxx', 'maxy', 'resolution', 'safety_threshold', 'k', 'tree', '_cost_cache', 'metrics')
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
|
@ -42,6 +44,7 @@ class DangerMap:
|
||||||
self.k = k
|
self.k = k
|
||||||
self.tree: cKDTree | None = None
|
self.tree: cKDTree | None = None
|
||||||
self._cost_cache: OrderedDict[tuple[int, int], float] = OrderedDict()
|
self._cost_cache: OrderedDict[tuple[int, int], float] = OrderedDict()
|
||||||
|
self.metrics: AStarMetrics | None = None
|
||||||
|
|
||||||
def precompute(self, obstacles: list[Polygon]) -> None:
|
def precompute(self, obstacles: list[Polygon]) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
@ -82,17 +85,28 @@ class DangerMap:
|
||||||
Get the proximity cost at a specific coordinate using the KD-Tree.
|
Get the proximity cost at a specific coordinate using the KD-Tree.
|
||||||
Coordinates are quantized to 1nm to improve cache performance.
|
Coordinates are quantized to 1nm to improve cache performance.
|
||||||
"""
|
"""
|
||||||
|
metrics = self.metrics
|
||||||
|
if metrics is not None:
|
||||||
|
metrics.total_danger_map_lookup_calls += 1
|
||||||
|
start_ns = perf_counter_ns()
|
||||||
qx_milli = int(round(x * 1000))
|
qx_milli = int(round(x * 1000))
|
||||||
qy_milli = int(round(y * 1000))
|
qy_milli = int(round(y * 1000))
|
||||||
key = (qx_milli, qy_milli)
|
key = (qx_milli, qy_milli)
|
||||||
if key in self._cost_cache:
|
if key in self._cost_cache:
|
||||||
|
if metrics is not None:
|
||||||
|
metrics.total_danger_map_cache_hits += 1
|
||||||
|
metrics.total_danger_map_total_ns += perf_counter_ns() - start_ns
|
||||||
self._cost_cache.move_to_end(key)
|
self._cost_cache.move_to_end(key)
|
||||||
return self._cost_cache[key]
|
return self._cost_cache[key]
|
||||||
|
|
||||||
|
if metrics is not None:
|
||||||
|
metrics.total_danger_map_cache_misses += 1
|
||||||
cost = self._compute_cost_quantized(qx_milli, qy_milli)
|
cost = self._compute_cost_quantized(qx_milli, qy_milli)
|
||||||
self._cost_cache[key] = cost
|
self._cost_cache[key] = cost
|
||||||
if len(self._cost_cache) > _COST_CACHE_SIZE:
|
if len(self._cost_cache) > _COST_CACHE_SIZE:
|
||||||
self._cost_cache.popitem(last=False)
|
self._cost_cache.popitem(last=False)
|
||||||
|
if metrics is not None:
|
||||||
|
metrics.total_danger_map_total_ns += perf_counter_ns() - start_ns
|
||||||
return cost
|
return cost
|
||||||
|
|
||||||
def _compute_cost_quantized(self, qx_milli: int, qy_milli: int) -> float:
|
def _compute_cost_quantized(self, qx_milli: int, qy_milli: int) -> float:
|
||||||
|
|
@ -102,6 +116,8 @@ class DangerMap:
|
||||||
return 1e15
|
return 1e15
|
||||||
if self.tree is None:
|
if self.tree is None:
|
||||||
return 0.0
|
return 0.0
|
||||||
|
if self.metrics is not None:
|
||||||
|
self.metrics.total_danger_map_query_calls += 1
|
||||||
dist, _ = self.tree.query([qx, qy], distance_upper_bound=self.safety_threshold)
|
dist, _ = self.tree.query([qx, qy], distance_upper_bound=self.safety_threshold)
|
||||||
if dist >= self.safety_threshold:
|
if dist >= self.safety_threshold:
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ class PathRefiner:
|
||||||
x_max = max(0.0, float(local_dx)) + 0.01
|
x_max = max(0.0, float(local_dx)) + 0.01
|
||||||
|
|
||||||
for bounds in self.collision_engine.iter_static_obstacle_bounds(query_bounds):
|
for bounds in self.collision_engine.iter_static_obstacle_bounds(query_bounds):
|
||||||
|
self.context.metrics.total_refinement_static_bounds_checked += 1
|
||||||
local_corners = (
|
local_corners = (
|
||||||
self._to_local_xy(start, bounds[0], bounds[1]),
|
self._to_local_xy(start, bounds[0], bounds[1]),
|
||||||
self._to_local_xy(start, bounds[0], bounds[3]),
|
self._to_local_xy(start, bounds[0], bounds[3]),
|
||||||
|
|
@ -144,6 +145,7 @@ class PathRefiner:
|
||||||
negative_anchors.add(obs_min_y)
|
negative_anchors.add(obs_min_y)
|
||||||
|
|
||||||
for bounds in self.collision_engine.iter_dynamic_path_bounds(query_bounds):
|
for bounds in self.collision_engine.iter_dynamic_path_bounds(query_bounds):
|
||||||
|
self.context.metrics.total_refinement_dynamic_bounds_checked += 1
|
||||||
local_corners = (
|
local_corners = (
|
||||||
self._to_local_xy(start, bounds[0], bounds[1]),
|
self._to_local_xy(start, bounds[0], bounds[1]),
|
||||||
self._to_local_xy(start, bounds[0], bounds[3]),
|
self._to_local_xy(start, bounds[0], bounds[3]),
|
||||||
|
|
@ -166,6 +168,7 @@ class PathRefiner:
|
||||||
if anchor < min(0.0, float(local_dy)) + 0.01:
|
if anchor < min(0.0, float(local_dy)) + 0.01:
|
||||||
direct_extents.add(anchor - pad)
|
direct_extents.add(anchor - pad)
|
||||||
|
|
||||||
|
self.context.metrics.total_refinement_candidate_side_extents += len(direct_extents)
|
||||||
return sorted(direct_extents, key=lambda value: (abs(value), value))
|
return sorted(direct_extents, key=lambda value: (abs(value), value))
|
||||||
|
|
||||||
def _build_same_orientation_dogleg(
|
def _build_same_orientation_dogleg(
|
||||||
|
|
@ -243,6 +246,7 @@ class PathRefiner:
|
||||||
local_dx, _ = self._to_local(window_start, window_end)
|
local_dx, _ = self._to_local(window_start, window_end)
|
||||||
if local_dx < 4.0 * min_radius - 0.01:
|
if local_dx < 4.0 * min_radius - 0.01:
|
||||||
continue
|
continue
|
||||||
|
self.context.metrics.total_refinement_windows_considered += 1
|
||||||
windows.append((start_idx, end_idx))
|
windows.append((start_idx, end_idx))
|
||||||
return windows
|
return windows
|
||||||
|
|
||||||
|
|
@ -270,12 +274,15 @@ class PathRefiner:
|
||||||
replacement = self._build_same_orientation_dogleg(window_start, window_end, net_width, radius, side_extent)
|
replacement = self._build_same_orientation_dogleg(window_start, window_end, net_width, radius, side_extent)
|
||||||
if replacement is None:
|
if replacement is None:
|
||||||
continue
|
continue
|
||||||
|
self.context.metrics.total_refinement_candidates_built += 1
|
||||||
candidate_path = path[:start_idx] + replacement + path[end_idx:]
|
candidate_path = path[:start_idx] + replacement + path[end_idx:]
|
||||||
|
self.context.metrics.total_refinement_candidates_verified += 1
|
||||||
report = self.collision_engine.verify_path_report(net_id, candidate_path)
|
report = self.collision_engine.verify_path_report(net_id, candidate_path)
|
||||||
if not report.is_valid:
|
if not report.is_valid:
|
||||||
continue
|
continue
|
||||||
candidate_cost = self.path_cost(candidate_path)
|
candidate_cost = self.path_cost(candidate_path)
|
||||||
if candidate_cost + 1e-6 < best_candidate_cost:
|
if candidate_cost + 1e-6 < best_candidate_cost:
|
||||||
|
self.context.metrics.total_refinement_candidates_accepted += 1
|
||||||
best_candidate_cost = candidate_cost
|
best_candidate_cost = candidate_cost
|
||||||
best_path = candidate_path
|
best_path = candidate_path
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ class VisibilityManager:
|
||||||
dx, dy = cx - p1.x, cy - p1.y
|
dx, dy = cx - p1.x, cy - p1.y
|
||||||
dist = numpy.sqrt(dx**2 + dy**2)
|
dist = numpy.sqrt(dx**2 + dy**2)
|
||||||
angle = numpy.degrees(numpy.arctan2(dy, dx))
|
angle = numpy.degrees(numpy.arctan2(dy, dx))
|
||||||
reach = self.collision_engine.ray_cast(p1, angle, max_dist=dist + 0.05)
|
reach = self.collision_engine.ray_cast(p1, angle, max_dist=dist + 0.05, caller="visibility_build")
|
||||||
if reach >= dist - 0.01:
|
if reach >= dist - 0.01:
|
||||||
self._corner_graph[i].append((cx, cy, dist))
|
self._corner_graph[i].append((cx, cy, dist))
|
||||||
|
|
||||||
|
|
@ -143,7 +143,7 @@ class VisibilityManager:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
angle = numpy.degrees(numpy.arctan2(dy, dx))
|
angle = numpy.degrees(numpy.arctan2(dy, dx))
|
||||||
reach = self.collision_engine.ray_cast(origin, angle, max_dist=dist + 0.05)
|
reach = self.collision_engine.ray_cast(origin, angle, max_dist=dist + 0.05, caller="visibility_query")
|
||||||
if reach >= dist - 0.01:
|
if reach >= dist - 0.01:
|
||||||
visible.append((cx, cy, dist))
|
visible.append((cx, cy, dist))
|
||||||
|
|
||||||
|
|
@ -156,7 +156,7 @@ class VisibilityManager:
|
||||||
This avoids the expensive arbitrary-point visibility scan in hot search paths.
|
This avoids the expensive arbitrary-point visibility scan in hot search paths.
|
||||||
"""
|
"""
|
||||||
if self.collision_engine.metrics is not None:
|
if self.collision_engine.metrics is not None:
|
||||||
self.collision_engine.metrics.total_visibility_corner_queries += 1
|
self.collision_engine.metrics.total_visibility_corner_queries_exact += 1
|
||||||
self._ensure_current()
|
self._ensure_current()
|
||||||
if max_dist < 0:
|
if max_dist < 0:
|
||||||
return []
|
return []
|
||||||
|
|
@ -164,6 +164,6 @@ class VisibilityManager:
|
||||||
corner_idx = self._corner_idx_at(origin)
|
corner_idx = self._corner_idx_at(origin)
|
||||||
if corner_idx is not None and corner_idx in self._corner_graph:
|
if corner_idx is not None and corner_idx in self._corner_graph:
|
||||||
if self.collision_engine.metrics is not None:
|
if self.collision_engine.metrics is not None:
|
||||||
self.collision_engine.metrics.total_visibility_corner_hits += 1
|
self.collision_engine.metrics.total_visibility_corner_hits_exact += 1
|
||||||
return [corner for corner in self._corner_graph[corner_idx] if corner[2] <= max_dist]
|
return [corner for corner in self._corner_graph[corner_idx] if corner[2] <= max_dist]
|
||||||
return []
|
return []
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,14 @@ def test_snapshot_example_01_exposes_metrics() -> None:
|
||||||
assert snapshot.metrics.route_iterations >= 1
|
assert snapshot.metrics.route_iterations >= 1
|
||||||
assert snapshot.metrics.nets_routed >= 1
|
assert snapshot.metrics.nets_routed >= 1
|
||||||
assert snapshot.metrics.nodes_expanded > 0
|
assert snapshot.metrics.nodes_expanded > 0
|
||||||
|
assert snapshot.metrics.score_component_calls >= 0
|
||||||
|
assert snapshot.metrics.danger_map_lookup_calls >= 0
|
||||||
assert snapshot.metrics.move_cache_abs_misses >= 0
|
assert snapshot.metrics.move_cache_abs_misses >= 0
|
||||||
assert snapshot.metrics.ray_cast_calls >= 0
|
assert snapshot.metrics.ray_cast_calls >= 0
|
||||||
|
assert snapshot.metrics.ray_cast_calls_expand_forward >= 0
|
||||||
assert snapshot.metrics.dynamic_tree_rebuilds >= 0
|
assert snapshot.metrics.dynamic_tree_rebuilds >= 0
|
||||||
assert snapshot.metrics.visibility_builds >= 0
|
assert snapshot.metrics.visibility_builds >= 0
|
||||||
|
assert snapshot.metrics.refinement_candidates_verified >= 0
|
||||||
|
|
||||||
|
|
||||||
def test_record_performance_baseline_script_writes_selected_scenario(tmp_path: Path) -> None:
|
def test_record_performance_baseline_script_writes_selected_scenario(tmp_path: Path) -> None:
|
||||||
|
|
@ -43,3 +47,41 @@ def test_record_performance_baseline_script_writes_selected_scenario(tmp_path: P
|
||||||
assert payload["generator"] == "scripts/record_performance_baseline.py"
|
assert payload["generator"] == "scripts/record_performance_baseline.py"
|
||||||
assert [entry["name"] for entry in payload["scenarios"]] == ["example_01_simple_route"]
|
assert [entry["name"] for entry in payload["scenarios"]] == ["example_01_simple_route"]
|
||||||
assert (tmp_path / "performance.md").exists()
|
assert (tmp_path / "performance.md").exists()
|
||||||
|
|
||||||
|
|
||||||
|
def test_diff_performance_baseline_script_writes_selected_scenario(tmp_path: Path) -> None:
|
||||||
|
repo_root = Path(__file__).resolve().parents[2]
|
||||||
|
record_script = repo_root / "scripts" / "record_performance_baseline.py"
|
||||||
|
diff_script = repo_root / "scripts" / "diff_performance_baseline.py"
|
||||||
|
baseline_dir = tmp_path / "baseline"
|
||||||
|
baseline_dir.mkdir()
|
||||||
|
output_path = tmp_path / "diff.md"
|
||||||
|
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
str(record_script),
|
||||||
|
"--output-dir",
|
||||||
|
str(baseline_dir),
|
||||||
|
"--scenario",
|
||||||
|
"example_01_simple_route",
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
str(diff_script),
|
||||||
|
"--baseline",
|
||||||
|
str(baseline_dir / "performance_baseline.json"),
|
||||||
|
"--scenario",
|
||||||
|
"example_01_simple_route",
|
||||||
|
"--output",
|
||||||
|
str(output_path),
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
report = output_path.read_text()
|
||||||
|
assert "Performance Baseline Diff" in report
|
||||||
|
assert "example_01_simple_route" in report
|
||||||
|
|
|
||||||
113
scripts/diff_performance_baseline.py
Normal file
113
scripts/diff_performance_baseline.py
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
from dataclasses import asdict
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from inire.tests.example_scenarios import SCENARIO_SNAPSHOTS
|
||||||
|
|
||||||
|
|
||||||
|
SUMMARY_KEYS = (
|
||||||
|
"duration_s",
|
||||||
|
"route_iterations",
|
||||||
|
"nets_routed",
|
||||||
|
"nodes_expanded",
|
||||||
|
"ray_cast_calls",
|
||||||
|
"moves_generated",
|
||||||
|
"moves_added",
|
||||||
|
"congestion_check_calls",
|
||||||
|
"verify_path_report_calls",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _current_snapshots(selected_scenarios: tuple[str, ...] | None) -> dict[str, dict[str, object]]:
|
||||||
|
allowed = None if selected_scenarios is None else set(selected_scenarios)
|
||||||
|
snapshots: dict[str, dict[str, object]] = {}
|
||||||
|
for name, run in SCENARIO_SNAPSHOTS:
|
||||||
|
if allowed is not None and name not in allowed:
|
||||||
|
continue
|
||||||
|
snapshots[name] = asdict(run())
|
||||||
|
return snapshots
|
||||||
|
|
||||||
|
|
||||||
|
def _load_baseline(path: Path, selected_scenarios: tuple[str, ...] | None) -> dict[str, dict[str, object]]:
|
||||||
|
payload = json.loads(path.read_text())
|
||||||
|
allowed = None if selected_scenarios is None else set(selected_scenarios)
|
||||||
|
return {
|
||||||
|
entry["name"]: entry
|
||||||
|
for entry in payload["scenarios"]
|
||||||
|
if allowed is None or entry["name"] in allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _metric_value(snapshot: dict[str, object], key: str) -> float:
|
||||||
|
if key == "duration_s":
|
||||||
|
return float(snapshot["duration_s"])
|
||||||
|
return float(snapshot["metrics"][key])
|
||||||
|
|
||||||
|
|
||||||
|
def _render_report(baseline: dict[str, dict[str, object]], current: dict[str, dict[str, object]]) -> str:
|
||||||
|
scenario_names = sorted(set(baseline) | set(current))
|
||||||
|
lines = [
|
||||||
|
"# Performance Baseline Diff",
|
||||||
|
"",
|
||||||
|
"| Scenario | Metric | Baseline | Current | Delta |",
|
||||||
|
"| :-- | :-- | --: | --: | --: |",
|
||||||
|
]
|
||||||
|
for scenario in scenario_names:
|
||||||
|
base_snapshot = baseline.get(scenario)
|
||||||
|
curr_snapshot = current.get(scenario)
|
||||||
|
if base_snapshot is None:
|
||||||
|
lines.append(f"| {scenario} | added | - | - | - |")
|
||||||
|
continue
|
||||||
|
if curr_snapshot is None:
|
||||||
|
lines.append(f"| {scenario} | missing | - | - | - |")
|
||||||
|
continue
|
||||||
|
for key in SUMMARY_KEYS:
|
||||||
|
base_value = _metric_value(base_snapshot, key)
|
||||||
|
curr_value = _metric_value(curr_snapshot, key)
|
||||||
|
lines.append(
|
||||||
|
f"| {scenario} | {key} | {base_value:.4f} | {curr_value:.4f} | {curr_value - base_value:+.4f} |"
|
||||||
|
)
|
||||||
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
parser = argparse.ArgumentParser(description="Diff the committed performance baseline against a fresh run.")
|
||||||
|
parser.add_argument(
|
||||||
|
"--baseline",
|
||||||
|
type=Path,
|
||||||
|
default=Path("docs/performance_baseline.json"),
|
||||||
|
help="Baseline JSON to compare against.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--output",
|
||||||
|
type=Path,
|
||||||
|
default=None,
|
||||||
|
help="Optional file to write the report to. Defaults to stdout.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--scenario",
|
||||||
|
action="append",
|
||||||
|
dest="scenarios",
|
||||||
|
default=[],
|
||||||
|
help="Optional scenario name to include. May be passed more than once.",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
selected = tuple(args.scenarios) if args.scenarios else None
|
||||||
|
baseline = _load_baseline(args.baseline, selected)
|
||||||
|
current = _current_snapshots(selected)
|
||||||
|
report = _render_report(baseline, current)
|
||||||
|
|
||||||
|
if args.output is None:
|
||||||
|
print(report, end="")
|
||||||
|
else:
|
||||||
|
args.output.write_text(report)
|
||||||
|
print(f"Wrote {args.output}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -46,6 +46,7 @@ def _render_markdown(payload: dict[str, object]) -> str:
|
||||||
f"Generated on {payload['generated_on']} by `{payload['generator']}`.",
|
f"Generated on {payload['generated_on']} by `{payload['generator']}`.",
|
||||||
"",
|
"",
|
||||||
"The full machine-readable snapshot lives in `docs/performance_baseline.json`.",
|
"The full machine-readable snapshot lives in `docs/performance_baseline.json`.",
|
||||||
|
"Use `scripts/diff_performance_baseline.py` to compare a fresh run against that snapshot.",
|
||||||
"",
|
"",
|
||||||
"| Scenario | Duration (s) | Total | Valid | Reached | Iter | Nets Routed | Nodes | Ray Casts | Moves Gen | Moves Added | Dyn Tree | Visibility Builds | Congestion Checks | Verify Calls |",
|
"| Scenario | Duration (s) | Total | Valid | Reached | Iter | Nets Routed | Nodes | Ray Casts | Moves Gen | Moves Added | Dyn Tree | Visibility Builds | Congestion Checks | Verify Calls |",
|
||||||
"| :-- | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: |",
|
"| :-- | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: |",
|
||||||
|
|
@ -77,6 +78,7 @@ def _render_markdown(payload: dict[str, object]) -> str:
|
||||||
"## Full Counter Set",
|
"## Full Counter Set",
|
||||||
"",
|
"",
|
||||||
"Each scenario entry in `docs/performance_baseline.json` records the full `RouteMetrics` snapshot, including cache, index, congestion, and verification counters.",
|
"Each scenario entry in `docs/performance_baseline.json` records the full `RouteMetrics` snapshot, including cache, index, congestion, and verification counters.",
|
||||||
|
"These counters are currently observational only and are not enforced as CI regression gates.",
|
||||||
"",
|
"",
|
||||||
"Tracked metric keys:",
|
"Tracked metric keys:",
|
||||||
"",
|
"",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue