From 937a4f133218c5e6746fa22f515c94807277f0a8 Mon Sep 17 00:00:00 2001 From: Aaron <58265908+aaronsms@users.noreply.github.com> Date: Tue, 30 Aug 2022 13:35:45 +0000 Subject: [PATCH] r.univar: Add parallel support (#1634) Co-authored-by: Anna Petrasova --- raster/r.univar/Makefile | 5 +- .../r.univar/benchmark/benchmark_r_univar.py | 54 +++ raster/r.univar/globals.h | 2 +- raster/r.univar/r.univar.html | 22 ++ raster/r.univar/r.univar_main.c | 332 ++++++++++++------ raster/r.univar/r_univar_benchmark_size.png | Bin 0 -> 41587 bytes raster/r.univar/testsuite/test_r_univar.py | 196 ++++++++++- 7 files changed, 494 insertions(+), 117 deletions(-) create mode 100644 raster/r.univar/benchmark/benchmark_r_univar.py create mode 100644 raster/r.univar/r_univar_benchmark_size.png diff --git a/raster/r.univar/Makefile b/raster/r.univar/Makefile index fd1e7fd3317..e6d2e5ba831 100644 --- a/raster/r.univar/Makefile +++ b/raster/r.univar/Makefile @@ -1,9 +1,10 @@ MODULE_TOPDIR = ../.. -LIBES2 = $(RASTERLIB) $(GISLIB) $(MATHLIB) -LIBES3 = $(RASTER3DLIB) $(RASTERLIB) $(GISLIB) $(MATHLIB) +LIBES2 = $(RASTERLIB) $(GISLIB) $(MATHLIB) $(OMPLIB) +LIBES3 = $(RASTER3DLIB) $(RASTERLIB) $(GISLIB) $(MATHLIB) $(OMPLIB) DEPENDENCIES = $(RASTER3DDEP) $(GISDEP) $(RASTERDEP) +EXTRA_CFLAGS = $(OMPCFLAGS) PROGRAMS = r.univar r3.univar diff --git a/raster/r.univar/benchmark/benchmark_r_univar.py b/raster/r.univar/benchmark/benchmark_r_univar.py new file mode 100644 index 00000000000..2765b067783 --- /dev/null +++ b/raster/r.univar/benchmark/benchmark_r_univar.py @@ -0,0 +1,54 @@ +"""Benchmarking of r.univar + +@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.univar_50M", results) + benchmark(10000, "r.univar_100M", results) + benchmark(14142, "r.univar_200M", results) + benchmark(20000, "r.univar_400M", results) + + bm.nprocs_plot(results) + + +def benchmark(size, label, results): + reference = "r_univar_reference_map" + output = "benchmark_r_univar_nprocs" + + generate_map(rows=size, cols=size, fname=reference) + module = Module( + "r.univar", + map=reference, + 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=output) + + +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() diff --git a/raster/r.univar/globals.h b/raster/r.univar/globals.h index d234a7fc62d..d152ae05be8 100644 --- a/raster/r.univar/globals.h +++ b/raster/r.univar/globals.h @@ -56,7 +56,7 @@ typedef struct typedef struct { struct Option *inputfile, *zonefile, *percentile, *output_file, - *separator; + *separator, *nprocs; struct Flag *shell_style, *extended, *table, *use_rast_region; } param_type; diff --git a/raster/r.univar/r.univar.html b/raster/r.univar/r.univar.html index 399fd495397..33e34169086 100644 --- a/raster/r.univar/r.univar.html +++ b/raster/r.univar/r.univar.html @@ -48,6 +48,28 @@

NOTES

map and uploads statistics to new attribute columns, see v.rast.stats. +

PERFORMANCE

+ +

+r.univar suports parallel processing using OpenMP. The user +can specify the number of threads to be used with the nprocs parameter. +However, parallelization is disabled when the -e extended statistics +flag is used. + +

+Due to the differences in summation order, users may encounter small floating points +discrepancies when r.univar is run on very large raster files when different +nprocs parameters are used. However, since the work allocation among threads +is static, users should expect to have the same results when run with the same +number of threads. + +

+ benchmark for number of cells +
+ Figure: Benchmark shows execution time for different + number of cells and cores. See benchmark scripts in source code. +
+

EXAMPLES

Univariate statistics

diff --git a/raster/r.univar/r.univar_main.c b/raster/r.univar/r.univar_main.c index 1e7740c3734..436e2c80c03 100644 --- a/raster/r.univar/r.univar_main.c +++ b/raster/r.univar/r.univar_main.c @@ -15,12 +15,18 @@ * This program is a replacement for the r.univar shell script */ +#if defined(_OPENMP) +#include +#endif + #include #include +#include #include "globals.h" param_type param; zone_type zone_info; +int nprocs; /* ************************************************************************* */ /* Set up the arguments we are expecting ********************************** */ @@ -52,6 +58,8 @@ void set_params() _("Percentile to calculate (requires extended statistics flag)"); param.percentile->guisection = _("Extended"); + param.nprocs = G_define_standard_option(G_OPT_M_NPROCS); + param.separator = G_define_standard_option(G_OPT_F_SEP); param.separator->guisection = _("Formatting"); @@ -82,8 +90,8 @@ void set_params() static int open_raster(const char *infile); static univar_stat *univar_stat_with_percentiles(int map_type); -static void process_raster(univar_stat * stats, int fd, int fdz, - const struct Cell_head *region); +static void process_raster(univar_stat * stats, int *fd, + int *fdz, const struct Cell_head *region); /* *************************************************************** */ /* **** the main functions for r.univar ************************** */ @@ -96,9 +104,10 @@ int main(int argc, char *argv[]) struct GModule *module; univar_stat *stats; char **p, *z; - int fd, fdz, cell_type, min, max; + int *fd, *fdz, cell_type, min, max; struct Range zone_range; const char *mapset, *name; + int t; G_gisinit(argv[0]); @@ -107,6 +116,7 @@ int main(int argc, char *argv[]) G_add_keyword(_("statistics")); G_add_keyword(_("univariate statistics")); G_add_keyword(_("zonal statistics")); + G_add_keyword(_("parallel")); module->label = _("Calculates univariate statistics from the non-null cells of a raster map."); @@ -132,6 +142,26 @@ int main(int argc, char *argv[]) } } + /* set nprocs parameter */ + sscanf(param.nprocs->answer, "%d", &nprocs); + if (nprocs < 1) + G_fatal_error(_("<%d> is not valid number of nprocs."), nprocs); +#if defined(_OPENMP) + if (param.extended->answer) { + /* Calculation of extended statistics is not parallelized yet */ + if (nprocs > 1) + G_warning(_("Computing extending statistics is not parallelized yet. Ignoring threads setting.")); + nprocs = 1; + } + else { + omp_set_num_threads(nprocs); + } +#else + if (nprocs != 1) + G_warning(_("GRASS is compiled without OpenMP support. Ignoring threads setting.")); + nprocs = 1; +#endif + /* table field separator */ zone_info.sep = G_option_to_separator(param.separator); @@ -139,15 +169,18 @@ int main(int argc, char *argv[]) zone_info.max = 0.0 / 0.0; /* set to nan as default */ zone_info.n_zones = 0; - fdz = -1; + fdz = NULL; + fd = G_malloc(nprocs * sizeof(int)); /* open zoning raster */ if ((z = param.zonefile->answer)) { mapset = G_find_raster2(z, ""); - fdz = open_raster(z); + fdz = G_malloc(nprocs * sizeof(int)); + for (t = 0; t < nprocs; t++) + fdz[t] = open_raster(z); - cell_type = Rast_get_map_type(fdz); + cell_type = Rast_get_map_type(fdz[0]); if (cell_type != CELL_TYPE) G_fatal_error("Zoning raster must be of type CELL"); @@ -187,11 +220,12 @@ int main(int argc, char *argv[]) G_get_window(®ion); } - fd = open_raster(*p); + for (t = 0; t < nprocs; t++) + fd[t] = open_raster(*p); if (map_type != -1) { /* NB: map_type must match when doing extended stats */ - int this_type = Rast_get_map_type(fd); + int this_type = Rast_get_map_type(fd[0]); assert(this_type > -1); if (map_type < -1) { @@ -208,12 +242,15 @@ int main(int argc, char *argv[]) process_raster(stats, fd, fdz, ®ion); /* close input raster */ - Rast_close(fd); + for (t = 0; t < nprocs; t++) + Rast_close(fd[t]); } /* close zoning raster */ - if (z) - Rast_close(fdz); + if (z) { + for (t = 0; t < nprocs; t++) + Rast_close(fdz[t]); + } /* create the output */ if (param.table->answer) @@ -238,6 +275,7 @@ static int open_raster(const char *infile) } fd = Rast_open_old(infile, mapset); + G_free((void *)mapset); return fd; } @@ -266,132 +304,214 @@ static univar_stat *univar_stat_with_percentiles(int map_type) } static void -process_raster(univar_stat * stats, int fd, int fdz, +process_raster(univar_stat * stats, int *fd, int *fdz, const struct Cell_head *region) { /* use G_window_rows(), G_window_cols() here? */ const unsigned int rows = region->rows; const unsigned int cols = region->cols; - const RASTER_MAP_TYPE map_type = Rast_get_map_type(fd); + const RASTER_MAP_TYPE map_type = Rast_get_map_type(fd[0]); const size_t value_sz = Rast_cell_size(map_type); + int t; unsigned int row; - void *raster_row; - CELL *zoneraster_row = NULL; + void **raster_row; + CELL **zoneraster_row = NULL; int n_zones = zone_info.n_zones; + int n_alloc = n_zones ? n_zones : 1; - raster_row = Rast_allocate_buf(map_type); - if (n_zones) - zoneraster_row = Rast_allocate_c_buf(); - - for (row = 0; row < rows; row++) { - void *ptr; - CELL *zptr = NULL; - unsigned int col; - - Rast_get_row(fd, raster_row, row, map_type); + raster_row = G_malloc(nprocs * sizeof(void *)); + if (n_zones) { + zoneraster_row = G_malloc(nprocs * sizeof(CELL *)); + } + for (t = 0; t < nprocs; t++) { + raster_row[t] = Rast_allocate_buf(map_type); if (n_zones) { - Rast_get_c_row(fdz, zoneraster_row, row); - zptr = zoneraster_row; + zoneraster_row[t] = Rast_allocate_c_buf(); } + } - ptr = raster_row; +#if defined(_OPENMP) + omp_lock_t *minmax = G_malloc(n_alloc * sizeof(omp_lock_t)); - for (col = 0; col < cols; col++) { - double val; - int zone = 0; + for (int i = 0; i < n_alloc; i++) { + omp_init_lock(&(minmax[i])); + } +#endif + int computed = 0; + +#pragma omp parallel if(nprocs > 1) + { + int i; + int t_id = 0; + +#if defined(_OPENMP) + if (!param.extended->answer) { + t_id = omp_get_thread_num(); + } +#endif + size_t *n = G_calloc(n_alloc, sizeof(size_t)); + double *sum = G_calloc(n_alloc, sizeof(double)); + double *sumsq = G_calloc(n_alloc, sizeof(double)); + double *sum_abs = G_calloc(n_alloc, sizeof(double)); + size_t *size = G_calloc(n_alloc, sizeof(size_t)); + double *min = G_malloc(n_alloc * sizeof(double)); + double *max = G_malloc(n_alloc * sizeof(double)); + + for (i = 0; i < n_alloc; i++) { + max[i] = DBL_MIN; + min[i] = DBL_MAX; + } + +#pragma omp for schedule(static) + for (row = 0; row < rows; row++) { + void *ptr; + CELL *zptr = NULL; + unsigned int col; + + Rast_get_row(fd[t_id], raster_row[t_id], row, map_type); if (n_zones) { - /* skip NULL cells in zone map */ - if (Rast_is_c_null_value(zptr)) { + Rast_get_c_row(fdz[t_id], zoneraster_row[t_id], row); + zptr = zoneraster_row[t_id]; + } + + ptr = raster_row[t_id]; + + for (col = 0; col < cols; col++) { + double val; + int zone = 0; + + if (n_zones) { + /* skip NULL cells in zone map */ + if (Rast_is_c_null_value(zptr)) { + ptr = G_incr_void_ptr(ptr, value_sz); + zptr++; + continue; + } + zone = *zptr - zone_info.min; + } + + /* count all including NULL cells in input map */ + size[zone]++; + + /* can't do stats with NULL cells in input map */ + if (Rast_is_null_value(ptr, map_type)) { ptr = G_incr_void_ptr(ptr, value_sz); - zptr++; + if (n_zones) + zptr++; continue; } - zone = *zptr - zone_info.min; - } - /* count all including NULL cells in input map */ - stats[zone].size++; + if (param.extended->answer) { + /* check allocated memory */ + /* parallelization is disabled, local variable reflects global state */ + if (stats[zone].n + n[zone] >= stats[zone].n_alloc) { + stats[zone].n_alloc += 1000; + size_t msize; + + switch (map_type) { + case DCELL_TYPE: + msize = stats[zone].n_alloc * sizeof(DCELL); + stats[zone].dcell_array = + (DCELL *) G_realloc((void *)stats[zone]. + dcell_array, msize); + stats[zone].nextp = + (void *)&(stats[zone].dcell_array[stats[zone].n + n[zone]]); + break; + case FCELL_TYPE: + msize = stats[zone].n_alloc * sizeof(FCELL); + stats[zone].fcell_array = + (FCELL *) G_realloc((void *)stats[zone]. + fcell_array, msize); + stats[zone].nextp = + (void *)&(stats[zone].fcell_array[stats[zone].n + n[zone]]); + break; + case CELL_TYPE: + msize = stats[zone].n_alloc * sizeof(CELL); + stats[zone].cell_array = + (CELL *) G_realloc((void *)stats[zone]. + cell_array, msize); + stats[zone].nextp = + (void *)&(stats[zone].cell_array[stats[zone].n + n[zone]]); + break; + default: + break; + } + } + /* put the value into stats->XXXcell_array */ + memcpy(stats[zone].nextp, ptr, value_sz); + stats[zone].nextp = + G_incr_void_ptr(stats[zone].nextp, value_sz); + } + + val = ((map_type == DCELL_TYPE) ? *((DCELL *) ptr) + : (map_type == FCELL_TYPE) ? *((FCELL *) ptr) + : *((CELL *) ptr)); + + sum[zone] += val; + sumsq[zone] += val * val; + sum_abs[zone] += fabs(val); + + if (val > max[zone]) + max[zone] = val; + if (val < min[zone]) + min[zone] = val; - /* can't do stats with NULL cells in input map */ - if (Rast_is_null_value(ptr, map_type)) { ptr = G_incr_void_ptr(ptr, value_sz); if (n_zones) zptr++; - continue; - } + n[zone]++; - if (param.extended->answer) { - /* check allocated memory */ - if (stats[zone].n >= stats[zone].n_alloc) { - stats[zone].n_alloc += 1000; - size_t msize; - - switch (map_type) { - case DCELL_TYPE: - msize = stats[zone].n_alloc * sizeof(DCELL); - stats[zone].dcell_array = - (DCELL *) G_realloc((void *)stats[zone]. - dcell_array, msize); - stats[zone].nextp = - (void *)&(stats[zone].dcell_array[stats[zone].n]); - break; - case FCELL_TYPE: - msize = stats[zone].n_alloc * sizeof(FCELL); - stats[zone].fcell_array = - (FCELL *) G_realloc((void *)stats[zone]. - fcell_array, msize); - stats[zone].nextp = - (void *)&(stats[zone].fcell_array[stats[zone].n]); - break; - case CELL_TYPE: - msize = stats[zone].n_alloc * sizeof(CELL); - stats[zone].cell_array = - (CELL *) G_realloc((void *)stats[zone].cell_array, - msize); - stats[zone].nextp = - (void *)&(stats[zone].cell_array[stats[zone].n]); - break; - default: - break; - } - } - /* put the value into stats->XXXcell_array */ - memcpy(stats[zone].nextp, ptr, value_sz); - stats[zone].nextp = - G_incr_void_ptr(stats[zone].nextp, value_sz); + } /* end column loop */ + if (!(param.shell_style->answer)) { +#pragma omp atomic update + computed++; + G_percent(computed, rows, 2); } - - val = ((map_type == DCELL_TYPE) ? *((DCELL *) ptr) - : (map_type == FCELL_TYPE) ? *((FCELL *) ptr) - : *((CELL *) ptr)); - - stats[zone].sum += val; - stats[zone].sumsq += val * val; - stats[zone].sum_abs += fabs(val); - - if (stats[zone].first) { - stats[zone].max = val; - stats[zone].min = val; - stats[zone].first = FALSE; + } /* end row loop */ + + for (i = 0; i < n_alloc; i++) { +#pragma omp atomic update + stats[i].n += n[i]; +#pragma omp atomic update + stats[i].size += size[i]; +#pragma omp atomic update + stats[i].sum += sum[i]; +#pragma omp atomic update + stats[i].sumsq += sumsq[i]; +#pragma omp atomic update + stats[i].sum_abs += sum_abs[i]; + +#if defined(_OPENMP) + omp_set_lock(&(minmax[i])); +#endif + if (stats[i].max < max[i] || + (stats[i].max != stats[i].max && max[i] != DBL_MIN)) { + stats[i].max = max[i]; } - else { - if (val > stats[zone].max) - stats[zone].max = val; - if (val < stats[zone].min) - stats[zone].min = val; + if (stats[i].min > min[i] || + (stats[i].min != stats[i].min && min[i] != DBL_MAX)) { + stats[i].min = min[i]; } +#if defined(_OPENMP) + omp_unset_lock(&(minmax[i])); +#endif + } - ptr = G_incr_void_ptr(ptr, value_sz); - if (n_zones) - zptr++; - stats[zone].n++; + } /* end parallel region */ + + for (t = 0; t < nprocs; t++) { + G_free(raster_row[t]); + } + G_free(raster_row); + if (n_zones) { + for (t = 0; t < nprocs; t++) { + G_free(zoneraster_row[t]); } - if (!(param.shell_style->answer)) - G_percent(row, rows, 2); + G_free(zoneraster_row); } if (!(param.shell_style->answer)) - G_percent(rows, rows, 2); /* finish it off */ + G_percent(rows, rows, 2); } diff --git a/raster/r.univar/r_univar_benchmark_size.png b/raster/r.univar/r_univar_benchmark_size.png new file mode 100644 index 0000000000000000000000000000000000000000..a9ca8b377af51d99fa2c9c2aa58c92b9cca868f4 GIT binary patch literal 41587 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