Batched BFS distance maps¶
cuplan.distance_maps(grid, sources, backend="auto") computes the
exact 4-connected distance from each of n sources to every cell —
n flood fills as one batch.
Why it is the workhorse¶
Every serious MAPF implementation runs on exact goal-distance tables: they are the only admissible heuristic worth having on a map with walls, and PIBT queries them millions of times. pymapf builds them with one backward Dijkstra per agent, serially. On a unit-cost grid Dijkstra is breadth-first search, and BFS is a wavefront — every frontier cell can be expanded simultaneously.
Parallelization¶
The batch is a (n, height, width) volume advanced one wave per sweep:
- CPU reference — four array shifts OR-ed together per wave, vectorized over the whole batch with NumPy.
- CUDA — a gather ("pull") kernel: at wave t every unlabelled free cell checks whether any neighbour was labelled t−1 (Merrill, Garland and Grimshaw 2012, Scalable GPU graph traversal, PPoPP). Pull needs no atomics and stays coalesced; the cost of touching settled cells each wave is amortized across the batch.
The number of kernel launches equals the graph diameter, not the number of sources — batching 512 sources costs barely more than 16. Measured scaling is in Benchmarks.
Semantics¶
- Returns
int32distances,-1for unreachable cells (blocked cells included). - Matches
pymapf.algorithms.search.distance_tablevalues exactly (tested against a reference Python BFS, and CPU == CUDA is asserted on GPU machines).
Batched grid BFS: one flood-fill distance map per source.
This is the workhorse primitive of the library. MAPF solvers consume
exact goal-distance tables — pymapf computes one backward Dijkstra per
agent, serially. On a 4-connected grid with unit edge costs Dijkstra
is BFS, and BFS is a wavefront: every cell on the frontier can be
expanded simultaneously. Batching N sources into one (N, H, W)
volume turns the whole heuristic-table build into makespan fully
parallel sweeps.
Reference: Merrill, D.; Garland, M.; and Grimshaw, A. 2012. Scalable GPU graph traversal. PPoPP 2012: 117-128 (frontier-parallel BFS).
distance_maps ¶
distance_maps(grid, sources, backend='auto', timings=None)
Return exact 4-connected distances from each source to every cell.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid
|
Grid
|
the occupancy grid. |
required |
sources
|
ndarray
|
|
required |
backend
|
Backend
|
|
'auto'
|
timings
|
dict[str, float] | None
|
optional dict the CUDA backend fills with per-phase
wall times in seconds — |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
ndarray
|
length of a shortest path from |
ndarray
|
|
Source code in cuplan/bfs.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | |