From 20cbbffe6396749b563d0c335e3f8116d14ffa47 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Wed, 19 Jun 2024 13:46:54 +0100 Subject: [PATCH] Use all cores by default in grdfilter (#8523) * Let x option synopsis be printed in grdfilter independently of having OMP or not. * Let all 3 modules built with Glib use max number of cores by default like the OMP case. * Do not use multi-threads with -Ff (custom filter). It's broken. * Use API->n_cores instead of gmtlib_get_num_processors() to see if it pleases Mac * Do not use all cores by default in potential modules. Some tests are failing. Integrate the ideas of #8319 * Remove mention to -x option (not in current surface module). Variable filter width (grdfilter) does not support -x --- doc/rst/source/explain_core.rst_ | 4 +++- src/gmt_dev.h | 1 + src/gmt_glib.h | 1 + src/gmt_init.c | 20 ++++++++++++-------- src/grdfilter.c | 18 ++++++++++++++++-- src/potential/gmtgravmag3d.c | 2 +- src/potential/grdgravmag3d.c | 2 +- src/surface.c | 4 ++-- 8 files changed, 37 insertions(+), 15 deletions(-) diff --git a/doc/rst/source/explain_core.rst_ b/doc/rst/source/explain_core.rst_ index 71af45a25f0..b427144f76e 100644 --- a/doc/rst/source/explain_core.rst_ +++ b/doc/rst/source/explain_core.rst_ @@ -1,2 +1,4 @@ **-x**\ [[-]\ *n*] :ref:`(more ...) ` - Limit number of cores used in multi-threaded algorithms (OpenMP required). + Limit number of cores used in multi-threaded algorithms. Multi-threaded behavior is enabled by default. + That covers the modules that implement the OpenMP API (required at compiling stage) and GThreads (Glib) + for the grdfilter module. diff --git a/src/gmt_dev.h b/src/gmt_dev.h index 1f8e32fd920..8de3861cfdf 100644 --- a/src/gmt_dev.h +++ b/src/gmt_dev.h @@ -154,6 +154,7 @@ struct GMT_CTRL; /* forward declaration of GMT_CTRL */ #include "gmt_nan.h" /* Machine-dependent macros for making and testing NaNs */ #include "gmt_error.h" /* Only contains error codes */ #include "gmt_synopsis.h" /* Only contains macros for synopsis lines */ +#include "gmt_glib.h" /* Make the GMT_xg_OPT define visible, even if HAVE_GLIB_GTHREAD is not defined */ #include "gmt_version.h" /* Only contains the current GMT version number */ #include "gmt_project.h" /* Define GMT->current.proj and GMT->current.map.frame structures */ #include "gmt_grd.h" /* Define grd file header structure */ diff --git a/src/gmt_glib.h b/src/gmt_glib.h index e8fece8e59a..ec13ae4019e 100644 --- a/src/gmt_glib.h +++ b/src/gmt_glib.h @@ -30,6 +30,7 @@ These are used only GLIB based multi-threading */ #ifndef GMT_GLIB_H +#define GMT_GLIB_H #ifdef HAVE_GLIB_GTHREAD #include diff --git a/src/gmt_init.c b/src/gmt_init.c index 75b3fe1e1b3..207d3ed6d1b 100644 --- a/src/gmt_init.c +++ b/src/gmt_init.c @@ -2607,8 +2607,8 @@ GMT_LOCAL int gmtinit_parse_U_option (struct GMT_CTRL *GMT, char *item) { } /*! -x[[-]] */ +GMT_LOCAL int gmtinit_parse_x_option (struct GMT_CTRL *GMT, char *arg) { /* Only effective if MP is enabled */ #ifdef GMT_MP_ENABLED -GMT_LOCAL int gmtinit_parse_x_option (struct GMT_CTRL *GMT, char *arg) { GMT->common.x.active = true; if (!arg) return (GMT_PARSE_ERROR); /* -x requires a non-NULL argument */ if (arg[0] == '\0') /* Use all processors */ @@ -2622,9 +2622,9 @@ GMT_LOCAL int gmtinit_parse_x_option (struct GMT_CTRL *GMT, char *arg) { GMT->common.x.n_threads = MAX(gmtlib_get_num_processors() - abs (GMT->common.x.n_threads), 1); /* Max-n but at least one */ if (GMT->current.setting.max_cores) /* Limit to max core defaults setting */ GMT->common.x.n_threads = GMT->current.setting.max_cores; +#endif return (GMT_NOERROR); } -#endif /*! . */ GMT_LOCAL int gmtinit_parse_colon_option (struct GMT_CTRL *GMT, char *item) { @@ -8124,9 +8124,9 @@ void gmtlib_explain_options (struct GMT_CTRL *GMT, char *options) { #if defined(GMT_MP_ENABLED) case 'y': /* Number of threads (reassigned from -x in GMT_Option) */ - if (strlen (GMT_x_OPT) > 1) { /* Only print this if it is in fact available */ + if (strlen(GMT_x_OPT) > 1 || strlen(GMT_xg_OPT) > 1) { /* Only print this if it is in fact available */ cores = gmtlib_get_num_processors(); - GMT_Usage (API, 1, "\n%s", GMT_x_OPT); + (strlen(GMT_x_OPT) > 1) ? GMT_Usage(API, 1, "\n%s", GMT_x_OPT) : GMT_Usage(API, 1, "\n%s", GMT_xg_OPT); GMT_Usage (API, -2, "Limit the number of cores used in multi-threaded algorithms [Default uses all %d cores]. " "If is negative then we select (%d - ) cores (or at least 1).", cores, cores); } @@ -9151,9 +9151,12 @@ int gmt_default_error (struct GMT_CTRL *GMT, char option) { case 's': error += GMT->common.s.active == false; break; case 't': error += GMT->common.t.active == false; break; case 'w': error += GMT->common.w.active == false; break; -#if defined(GMT_MP_ENABLED) - case 'x': error += GMT->common.x.active == false; break; + case 'x': error += GMT->common.x.active == false; +#if !defined(GMT_MP_ENABLED) + error --; + GMT_Report (GMT->parent, GMT_MSG_INFORMATION, "Option -x: GMT is not compiled with parallel support. Only one core is used\n"); #endif + break; case ':': error += GMT->common.colon.active == false; break; default: @@ -18792,12 +18795,13 @@ int gmt_parse_common_options (struct GMT_CTRL *GMT, char *list, char option, cha error += gmt_M_more_than_once (GMT, GMT->common.w.active) || gmtinit_parse_w_option (GMT, item); break; -#ifdef GMT_MP_ENABLED case 'x': error += (gmt_M_more_than_once (GMT, GMT->common.x.active) || gmtinit_parse_x_option (GMT, item)); GMT->common.x.active = true; - break; +#if !defined(GMT_MP_ENABLED) + GMT_Report (GMT->parent, GMT_MSG_WARNING, "Option -x: GMT is not compiled with parallel support. Only one core is used\n"); #endif + break; case ':': error += (gmt_M_more_than_once (GMT, GMT->common.colon.active) || gmtinit_parse_colon_option (GMT, item)); diff --git a/src/grdfilter.c b/src/grdfilter.c index 61e450e4966..916c649acea 100644 --- a/src/grdfilter.c +++ b/src/grdfilter.c @@ -47,7 +47,7 @@ Use option -x to set the number of threads. e.g. -x2, -x4, ... or -xa to use all #include "gmt_dev.h" #include "longopt/grdfilter_inc.h" -#include "gmt_glib.h" +//#include "gmt_glib.h" /* Now included in gmt_dev.h */ #define THIS_MODULE_CLASSIC_NAME "grdfilter" #define THIS_MODULE_MODERN_NAME "grdfilter" @@ -828,7 +828,7 @@ static int parse (struct GMT_CTRL *GMT, struct GRDFILTER_CTRL *Ctrl, struct GMT_ Ctrl->F.rect = true; } else - Ctrl->F.width = grdfilter_get_filter_width (API, Ctrl, &txt[1]); + Ctrl->F.width = grdfilter_get_filter_width (API, Ctrl, &txt[1]); /* This has an undocumented option of reading a grid */ if (Ctrl->F.width < 0.0) { /* Old-style specification for high-pass filtering */ if (gmt_M_compat_check (GMT, 5)) { GMT_Report (API, GMT_MSG_COMPAT, @@ -893,6 +893,20 @@ static int parse (struct GMT_CTRL *GMT, struct GRDFILTER_CTRL *Ctrl, struct GMT_ } } +#ifdef HAVE_GLIB_GTHREAD + /* Make the default equal to the OMP case where we use all threads if not stated otherwise. */ + if (Ctrl->F.varwidth) { /* Variable filter width. This option is currently undocumented. */ + if (GMT->common.x.active) + GMT_Report (GMT->parent, GMT_MSG_WARNING, "Sorry, variable filter width does not support multiple threads. Reset to 1.\n" ); + GMT->common.x.n_threads = 1; + GMT->common.x.active = true; + } + if (!GMT->common.x.active) { + GMT->common.x.n_threads = API->n_cores; + GMT_Report (GMT->parent, GMT_MSG_INFORMATION, "Enable all available threads (up to %d)\n", API->n_cores); + } +#endif + n_errors += gmt_M_check_condition (GMT, !Ctrl->G.active, "Option -G: Must specify output file\n"); n_errors += gmt_M_check_condition (GMT, !Ctrl->In.file, "Must specify input file\n"); n_errors += gmt_M_check_condition (GMT, !Ctrl->D.active, "Option -D: Choose from p or 0-5\n"); diff --git a/src/potential/gmtgravmag3d.c b/src/potential/gmtgravmag3d.c index 2ac7b746ccd..1c2da2a8828 100644 --- a/src/potential/gmtgravmag3d.c +++ b/src/potential/gmtgravmag3d.c @@ -252,7 +252,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) { return (GMT_MODULE_USAGE); } -static int parse (struct GMT_CTRL *GMT, struct GMTGRAVMAG3D_CTRL *Ctrl, struct GMT_OPTION *options) { +static int parse(struct GMT_CTRL *GMT, struct GMTGRAVMAG3D_CTRL *Ctrl, struct GMT_OPTION *options) { /* This parses the options provided to gmtgravmag3d and sets parameters in Ctrl. * Note Ctrl has already been initialized and non-zero default values set. diff --git a/src/potential/grdgravmag3d.c b/src/potential/grdgravmag3d.c index 9ca9129ebc6..168384fb56c 100644 --- a/src/potential/grdgravmag3d.c +++ b/src/potential/grdgravmag3d.c @@ -262,7 +262,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) { return (GMT_MODULE_USAGE); } -static int parse (struct GMT_CTRL *GMT, struct GRDGRAVMAG3D_CTRL *Ctrl, struct GMT_OPTION *options) { +static int parse(struct GMT_CTRL *GMT, struct GRDGRAVMAG3D_CTRL *Ctrl, struct GMT_OPTION *options) { /* This parses the options provided to grdgravmag3d and sets parameters in Ctrl. * Note Ctrl has already been initialized and non-zero default values set. diff --git a/src/surface.c b/src/surface.c index 9dc34f3700f..28ee64cc616 100644 --- a/src/surface.c +++ b/src/surface.c @@ -57,7 +57,7 @@ #define THIS_MODULE_PURPOSE "Grid table data using adjustable tension continuous curvature splines" #define THIS_MODULE_KEYS " */ @@ -1790,7 +1790,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) { GMT_Usage (API, -2, "Change over-relaxation parameter [Default = %g]. Use a value " "between 1 and 2. Larger number accelerates convergence but can be unstable. " "Use 1 if you want to be sure to have (slow) stable convergence.", SURFACE_OVERRELAXATION); - GMT_Option (API, "a,bi3,di,e,f,h,i,qi,r,w,x,:,."); + GMT_Option (API, "a,bi3,di,e,f,h,i,qi,r,w,:,."); if (gmt_M_showusage (API)) GMT_Usage (API, -2, "Note: Geographic data with 360-degree range use periodic boundary condition in longitude. " "For additional details, see Smith & Wessel, Geophysics, 55, 293-305, 1990.");