[OpenMP] Ignore teams ICV setters in restricted contexts (#194428)
This patch prevents `omp_set_num_teams()` and `omp_set_teams_thread_limit()` from updating teams-related ICVs when called from restricted runtime contexts. The non-implicit parallel-region case follows the OpenMP 5.1 restriction. The active `teams`-region case is handled defensively because these ICVs are device-scoped and updating them during an active `teams` region can affect later teams execution. The calls now warn and return without updating the ICVs. Fixes #194426.
This commit is contained in:
parent
e0d0d3db9d
commit
5adc7ddc15
3 changed files with 102 additions and 0 deletions
|
|
@ -482,6 +482,8 @@ AffHWSubsetIgnoringAttr "KMP_HW_SUBSET: ignoring %1$s attribute. This machi
|
|||
TargetMemNotAvailable "Target memory not available, will use default allocator."
|
||||
AffIgnoringNonHybrid "%1$s ignored: This machine is not a hybrid architecutre. Using \"%2$s\" instead."
|
||||
AffIgnoringNotAvailable "%1$s ignored: %2$s is not available. Using \"%3$s\" instead."
|
||||
SetNumTeamsInParOrTeamsRegion "%1$s() called inside a parallel or teams region; call ignored."
|
||||
SetTeamsThreadLimitInParOrTeamsRegion "%1$s() called inside a parallel or teams region; call ignored."
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
-*- HINTS -*-
|
||||
|
|
|
|||
|
|
@ -1636,9 +1636,23 @@ void FTN_STDCALL FTN_SET_NUM_TEAMS(int KMP_DEREF num_teams) {
|
|||
if (!__kmp_init_serial) {
|
||||
__kmp_serial_initialize();
|
||||
}
|
||||
kmp_info_t *th = __kmp_entry_thread();
|
||||
// OpenMP 5.1, Section 3.4.3: omp_set_num_teams may not be called from
|
||||
// within a parallel region other than the implicit parallel region.
|
||||
// Also guard against calls from within a teams region: nteams-var is a
|
||||
// device-scoped ICV and concurrent modification from multiple team initial
|
||||
// threads may race.
|
||||
// t_level counts both active and serialized parallel levels (0 at the
|
||||
// implicit top-level parallel region), so this catches all non-implicit
|
||||
// parallel regions.
|
||||
if (th->th.th_teams_microtask || th->th.th_team->t.t_level > 0) {
|
||||
KMP_WARNING(SetNumTeamsInParOrTeamsRegion, "omp_set_num_teams");
|
||||
return;
|
||||
}
|
||||
__kmp_set_num_teams(KMP_DEREF num_teams);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FTN_STDCALL FTN_GET_MAX_TEAMS(void) {
|
||||
#ifdef KMP_STUB
|
||||
return 1;
|
||||
|
|
@ -1657,9 +1671,24 @@ void FTN_STDCALL FTN_SET_TEAMS_THREAD_LIMIT(int KMP_DEREF limit) {
|
|||
if (!__kmp_init_serial) {
|
||||
__kmp_serial_initialize();
|
||||
}
|
||||
kmp_info_t *th = __kmp_entry_thread();
|
||||
// OpenMP 5.1, Section 3.4.5: omp_set_teams_thread_limit may not be called
|
||||
// from within a parallel region other than the implicit parallel region.
|
||||
// Also guard against calls from within a teams region:
|
||||
// teams-thread-limit-var is a device-scoped ICV and concurrent modification
|
||||
// from multiple team initial threads may race.
|
||||
// t_level counts both active and serialized parallel levels (0 at the
|
||||
// implicit top-level parallel region), so this catches all non-implicit
|
||||
// parallel regions.
|
||||
if (th->th.th_teams_microtask || th->th.th_team->t.t_level > 0) {
|
||||
KMP_WARNING(SetTeamsThreadLimitInParOrTeamsRegion,
|
||||
"omp_set_teams_thread_limit");
|
||||
return;
|
||||
}
|
||||
__kmp_set_teams_thread_limit(KMP_DEREF limit);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FTN_STDCALL FTN_GET_TEAMS_THREAD_LIMIT(void) {
|
||||
#ifdef KMP_STUB
|
||||
return 1;
|
||||
|
|
|
|||
71
openmp/runtime/test/api/omp_nteams_api_restriction.c
Normal file
71
openmp/runtime/test/api/omp_nteams_api_restriction.c
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// RUN: %libomp-compile-and-run 2>&1 | FileCheck %s
|
||||
// Verify that omp_set_num_teams() and omp_set_teams_thread_limit() are
|
||||
// ignored when called from within a parallel or teams region.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <omp.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int err = 0;
|
||||
|
||||
// Set initial values outside any region.
|
||||
omp_set_num_teams(5);
|
||||
omp_set_teams_thread_limit(7);
|
||||
|
||||
if (omp_get_max_teams() != 5) {
|
||||
fprintf(stderr, "error: nteams-var not set correctly\n");
|
||||
exit(1);
|
||||
}
|
||||
if (omp_get_teams_thread_limit() != 7) {
|
||||
fprintf(stderr, "error: teams-thread-limit-var not set correctly\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Call from inside a teams region -- should be ignored.
|
||||
// Use num_teams(1) to ensure exactly one team and deterministic warning
|
||||
// count.
|
||||
#pragma omp teams num_teams(1)
|
||||
{
|
||||
omp_set_num_teams(99);
|
||||
omp_set_teams_thread_limit(99);
|
||||
}
|
||||
|
||||
if (omp_get_max_teams() != 5) {
|
||||
fprintf(stderr, "error: nteams-var modified inside teams region\n");
|
||||
err++;
|
||||
}
|
||||
if (omp_get_teams_thread_limit() != 7) {
|
||||
fprintf(stderr, "error: teams-thread-limit-var modified inside teams "
|
||||
"region\n");
|
||||
err++;
|
||||
}
|
||||
|
||||
// Call from inside a parallel region -- should be ignored.
|
||||
#pragma omp parallel num_threads(1)
|
||||
{
|
||||
omp_set_num_teams(99);
|
||||
omp_set_teams_thread_limit(99);
|
||||
}
|
||||
|
||||
if (omp_get_max_teams() != 5) {
|
||||
fprintf(stderr, "error: nteams-var modified inside parallel region\n");
|
||||
err++;
|
||||
}
|
||||
if (omp_get_teams_thread_limit() != 7) {
|
||||
fprintf(stderr, "error: teams-thread-limit-var modified inside parallel "
|
||||
"region\n");
|
||||
err++;
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
printf("passed\n");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// CHECK: OMP: Warning{{.*}}omp_set_num_teams{{.*}}call ignored
|
||||
// CHECK: OMP: Warning{{.*}}omp_set_teams_thread_limit{{.*}}call ignored
|
||||
// CHECK: OMP: Warning{{.*}}omp_set_num_teams{{.*}}call ignored
|
||||
// CHECK: OMP: Warning{{.*}}omp_set_teams_thread_limit{{.*}}call ignored
|
||||
// CHECK: passed
|
||||
Loading…
Reference in a new issue