From 8949b985dbaf07d433bd57d2883e1e5414f20e75 Mon Sep 17 00:00:00 2001 From: Kwok Cheung Yeung Date: Wed, 7 Oct 2020 09:34:32 -0700 Subject: [PATCH] openmp: Add support for the omp_get_supported_active_levels runtime library routine This patch implements the omp_get_supported_active_levels runtime routine from the OpenMP 5.0 specification, which returns the maximum number of active nested parallel regions supported by this implementation. The current maximum (set using the omp_set_max_active_levels routine or the OMP_MAX_ACTIVE_LEVELS environment variable) cannot exceed this number. 2020-10-13 Kwok Cheung Yeung libgomp/ * env.c (gomp_max_active_levels_var): Initialize to gomp_supported_active_levels. (initialize_env): Limit gomp_max_active_levels_var to be at most equal to gomp_supported_active_levels. * fortran.c (omp_get_supported_active_levels): Add ialias_redirect. (omp_get_supported_active_levels_): New. * icv.c (omp_set_max_active_levels): Limit gomp_max_active_levels_var to at most equal to gomp_supported_active_levels. (omp_get_supported_active_levels): New. * libgomp.h (gomp_supported_active_levels): New. * libgomp.map (OMP_5.0.1): Add omp_get_supported_active_levels and omp_get_supported_active_levels_. * libgomp.texi (omp_get_supported_active_levels): New. (omp_set_max_active_levels): Update. Add reference to omp_get_supported_active_levels. * omp.h.in (omp_get_supported_active_levels): New. * omp_lib.f90.in (omp_get_supported_active_levels): New. * omp_lib.h.in (omp_get_supported_active_levels): New. * testsuite/libgomp.c/lib-2.c (main): Check omp_get_max_active_levels against omp_get_supported_active_levels. * testsuite/libgomp.fortran/lib4.f90 (lib4): Likewise. --- libgomp/env.c | 4 ++- libgomp/fortran.c | 7 +++++ libgomp/icv.c | 14 +++++++++- libgomp/libgomp.h | 2 ++ libgomp/libgomp.map | 2 ++ libgomp/libgomp.texi | 32 ++++++++++++++++++++-- libgomp/omp.h.in | 1 + libgomp/omp_lib.f90.in | 6 ++++ libgomp/omp_lib.h.in | 2 ++ libgomp/testsuite/libgomp.c/lib-2.c | 2 ++ libgomp/testsuite/libgomp.fortran/lib4.f90 | 2 ++ 11 files changed, 70 insertions(+), 4 deletions(-) diff --git a/libgomp/env.c b/libgomp/env.c index c0c4730d47c..d730c483d7f 100644 --- a/libgomp/env.c +++ b/libgomp/env.c @@ -73,7 +73,7 @@ struct gomp_task_icv gomp_global_icv = { .target_data = NULL }; -unsigned long gomp_max_active_levels_var = INT_MAX; +unsigned long gomp_max_active_levels_var = gomp_supported_active_levels; bool gomp_cancel_var = false; int gomp_max_task_priority_var = 0; #ifndef HAVE_SYNC_BUILTINS @@ -1369,6 +1369,8 @@ initialize_env (void) parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true); parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var, true); + if (gomp_max_active_levels_var > gomp_supported_active_levels) + gomp_max_active_levels_var = gomp_supported_active_levels; gomp_def_allocator = parse_allocator (); if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var, false)) { diff --git a/libgomp/fortran.c b/libgomp/fortran.c index 9d838b3b56f..029dec17459 100644 --- a/libgomp/fortran.c +++ b/libgomp/fortran.c @@ -63,6 +63,7 @@ ialias_redirect (omp_get_schedule) ialias_redirect (omp_get_thread_limit) ialias_redirect (omp_set_max_active_levels) ialias_redirect (omp_get_max_active_levels) +ialias_redirect (omp_get_supported_active_levels) ialias_redirect (omp_get_level) ialias_redirect (omp_get_ancestor_thread_num) ialias_redirect (omp_get_team_size) @@ -417,6 +418,12 @@ omp_get_max_active_levels_ (void) return omp_get_max_active_levels (); } +int32_t +omp_get_supported_active_levels_ (void) +{ + return omp_get_supported_active_levels (); +} + int32_t omp_get_level_ (void) { diff --git a/libgomp/icv.c b/libgomp/icv.c index 3c16abb9123..1bb46abac43 100644 --- a/libgomp/icv.c +++ b/libgomp/icv.c @@ -116,7 +116,12 @@ void omp_set_max_active_levels (int max_levels) { if (max_levels >= 0) - gomp_max_active_levels_var = max_levels; + { + if (max_levels <= gomp_supported_active_levels) + gomp_max_active_levels_var = max_levels; + else + gomp_max_active_levels_var = gomp_supported_active_levels; + } } int @@ -125,6 +130,12 @@ omp_get_max_active_levels (void) return gomp_max_active_levels_var; } +int +omp_get_supported_active_levels (void) +{ + return gomp_supported_active_levels; +} + int omp_get_cancellation (void) { @@ -227,6 +238,7 @@ ialias (omp_get_max_threads) ialias (omp_get_thread_limit) ialias (omp_set_max_active_levels) ialias (omp_get_max_active_levels) +ialias (omp_get_supported_active_levels) ialias (omp_get_cancellation) ialias (omp_get_proc_bind) ialias (omp_get_initial_device) diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h index 87f939a1f21..9d26de25cd7 100644 --- a/libgomp/libgomp.h +++ b/libgomp/libgomp.h @@ -434,6 +434,8 @@ struct gomp_task_icv struct target_mem_desc *target_data; }; +#define gomp_supported_active_levels INT_MAX + extern struct gomp_task_icv gomp_global_icv; #ifndef HAVE_SYNC_BUILTINS extern gomp_mutex_t gomp_managed_threads_lock; diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map index c808e810702..c5f52f725d0 100644 --- a/libgomp/libgomp.map +++ b/libgomp/libgomp.map @@ -193,6 +193,8 @@ OMP_5.0.1 { omp_destroy_allocator_; omp_alloc; omp_free; + omp_get_supported_active_levels; + omp_get_supported_active_levels_; } OMP_5.0; GOMP_1.0 { diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 5331230c207..1b7710cc935 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -177,6 +177,7 @@ linkage, and do not throw exceptions. * omp_get_num_threads:: Size of the active team * omp_get_proc_bind:: Whether theads may be moved between CPUs * omp_get_schedule:: Obtain the runtime scheduling method +* omp_get_supported_active_levels:: Maxiumum number of active levels supported * omp_get_team_num:: Get team number * omp_get_team_size:: Number of threads in a team * omp_get_thread_limit:: Maximum number of threads @@ -638,6 +639,31 @@ set to the value @code{omp_sched_static}, @code{omp_sched_dynamic}, @end table +@node omp_get_supported_active_levels +@section @code{omp_get_supported_active_levels} -- Maximum number of active regions supported +@table @asis +@item @emph{Description}: +This function returns the maximum number of nested, active parallel regions +supported by this implementation. + +@item @emph{C/C++} +@multitable @columnfractions .20 .80 +@item @emph{Prototype}: @tab @code{int omp_get_supported_active_levels(void);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{integer function omp_get_supported_active_levels()} +@end multitable + +@item @emph{See also}: +@ref{omp_get_max_active_levels}, @ref{omp_set_max_active_levels} + +@item @emph{Reference}: +@uref{https://www.openmp.org, OpenMP specification v5.0}, Section 3.2.15. +@end table + + @node omp_get_team_num @section @code{omp_get_team_num} -- Get team number @@ -877,7 +903,8 @@ adjustment of team sizes and @code{false} disables it. @table @asis @item @emph{Description}: This function limits the maximum allowed number of nested, active -parallel regions. +parallel regions. @var{max_levels} must be less or equal to +the value returned by @code{omp_get_supported_active_levels}. @item @emph{C/C++} @multitable @columnfractions .20 .80 @@ -891,7 +918,8 @@ parallel regions. @end multitable @item @emph{See also}: -@ref{omp_get_max_active_levels}, @ref{omp_get_active_level} +@ref{omp_get_max_active_levels}, @ref{omp_get_active_level}, +@ref{omp_get_supported_active_levels} @item @emph{Reference}: @uref{https://www.openmp.org, OpenMP specification v4.5}, Section 3.2.15. diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in index 57af73720f1..a9e6c448dc3 100644 --- a/libgomp/omp.h.in +++ b/libgomp/omp.h.in @@ -211,6 +211,7 @@ extern void omp_get_schedule (omp_sched_t *, int *) __GOMP_NOTHROW; extern int omp_get_thread_limit (void) __GOMP_NOTHROW; extern void omp_set_max_active_levels (int) __GOMP_NOTHROW; extern int omp_get_max_active_levels (void) __GOMP_NOTHROW; +extern int omp_get_supported_active_levels (void) __GOMP_NOTHROW; extern int omp_get_level (void) __GOMP_NOTHROW; extern int omp_get_ancestor_thread_num (int) __GOMP_NOTHROW; extern int omp_get_team_size (int) __GOMP_NOTHROW; diff --git a/libgomp/omp_lib.f90.in b/libgomp/omp_lib.f90.in index 3ec31ac1f1f..2fae57b0e5f 100644 --- a/libgomp/omp_lib.f90.in +++ b/libgomp/omp_lib.f90.in @@ -393,6 +393,12 @@ end function omp_get_max_active_levels end interface + interface + function omp_get_supported_active_levels () + integer (4) :: omp_get_supported_active_levels + end function omp_get_supported_active_levels + end interface + interface function omp_get_level () integer (4) :: omp_get_level diff --git a/libgomp/omp_lib.h.in b/libgomp/omp_lib.h.in index 26dbe03a629..eb1dcc44cfc 100644 --- a/libgomp/omp_lib.h.in +++ b/libgomp/omp_lib.h.in @@ -205,9 +205,11 @@ external omp_get_max_active_levels, omp_get_level external omp_get_ancestor_thread_num, omp_get_team_size external omp_get_active_level + external omp_get_supported_active_levels integer(4) omp_get_thread_limit, omp_get_max_active_levels integer(4) omp_get_level, omp_get_ancestor_thread_num integer(4) omp_get_team_size, omp_get_active_level + integer(4) omp_get_supported_active_levels external omp_in_final logical(4) omp_in_final diff --git a/libgomp/testsuite/libgomp.c/lib-2.c b/libgomp/testsuite/libgomp.c/lib-2.c index 3a3b3f65517..ea7a71904f0 100644 --- a/libgomp/testsuite/libgomp.c/lib-2.c +++ b/libgomp/testsuite/libgomp.c/lib-2.c @@ -20,6 +20,8 @@ main (void) omp_set_max_active_levels (6); if (omp_get_max_active_levels () != 6) abort (); + if (omp_get_max_active_levels () > omp_get_supported_active_levels ()) + abort (); return 0; } diff --git a/libgomp/testsuite/libgomp.fortran/lib4.f90 b/libgomp/testsuite/libgomp.fortran/lib4.f90 index d551cde35c6..5259b3bd95d 100644 --- a/libgomp/testsuite/libgomp.fortran/lib4.f90 +++ b/libgomp/testsuite/libgomp.fortran/lib4.f90 @@ -13,4 +13,6 @@ program lib4 if (omp_get_thread_limit ().lt.0) stop 3 call omp_set_max_active_levels (6) if (omp_get_max_active_levels ().ne.6) stop 4 + if (omp_get_max_active_levels () & + .gt.omp_get_supported_active_levels ()) stop 5 end program lib4 -- 2.30.2