diff options
Diffstat (limited to 'libgomp/testsuite/libgomp.c')
68 files changed, 3150 insertions, 0 deletions
diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.15.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.15.1.c new file mode 100644 index 00000000000..276ac6caad9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.15.1.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ + +#include <stdio.h> + +void +work (int n) +{ + printf ("[%d of %d], nested = %d, n = %d\n", omp_get_thread_num (), omp_get_num_threads(), omp_get_nested (), n); +} + +void +sub3 (int n) +{ + work (n); +#pragma omp barrier + work (n); +} + +void +sub2 (int k) +{ +#pragma omp parallel shared(k) + sub3 (k); +} + +void +sub1 (int n) +{ + int i; +#pragma omp parallel private(i) shared(n) + { +#pragma omp for + for (i = 0; i < n; i++) + sub2 (i); + } +} +int +main () +{ + sub1 (2); + sub2 (15); + sub3 (20); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.16.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.16.1.c new file mode 100644 index 00000000000..28a994a28fa --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.16.1.c @@ -0,0 +1,47 @@ +/* { dg-do run } */ + +#include <stdio.h> + +float +work1 (int i) +{ + return 1.0 * i; +} + +float +work2 (int i) +{ + return 2.0 * i; +} + +void +a16 (float *x, float *y, int *index, int n) +{ + int i; +#pragma omp parallel for shared(x, y, index, n) + for (i = 0; i < n; i++) + { +#pragma omp atomic + x[index[i]] += work1 (i); + y[i] += work2 (i); + } +} +int +main () +{ + float x[1000]; + float y[10000]; + int index[10000]; + int i; + for (i = 0; i < 10000; i++) + { + index[i] = i % 1000; + y[i] = 0.0; + } + for (i = 0; i < 1000; i++) + x[i] = 0.0; + a16 (x, y, index, 10000); + for (i = 0; i < 10; i++) + printf ("x[%d] = %f, y[%d] = %f\n", i, x[i], i, y[i]); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.18.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.18.1.c new file mode 100644 index 00000000000..388763e59d1 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.18.1.c @@ -0,0 +1,67 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdio.h> + +extern void abort (void); + +#define NUMBER_OF_THREADS 4 + +int synch[NUMBER_OF_THREADS]; +int work[NUMBER_OF_THREADS]; +int result[NUMBER_OF_THREADS]; +int +fn1 (int i) +{ + return i * 2; +} + +int +fn2 (int a, int b) +{ + return a + b; +} + +int +main () +{ + int i, iam, neighbor; + omp_set_num_threads (NUMBER_OF_THREADS); +#pragma omp parallel private(iam,neighbor) shared(work,synch) + { + iam = omp_get_thread_num (); + synch[iam] = 0; +#pragma omp barrier + /*Do computation into my portion of work array */ + work[iam] = fn1 (iam); + /* Announce that I am done with my work. The first flush + * ensures that my work is made visible before synch. + * The second flush ensures that synch is made visible. + */ +#pragma omp flush(work,synch) + synch[iam] = 1; +#pragma omp flush(synch) + /* Wait for neighbor. The first flush ensures that synch is read + * from memory, rather than from the temporary view of memory. + * The second flush ensures that work is read from memory, and + * is done so after the while loop exits. + */ + neighbor = (iam > 0 ? iam : omp_get_num_threads ()) - 1; + while (synch[neighbor] == 0) + { +#pragma omp flush(synch) + } +#pragma omp flush(work,synch) + /* Read neighbor's values of work array */ + result[iam] = fn2 (work[neighbor], work[iam]); + } + /* output result here */ + for (i = 0; i < NUMBER_OF_THREADS; i++) + { + neighbor = (i > 0 ? i : NUMBER_OF_THREADS) - 1; + if (result[i] != i * 2 + neighbor * 2) + abort (); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.19.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.19.1.c new file mode 100644 index 00000000000..65ffe624c25 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.19.1.c @@ -0,0 +1,55 @@ +/* { dg-do run } */ + +int x, *p = &x; +extern void abort (void); +void +f1 (int *q) +{ + *q = 1; +#pragma omp flush + /* x, p, and *q are flushed */ + /* because they are shared and accessible */ + /* q is not flushed because it is not shared. */ +} + +void +f2 (int *q) +{ +#pragma omp barrier + *q = 2; +#pragma omp barrier + /* a barrier implies a flush */ + /* x, p, and *q are flushed */ + /* because they are shared and accessible */ + /* q is not flushed because it is not shared. */ +} + +int +g (int n) +{ + int i = 1, j, sum = 0; + *p = 1; +#pragma omp parallel reduction(+: sum) num_threads(2) + { + f1 (&j); + /* i, n and sum were not flushed */ + /* because they were not accessible in f1 */ + /* j was flushed because it was accessible */ + sum += j; + f2 (&j); + /* i, n, and sum were not flushed */ + /* because they were not accessible in f2 */ + /* j was flushed because it was accessible */ + sum += i + j + *p + n; + } + return sum; +} + +int +main () +{ + int result = g (10); + if (result != 30) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.2.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.2.1.c new file mode 100644 index 00000000000..f6ae4c7c5d0 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.2.1.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ + +#include <stdio.h> +#include <omp.h> +extern void abort (void); +int +main () +{ + int bad, x; + x = 2; + bad = 0; +#pragma omp parallel num_threads(2) shared(x, bad) + { + if (omp_get_thread_num () == 0) + { + volatile int i; + for (i = 0; i < 100000000; i++) + x = 5; + } + else + { + /* Print 1: the following read of x has a race */ + if (x != 2 && x != 5) + bad = 1; + } +#pragma omp barrier + if (omp_get_thread_num () == 0) + { + /* x must be 5 now. */ + if (x != 5) + bad = 1; + } + else + { + /* x must be 5 now. */ + if (x != 5) + bad = 1; + } + } + + if (bad) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.21.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.21.1.c new file mode 100644 index 00000000000..0c1c39a1271 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.21.1.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +#include <stdio.h> +void +work (int k) +{ +#pragma omp ordered + printf (" %d\n", k); +} + +void +a21 (int lb, int ub, int stride) +{ + int i; +#pragma omp parallel for ordered schedule(dynamic) + for (i = lb; i < ub; i += stride) + work (i); +} + +int +main () +{ + a21 (0, 100, 5); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.26.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.26.1.c new file mode 100644 index 00000000000..e146fa2041c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.26.1.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ + +#include <stdio.h> +int +main () +{ + int i, j; + i = 1; + j = 2; +#pragma omp parallel private(i) firstprivate(j) + { + i = 3; + j = j + 2; + } + printf ("%d %d\n", i, j); /* i and j are undefined */ + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.29.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.29.1.c new file mode 100644 index 00000000000..6f0f65fa03e --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.29.1.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ + +#include <assert.h> +int A[2][2] = { 1, 2, 3, 4 }; +void +f (int n, int B[n][n], int C[]) +{ + int D[2][2] = { 1, 2, 3, 4 }; + int E[n][n]; + assert (n >= 2); + E[1][1] = 4; +#pragma omp parallel firstprivate(B, C, D, E) + { + assert (sizeof (B) == sizeof (int (*)[n])); + assert (sizeof (C) == sizeof (int *)); + assert (sizeof (D) == 4 * sizeof (int)); + assert (sizeof (E) == n * n * sizeof (int)); + /* Private B and C have values of original B and C. */ + assert (&B[1][1] == &A[1][1]); + assert (&C[3] == &A[1][1]); + assert (D[1][1] == 4); + assert (E[1][1] == 4); + } +} +int +main () +{ + f (2, A, A[0]); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.3.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.3.1.c new file mode 100644 index 00000000000..9e7c24f7546 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.3.1.c @@ -0,0 +1,11 @@ +/* { dg-do run } */ + +#include <stdio.h> +int +main () +{ +# ifdef _OPENMP + printf ("Compiled by an OpenMP-compliant implementation.\n"); +# endif + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.33.3.c b/libgomp/testsuite/libgomp.c/appendix-a/a.33.3.c new file mode 100644 index 00000000000..0b7f0197ce9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.33.3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> +#include <omp.h> +omp_lock_t * +new_lock () +{ + omp_lock_t *lock_ptr; +#pragma omp single copyprivate(lock_ptr) + { + lock_ptr = (omp_lock_t *) malloc (sizeof (omp_lock_t)); + omp_init_lock (lock_ptr); + } + return lock_ptr; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.36.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.36.1.c new file mode 100644 index 00000000000..b60534d1166 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.36.1.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> +void +do_by_16 (float *x, int iam, int ipoints) +{ +} + +void +a36 (float *x, int npoints) +{ + int iam, ipoints; + omp_set_dynamic (0); + omp_set_num_threads (16); +#pragma omp parallel shared(x, npoints) private(iam, ipoints) + { + if (omp_get_num_threads () != 16) + abort (); + iam = omp_get_thread_num (); + ipoints = npoints / 16; + do_by_16 (x, iam, ipoints); + } +} + +int main() +{ + float a[10]; + a36 (a, 10); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.39.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.39.1.c new file mode 100644 index 00000000000..a129e87fc49 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.39.1.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +#include <stdio.h> +#include <omp.h> +void +skip (int i) +{ +} + +void +work (int i) +{ +} +int +main () +{ + omp_lock_t lck; + int id; + omp_init_lock (&lck); +#pragma omp parallel shared(lck) private(id) + { + id = omp_get_thread_num (); + omp_set_lock (&lck); + /* only one thread at a time can execute this printf */ + printf ("My thread id is %d.\n", id); + omp_unset_lock (&lck); + while (!omp_test_lock (&lck)) + { + skip (id); /* we do not yet have the lock, + so we must do something else */ + } + work (id); /* we now have the lock + and can do the work */ + omp_unset_lock (&lck); + } + omp_destroy_lock (&lck); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.4.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.4.1.c new file mode 100644 index 00000000000..c6be4909002 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.4.1.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +#include <omp.h> +extern void abort (void); +void +subdomain (float *x, int istart, int ipoints) +{ + int i; + for (i = 0; i < ipoints; i++) + x[istart + i] = 123.456; +} + +void +sub (float *x, int npoints) +{ + int iam, nt, ipoints, istart; +#pragma omp parallel default(shared) private(iam,nt,ipoints,istart) + { + iam = omp_get_thread_num (); + nt = omp_get_num_threads (); + ipoints = npoints / nt; /* size of partition */ + istart = iam * ipoints; /* starting array index */ + if (iam == nt - 1) /* last thread may do more */ + ipoints = npoints - istart; + subdomain (x, istart, ipoints); + } +} +int +main () +{ + int i; + float array[10000]; + sub (array, 10000); + for (i = 0; i < 10000; i++) + if (array[i] < 123.45 || array[i] > 123.46) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.40.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.40.1.c new file mode 100644 index 00000000000..aa7b88d7098 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.40.1.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ + +#include <omp.h> +typedef struct +{ + int a, b; + omp_nest_lock_t lck; +} pair; +int work1 (); +int work2 (); +int work3 (); +void +incr_a (pair * p, int a) +{ + /* Called only from incr_pair, no need to lock. */ + p->a += a; +} + +void +incr_b (pair * p, int b) +{ + /* Called both from incr_pair and elsewhere, */ + /* so need a nestable lock. */ + omp_set_nest_lock (&p->lck); + p->b += b; + omp_unset_nest_lock (&p->lck); +} + +void +incr_pair (pair * p, int a, int b) +{ + omp_set_nest_lock (&p->lck); + incr_a (p, a); + incr_b (p, b); + omp_unset_nest_lock (&p->lck); +} + +void +a40 (pair * p) +{ +#pragma omp parallel sections + { +#pragma omp section + incr_pair (p, work1 (), work2 ()); +#pragma omp section + incr_b (p, work3 ()); + } +} diff --git a/libgomp/testsuite/libgomp.c/appendix-a/a.5.1.c b/libgomp/testsuite/libgomp.c/appendix-a/a.5.1.c new file mode 100644 index 00000000000..b909c4ddbc5 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/appendix-a/a.5.1.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ + +#include <omp.h> +int +main () +{ + omp_set_dynamic (1); +#pragma omp parallel num_threads(10) + { + /* do work here */ + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-1.c b/libgomp/testsuite/libgomp.c/atomic-1.c new file mode 100644 index 00000000000..82642a4e48d --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-1.c @@ -0,0 +1,64 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fopenmp" } */ +/* { dg-options "-O2 -fopenmp -march=pentium" { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O2 -fopenmp" { target lp64 } } */ + +#ifdef __i386__ +#include "../../../gcc/testsuite/gcc.dg/i386-cpuid.h" +#define bit_CX8 (1 << 8) +#endif + +extern void abort (void); +double d; +struct +{ + int i; + double e; + int j; +} x; + +void +f1 (void) +{ + #pragma omp atomic + d += 7.5; + #pragma omp atomic + d *= 2.5; + #pragma omp atomic + d /= 0.25; +} + +void +f2 (void) +{ + #pragma omp atomic + x.e += 7.5; + #pragma omp atomic + x.e *= 2.5; + #pragma omp atomic + x.e /= 0.25; +} + +int +main (void) +{ +#ifdef __i386__ + unsigned long cpu_facilities; + + cpu_facilities = i386_cpuid (); + + if ((cpu_facilities & bit_CX8) == 0) + return 0; +#endif + + d = 1.0; + f1 (); + if (d != 85.0) + abort (); + + x.e = 1.0; + f2 (); + if (x.i != 0 || x.e != 85.0 || x.j != 0) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-10.c b/libgomp/testsuite/libgomp.c/atomic-10.c new file mode 100644 index 00000000000..6565279b9e8 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-10.c @@ -0,0 +1,140 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fopenmp" } */ + +extern void abort (void); +int x1, x2, x3, x4, x5; +volatile int y6 = 9, y2, y3, y4, y5; +volatile unsigned char z1, z2, z3, z4, z5; +float a1, a2, a3, a4; + +void +f1 (void) +{ + #pragma omp atomic + x1++; + #pragma omp atomic + x2--; + #pragma omp atomic + ++x3; + #pragma omp atomic + --x4; + #pragma omp atomic + x5 += 1; + #pragma omp atomic + x1 -= y6; + #pragma omp atomic + x2 |= 1; + #pragma omp atomic + x3 &= 1; + #pragma omp atomic + x4 ^= 1; + #pragma omp atomic + x5 *= 3; + #pragma omp atomic + x1 /= 3; + #pragma omp atomic + x2 /= 3; + #pragma omp atomic + x3 <<= 3; + #pragma omp atomic + x4 >>= 3; +} + +void +f2 (void) +{ + #pragma omp atomic + y6++; + #pragma omp atomic + y2--; + #pragma omp atomic + ++y3; + #pragma omp atomic + --y4; + #pragma omp atomic + y5 += 1; + #pragma omp atomic + y6 -= x1; + #pragma omp atomic + y2 |= 1; + #pragma omp atomic + y3 &= 1; + #pragma omp atomic + y4 ^= 1; + #pragma omp atomic + y5 *= 3; + #pragma omp atomic + y6 /= 3; + #pragma omp atomic + y2 /= 3; + #pragma omp atomic + y3 <<= 3; + #pragma omp atomic + y4 >>= 3; +} + +void +f3 (void) +{ + #pragma omp atomic + z1++; + #pragma omp atomic + z2--; + #pragma omp atomic + ++z3; + #pragma omp atomic + --z4; + #pragma omp atomic + z5 += 1; + #pragma omp atomic + z1 |= 1; + #pragma omp atomic + z2 &= 1; + #pragma omp atomic + z3 ^= 1; + #pragma omp atomic + z4 *= 3; + #pragma omp atomic + z5 /= 3; + #pragma omp atomic + z1 /= 3; + #pragma omp atomic + z2 <<= 3; + #pragma omp atomic + z3 >>= 3; +} + +void +f4 (void) +{ + #pragma omp atomic + a1 += 8.0; + #pragma omp atomic + a2 *= 3.5; + #pragma omp atomic + a3 -= a1 + a2; + #pragma omp atomic + a4 /= 2.0; +} + +int +main (void) +{ + f1 (); + if (x1 != -2 || x2 != 0 || x3 != 8 || x4 != -1 || x5 != 3) + abort (); + f2 (); + if (y6 != 4 || y2 != 0 || y3 != 8 || y4 != -1 || y5 != 3) + abort (); + f3 (); + if (z1 != 0 || z2 != 8 || z3 != 0 || z4 != 253 || z5 != 0) + abort (); + a1 = 7; + a2 = 10; + a3 = 11; + a4 = 13; + f4 (); + if (a1 != 15.0 || a2 != 35.0 || a3 != -39.0 || a4 != 6.5) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/atomic-2.c b/libgomp/testsuite/libgomp.c/atomic-2.c new file mode 100644 index 00000000000..6f4939256b7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/atomic-2.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fopenmp" } */ +/* { dg-options "-O2 -fopenmp -march=nocona" { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O2 -fopenmp" { target ilp32 } } */ + +double d = 1.5; +long double ld = 3; +extern void abort (void); + +void +test (void) +{ +#pragma omp atomic + d *= 1.25; +#pragma omp atomic + ld /= 0.75; + if (d != 1.875 || ld != 4.0L) + abort (); +} + +int +main (void) +{ +#ifdef __x86_64__ +# define bit_SSE3 (1 << 0) +# define bit_CX16 (1 << 13) + unsigned int ax, bx, cx, dx; + __asm__ ("cpuid" : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) + : "0" (1) : "cc"); + if ((cx & (bit_SSE3 | bit_CX16)) != (bit_SSE3 | bit_CX16)) + return 0; +#endif + test (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/barrier-1.c b/libgomp/testsuite/libgomp.c/barrier-1.c new file mode 100644 index 00000000000..915f2dea97c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/barrier-1.c @@ -0,0 +1,50 @@ +/* Trivial test of barrier. */ + +#include <omp.h> +#include <sys/time.h> +#include <unistd.h> +#include <assert.h> +#include "libgomp_g.h" + + +struct timeval stamps[3][3]; + +static void function(void *dummy) +{ + int iam = omp_get_thread_num (); + + gettimeofday (&stamps[iam][0], NULL); + if (iam == 0) + usleep (10); + + GOMP_barrier (); + + if (iam == 0) + { + gettimeofday (&stamps[0][1], NULL); + usleep (10); + } + + GOMP_barrier (); + + gettimeofday (&stamps[iam][2], NULL); +} + +int main() +{ + omp_set_dynamic (0); + + GOMP_parallel_start (function, NULL, 3); + function (NULL); + GOMP_parallel_end (); + + assert (timercmp (&stamps[0][0], &stamps[0][1], <)); + assert (timercmp (&stamps[1][0], &stamps[0][1], <)); + assert (timercmp (&stamps[2][0], &stamps[0][1], <)); + + assert (timercmp (&stamps[0][1], &stamps[0][2], <)); + assert (timercmp (&stamps[0][1], &stamps[1][2], <)); + assert (timercmp (&stamps[0][1], &stamps[2][2], <)); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/c.exp b/libgomp/testsuite/libgomp.c/c.exp new file mode 100644 index 00000000000..8056a86054d --- /dev/null +++ b/libgomp/testsuite/libgomp.c/c.exp @@ -0,0 +1,24 @@ +if [info exists lang_library_path] then { + unset lang_library_path + unset lang_test_file + unset lang_link_flags +} + +load_lib libgomp-dg.exp + +# If a testcase doesn't have special options, use these. +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS "-O2 -fopenmp" +} + +# Initialize dg. +dg-init + +# Gather a list of all tests. +set tests [lsort [find $srcdir/$subdir *.c]] + +# Main loop. +dg-runtest $tests "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/libgomp/testsuite/libgomp.c/copyin-1.c b/libgomp/testsuite/libgomp.c/copyin-1.c new file mode 100644 index 00000000000..49c546004c8 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/copyin-1.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target tls_runtime } */ + +#include <omp.h> +#include <stdlib.h> + +int thr = 32; +#pragma omp threadprivate (thr) + +int +main (void) +{ + int l = 0; + + omp_set_dynamic (0); + omp_set_num_threads (6); + +#pragma omp parallel copyin (thr) reduction (||:l) + { + l = thr != 32; + thr = omp_get_thread_num () + 11; + } + + if (l || thr != 11) + abort (); + +#pragma omp parallel reduction (||:l) + l = thr != omp_get_thread_num () + 11; + + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/copyin-2.c b/libgomp/testsuite/libgomp.c/copyin-2.c new file mode 100644 index 00000000000..ae2451ef1d8 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/copyin-2.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target tls_runtime } */ + +#include <omp.h> +#include <stdlib.h> + +struct { int t; char buf[64]; } thr = { 32, "" }; +#pragma omp threadprivate (thr) + +int +main (void) +{ + int l = 0; + + omp_set_dynamic (0); + omp_set_num_threads (6); + +#pragma omp parallel copyin (thr) reduction (||:l) + { + l = thr.t != 32; + thr.t = omp_get_thread_num () + 11; + } + + if (l || thr.t != 11) + abort (); + +#pragma omp parallel reduction (||:l) + l = thr.t != omp_get_thread_num () + 11; + + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/copyin-3.c b/libgomp/testsuite/libgomp.c/copyin-3.c new file mode 100644 index 00000000000..86b0d691f3a --- /dev/null +++ b/libgomp/testsuite/libgomp.c/copyin-3.c @@ -0,0 +1,42 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target tls_runtime } */ + +#include <omp.h> +#include <stdlib.h> + +int thr; +#pragma omp threadprivate (thr) + +int +test (int l) +{ + return l || (thr != omp_get_thread_num () * 2); +} + +int +main (void) +{ + int l = 0; + + omp_set_dynamic (0); + omp_set_num_threads (6); + + thr = 8; + /* Broadcast the value to all threads. */ +#pragma omp parallel copyin (thr) + ; + +#pragma omp parallel reduction (||:l) + { + /* Now test if the broadcast succeeded. */ + l = thr != 8; + thr = omp_get_thread_num () * 2; +#pragma omp barrier + l = test (l); + } + + if (l) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/critical-1.c b/libgomp/testsuite/libgomp.c/critical-1.c new file mode 100644 index 00000000000..ecf54324523 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/critical-1.c @@ -0,0 +1,37 @@ +/* Trivial test of critical sections. */ + +#include <omp.h> +#include <sys/time.h> +#include <unistd.h> +#include <assert.h> +#include "libgomp_g.h" + + +static volatile int test = -1; + +static void function(void *dummy) +{ + int iam = omp_get_thread_num (); + int old; + + GOMP_critical_start (); + + old = __sync_lock_test_and_set (&test, iam); + assert (old == -1); + + usleep (10); + test = -1; + + GOMP_critical_end (); +} + +int main() +{ + omp_set_dynamic (0); + + GOMP_parallel_start (function, NULL, 3); + function (NULL); + GOMP_parallel_end (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/critical-2.c b/libgomp/testsuite/libgomp.c/critical-2.c new file mode 100644 index 00000000000..530a891f6b0 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/critical-2.c @@ -0,0 +1,35 @@ +// { dg-do run } +// Test several constructs within a parallel. At one point in development, +// the critical directive clobbered the shared clause of the parallel. + +#include <omp.h> +#include <stdlib.h> + +#define N 2000 + +int main() +{ + int A[N]; + int nthreads; + int i; + +#pragma omp parallel shared (A, nthreads) + { + #pragma omp master + nthreads = omp_get_num_threads (); + + #pragma omp for + for (i = 0; i < N; i++) + A[i] = 0; + + #pragma omp critical + for (i = 0; i < N; i++) + A[i] += 1; + } + + for (i = 0; i < N; i++) + if (A[i] != nthreads) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/lib-1.c b/libgomp/testsuite/libgomp.c/lib-1.c new file mode 100644 index 00000000000..4839cf936f2 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/lib-1.c @@ -0,0 +1,99 @@ +#include <stdlib.h> +#include <omp.h> + +int +main (void) +{ + double d, e; + int l; + omp_lock_t lck; + omp_nest_lock_t nlck; + + d = omp_get_wtime (); + + omp_init_lock (&lck); + omp_set_lock (&lck); + if (omp_test_lock (&lck)) + abort (); + omp_unset_lock (&lck); + if (! omp_test_lock (&lck)) + abort (); + if (omp_test_lock (&lck)) + abort (); + omp_unset_lock (&lck); + omp_destroy_lock (&lck); + + omp_init_nest_lock (&nlck); + if (omp_test_nest_lock (&nlck) != 1) + abort (); + omp_set_nest_lock (&nlck); + if (omp_test_nest_lock (&nlck) != 3) + abort (); + omp_unset_nest_lock (&nlck); + omp_unset_nest_lock (&nlck); + if (omp_test_nest_lock (&nlck) != 2) + abort (); + omp_unset_nest_lock (&nlck); + omp_unset_nest_lock (&nlck); + omp_destroy_nest_lock (&nlck); + + omp_set_dynamic (1); + if (! omp_get_dynamic ()) + abort (); + omp_set_dynamic (0); + if (omp_get_dynamic ()) + abort (); + + omp_set_nested (1); + if (! omp_get_nested ()) + abort (); + omp_set_nested (0); + if (omp_get_nested ()) + abort (); + + omp_set_num_threads (5); + if (omp_get_num_threads () != 1) + abort (); + if (omp_get_max_threads () != 5) + abort (); + if (omp_get_thread_num () != 0) + abort (); + omp_set_num_threads (3); + if (omp_get_num_threads () != 1) + abort (); + if (omp_get_max_threads () != 3) + abort (); + if (omp_get_thread_num () != 0) + abort (); + l = 0; +#pragma omp parallel reduction (|:l) + { + l = omp_get_num_threads () != 3; + l |= omp_get_thread_num () < 0; + l |= omp_get_thread_num () >= 3; +#pragma omp master + l |= omp_get_thread_num () != 0; + } + if (l) + abort (); + + if (omp_get_num_procs () <= 0) + abort (); + if (omp_in_parallel ()) + abort (); +#pragma omp parallel reduction (|:l) + l = ! omp_in_parallel (); +#pragma omp parallel reduction (|:l) if (1) + l = ! omp_in_parallel (); + + e = omp_get_wtime (); + if (d > e) + abort (); + d = omp_get_wtick (); + /* Negative precision is definitely wrong, + bigger than 1s clock resolution is also strange. */ + if (d <= 0 || d > 1) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-1.c b/libgomp/testsuite/libgomp.c/loop-1.c new file mode 100644 index 00000000000..a90a8e601c7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-1.c @@ -0,0 +1,138 @@ +/* Test that all loop iterations are touched. This doesn't verify + scheduling order, merely coverage. */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 10000 +static int S, E, INCR, CHUNK, NTHR; +static int data[N]; + +static void clean_data (void) +{ + memset (data, -1, sizeof (data)); +} + +static void test_data (void) +{ + int i, j; + + for (i = 0; i < S; ++i) + assert (data[i] == -1); + + for (j = 0; i < E; ++i, j = (j + 1) % INCR) + if (j == 0) + assert (data[i] != -1); + else + assert (data[i] == -1); + + for (; i < N; ++i) + assert (data[i] == -1); +} + +static void set_data (long i, int val) +{ + int old; + assert (i >= 0 && i < N); + old = __sync_lock_test_and_set (data+i, val); + assert (old == -1); +} + + +#define TMPL_1(sched) \ +static void f_##sched##_1 (void *dummy) \ +{ \ + int iam = omp_get_thread_num (); \ + long s0, e0, i; \ + if (GOMP_loop_##sched##_start (S, E, INCR, CHUNK, &s0, &e0)) \ + do \ + { \ + for (i = s0; i < e0; i += INCR) \ + set_data (i, iam); \ + } \ + while (GOMP_loop_##sched##_next (&s0, &e0)); \ + GOMP_loop_end (); \ +} \ +static void t_##sched##_1 (void) \ +{ \ + clean_data (); \ + GOMP_parallel_start (f_##sched##_1, NULL, NTHR); \ + f_##sched##_1 (NULL); \ + GOMP_parallel_end (); \ + test_data (); \ +} + +TMPL_1(static) +TMPL_1(dynamic) +TMPL_1(guided) + +#define TMPL_2(sched) \ +static void f_##sched##_2 (void *dummy) \ +{ \ + int iam = omp_get_thread_num (); \ + long s0, e0, i; \ + while (GOMP_loop_##sched##_next (&s0, &e0)) \ + { \ + for (i = s0; i < e0; i += INCR) \ + set_data (i, iam); \ + } \ + GOMP_loop_end_nowait (); \ +} \ +static void t_##sched##_2 (void) \ +{ \ + clean_data (); \ + GOMP_parallel_loop_##sched##_start \ + (f_##sched##_2, NULL, NTHR, S, E, INCR, CHUNK); \ + f_##sched##_2 (NULL); \ + GOMP_parallel_end (); \ + test_data (); \ +} + +TMPL_2(static) +TMPL_2(dynamic) +TMPL_2(guided) + +static void test (void) +{ + t_static_1 (); + t_dynamic_1 (); + t_guided_1 (); + t_static_2 (); + t_dynamic_2 (); + t_guided_2 (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 4; + + S = 0, E = N, INCR = 1, CHUNK = 4; + test (); + + S = 0, E = N, INCR = 2, CHUNK = 4; + test (); + + S = 1, E = N-1, INCR = 1, CHUNK = 5; + test (); + + S = 1, E = N-1, INCR = 2, CHUNK = 5; + test (); + + S = 2, E = 4, INCR = 1, CHUNK = 1; + test (); + + S = 0, E = N, INCR = 1, CHUNK = 0; + t_static_1 (); + t_static_2 (); + + S = 1, E = N-1, INCR = 1, CHUNK = 0; + t_static_1 (); + t_static_2 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-2.c b/libgomp/testsuite/libgomp.c/loop-2.c new file mode 100644 index 00000000000..14f371dc8a9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-2.c @@ -0,0 +1,112 @@ +/* Validate static scheduling iteration dispatch. We only test with + even thread distributions here; there are multiple valid solutions + for uneven thread distributions. */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 360 +static int data[N][2]; +static int INCR, NTHR, CHUNK; + +static void clean_data (void) +{ + memset (data, -1, sizeof (data)); +} + +static void test_data (void) +{ + int n, i, c, thr, iter, chunk; + + chunk = CHUNK; + if (chunk == 0) + chunk = N / INCR / NTHR; + + thr = iter = c = i = 0; + + for (n = 0; n < N; ++n) + { + if (i == 0) + { + assert (data[n][0] == thr); + assert (data[n][1] == iter); + } + else + { + assert (data[n][0] == -1); + assert (data[n][1] == -1); + } + + if (++i == INCR) + { + i = 0; + if (++c == chunk) + { + c = 0; + if (++thr == NTHR) + { + thr = 0; + ++iter; + } + } + } + } +} + +static void set_data (long i, int thr, int iter) +{ + int old; + assert (i >= 0 && i < N); + old = __sync_lock_test_and_set (&data[i][0], thr); + assert (old == -1); + old = __sync_lock_test_and_set (&data[i][1], iter); + assert (old == -1); +} + +static void f_static_1 (void *dummy) +{ + int iam = omp_get_thread_num (); + long s0, e0, i, count = 0; + if (GOMP_loop_static_start (0, N, INCR, CHUNK, &s0, &e0)) + do + { + for (i = s0; i < e0; i += INCR) + set_data (i, iam, count); + ++count; + } + while (GOMP_loop_static_next (&s0, &e0)); + GOMP_loop_end (); +} + +static void test (void) +{ + clean_data (); + GOMP_parallel_start (f_static_1, NULL, NTHR); + f_static_1 (NULL); + GOMP_parallel_end (); + test_data (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 5; + + INCR = 1, CHUNK = 0; /* chunk = 360 / 5 = 72 */ + test (); + + INCR = 4, CHUNK = 0; /* chunk = 360 / 4 / 5 = 18 */ + test (); + + INCR = 1, CHUNK = 4; /* 1 * 4 * 5 = 20 -> 360 / 20 = 18 iterations. */ + test (); + + INCR = 3, CHUNK = 4; /* 3 * 4 * 5 = 60 -> 360 / 60 = 6 iterations. */ + test (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/loop-3.c b/libgomp/testsuite/libgomp.c/loop-3.c new file mode 100644 index 00000000000..ba3ecdaca3a --- /dev/null +++ b/libgomp/testsuite/libgomp.c/loop-3.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ + +extern void abort (void); + +volatile int count; +static int test(void) +{ + return ++count > 0; +} + +int main() +{ + int i; + #pragma omp for + for (i = 0; i < 10; ++i) + { + if (test()) + continue; + abort (); + } + if (i != count) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nested-1.c b/libgomp/testsuite/libgomp.c/nested-1.c new file mode 100644 index 00000000000..d3cfb010069 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nested-1.c @@ -0,0 +1,30 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = -1, j = -1; + + omp_set_nested (1); + omp_set_dynamic (0); +#pragma omp parallel num_threads (4) + { +#pragma omp single + { + i = omp_get_thread_num () + omp_get_num_threads () * 256; +#pragma omp parallel num_threads (2) + { +#pragma omp single + { + j = omp_get_thread_num () + omp_get_num_threads () * 256; + } + } + } + } + if (i < 4 * 256 || i >= 4 * 256 + 4) + abort (); + if (j < 2 * 256 || j >= 2 * 256 + 2) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nested-2.c b/libgomp/testsuite/libgomp.c/nested-2.c new file mode 100644 index 00000000000..f52b074ff13 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nested-2.c @@ -0,0 +1,30 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = -1, j = -1; + + omp_set_nested (0); + omp_set_dynamic (0); +#pragma omp parallel num_threads (4) + { +#pragma omp single + { + i = omp_get_thread_num () + omp_get_num_threads () * 256; +#pragma omp parallel num_threads (2) + { +#pragma omp single + { + j = omp_get_thread_num () + omp_get_num_threads () * 256; + } + } + } + } + if (i < 4 * 256 || i >= 4 * 256 + 4) + abort (); + if (j != 256 + 0) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nestedfn-1.c b/libgomp/testsuite/libgomp.c/nestedfn-1.c new file mode 100644 index 00000000000..26c0d237cd2 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-1.c @@ -0,0 +1,49 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int a = 1, b = 2, c = 3; + void + foo (void) + { + int l = 0; +#pragma omp parallel shared (a) private (b) firstprivate (c) \ + num_threads (2) reduction (||:l) + { + if (a != 1 || c != 3) l = 1; +#pragma omp barrier + if (omp_get_thread_num () == 0) + { + a = 4; + b = 5; + c = 6; + } +#pragma omp barrier + if (omp_get_thread_num () == 1) + { + if (a != 4 || c != 3) l = 1; + a = 7; + b = 8; + c = 9; + } + else if (omp_get_num_threads () == 1) + a = 7; +#pragma omp barrier + if (omp_get_thread_num () == 0) + if (a != 7 || b != 5 || c != 6) l = 1; +#pragma omp barrier + if (omp_get_thread_num () == 1) + if (a != 7 || b != 8 || c != 9) l = 1; + } + if (l) + abort (); + } + foo (); + if (a != 7) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nestedfn-2.c b/libgomp/testsuite/libgomp.c/nestedfn-2.c new file mode 100644 index 00000000000..fdbbe0f735c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-2.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ + +extern void abort (void); + +int +main (void) +{ + int i; + void + foo (void) + { +#pragma omp master + i += 8; + } + i = 4; + foo (); + if (i != 12) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/nestedfn-3.c b/libgomp/testsuite/libgomp.c/nestedfn-3.c new file mode 100644 index 00000000000..8f8847f97e9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/nestedfn-3.c @@ -0,0 +1,52 @@ +/* { dg-do run } */ + +#include <omp.h> + +extern void abort (void); + +int +main (void) +{ + int i = 5, l = 0; + int foo (void) { return i == 6; } + int bar (void) { return i - 3; } + + omp_set_dynamic (0); + +#pragma omp parallel if (foo ()) num_threads (bar ()) reduction (|:l) + if (omp_get_num_threads () != 1) + l = 1; + + i++; + +#pragma omp parallel if (foo ()) num_threads (bar ()) reduction (|:l) + if (omp_get_num_threads () != 3) + l = 1; + + i++; + +#pragma omp master + if (bar () != 4) + abort (); + +#pragma omp single + { + if (foo ()) + abort (); + i--; + if (! foo ()) + abort (); + } + + if (l) + abort (); + + i = 8; +#pragma omp atomic + l += bar (); + + if (l != 5) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-loop01.c b/libgomp/testsuite/libgomp.c/omp-loop01.c new file mode 100644 index 00000000000..0e83c95832f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-loop01.c @@ -0,0 +1,96 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <omp.h> + +#define MAX 1000 + +void main1() +{ + int i, N1, N2, step; + int a[MAX], b[MAX]; + + N1 = rand () % 13; + N2 = rand () % (MAX - 51) + 50; + step = rand () % 7 + 1; + + printf ("N1 = %d\nN2 = %d\nstep = %d\n", N1, N2, step); + + for (i = N1; i <= N2; i += step) + a[i] = 42+ i; + + /* COUNTING UP (<). Fill in array 'b' in parallel. */ + memset (b, 0, sizeof b); +#pragma omp parallel shared(a,b,N1,N2,step) private(i) + { +#pragma omp for + for (i = N1; i < N2; i += step) + b[i] = a[i]; + } + + /* COUNTING UP (<). Check that all the cells were filled in properly. */ + for (i = N1; i < N2; i += step) + if (a[i] != b[i]) + abort (); + + printf ("for (i = %d; i < %d; i += %d) [OK]\n", N1, N2, step); + + /* COUNTING UP (<=). Fill in array 'b' in parallel. */ + memset (b, 0, sizeof b); +#pragma omp parallel shared(a,b,N1,N2,step) private(i) + { +#pragma omp for + for (i = N1; i <= N2; i += step) + b[i] = a[i]; + } + + /* COUNTING UP (<=). Check that all the cells were filled in properly. */ + for (i = N1; i <= N2; i += step) + if (a[i] != b[i]) + abort (); + + printf ("for (i = %d; i <= %d; i += %d) [OK]\n", N1, N2, step); + + /* COUNTING DOWN (>). Fill in array 'b' in parallel. */ + memset (b, 0, sizeof b); +#pragma omp parallel shared(a,b,N1,N2,step) private(i) + { +#pragma omp for + for (i = N2; i > N1; i -= step) + b[i] = a[i]; + } + + /* COUNTING DOWN (>). Check that all the cells were filled in properly. */ + for (i = N2; i > N1; i -= step) + if (a[i] != b[i]) + abort (); + + printf ("for (i = %d; i > %d; i -= %d) [OK]\n", N2, N1, step); + + /* COUNTING DOWN (>=). Fill in array 'b' in parallel. */ + memset (b, 0, sizeof b); +#pragma omp parallel shared(a,b,N1,N2,step) private(i) + { +#pragma omp for + for (i = N2; i >= N1; i -= step) + b[i] = a[i]; + } + + /* COUNTING DOWN (>=). Check that all the cells were filled in properly. */ + for (i = N2; i >= N1; i -= step) + if (a[i] != b[i]) + abort (); + + printf ("for (i = %d; i >= %d; i -= %d) [OK]\n", N2, N1, step); +} + +int +main () +{ + int i; + + srand (0); + for (i = 0; i < 10; ++i) + main1(); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-loop02.c b/libgomp/testsuite/libgomp.c/omp-loop02.c new file mode 100644 index 00000000000..04aaea2e356 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-loop02.c @@ -0,0 +1,32 @@ +#include <omp.h> + +/* Orphaned work sharing. */ + +extern void abort (void); + +#define N 10 + +void parloop (int *a) +{ + int i; + +#pragma omp for + for (i = 0; i < N; i++) + a[i] = i + 3; +} + +main() +{ + int i, a[N]; + +#pragma omp parallel shared(a) + { + parloop (a); + } + + for (i = 0; i < N; i++) + if (a[i] != i + 3) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-loop03.c b/libgomp/testsuite/libgomp.c/omp-loop03.c new file mode 100644 index 00000000000..7bb9a194331 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-loop03.c @@ -0,0 +1,26 @@ +extern void abort (void); +int a; + +void +foo () +{ + int i; + a = 30; +#pragma omp barrier +#pragma omp for lastprivate (a) + for (i = 0; i < 1024; i++) + { + a = i; + } + if (a != 1023) + abort (); +} + +int +main (void) +{ +#pragma omp parallel num_threads (64) + foo (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-nested-1.c b/libgomp/testsuite/libgomp.c/omp-nested-1.c new file mode 100644 index 00000000000..655ef26fa8c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-nested-1.c @@ -0,0 +1,28 @@ +// { dg-do run } + +extern void abort(void); +#define N 1000 + +int foo() +{ + int i = 0, j; + + #pragma omp parallel for num_threads(2) shared (i) + for (j = 0; j < N; ++j) + { + #pragma omp parallel num_threads(1) shared (i) + { + #pragma omp atomic + i++; + } + } + + return i; +} + +int main() +{ + if (foo() != N) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-parallel-for.c b/libgomp/testsuite/libgomp.c/omp-parallel-for.c new file mode 100644 index 00000000000..c6631a0a7cb --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-parallel-for.c @@ -0,0 +1,20 @@ +extern void abort (void); + +main() +{ + int i, a; + + a = 30; + +#pragma omp parallel for firstprivate (a) lastprivate (a) \ + num_threads (2) schedule(static) + for (i = 0; i < 10; i++) + a = a + i; + + /* The thread that owns the last iteration will have computed + 30 + 5 + 6 + 7 + 8 + 9 = 65. */ + if (a != 65) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-parallel-if.c b/libgomp/testsuite/libgomp.c/omp-parallel-if.c new file mode 100644 index 00000000000..5e378359aac --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-parallel-if.c @@ -0,0 +1,40 @@ +#include <omp.h> + +extern void abort (void); + +int +foo (void) +{ + return 10; +} + +main () +{ + int A = 0; + + #pragma omp parallel if (foo () > 10) shared (A) + { + A = omp_get_num_threads (); + } + + if (A != 1) + abort (); + + #pragma omp parallel if (foo () == 10) num_threads (3) shared (A) + { + A = omp_get_num_threads (); + } + + if (A != 3) + abort (); + + #pragma omp parallel if (foo () == 10) num_threads (foo ()) shared (A) + { + A = omp_get_num_threads (); + } + + if (A != 10) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-single-1.c b/libgomp/testsuite/libgomp.c/omp-single-1.c new file mode 100644 index 00000000000..a44ca54ace7 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-single-1.c @@ -0,0 +1,19 @@ +extern void abort (void); + +main() +{ + int i = 0; + + #pragma omp parallel shared (i) + { + #pragma omp single + { + i++; + } + } + + if (i != 1) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-single-2.c b/libgomp/testsuite/libgomp.c/omp-single-2.c new file mode 100644 index 00000000000..68785597397 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-single-2.c @@ -0,0 +1,38 @@ +#include <omp.h> + +extern void abort (void); + +struct X +{ + int a; + char b; + int c; +}; + +main() +{ + int i = 0; + struct X x; + int bad = 0; + + #pragma omp parallel private (i, x) shared (bad) + { + i = 5; + + #pragma omp single copyprivate (i, x) + { + i++; + x.a = 23; + x.b = 42; + x.c = 26; + } + + if (i != 6 || x.a != 23 || x.b != 42 || x.c != 26) + bad = 1; + } + + if (bad) + abort (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp-single-3.c b/libgomp/testsuite/libgomp.c/omp-single-3.c new file mode 100644 index 00000000000..5a06532448e --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp-single-3.c @@ -0,0 +1,21 @@ +extern void abort (void); + +void +single (int a, int b) +{ + #pragma omp single copyprivate(a) copyprivate(b) + { + a = b = 5; + } + + if (a != b) + abort (); +} + +int main() +{ + #pragma omp parallel + single (1, 2); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_hello.c b/libgomp/testsuite/libgomp.c/omp_hello.c new file mode 100644 index 00000000000..8d58cd43bf6 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_hello.c @@ -0,0 +1,39 @@ +/****************************************************************************** +* FILE: omp_hello.c +* DESCRIPTION: +* OpenMP Example - Hello World - C/C++ Version +* In this simple example, the master thread forks a parallel region. +* All threads in the team obtain their unique thread number and print it. +* The master thread only prints the total number of threads. Two OpenMP +* library routines are used to obtain the number of threads and each +* thread's number. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) { + +int nthreads, tid; + +/* Fork a team of threads giving them their own copies of variables */ +#pragma omp parallel private(nthreads, tid) + { + + /* Obtain thread number */ + tid = omp_get_thread_num(); + printf("Hello World from thread = %d\n", tid); + + /* Only master thread does this */ + if (tid == 0) + { + nthreads = omp_get_num_threads(); + printf("Number of threads = %d\n", nthreads); + } + + } /* All threads join master thread and disband */ + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_matvec.c b/libgomp/testsuite/libgomp.c/omp_matvec.c new file mode 100644 index 00000000000..12b8c689608 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_matvec.c @@ -0,0 +1,72 @@ +/****************************************************************************** +* OpenMP Example - Matrix-vector multiplication - C/C++ Version +* FILE: omp_matvec.c +* DESCRIPTION: +* This example multiplies all row i elements of matrix A with vector +* element b(i) and stores the summed products in vector c(i). A total is +* maintained for the entire matrix. Performed by using the OpenMP loop +* work-sharing construct. The update of the shared global total is +* serialized by using the OpenMP critical directive. +* SOURCE: Blaise Barney 5/99 +* LAST REVISED: +******************************************************************************/ + +#include <omp.h> +#include <stdio.h> +#define SIZE 10 + + +main () +{ + +float A[SIZE][SIZE], b[SIZE], c[SIZE], total; +int i, j, tid; + +/* Initializations */ +total = 0.0; +for (i=0; i < SIZE; i++) + { + for (j=0; j < SIZE; j++) + A[i][j] = (j+1) * 1.0; + b[i] = 1.0 * (i+1); + c[i] = 0.0; + } +printf("\nStarting values of matrix A and vector b:\n"); +for (i=0; i < SIZE; i++) + { + printf(" A[%d]= ",i); + for (j=0; j < SIZE; j++) + printf("%.1f ",A[i][j]); + printf(" b[%d]= %.1f\n",i,b[i]); + } +printf("\nResults by thread/row:\n"); + +/* Create a team of threads and scope variables */ +#pragma omp parallel shared(A,b,c,total) private(tid,i) + { + tid = omp_get_thread_num(); + +/* Loop work-sharing construct - distribute rows of matrix */ +#pragma omp for private(j) + for (i=0; i < SIZE; i++) + { + for (j=0; j < SIZE; j++) + c[i] += (A[i][j] * b[i]); + + /* Update and display of running total must be serialized */ + #pragma omp critical + { + total = total + c[i]; + printf(" thread %d did row %d\t c[%d]=%.2f\t",tid,i,i,c[i]); + printf("Running total= %.2f\n",total); + } + + } /* end of parallel i loop */ + + } /* end of parallel construct */ + +printf("\nMatrix-vector total - sum of all c[] = %.2f\n\n",total); + + return 0; +} + diff --git a/libgomp/testsuite/libgomp.c/omp_orphan.c b/libgomp/testsuite/libgomp.c/omp_orphan.c new file mode 100644 index 00000000000..cbf7abf3756 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_orphan.c @@ -0,0 +1,47 @@ +/****************************************************************************** +* FILE: omp_orphan.c +* DESCRIPTION: +* OpenMP Example - Parallel region with an orphaned directive - C/C++ Version +* This example demonstrates a dot product being performed by an orphaned +* loop reduction construct. Scoping of the reduction variable is critical. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> +#define VECLEN 100 + +float a[VECLEN], b[VECLEN], sum; + +float dotprod () +{ +int i,tid; + +tid = omp_get_thread_num(); +#pragma omp for reduction(+:sum) + for (i=0; i < VECLEN; i++) + { + sum = sum + (a[i]*b[i]); + printf(" tid= %d i=%d\n",tid,i); + } + +return(sum); +} + + +int main (int argc, char *argv[]) +{ +int i; + +for (i=0; i < VECLEN; i++) + a[i] = b[i] = 1.0 * i; +sum = 0.0; + +#pragma omp parallel + sum = dotprod(); + +printf("Sum = %f\n",sum); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_reduction.c b/libgomp/testsuite/libgomp.c/omp_reduction.c new file mode 100644 index 00000000000..5c9c41ec749 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_reduction.c @@ -0,0 +1,35 @@ +/****************************************************************************** +* FILE: omp_reduction.c +* DESCRIPTION: +* OpenMP Example - Combined Parallel Loop Reduction - C/C++ Version +* This example demonstrates a sum reduction within a combined parallel loop +* construct. Notice that default data element scoping is assumed - there +* are no clauses specifying shared or private variables. OpenMP will +* automatically make loop index variables private within team threads, and +* global variables shared. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) { + +int i, n; +float a[100], b[100], sum; + +/* Some initializations */ +n = 100; +for (i=0; i < n; i++) + a[i] = b[i] = i * 1.0; +sum = 0.0; + +#pragma omp parallel for reduction(+:sum) + for (i=0; i < n; i++) + sum = sum + (a[i] * b[i]); + +printf(" Sum = %f\n",sum); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_workshare1.c b/libgomp/testsuite/libgomp.c/omp_workshare1.c new file mode 100644 index 00000000000..e33bef316d8 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_workshare1.c @@ -0,0 +1,47 @@ +/****************************************************************************** +* FILE: omp_workshare1.c +* DESCRIPTION: +* OpenMP Example - Loop Work-sharing - C/C++ Version +* In this example, the iterations of a loop are scheduled dynamically +* across the team of threads. A thread will perform CHUNK iterations +* at a time before being scheduled for the next CHUNK of work. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> +#define CHUNKSIZE 10 +#define N 100 + +int main (int argc, char *argv[]) { + +int nthreads, tid, i, chunk; +float a[N], b[N], c[N]; + +/* Some initializations */ +for (i=0; i < N; i++) + a[i] = b[i] = i * 1.0; +chunk = CHUNKSIZE; + +#pragma omp parallel shared(a,b,c,nthreads,chunk) private(i,tid) + { + tid = omp_get_thread_num(); + if (tid == 0) + { + nthreads = omp_get_num_threads(); + printf("Number of threads = %d\n", nthreads); + } + printf("Thread %d starting...\n",tid); + + #pragma omp for schedule(dynamic,chunk) + for (i=0; i<N; i++) + { + c[i] = a[i] + b[i]; + printf("Thread %d: c[%d]= %f\n",tid,i,c[i]); + } + + } /* end of parallel section */ + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_workshare2.c b/libgomp/testsuite/libgomp.c/omp_workshare2.c new file mode 100644 index 00000000000..32c93dbdef6 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_workshare2.c @@ -0,0 +1,64 @@ +/****************************************************************************** +* FILE: omp_workshare2.c +* DESCRIPTION: +* OpenMP Example - Sections Work-sharing - C/C++ Version +* In this example, the OpenMP SECTION directive is used to assign +* different array operations to threads that execute a SECTION. Each +* thread receives its own copy of the result array to work with. +* AUTHOR: Blaise Barney 5/99 +* LAST REVISED: 04/06/05 +******************************************************************************/ +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> +#define N 50 + +int main (int argc, char *argv[]) { + +int i, nthreads, tid; +float a[N], b[N], c[N]; + +/* Some initializations */ +for (i=0; i<N; i++) + a[i] = b[i] = i * 1.0; + +#pragma omp parallel shared(a,b,nthreads) private(c,i,tid) + { + tid = omp_get_thread_num(); + if (tid == 0) + { + nthreads = omp_get_num_threads(); + printf("Number of threads = %d\n", nthreads); + } + printf("Thread %d starting...\n",tid); + + #pragma omp sections nowait + { + #pragma omp section + { + printf("Thread %d doing section 1\n",tid); + for (i=0; i<N; i++) + { + c[i] = a[i] + b[i]; + printf("Thread %d: c[%d]= %f\n",tid,i,c[i]); + } + } + + #pragma omp section + { + printf("Thread %d doing section 2\n",tid); + for (i=0; i<N; i++) + { + c[i] = a[i] * b[i]; + printf("Thread %d: c[%d]= %f\n",tid,i,c[i]); + } + } + + } /* end of sections */ + + printf("Thread %d done.\n",tid); + + } /* end of parallel section */ + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_workshare3.c b/libgomp/testsuite/libgomp.c/omp_workshare3.c new file mode 100644 index 00000000000..913f1f731bf --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_workshare3.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ + +/****************************************************************************** +* OpenMP Example - Combined Parallel Loop Work-sharing - C/C++ Version +* FILE: omp_workshare3.c +* DESCRIPTION: +* This example attempts to show use of the parallel for construct. However +* it will generate errors at compile time. Try to determine what is causing +* the error. See omp_workshare4.c for a corrected version. +* SOURCE: Blaise Barney 5/99 +* LAST REVISED: 03/03/2002 +******************************************************************************/ + +#include <omp.h> +#include <stdio.h> +#define N 50 +#define CHUNKSIZE 5 + +main () { + +int i, chunk, tid; +float a[N], b[N], c[N]; + +/* Some initializations */ +for (i=0; i < N; i++) + a[i] = b[i] = i * 1.0; +chunk = CHUNKSIZE; + +#pragma omp parallel for \ + shared(a,b,c,chunk) \ + private(i,tid) \ + schedule(static,chunk) + { /* { dg-error "expected" } */ + tid = omp_get_thread_num(); + for (i=0; i < N; i++) + { + c[i] = a[i] + b[i]; + printf("tid= %d i= %d c[i]= %f\n", tid, i, c[i]); + } + } /* end of parallel for construct */ + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/omp_workshare4.c b/libgomp/testsuite/libgomp.c/omp_workshare4.c new file mode 100644 index 00000000000..67605e38b56 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/omp_workshare4.c @@ -0,0 +1,48 @@ +/****************************************************************************** +* OpenMP Example - Combined Parallel Loop Work-sharing - C/C++ Version +* FILE: omp_workshare4.c +* DESCRIPTION: +* This is a corrected version of the omp_workshare3.c example. Corrections +* include removing all statements between the parallel for construct and +* the actual for loop, and introducing logic to preserve the ability to +* query a thread's id and print it from inside the for loop. +* SOURCE: Blaise Barney 5/99 +* LAST REVISED: 03/03/2002 +******************************************************************************/ + +#include <omp.h> +#include <stdio.h> +#define N 50 +#define CHUNKSIZE 5 + +main () { + +int i, chunk, tid; +float a[N], b[N], c[N]; +char first_time; + +/* Some initializations */ +for (i=0; i < N; i++) + a[i] = b[i] = i * 1.0; +chunk = CHUNKSIZE; +first_time = 'y'; + +#pragma omp parallel for \ + shared(a,b,c,chunk) \ + private(i,tid) \ + schedule(static,chunk) \ + firstprivate(first_time) + + for (i=0; i < N; i++) + { + if (first_time == 'y') + { + tid = omp_get_thread_num(); + first_time = 'n'; + } + c[i] = a[i] + b[i]; + printf("tid= %d i= %d c[i]= %f\n", tid, i, c[i]); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/ordered-1.c b/libgomp/testsuite/libgomp.c/ordered-1.c new file mode 100644 index 00000000000..23ec12547b9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/ordered-1.c @@ -0,0 +1,113 @@ +/* Test that all loop iterations are touched. This doesn't verify + scheduling order, merely coverage. */ +/* Note that we never call GOMP_ordered_start in here. AFAICS, this is + valid; the only requirement is "not more than once per iteration". */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 1000 +static int S, E, INCR, CHUNK, NTHR; +static int data[N]; + +static void clean_data (void) +{ + memset (data, -1, sizeof (data)); +} + +static void test_data (void) +{ + int i, j; + + for (i = 0; i < S; ++i) + assert (data[i] == -1); + + for (j = 0; i < E; ++i, j = (j + 1) % INCR) + if (j == 0) + assert (data[i] != -1); + else + assert (data[i] == -1); + + for (; i < N; ++i) + assert (data[i] == -1); +} + +static void set_data (long i, int val) +{ + int old; + assert (i >= 0 && i < N); + old = __sync_lock_test_and_set (data+i, val); + assert (old == -1); +} + + +#define TMPL_1(sched) \ +static void f_##sched##_1 (void *dummy) \ +{ \ + int iam = omp_get_thread_num (); \ + long s0, e0, i; \ + if (GOMP_loop_ordered_##sched##_start (S, E, INCR, CHUNK, &s0, &e0)) \ + do \ + { \ + for (i = s0; i < e0; i += INCR) \ + set_data (i, iam); \ + } \ + while (GOMP_loop_ordered_##sched##_next (&s0, &e0)); \ + GOMP_loop_end (); \ +} \ +static void t_##sched##_1 (void) \ +{ \ + clean_data (); \ + GOMP_parallel_start (f_##sched##_1, NULL, NTHR); \ + f_##sched##_1 (NULL); \ + GOMP_parallel_end (); \ + test_data (); \ +} + +TMPL_1(static) +TMPL_1(dynamic) +TMPL_1(guided) + +static void test (void) +{ + t_static_1 (); + t_dynamic_1 (); + t_guided_1 (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 4; + + S = 0, E = N, INCR = 1, CHUNK = 4; + test (); + + S = 0, E = N, INCR = 2, CHUNK = 4; + test (); + + S = 1, E = N-1, INCR = 1, CHUNK = 5; + test (); + + S = 1, E = N-1, INCR = 2, CHUNK = 5; + test (); + + S = 2, E = 4, INCR = 1, CHUNK = 1; + test (); + + S = 0, E = N, INCR = 1, CHUNK = 0; + t_static_1 (); + + S = 1, E = N-1, INCR = 1, CHUNK = 0; + t_static_1 (); + + NTHR = 10; + S = 1, E = 9, INCR = 1, CHUNK = 0; + t_static_1 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/ordered-2.c b/libgomp/testsuite/libgomp.c/ordered-2.c new file mode 100644 index 00000000000..15325b48bb3 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/ordered-2.c @@ -0,0 +1,80 @@ +/* Trivial test of ordered. */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 100 +static int next; +static int CHUNK, NTHR; + +static void clean_data (void) +{ + next = 0; +} + +static void set_data (long i) +{ + int n = __sync_fetch_and_add (&next, 1); + assert (n == i); +} + + +#define TMPL_1(sched) \ +static void f_##sched##_1 (void *dummy) \ +{ \ + long s0, e0, i; \ + if (GOMP_loop_ordered_##sched##_start (0, N, 1, CHUNK, &s0, &e0)) \ + do \ + { \ + for (i = s0; i < e0; ++i) \ + { \ + GOMP_ordered_start (); \ + set_data (i); \ + GOMP_ordered_end (); \ + } \ + } \ + while (GOMP_loop_ordered_##sched##_next (&s0, &e0)); \ + GOMP_loop_end (); \ +} \ +static void t_##sched##_1 (void) \ +{ \ + clean_data (); \ + GOMP_parallel_start (f_##sched##_1, NULL, NTHR); \ + f_##sched##_1 (NULL); \ + GOMP_parallel_end (); \ +} + +TMPL_1(static) +TMPL_1(dynamic) +TMPL_1(guided) + +static void test (void) +{ + t_static_1 (); + t_dynamic_1 (); + t_guided_1 (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 4; + + CHUNK = 1; + test (); + + CHUNK = 5; + test (); + + CHUNK = 7; + test (); + + CHUNK = 0; + t_static_1 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/ordered-3.c b/libgomp/testsuite/libgomp.c/ordered-3.c new file mode 100644 index 00000000000..2a2f219703f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/ordered-3.c @@ -0,0 +1,82 @@ +#include <stdlib.h> + +int cnt; + +void +check (int x) +{ + if (cnt++ != x) + abort (); +} + +int +main (void) +{ + int j; + + cnt = 0; +#pragma omp parallel for ordered schedule (static, 1) num_threads (4) if (0) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (static, 1) num_threads (4) if (1) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (runtime) num_threads (4) if (0) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (runtime) num_threads (4) if (1) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (dynamic) num_threads (4) if (0) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (dynamic) num_threads (4) if (1) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (guided) num_threads (4) if (0) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + cnt = 0; +#pragma omp parallel for ordered schedule (guided) num_threads (4) if (1) + for (j = 0; j < 1000; j++) + { +#pragma omp ordered + check (j); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/parallel-1.c b/libgomp/testsuite/libgomp.c/parallel-1.c new file mode 100644 index 00000000000..031f5bf8812 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/parallel-1.c @@ -0,0 +1,48 @@ +/* Trivial test of thread startup. */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +static int nthr; +static int saw[4]; + +static void function(void *dummy) +{ + int iam = omp_get_thread_num (); + + if (iam == 0) + nthr = omp_get_num_threads (); + + saw[iam] = 1; +} + +int main() +{ + omp_set_dynamic (0); + + GOMP_parallel_start (function, NULL, 2); + function (NULL); + GOMP_parallel_end (); + + assert (nthr == 2); + assert (saw[0] != 0); + assert (saw[1] != 0); + assert (saw[2] == 0); + + memset (saw, 0, sizeof (saw)); + + GOMP_parallel_start (function, NULL, 3); + function (NULL); + GOMP_parallel_end (); + + assert (nthr == 3); + assert (saw[0] != 0); + assert (saw[1] != 0); + assert (saw[2] != 0); + assert (saw[3] == 0); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr24455-1.c b/libgomp/testsuite/libgomp.c/pr24455-1.c new file mode 100644 index 00000000000..c39068f8068 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr24455-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target tls } */ +extern int i; +#pragma omp threadprivate (i) + +int i; diff --git a/libgomp/testsuite/libgomp.c/pr24455.c b/libgomp/testsuite/libgomp.c/pr24455.c new file mode 100644 index 00000000000..8af449e7b5c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr24455.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-additional-sources pr24455-1.c } */ +/* { dg-require-effective-target tls_runtime } */ + +extern void abort (void); + +extern int i; +#pragma omp threadprivate(i) + +int main() +{ + i = 0; + +#pragma omp parallel default(none) num_threads(10) + { + i++; +#pragma omp barrier + if (i != 1) + abort (); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-1.c b/libgomp/testsuite/libgomp.c/reduction-1.c new file mode 100644 index 00000000000..665163af09f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-1.c @@ -0,0 +1,36 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 0, j = 0, k = ~0; + double d = 1.0; +#pragma omp parallel num_threads(4) reduction(+:i) reduction(*:d) reduction(&:k) + { + if (i != 0 || d != 1.0 || k != ~0) +#pragma omp atomic + j |= 1; + + if (omp_get_num_threads () != 4) +#pragma omp atomic + j |= 2; + + i = omp_get_thread_num (); + d = i + 1; + k = ~(1 << (2 * i)); + } + + if (j & 1) + abort (); + if ((j & 2) == 0) + { + if (i != (0 + 1 + 2 + 3)) + abort (); + if (d != (1.0 * 2.0 * 3.0 * 4.0)) + abort (); + if (k != (~0 ^ 0x55)) + abort (); + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-2.c b/libgomp/testsuite/libgomp.c/reduction-2.c new file mode 100644 index 00000000000..52b3faff787 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-2.c @@ -0,0 +1,50 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 0, j = 0, k = ~0, l; + double d = 1.0; +#pragma omp parallel num_threads(4) + { +#pragma omp single + { + i = 16; + k ^= (1 << 16); + d += 32.0; + } + +#pragma omp for reduction(+:i) reduction(*:d) reduction(&:k) + for (l = 0; l < 4; l++) + { + if (omp_get_num_threads () == 4 && (i != 0 || d != 1.0 || k != ~0)) +#pragma omp atomic + j |= 1; + + if (l == omp_get_thread_num ()) + { + i = omp_get_thread_num (); + d = i + 1; + k = ~(1 << (2 * i)); + } + } + + if (omp_get_num_threads () == 4) + { + if (i != (16 + 0 + 1 + 2 + 3)) +#pragma omp atomic + j |= 2; + if (d != (33.0 * 1.0 * 2.0 * 3.0 * 4.0)) +#pragma omp atomic + j |= 4; + if (k != (~0 ^ 0x55 ^ (1 << 16))) +#pragma omp atomic + j |= 8; + } + } + + if (j) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-3.c b/libgomp/testsuite/libgomp.c/reduction-3.c new file mode 100644 index 00000000000..4f8f2fc1236 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-3.c @@ -0,0 +1,51 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 0, j = 0, k = ~0, l; + double d = 1.0; +#pragma omp parallel num_threads(4) + { +#pragma omp single + { + i = 16; + k ^= (1 << 16); + d += 32.0; + } + +#pragma omp for reduction(+:i) reduction(*:d) reduction(&:k) nowait + for (l = 0; l < 4; l++) + { + if (omp_get_num_threads () == 4 && (i != 0 || d != 1.0 || k != ~0)) +#pragma omp atomic + j |= 1; + + if (l == omp_get_thread_num ()) + { + i = omp_get_thread_num (); + d = i + 1; + k = ~(1 << (2 * i)); + } + } + + if (omp_get_num_threads () == 4) + { +#pragma omp barrier + if (i != (16 + 0 + 1 + 2 + 3)) +#pragma omp atomic + j |= 2; + if (d != (33.0 * 1.0 * 2.0 * 3.0 * 4.0)) +#pragma omp atomic + j |= 4; + if (k != (~0 ^ 0x55 ^ (1 << 16))) +#pragma omp atomic + j |= 8; + } + } + + if (j) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/reduction-4.c b/libgomp/testsuite/libgomp.c/reduction-4.c new file mode 100644 index 00000000000..23e9d6d5bda --- /dev/null +++ b/libgomp/testsuite/libgomp.c/reduction-4.c @@ -0,0 +1,36 @@ +#include <omp.h> +#include <stdlib.h> + +int +main (void) +{ + int i = 0, j = 0, k = 0, l = 0; +#pragma omp parallel num_threads(4) reduction(-:i) reduction(|:k) \ + reduction(^:l) + { + if (i != 0 || k != 0 || l != 0) +#pragma omp atomic + j |= 1; + + if (omp_get_num_threads () != 4) +#pragma omp atomic + j |= 2; + + i = omp_get_thread_num (); + k = 1 << (2 * i); + l = 0xea << (3 * i); + } + + if (j & 1) + abort (); + if ((j & 2) == 0) + { + if (i != (0 + 1 + 2 + 3)) + abort (); + if (k != 0x55) + abort (); + if (l != 0x1e93a) + abort (); + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/sections-1.c b/libgomp/testsuite/libgomp.c/sections-1.c new file mode 100644 index 00000000000..6785941be6c --- /dev/null +++ b/libgomp/testsuite/libgomp.c/sections-1.c @@ -0,0 +1,83 @@ +/* Test that all sections are touched. */ + +#include <omp.h> +#include <string.h> +#include <assert.h> +#include "libgomp_g.h" + + +#define N 100 +static int data[N]; +static int NTHR; + +static void clean_data (void) +{ + memset (data, -1, sizeof (data)); +} + +static void test_data (void) +{ + int i; + + for (i = 0; i < N; ++i) + assert (data[i] != -1); +} + +static void set_data (unsigned i, int val) +{ + int old; + assert (i >= 1 && i <= N); + old = __sync_lock_test_and_set (data+i-1, val); + assert (old == -1); +} + + +static void f_1 (void *dummy) +{ + int iam = omp_get_thread_num (); + unsigned long s; + + for (s = GOMP_sections_start (N); s ; s = GOMP_sections_next ()) + set_data (s, iam); + GOMP_sections_end (); +} + +static void test_1 (void) +{ + clean_data (); + GOMP_parallel_start (f_1, NULL, NTHR); + f_1 (NULL); + GOMP_parallel_end (); + test_data (); +} + +static void f_2 (void *dummy) +{ + int iam = omp_get_thread_num (); + unsigned s; + + while ((s = GOMP_sections_next ())) + set_data (s, iam); + GOMP_sections_end_nowait (); +} + +static void test_2 (void) +{ + clean_data (); + GOMP_parallel_sections_start (f_2, NULL, NTHR, N); + f_2 (NULL); + GOMP_parallel_end (); + test_data (); +} + +int main() +{ + omp_set_dynamic (0); + + NTHR = 4; + + test_1 (); + test_2 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/shared-1.c b/libgomp/testsuite/libgomp.c/shared-1.c new file mode 100644 index 00000000000..f7d4fb2d60f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/shared-1.c @@ -0,0 +1,58 @@ +extern void abort (void); + +struct Y +{ + int l[5][10]; +}; + +struct X +{ + struct Y y; + float b[10]; +}; + +void +parallel (int a, int b) +{ + int i, j; + struct X A[10][5]; + a = b = 3; + + for (i = 0; i < 10; i++) + for (j = 0; j < 5; j++) + A[i][j].y.l[3][3] = -10; + + #pragma omp parallel shared (a, b, A) num_threads (5) + { + int i, j; + + #pragma omp atomic + a += omp_get_num_threads (); + + #pragma omp atomic + b += omp_get_num_threads (); + + #pragma omp for private (j) + for (i = 0; i < 10; i++) + for (j = 0; j < 5; j++) + A[i][j].y.l[3][3] += 20; + + } + + for (i = 0; i < 10; i++) + for (j = 0; j < 5; j++) + if (A[i][j].y.l[3][3] != 10) + abort (); + + if (a != 28) + abort (); + + if (b != 28) + abort (); +} + +main() +{ + parallel (1, 2); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/shared-2.c b/libgomp/testsuite/libgomp.c/shared-2.c new file mode 100644 index 00000000000..56c88ecc734 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/shared-2.c @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <omp.h> + +extern void abort (void); + +void +parallel (int a, int b) +{ + int bad, LASTPRIV, LASTPRIV_SEC; + int i; + + a = b = 3; + + bad = 0; + + #pragma omp parallel firstprivate (a,b) shared (bad) num_threads (5) + { + if (a != 3 || b != 3) + bad = 1; + + #pragma omp for lastprivate (LASTPRIV) + for (i = 0; i < 10; i++) + LASTPRIV = i; + + #pragma omp sections lastprivate (LASTPRIV_SEC) + { + #pragma omp section + { LASTPRIV_SEC = 3; } + + #pragma omp section + { LASTPRIV_SEC = 42; } + } + + } + + if (LASTPRIV != 9) + abort (); + + if (LASTPRIV_SEC != 42) + abort (); + + if (bad) + abort (); +} + +int main() +{ + parallel (1, 2); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/shared-3.c b/libgomp/testsuite/libgomp.c/shared-3.c new file mode 100644 index 00000000000..494a970ad8f --- /dev/null +++ b/libgomp/testsuite/libgomp.c/shared-3.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ + +void abort (void); + +int main() +{ + int x; + int *p; + + p = &x; + + #pragma omp parallel + { + if (p != &x) + abort (); + } + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/single-1.c b/libgomp/testsuite/libgomp.c/single-1.c new file mode 100644 index 00000000000..d1fd5e2de62 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/single-1.c @@ -0,0 +1,51 @@ +/* Trivial test of single. */ + +#include <omp.h> +#include <sys/time.h> +#include <unistd.h> +#include <assert.h> +#include "libgomp_g.h" + + +static int test; + +static void f_nocopy (void *dummy) +{ + if (GOMP_single_start ()) + { + int iam = omp_get_thread_num (); + int old = __sync_lock_test_and_set (&test, iam); + assert (old == -1); + } +} + +static void f_copy (void *dummy) +{ + int *x = GOMP_single_copy_start (); + if (x == NULL) + { + int iam = omp_get_thread_num (); + int old = __sync_lock_test_and_set (&test, iam); + assert (old == -1); + GOMP_single_copy_end (&test); + } + else + assert (x == &test); +} + +int main() +{ + omp_set_dynamic (0); + + test = -1; + GOMP_parallel_start (f_nocopy, NULL, 3); + f_nocopy (NULL); + GOMP_parallel_end (); + + test = -1; + GOMP_parallel_start (f_copy, NULL, 3); + f_copy (NULL); + GOMP_parallel_end (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/single-2.c b/libgomp/testsuite/libgomp.c/single-2.c new file mode 100644 index 00000000000..b510ce735e2 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/single-2.c @@ -0,0 +1,15 @@ +#include <stdlib.h> + +int +main (void) +{ + int i; + i = 4; +#pragma omp single copyprivate (i) + { + i = 6; + } + if (i != 6) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/vla-1.c b/libgomp/testsuite/libgomp.c/vla-1.c new file mode 100644 index 00000000000..bdacdbbe883 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/vla-1.c @@ -0,0 +1,60 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> +#include <string.h> + +int +main (int argc, char **argv[]) +{ + int n = argc < 5 ? 12 : 31, i, m, l; + char a[n + 3]; + unsigned short b[n / 2 - 1]; + int c[n * 2 + 1]; + + for (i = 0; i < n + 3; i++) + a[i] = i; + for (i = 0; i < n / 2 - 1; i++) + b[i] = (i << 8) | i; + for (i = 0; i < n * 2 + 1; i++) + c[i] = (i << 24) | i; + l = 0; + m = n; +#pragma omp parallel default (shared) num_threads (4) \ + firstprivate (a, m) private (b, i) reduction (+:l) + { + for (i = 0; i < m + 3; i++) + if (a[i] != i) + l++; + for (i = 0; i < m * 2 + 1; i++) + if (c[i] != ((i << 24) | i)) + l++; +#pragma omp barrier + memset (a, omp_get_thread_num (), m + 3); + for (i = 0; i < m / 2 - 1; i++) + b[i] = a[0] + 7; +#pragma omp master + { + for (i = 0; i < m * 2 + 1; i++) + c[i] = a[0] + 16; + } +#pragma omp barrier + if (a[0] != omp_get_thread_num ()) + l++; + for (i = 1; i < m + 3; i++) + if (a[i] != a[0]) + l++; + for (i = 0; i < m / 2 - 1; i++) + if (b[i] != a[0] + 7) + l++; + for (i = 0; i < m * 2 + 1; i++) + if (c[i] != 16) + l++; + } + if (l) + abort (); + for (i = 0; i < n * 2 + 1; i++) + if (c[i] != 16) + l++; + return 0; +} |