GRASS GSoC 2026 Parallelizing r.proj and Raster Processing Modules in GRASS
| Student Name | Kaushik Raja |
| Organization | NumFOCUS |
| Mentor Name | Huidae Cho, Anna Petrasova, Vaclav Petras |
| GitHub Fork | View Repo |
| LinkedIn Profile | View LinkedIn |
Abstract
R.proj, r.param.scale, and r.geomorphon are some of the most commonly used modules in GRASS. R.proj reprojects raster maps between coordinate systems. This is important because real world data comes in many different projections, and maps have to be in the same one before they can be analyzed together. So many GRASS workflows that combine data sources start with r.proj. R.param.scale calculates terrain parameters like slope and curvature by sliding a window over an elevation map. R.geomorphon classifies every cell of an elevation map into a landform like a ridge, valley, or peak. It does this by looking outward from each cell in eight different directions and checks whether the terrain rises above or drops below the line of sight. That pattern of visible horizons tells it what shape the land around the cell is.
The problem with all three modules is that they have always been single threaded. On modern hardware most CPU cores sit idle while one core does all the work, so large maps take much longer time to work and return an output. The goal of this project is to parallelize them with OpenMP so that many threads work on the map at the same time.
The main challenge with parallelizing these modules is memory. To help manage memory and get the most speedup ratios possible, each module will work on a chunk of rows at a time, called a band. The band is sized so that the input it needs stays under a memory limit the user controls. The threads then split the rows of the band among themselves and work on them at the same time. In r.proj, each thread also gets its own file descriptor and its own PROJ object (for thread safety). Some projections bend so much that even one full row’s width is too much input to fit under the memory limit, so those are read in smaller column pieces instead. In r.param.scale the old sliding window was replaced with this same band design, and in between I found and fixed a data race in the GRASS math library.
As a result of this, users can use one of the three modules and get their outputs faster than before. Also, the band pattern used in these modules gives future contributors a template for parallelizing other raster modules.
Project Scope
- Parallelize r.param.scale with OpenMP under a user controlled memory limit
- Parallelize r.proj
- Parallelize r.geomorphon
- Add nprocs option so user can say how many threads form their machine they want to use
- Find and fix data races in the GRASS libraries that block modules from being parallelized
- Replace the old testsuites for r.param.scale, r.proj, and r.geomorphon with pytest tests
- Verify every parallel module produces output identical to the serial version
- Add a benchmarking script for each module and benchmark all modules across thread counts
Timeline
| Period | Timeline | Tasks | Status |
|---|---|---|---|
| Community Bonding Period | May 1 - May 25 |
|
Done |
| Official Coding Period | May 25 - June 8 |
|
Done |
| June 9 - June 22 |
|
Done | |
| June 23 - July 6 |
|
Done | |
| July 7 - July 11 |
|
Done | |
| July 20 - August 3 |
|
Done | |
| August 4 - August 11 |
|
Done | |
| August 12 - August 18 |
|
In Progress | |
| Final Week | August 19 - August 26 |
|
In Progress |
Reports
Community Bonding Period
During this period I:
- Started off with an introductory call with my mentors.
- I introduced myself to the community on the OSGeo discourse.
- I started this wiki page, created the abstract, project scope, and the timeline.
- Did a thread safety audit of the gproj library calls
- Studied how the code in readcell.c works
- Set up the benchmarking infrastructure and figured out how it works
- Looked at the remaining modules and understood how they work
- Finalized my dev environment
- Confirmed my benchmarks are reproducible
- Decided to parallelize r.param.scale first, r.proj second, and then finally r.geomorphon
- Worked on identifying methods to parallelize r.param.scale
Week 1
Posted what I did in week 1 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-1-report/153925
Week 2
Posted what I did in week 2 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-2-report/154036
Week 3
Posted what I did in week 3 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-3-report/154478
Week 4 & Week 5
Posted what I did in weeks 4 and 5 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-4-5-report/154479
Week 6
Posted what I did in week 6 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-6-report/154480
Week 7
Posted what I did in week 7 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-7-report/154481
Week 8
Posted what I did in week 8 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-8-report/154560
Week 9
Posted what I did in week 9 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-9-report/154659
Week 10
Posted what I did in week 10 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-10-report/154761
Week 11
Posted what I did in week 11 in the OSGeo discourse: https://discourse.osgeo.org/t/gsoc-coding-period-week-11-report/154833
Week 12
Log of Pull Requests
| Pull Request / Issue | Description | Status |
|---|---|---|
| PR #7440 | r.param.scale parallelization and G_ludcmp race fix | Merged |
| PR #7764 | Fix a data race on two globals in the projection library | Merged |
| PR #7773 | Fix a r.geomorphon crash on regions smaller than the search window | Merged |
| PR #7785 | Replace the r.geomorphon testsuite with pytest tests | Merged |
| PR #7627 | r.proj parallelization with memory bounded bands | In review |
| PR #7807 | Simpler r.proj band sizing from a precomputed footprint grid | Draft, in review |
| PR #7783 | r.geomorphon parallelization | In review |
| PR #7766 | Replace the r.proj method testsuite with pytest tests | In review |
| Issue #7539 | G_ludcmp data race report | Addressed within #7440 |
| PR #7185 | r.proj proof of concept | Closed in favor of #7627 |
| PR #7236 | r.param.scale proof of concept | Closed in favor of #7440 |