Skip to content

r.sim: Simulate all walkers when running in parallel - #7964

Merged
wenzeslaus merged 1 commit into
OSGeo:mainfrom
wenzeslaus:simwe-nprocs-base
Sep 29, 2026
Merged

wenzeslaus merged 1 commit into
OSGeo:mainfrom
wenzeslaus:simwe-nprocs-base

Conversation

@wenzeslaus

Copy link
Copy Markdown
Member

With nprocs > 1, r.sim.water and r.sim.sediment skipped some walkers in every iteration: up to (nthreads - 1) / 2 walkers were never moved and never added their water. This rounds the per-thread chunk size up instead of to the nearest integer, a two-line change. Single-threaded results do not change.

Details (AI generated)

Each thread computed its range of walkers from a chunk size rounded to the nearest integer, steps = (int)(nwalk / nthreads + 0.5). When the division rounded down, the walkers past the last range were never moved:

nwalk nthreads steps covered dropped
2205 4 551 2204 1
2206 4 552 2208 0 (last range cut at nwalk)
2211 8 276 2208 3
1000007 16 62500 1000000 7

The chunk size is now rounded up, so the ranges cover all walkers. The last range is cut at nwalk as before, and with fewer walkers than threads the last threads get empty ranges. No other OpenMP code changes.

Verification: single-threaded depth and discharge (with and without infiltration), sediment flux and erosion/deposition on nc_spm are byte-identical to main.

The analysis, code and measurements were done with Claude Code (Opus) and reviewed by me.

Each thread computed its own range of walkers from a chunk size rounded
to the nearest integer, steps = (int)(nwalk / nthreads + 0.5). When the
division rounded down, the walkers past the last range were never moved
and never added their water, up to (nthreads - 1) / 2 walkers in every
iteration:

  nwalk    nthreads  steps  covered  dropped
  2205     4         551    2204     1
  2206     4         552    2208     0 (last range cut at nwalk)
  2211     8         276    2208     3
  1000007  16        62500  1000000  7

Round the chunk size up instead, so that the ranges cover all walkers.
The last range is then cut at nwalk as before, and with fewer walkers
than threads, the last threads get empty ranges.

Single-threaded results do not change: the depth, discharge, sediment
flux and erosion/deposition maps computed from the nc_spm elevation are
byte-identical to those before this change.

Written with the help of Claude Code.
@github-actions github-actions Bot added raster Related to raster data processing C Related code is in C module labels Sep 28, 2026
@wenzeslaus
wenzeslaus merged commit 9843891 into OSGeo:main Sep 29, 2026
26 checks passed
@github-actions github-actions Bot added this to the 8.6.0 milestone Sep 29, 2026
wenzeslaus added a commit to wenzeslaus/grass that referenced this pull request Sep 29, 2026
Each thread computed its range of walkers from a chunk size rounded to
the nearest integer, steps = (int)(nwalk / nthreads + 0.5). When the
division rounded down, the walkers past the last range were never moved
and never added their water, up to (nthreads - 1) / 2 walkers in every
iteration, e.g., 1 of 2205 walkers with 4 threads, 7 of 1000007 with 16.

Round the chunk size up instead, so that the ranges cover all walkers.
The last range is cut at nwalk as before, and with fewer walkers than
threads, the last threads get empty ranges.

Single-threaded results do not change: the depth, discharge, sediment
flux and erosion/deposition maps computed from the nc_spm elevation are
byte-identical to those before this change.

Written with the help of Claude Code.
wenzeslaus added a commit to wenzeslaus/grass that referenced this pull request Sep 29, 2026
Each thread computed its range of walkers from a chunk size rounded to
the nearest integer, steps = (int)(nwalk / nthreads + 0.5). When the
division rounded down, the walkers past the last range were never moved
and never added their water, up to (nthreads - 1) / 2 walkers in every
iteration, e.g., 1 of 2205 walkers with 4 threads, 7 of 1000007 with 16.

Round the chunk size up instead, so that the ranges cover all walkers.
The last range is cut at nwalk as before, and with fewer walkers than
threads, the last threads get empty ranges.

Single-threaded results do not change: the depth, discharge, sediment
flux and erosion/deposition maps computed from the nc_spm elevation are
byte-identical to those before this change.

Written with the help of Claude Code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C Related code is in C module raster Related to raster data processing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants