Skip to content

Commit 25b3693

Browse files
authored
Extend pathfinding asv benchmarks to dask/cupy and multi_stop_search (#3645) (#3648)
The pathfinding benchmark only ran a_star_search on numpy at nx<=300. Parameterize AStarSearch over numpy/cupy/dask and add nx=1000 (dask capped at 300: the sparse Python A* takes ~4s per call at 1000). Add a MultiStopSearch class timing ordered routing and optimize_order. Every combo was executed locally, including cupy on a GPU host. Benchmark-only change; no edits to xrspatial/pathfinding.py. Claude-Session: https://claude.ai/code/session_0155N4QGamQVxgpAAPbpQNq4
1 parent 04df019 commit 25b3693

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

.claude/sweep-benchmarks-state.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
module,last_inspected,issue,severity_max,categories_found,notes
22
geotiff,2026-07-02,3603,HIGH,1;2,"No benchmark existed for geotiff; open_geotiff/to_geotiff had zero asv coverage across numpy/dask/cupy. Added benchmarks/benchmarks/geotiff.py: WriteGeoTIFF (numpy/dask/cupy streaming), WriteCOG (numpy/cupy overview pyramid), ReadGeoTIFF (numpy/cupy decode), ReadGeoTIFFChunked (dask). All classes executed locally via direct call; cupy paths run on this GPU host. asv check discover fails suite-wide from an asv_runner + py3.14 metadata bug, unrelated to this file."
3+
pathfinding,2026-07-08,3645,HIGH,1;2;3,"Bench covered only numpy a_star_search at nx<=300; module also ships dask (separate sparse-Python A* + LRU chunk cache), cupy fallback, and public multi_stop_search with zero coverage. Extended AStarSearch to numpy/cupy/dask with nx up to 1000 (dask capped at 300, ~4s/call at 1000) and added MultiStopSearch (ordered + optimize_order). All combos executed locally incl. cupy (GPU host). LOW noted, not fixed: open-grid no-barrier/no-friction input is A* best case. dask+cupy not parameterized anywhere in suite (common.get_xr_dataarray has no such type). Existing bench imports/runs fine (Cat 4 clean)."

benchmarks/benchmarks/pathfinding.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,49 @@ def peakmem_multi_stop_search(self):
3636

3737

3838
class AStarSearch:
39-
params = ([10, 100, 300], [4, 8], ["numpy"])
39+
params = ([100, 300, 1000], [4, 8], ["numpy", "cupy", "dask"])
4040
param_names = ("nx", "connectivity", "type")
4141

4242
def setup(self, nx, connectivity, type):
43+
if type == "dask" and nx > 300:
44+
# The dask backend is a pure-Python sparse A* that loads
45+
# chunks on demand; at nx=1000 a single call takes ~4 s,
46+
# which would dominate the suite's runtime.
47+
raise NotImplementedError()
4348
ny = nx // 2
4449
self.agg = get_xr_dataarray((ny, nx), type)
4550
self.start = self.agg.y[0], self.agg.x[0]
4651
self.goal = self.agg.y[-1], self.agg.x[-1]
52+
# snap_start/snap_goal raise on dask-backed arrays by design
53+
self.snap = type != "dask"
4754

4855
def time_a_star_search(self, nx, connectivity, type):
4956
a_star_search(
5057
self.agg, self.start, self.goal,
5158
connectivity=connectivity,
52-
snap_start=True, snap_goal=True
59+
snap_start=self.snap, snap_goal=self.snap
5360
)
61+
62+
63+
class MultiStopSearch:
64+
params = ([100, 300], ["numpy", "cupy", "dask"])
65+
param_names = ("nx", "type")
66+
67+
def setup(self, nx, type):
68+
ny = nx // 2
69+
self.agg = get_xr_dataarray((ny, nx), type)
70+
ys = self.agg.y.data
71+
xs = self.agg.x.data
72+
# 4 waypoints zigzagging across the grid (3 segments)
73+
self.waypoints = [
74+
(ys[0], xs[0]),
75+
(ys[-1], xs[nx // 3]),
76+
(ys[0], xs[2 * nx // 3]),
77+
(ys[-1], xs[-1]),
78+
]
79+
80+
def time_multi_stop_search(self, nx, type):
81+
multi_stop_search(self.agg, self.waypoints)
82+
83+
def time_multi_stop_search_optimize_order(self, nx, type):
84+
multi_stop_search(self.agg, self.waypoints, optimize_order=True)

0 commit comments

Comments
 (0)