Skip to content

Commit

Permalink
r.slope.aspect: implement parallelization with OpenMP (#1767)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronsms committed Mar 10, 2022
1 parent a9ec508 commit fdff46c
Show file tree
Hide file tree
Showing 9 changed files with 1,125 additions and 416 deletions.
4 changes: 3 additions & 1 deletion lib/gis/testsuite/test_parser_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def test_r_slope_aspect_json(self):
{"param": "precision", "value": "FCELL"},
{"param": "zscale", "value": "1.0"},
{"param": "min_slope", "value": "0.0"},
{"param": "nprocs", "value": "1"},
{"param": "memory", "value": "300"},
]

outputs = [
Expand All @@ -52,7 +54,7 @@ def test_r_slope_aspect_json(self):
print(stdout)
json_code = json.loads(decode(stdout))
self.assertEqual(json_code["module"], "r.slope.aspect")
self.assertEqual(len(json_code["inputs"]), 5)
self.assertEqual(len(json_code["inputs"]), 7)
self.assertEqual(json_code["inputs"], inputs)
self.assertEqual(json_code["outputs"], outputs)

Expand Down
3 changes: 2 additions & 1 deletion raster/r.slope.aspect/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ MODULE_TOPDIR = ../..

PGM = r.slope.aspect

LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB)
LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB) $(OMPLIB)
DEPENDENCIES = $(RASTERDEP) $(GISDEP)
EXTRA_CFLAGS = $(OMPCFLAGS)

include $(MODULE_TOPDIR)/include/Make/Module.make

Expand Down
64 changes: 64 additions & 0 deletions raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""Benchmarking of r.slope aspect
@author Aaron Saw Min Sern
"""

from grass.exceptions import CalledModuleError
from grass.pygrass.modules import Module
from subprocess import DEVNULL

import grass.benchmark as bm


def main():
results = []

# Users can add more or modify existing reference maps
benchmark(7071, "r.slope.aspect_50M", results)
benchmark(10000, "r.slope.aspect_100M", results)
benchmark(14142, "r.slope.aspect_200M", results)
benchmark(20000, "r.slope.aspect_400M", results)

bm.nprocs_plot(results, filename="r_slope_aspect_benchmark_size.svg")


def benchmark(size, label, results):
reference = "r_slope_aspect_reference_map"
slope = "benchmark_slope"
aspect = "benchmark_aspect"
pcurv = "benchmark_pcurv"
tcurv = "benchmark_tcurv"

generate_map(rows=size, cols=size, fname=reference)
module = Module(
"r.slope.aspect",
elevation=reference,
slope=slope,
aspect=aspect,
pcurvature=pcurv,
tcurvature=tcurv,
run_=False,
stdout_=DEVNULL,
overwrite=True,
)
results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=16, repeat=3))
Module("g.remove", quiet=True, flags="f", type="raster", name=reference)
Module("g.remove", quiet=True, flags="f", type="raster", name=slope)
Module("g.remove", quiet=True, flags="f", type="raster", name=aspect)
Module("g.remove", quiet=True, flags="f", type="raster", name=pcurv)
Module("g.remove", quiet=True, flags="f", type="raster", name=tcurv)


def generate_map(rows, cols, fname):
Module("g.region", flags="p", s=0, n=rows, w=0, e=cols, res=1)
# Generate using r.random.surface if r.surf.fractal fails
try:
print("Generating reference map using r.surf.fractal...")
Module("r.surf.fractal", output=fname)
except CalledModuleError:
print("r.surf.fractal fails, using r.random.surface instead...")
Module("r.random.surface", output=fname)


if __name__ == "__main__":
main()
68 changes: 68 additions & 0 deletions raster/r.slope.aspect/benchmark/benchmark_r_slope_aspect_memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Benchmarking of r.slope aspect
@author Aaron Saw Min Sern
@author Anna Petrasova
"""

from grass.exceptions import CalledModuleError
from grass.pygrass.modules import Module
from subprocess import DEVNULL

import grass.benchmark as bm


def main():
results = []

reference = "r_slope_aspect_reference_map"
generate_map(rows=10000, cols=10000, fname=reference)
# Users can add more or modify existing reference maps
benchmark(0, "r.slope.aspect_0MB", results, reference)
benchmark(5, "r.slope.aspect_5MB", results, reference)
benchmark(10, "r.slope.aspect_10MB", results, reference)
benchmark(100, "r.slope.aspect_100MB", results, reference)
benchmark(300, "r.slope.aspect_300MB", results, reference)

Module("g.remove", quiet=True, flags="f", type="raster", name=reference)
bm.nprocs_plot(results, filename="r_slope_aspect_benchmark_memory.svg")


def benchmark(memory, label, results, reference):

slope = "benchmark_slope"
aspect = "benchmark_aspect"
pcurv = "benchmark_pcurv"
tcurv = "benchmark_tcurv"

module = Module(
"r.slope.aspect",
elevation=reference,
slope=slope,
aspect=aspect,
pcurvature=pcurv,
tcurvature=tcurv,
run_=False,
stdout_=DEVNULL,
overwrite=True,
)
results.append(bm.benchmark_nprocs(module, label=label, max_nprocs=20, repeat=10))

Module("g.remove", quiet=True, flags="f", type="raster", name=slope)
Module("g.remove", quiet=True, flags="f", type="raster", name=aspect)
Module("g.remove", quiet=True, flags="f", type="raster", name=pcurv)
Module("g.remove", quiet=True, flags="f", type="raster", name=tcurv)


def generate_map(rows, cols, fname):
Module("g.region", flags="p", s=0, n=rows, w=0, e=cols, res=1)
# Generate using r.random.surface if r.surf.fractal fails
try:
print("Generating reference map using r.surf.fractal...")
Module("r.surf.fractal", output=fname)
except CalledModuleError:
print("r.surf.fractal fails, using r.random.surface instead...")
Module("r.random.surface", output=fname)


if __name__ == "__main__":
main()

0 comments on commit fdff46c

Please sign in to comment.