OpenMP parallel region scope tests
Add tests which check for accessibility of variables from within
various OpenMP parallel regions.
Tested on Fedora 27, 28, 29, 30, and 31. I also tested with my OpenMP
work on Fedora 30. The test has been annotated with setup_xfail and
setup_kfail statements so that there are no unexpected failures on any
of these platforms when using gcc. Better still, for my own testing
anyway, is that there are also no XPASSes or KPASSes either. So,
regardless of platform, when using gcc, and regardless of whether my
(not yet public) OpenMP work is used, seeing a FAIL indicates a real
problem.
Fedora 27 results:
# of expected passes 85
# of expected failures 65
(Note: I have not retested F27 since v1 of the patch; it's possible
that the numbers will be slightly different for v2.)
Fedora 28, 29, 30 results:
# of expected passes 131
# of expected failures 4
# of known failures 16
Fedora 30, 31 results w/ my OpenMP work:
# of expected passes 151
The above results all use gcc, either the system gcc or a development
gcc (when testing against my OpenMP work in GDB). I've also tested
with clang 9.0.0 and icc 19.0.5.281 20190815 on Fedora 31.
Fedora 31, clang:
FAIL: gdb.threads/omp-par-scope.exp: single_scope: first thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: single_scope: first thread: print s3
FAIL: gdb.threads/omp-par-scope.exp: single_scope: first thread: print i1
FAIL: gdb.threads/omp-par-scope.exp: single_scope: first thread: print i3
FAIL: gdb.threads/omp-par-scope.exp: single_scope: second thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: single_scope: second thread: print s3
FAIL: gdb.threads/omp-par-scope.exp: single_scope: second thread: print i1
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i02
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i11
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i12
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i22
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: second thread: print i11
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: second thread: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: after parallel: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print num
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print l
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 2nd stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 2nd stop: print num
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print num
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print l
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 4th stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 4th stop: print num
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: outer_threads: outer stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: outer_threads: outer stop: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: outer_threads: outer stop: print j
Fedora 31, icc:
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i12
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i22
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 1st thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 1st thread: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 1st thread: print j
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print j
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print z
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 1st thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 1st thread: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 1st thread: print j
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print j
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print z
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print l
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print l
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print k
For both clang and icc, it turns out that there are some problems with
the DWARF that these compilers generate. Of the two, icc does at
least nest the subprogram of the outlined function representing the
parallel region within the function that it's defined, but does not
handle inner scopes if they exist. clang places the subprogram for
the outlined function at the same level as the containing function, so
variables declared within the function aren't visible at all.
I could call setup_xfail to avoid FAILs for clang and icc also, but I don't
want to further complicate the test.
gdb/testsuite/ChangeLog:
* gdb.threads/omp-par-scope.c: New file.
* gdb/threads/omp-par-scope.exp: New file.
Change-Id: Icb9c991730d84ca7509380af817dfcc778e764ea
2017-09-21 06:40:14 +08:00
|
|
|
/* This testcase is part of GDB, the GNU debugger.
|
|
|
|
|
2020-01-01 14:20:01 +08:00
|
|
|
Copyright 2017-2020 Free Software Foundation, Inc.
|
OpenMP parallel region scope tests
Add tests which check for accessibility of variables from within
various OpenMP parallel regions.
Tested on Fedora 27, 28, 29, 30, and 31. I also tested with my OpenMP
work on Fedora 30. The test has been annotated with setup_xfail and
setup_kfail statements so that there are no unexpected failures on any
of these platforms when using gcc. Better still, for my own testing
anyway, is that there are also no XPASSes or KPASSes either. So,
regardless of platform, when using gcc, and regardless of whether my
(not yet public) OpenMP work is used, seeing a FAIL indicates a real
problem.
Fedora 27 results:
# of expected passes 85
# of expected failures 65
(Note: I have not retested F27 since v1 of the patch; it's possible
that the numbers will be slightly different for v2.)
Fedora 28, 29, 30 results:
# of expected passes 131
# of expected failures 4
# of known failures 16
Fedora 30, 31 results w/ my OpenMP work:
# of expected passes 151
The above results all use gcc, either the system gcc or a development
gcc (when testing against my OpenMP work in GDB). I've also tested
with clang 9.0.0 and icc 19.0.5.281 20190815 on Fedora 31.
Fedora 31, clang:
FAIL: gdb.threads/omp-par-scope.exp: single_scope: first thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: single_scope: first thread: print s3
FAIL: gdb.threads/omp-par-scope.exp: single_scope: first thread: print i1
FAIL: gdb.threads/omp-par-scope.exp: single_scope: first thread: print i3
FAIL: gdb.threads/omp-par-scope.exp: single_scope: second thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: single_scope: second thread: print s3
FAIL: gdb.threads/omp-par-scope.exp: single_scope: second thread: print i1
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i02
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i11
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i12
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i22
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: second thread: print i11
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: second thread: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: after parallel: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print num
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print l
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 2nd stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 2nd stop: print num
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print num
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print l
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 4th stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 4th stop: print num
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: outer_threads: outer stop: print file_scope_var
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: outer_threads: outer stop: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: outer_threads: outer stop: print j
Fedora 31, icc:
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i12
FAIL: gdb.threads/omp-par-scope.exp: multi_scope: first thread: print i22
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 1st thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 1st thread: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 1st thread: print j
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print j
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 1st call: 2nd thread: print z
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 1st thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 1st thread: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 1st thread: print j
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print s1
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print i
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print j
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_func: 2nd call: 2nd thread: print z
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print l
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 1st stop: print k
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print l
FAIL: gdb.threads/omp-par-scope.exp: nested_parallel: inner_threads: 3rd stop: print k
For both clang and icc, it turns out that there are some problems with
the DWARF that these compilers generate. Of the two, icc does at
least nest the subprogram of the outlined function representing the
parallel region within the function that it's defined, but does not
handle inner scopes if they exist. clang places the subprogram for
the outlined function at the same level as the containing function, so
variables declared within the function aren't visible at all.
I could call setup_xfail to avoid FAILs for clang and icc also, but I don't
want to further complicate the test.
gdb/testsuite/ChangeLog:
* gdb.threads/omp-par-scope.c: New file.
* gdb/threads/omp-par-scope.exp: New file.
Change-Id: Icb9c991730d84ca7509380af817dfcc778e764ea
2017-09-21 06:40:14 +08:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <omp.h>
|
|
|
|
|
|
|
|
/* Testcase for checking access to variables in a single / outer scope.
|
|
|
|
Make sure that variables not referred to in the parallel section are
|
|
|
|
accessible from the debugger. */
|
|
|
|
|
|
|
|
void
|
|
|
|
single_scope (void)
|
|
|
|
{
|
|
|
|
static int s1 = -41, s2 = -42, s3 = -43;
|
|
|
|
int i1 = 11, i2 = 12, i3 = 13;
|
|
|
|
|
|
|
|
#pragma omp parallel num_threads (2) shared (s1, i1) private (s2, i2)
|
|
|
|
{
|
|
|
|
int thread_num = omp_get_thread_num ();
|
|
|
|
|
|
|
|
s2 = 100 * (thread_num + 1) + 2;
|
|
|
|
i2 = s2 + 10;
|
|
|
|
|
|
|
|
#pragma omp critical
|
|
|
|
printf ("single_scope: thread_num=%d, s1=%d, i1=%d, s2=%d, i2=%d\n",
|
|
|
|
thread_num, s1, i1, s2, i2);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf ("single_scope: s1=%d, s2=%d, s3=%d, i1=%d, i2=%d, i3=%d\n",
|
|
|
|
s1, s2, s3, i1, i2, i3);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int file_scope_var = 9876;
|
|
|
|
|
|
|
|
/* Testcase for checking access to variables from parallel region
|
|
|
|
nested within more than one lexical scope. Of particular interest
|
|
|
|
are variables which are not referenced in the parallel section. */
|
|
|
|
|
|
|
|
void
|
|
|
|
multi_scope (void)
|
|
|
|
{
|
|
|
|
int i01 = 1, i02 = 2;
|
|
|
|
|
|
|
|
{
|
|
|
|
int i11 = 11, i12 = 12;
|
|
|
|
|
|
|
|
{
|
|
|
|
int i21 = -21, i22 = 22;
|
|
|
|
|
|
|
|
#pragma omp parallel num_threads (2) \
|
|
|
|
firstprivate (i01) \
|
|
|
|
shared (i11) \
|
|
|
|
private (i21)
|
|
|
|
{
|
|
|
|
int thread_num = omp_get_thread_num ();
|
|
|
|
i21 = 100 * (thread_num + 1) + 21;
|
|
|
|
|
|
|
|
#pragma omp critical
|
|
|
|
printf ("multi_scope: thread_num=%d, i01=%d, i11=%d, i21=%d\n",
|
|
|
|
thread_num, i01, i11, i21);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf ("multi_scope: i01=%d, i02=%d, i11=%d, "
|
|
|
|
"i12=%d, i21=%d, i22=%d\n",
|
|
|
|
i01, i02, i11, i12, i21, i22);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Nested functions in C is a GNU extension. Some non-GNU compilers
|
|
|
|
define __GNUC__, but they don't support nested functions. So,
|
|
|
|
unfortunately, we can't use that for our test. */
|
|
|
|
#if HAVE_NESTED_FUNCTION_SUPPORT
|
|
|
|
|
|
|
|
/* Testcase for checking access of variables from within parallel
|
|
|
|
region in a lexically nested function. */
|
|
|
|
|
|
|
|
void
|
|
|
|
nested_func (void)
|
|
|
|
{
|
|
|
|
static int s1 = -42;
|
|
|
|
int i = 1, j = 2, k = 3;
|
|
|
|
|
|
|
|
void
|
|
|
|
foo (int p, int q, int r)
|
|
|
|
{
|
|
|
|
int x = 4;
|
|
|
|
|
|
|
|
{
|
|
|
|
int y = 5, z = 6;
|
|
|
|
#pragma omp parallel num_threads (2) shared (i, p, x) private (j, q, y)
|
|
|
|
{
|
|
|
|
int tn = omp_get_thread_num ();
|
|
|
|
|
|
|
|
j = 1000 * (tn + 1);
|
|
|
|
q = j + 1;
|
|
|
|
y = q + 1;
|
|
|
|
#pragma omp critical
|
|
|
|
printf ("nested_func: tn=%d: i=%d, p=%d, x=%d, j=%d, q=%d, y=%d\n",
|
|
|
|
tn, i, p, x, j, q, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foo (10, 11, 12);
|
|
|
|
|
|
|
|
i = 101; j = 102; k = 103;
|
|
|
|
foo (20, 21, 22);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Testcase for checking access to variables from within a nested parallel
|
|
|
|
region. */
|
|
|
|
|
|
|
|
void
|
|
|
|
nested_parallel (void)
|
|
|
|
{
|
|
|
|
int i = 1, j = 2;
|
|
|
|
int l = -1;
|
|
|
|
|
|
|
|
omp_set_nested (1);
|
|
|
|
omp_set_dynamic (0);
|
|
|
|
#pragma omp parallel num_threads (2) private (l)
|
|
|
|
{
|
|
|
|
int num = omp_get_thread_num ();
|
|
|
|
int nthr = omp_get_num_threads ();
|
|
|
|
int off = num * nthr;
|
|
|
|
int k = off + 101;
|
|
|
|
l = off + 102;
|
|
|
|
#pragma omp parallel num_threads (2) shared (num)
|
|
|
|
{
|
|
|
|
int inner_num = omp_get_thread_num ();
|
|
|
|
#pragma omp critical
|
|
|
|
printf ("nested_parallel (inner threads): outer thread num = %d, thread num = %d\n", num, inner_num);
|
|
|
|
}
|
|
|
|
#pragma omp critical
|
|
|
|
printf ("nested_parallel (outer threads) %d: k = %d, l = %d\n", num, k, l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
single_scope ();
|
|
|
|
multi_scope ();
|
|
|
|
#if HAVE_NESTED_FUNCTION_SUPPORT
|
|
|
|
nested_func ();
|
|
|
|
#endif
|
|
|
|
nested_parallel ();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|