From 4f7833b6eb88438ba2a2c29371471ac18db3f458 Mon Sep 17 00:00:00 2001 From: Chung-Yuan Liang <77927944+cyliang368@users.noreply.github.com> Date: Mon, 5 Aug 2024 18:55:45 -0400 Subject: [PATCH] lib/gis: Add a helper function to determine the number of threads for OpenMP (#3929) * determine the number of threads for OpenMP in opt parser * add OpenMP library paths * solve segfault when nprocs option is not specified in the command * only change nprocs for C module * update the description of the function, which does not return any value * add helper function, left parser unchanged * return threads rather than change the answer of nprocs * modify code based on review comments * remove threads > logic cores check, update based on review comments --- include/grass/defs/gis.h | 3 +++ lib/gis/Makefile | 5 +++-- lib/gis/omp_threads.c | 45 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 lib/gis/omp_threads.c diff --git a/include/grass/defs/gis.h b/include/grass/defs/gis.h index 1eacd9ed933..4125a3aeed3 100644 --- a/include/grass/defs/gis.h +++ b/include/grass/defs/gis.h @@ -548,6 +548,9 @@ int G_name_is_fully_qualified(const char *, char *, char *); char *G_fully_qualified_name(const char *, const char *); int G_unqualified_name(const char *, const char *, char *, char *); +/* omp_threads.c */ +int G_set_omp_num_threads(struct Option *); + /* open.c */ int G_open_new(const char *, const char *); int G_open_old(const char *, const char *, const char *); diff --git a/lib/gis/Makefile b/lib/gis/Makefile index a1579dbf862..90b39f374a4 100644 --- a/lib/gis/Makefile +++ b/lib/gis/Makefile @@ -2,8 +2,9 @@ MODULE_TOPDIR = ../.. LIB = GIS -EXTRA_INC = $(ZLIBINCPATH) $(BZIP2INCPATH) $(ZSTDINCPATH) $(PTHREADINCPATH) $(REGEXINCPATH) -EXTRA_CFLAGS = -DGRASS_VERSION_DATE=\"'$(GRASS_VERSION_DATE)'\" +LIBES = $(OPENMP_LIBPATH) $(OPENMP_LIB) +EXTRA_INC = $(ZLIBINCPATH) $(BZIP2INCPATH) $(ZSTDINCPATH) $(PTHREADINCPATH) $(REGEXINCPATH) $(OPENMP_INCPATH) +EXTRA_CFLAGS = $(OPENMP_CFLAGS) -DGRASS_VERSION_DATE=\"'$(GRASS_VERSION_DATE)'\" PROJSRC = ellipse.table ellipse.table.solar.system datum.table \ datumtransform.table FIPS.code state27 state83 projections diff --git a/lib/gis/omp_threads.c b/lib/gis/omp_threads.c new file mode 100644 index 00000000000..f5169d8624e --- /dev/null +++ b/lib/gis/omp_threads.c @@ -0,0 +1,45 @@ +#if defined(_OPENMP) +#include +#endif + +#include +#include +#include +#include +#include + +/*! \brief Set the number of threads for OpenMP + The intended usage is at the beginning of a C tool when parameters are + processed, namely the G_OPT_M_NPROCS standard option. + + \param opt A nprocs Option struct to specify the number of threads + \return the number of threads set up for OpenMP parallel computing +*/ + +int G_set_omp_num_threads(struct Option *opt) +{ + /* make sure Option is not null */ + if (opt == NULL) + G_fatal_error(_("Option is NULL.")); + else if (opt->key == NULL) + G_fatal_error(_("Option key is NULL.")); + + int threads = atoi(opt->answer); +#if defined(_OPENMP) + int num_logic_procs = omp_get_num_procs(); + if (threads < 1) { + threads += num_logic_procs; + threads = (threads < 1) ? 1 : threads; + } + omp_set_num_threads(threads); + G_verbose_message(_("%d threads are set up for parallel computing."), + threads); +#else + if (threads != 1) { + G_warning(_("GRASS GIS is not compiled with OpenMP support, parallel " + "computation is disabled. Only one thread will be used.")); + threads = 1; + } +#endif + return threads; +}