218 changes: 218 additions & 0 deletions openmp/runtime/test/worksharing/for/omp_for_schedule_guided.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
// RUN: %libomp-compile-and-run

/* Test for guided scheduling
* Ensure threads get chunks interleavely first
* Then judge the chunk sizes are decreasing to a stable value
* Modified by Chunhua Liao
* For example, 100 iteration on 2 threads, chunksize 7
* one line for each dispatch, 0/1 means thread id
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24
* 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 18
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14
* 1 1 1 1 1 1 1 1 1 1 10
* 0 0 0 0 0 0 0 0 8
* 1 1 1 1 1 1 1 7
* 0 0 0 0 0 0 0 7
* 1 1 1 1 1 1 1 7
* 0 0 0 0 0 5
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"

#define CFSMAX_SIZE 1000
#define MAX_TIME 0.005

#ifdef SLEEPTIME
#undef SLEEPTIME
#define SLEEPTIME 0.0001
#endif

int test_omp_for_schedule_guided()
{
int * tids;
int * chunksizes;
int notout;
int maxiter;
int threads;
int i;
int result;

tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
maxiter = 0;
result = 1;
notout = 1;

/* Testing if enough threads are available for this check. */
#pragma omp parallel
{
#pragma omp single
{
threads = omp_get_num_threads();
}
}

/* ensure there are at least two threads */
if (threads < 2) {
omp_set_num_threads(2);
threads = 2;
}

/* Now the real parallel work:
* Each thread will start immediately with the first chunk.
*/
#pragma omp parallel shared(tids,maxiter)
{ /* begin of parallel */
double count;
int tid;
int j;

tid = omp_get_thread_num ();

#pragma omp for nowait schedule(guided)
for(j = 0; j < CFSMAX_SIZE; ++j) {
count = 0.;
#pragma omp flush(maxiter)
if (j > maxiter) {
#pragma omp critical
{
maxiter = j;
}
}
/*printf ("thread %d sleeping\n", tid);*/
#pragma omp flush(maxiter,notout)
while (notout && (count < MAX_TIME) && (maxiter == j)) {
#pragma omp flush(maxiter,notout)
my_sleep (SLEEPTIME);
count += SLEEPTIME;
#ifdef VERBOSE
printf(".");
#endif
}
#ifdef VERBOSE
if (count > 0.) printf(" waited %lf s\n", count);
#endif
/*printf ("thread %d awake\n", tid);*/
tids[j] = tid;
#ifdef VERBOSE
printf("%d finished by %d\n",j,tid);
#endif
} /* end of for */
notout = 0;
#pragma omp flush(maxiter,notout)
} /* end of parallel */

/*******************************************************
* evaluation of the values *
*******************************************************/
{
int determined_chunksize = 1;
int last_threadnr = tids[0];
int global_chunknr = 0;
int openwork = CFSMAX_SIZE;
int expected_chunk_size;
int* local_chunknr = (int*)malloc(threads * sizeof(int));
double c = 1;

for (i = 0; i < threads; i++)
local_chunknr[i] = 0;

tids[CFSMAX_SIZE] = -1;

/*
* determine the number of global chunks
*/
// fprintf(stderr,"# global_chunknr thread local_chunknr chunksize\n");
for(i = 1; i <= CFSMAX_SIZE; ++i) {
if (last_threadnr==tids[i]) {
determined_chunksize++;
} else {
/* fprintf(stderr, "%d\t%d\t%d\t%d\n", global_chunknr,
last_threadnr, local_chunknr[last_threadnr], m); */
global_chunknr++;
local_chunknr[last_threadnr]++;
last_threadnr = tids[i];
determined_chunksize = 1;
}
}
/* now allocate the memory for saving the sizes of the global chunks */
chunksizes = (int*)malloc(global_chunknr * sizeof(int));

/*
* Evaluate the sizes of the global chunks
*/
global_chunknr = 0;
determined_chunksize = 1;
last_threadnr = tids[0];
for (i = 1; i <= CFSMAX_SIZE; ++i) {
/* If the threadnumber was the same as before increase the
* detected chunksize for this chunk otherwise set the detected
* chunksize again to one and save the number of the next
* thread in last_threadnr.
*/
if (last_threadnr == tids[i]) {
determined_chunksize++;
} else {
chunksizes[global_chunknr] = determined_chunksize;
global_chunknr++;
local_chunknr[last_threadnr]++;
last_threadnr = tids[i];
determined_chunksize = 1;
}
}

#ifdef VERBOSE
fprintf(stderr, "found\texpected\tconstant\n");
#endif

/* identify the constant c for the exponential
decrease of the chunksize */
expected_chunk_size = openwork / threads;
c = (double) chunksizes[0] / expected_chunk_size;

for (i = 0; i < global_chunknr; i++) {
/* calculate the new expected chunksize */
if (expected_chunk_size > 1)
expected_chunk_size = c * openwork / threads;
#ifdef VERBOSE
fprintf(stderr, "%8d\t%8d\t%lf\n", chunksizes[i],
expected_chunk_size, c * chunksizes[i]/expected_chunk_size);
#endif
/* check if chunksize is inside the rounding errors */
if (abs (chunksizes[i] - expected_chunk_size) >= 2) {
result = 0;
#ifndef VERBOSE
fprintf(stderr, "Chunksize differed from expected "
"value: %d instead of %d\n", chunksizes[i],
expected_chunk_size);
return 0;
#endif
} /* end if */

#ifndef VERBOSE
if (expected_chunk_size - chunksizes[i] < 0)
fprintf(stderr, "Chunksize did not decrease: %d"
" instead of %d\n", chunksizes[i],expected_chunk_size);
#endif

/* calculating the remaining amount of work */
openwork -= chunksizes[i];
}
}
return result;
}

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_for_schedule_guided()) {
num_failed++;
}
}
return num_failed;
}
155 changes: 155 additions & 0 deletions openmp/runtime/test/worksharing/for/omp_for_schedule_static.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"

#define CFSMAX_SIZE 1000
#define MAX_TIME 0.01

#ifdef SLEEPTIME
#undef SLEEPTIME
#define SLEEPTIME 0.0005
#endif

int test_omp_for_schedule_static()
{
int threads;
int i,lasttid;
int * tids;
int notout;
int maxiter;
int chunk_size;
int counter = 0;
int tmp_count=1;
int lastthreadsstarttid = -1;
int result = 1;

chunk_size = 7;
tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
notout = 1;
maxiter = 0;

#pragma omp parallel shared(tids,counter)
{ /* begin of parallel*/
#pragma omp single
{
threads = omp_get_num_threads ();
} /* end of single */
} /* end of parallel */

if (threads < 2) {
omp_set_num_threads(2);
threads = 2;
}
fprintf (stderr,"Using an internal count of %d\nUsing a specified"
" chunksize of %d\n", CFSMAX_SIZE, chunk_size);
tids[CFSMAX_SIZE] = -1; /* setting endflag */
#pragma omp parallel shared(tids)
{ /* begin of parallel */
double count;
int tid;
int j;

tid = omp_get_thread_num ();

#pragma omp for nowait schedule(static,chunk_size)
for(j = 0; j < CFSMAX_SIZE; ++j) {
count = 0.;
#pragma omp flush(maxiter)
if (j > maxiter) {
#pragma omp critical
{
maxiter = j;
}
}
/*printf ("thread %d sleeping\n", tid);*/
while (notout && (count < MAX_TIME) && (maxiter == j)) {
#pragma omp flush(maxiter,notout)
my_sleep (SLEEPTIME);
count += SLEEPTIME;
printf(".");
}
#ifdef VERBOSE
if (count > 0.) printf(" waited %lf s\n", count);
#endif
/*printf ("thread %d awake\n", tid);*/
tids[j] = tid;
#ifdef VERBOSE
printf("%d finished by %d\n",j,tid);
#endif
} /* end of for */
notout = 0;
#pragma omp flush(maxiter,notout)
} /* end of parallel */

/**** analysing the data in array tids ****/

lasttid = tids[0];
tmp_count = 0;

for (i = 0; i < CFSMAX_SIZE + 1; ++i) {
/* If the work was done by the same thread increase tmp_count by one. */
if (tids[i] == lasttid) {
tmp_count++;
#ifdef VERBOSE
fprintf (stderr, "%d: %d \n", i, tids[i]);
#endif
continue;
}

/* Check if the next thread had has the right thread number. When finding
* threadnumber -1 the end should be reached.
*/
if (tids[i] == (lasttid + 1) % threads || tids[i] == -1) {
/* checking for the right chunk size */
if (tmp_count == chunk_size) {
tmp_count = 1;
lasttid = tids[i];
#ifdef VERBOSE
fprintf (stderr, "OK\n");
#endif
} else {
/* If the chunk size was wrong, check if the end was reached */
if (tids[i] == -1) {
if (i == CFSMAX_SIZE) {
fprintf (stderr, "Last thread had chunk size %d\n",
tmp_count);
break;
} else {
fprintf (stderr, "ERROR: Last thread (thread with"
" number -1) was found before the end.\n");
result = 0;
}
} else {
fprintf (stderr, "ERROR: chunk size was %d. (assigned"
" was %d)\n", tmp_count, chunk_size);
result = 0;
}
}
} else {
fprintf(stderr, "ERROR: Found thread with number %d (should be"
" inbetween 0 and %d).", tids[i], threads - 1);
result = 0;
}
#ifdef VERBOSE
fprintf (stderr, "%d: %d \n", i, tids[i]);
#endif
}

return result;
}

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_for_schedule_static()) {
num_failed++;
}
}
return num_failed;
}
203 changes: 203 additions & 0 deletions openmp/runtime/test/worksharing/for/omp_for_schedule_static_3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"

#define CFSMAX_SIZE 1000
#define MAX_TIME 0.01

#ifdef SLEEPTIME
#undef SLEEPTIME
#define SLEEPTIME 0.0005
#endif

#define VERBOSE 0

int test_omp_for_schedule_static_3()
{
int threads;
int i,lasttid;

int * tids;
int * tids2;
int notout;
int maxiter;
int chunk_size;

int counter = 0;
int tmp_count=1;
int lastthreadsstarttid = -1;
int result = 1;
chunk_size = 7;

tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
notout = 1;
maxiter = 0;

#pragma omp parallel shared(tids,counter)
{ /* begin of parallel*/
#pragma omp single
{
threads = omp_get_num_threads ();
} /* end of single */
} /* end of parallel */

/* Ensure that at least two threads are created */
if (threads < 2) {
omp_set_num_threads(2);
threads = 2;
}
fprintf (stderr,"Using an internal count of %d\nUsing a"
" specified chunksize of %d\n", CFSMAX_SIZE, chunk_size);
tids[CFSMAX_SIZE] = -1; /* setting endflag */

#pragma omp parallel shared(tids)
{ /* begin of parallel */
double count;
int tid;
int j;

tid = omp_get_thread_num ();

#pragma omp for nowait schedule(static,chunk_size)
for(j = 0; j < CFSMAX_SIZE; ++j) {
count = 0.;
#pragma omp flush(maxiter)
if (j > maxiter) {
#pragma omp critical
{
maxiter = j;
}
}
/*printf ("thread %d sleeping\n", tid);*/
while (notout && (count < MAX_TIME) && (maxiter == j)) {
#pragma omp flush(maxiter,notout)
my_sleep (SLEEPTIME);
count += SLEEPTIME;
printf(".");
}
#ifdef VERBOSE
if (count > 0.) printf(" waited %lf s\n", count);
#endif
/*printf ("thread %d awake\n", tid);*/
tids[j] = tid;
#ifdef VERBOSE
printf("%d finished by %d\n",j,tid);
#endif
} /* end of omp parallel for */

notout = 0;
#pragma omp flush(maxiter,notout)
} /* end of parallel */

/**** analysing the data in array tids ****/

lasttid = tids[0];
tmp_count = 0;

for (i = 0; i < CFSMAX_SIZE + 1; ++i) {
/* If the work was done by the same thread
increase tmp_count by one. */
if (tids[i] == lasttid) {
tmp_count++;
#ifdef VERBOSE
fprintf (stderr, "%d: %d \n", i, tids[i]);
#endif
continue;
}

/* Check if the next thread had has the right thread number.
* When finding threadnumber -1 the end should be reached.
*/
if (tids[i] == (lasttid + 1) % threads || tids[i] == -1) {
/* checking for the right chunk size */
if (tmp_count == chunk_size) {
tmp_count = 1;
lasttid = tids[i];
#ifdef VERBOSE
fprintf (stderr, "OK\n");
#endif
} else {
/* If the chunk size was wrong, check if the end was reached */
if (tids[i] == -1) {
if (i == CFSMAX_SIZE) {
fprintf (stderr, "Last thread had chunk size %d\n",
tmp_count);
break;
} else {
fprintf (stderr, "ERROR: Last thread (thread with"
" number -1) was found before the end.\n");
result = 0;
}
} else {
fprintf (stderr, "ERROR: chunk size was %d. (assigned"
" was %d)\n", tmp_count, chunk_size);
result = 0;
}
}
} else {
fprintf(stderr, "ERROR: Found thread with number %d (should be"
" inbetween 0 and %d).", tids[i], threads - 1);
result = 0;
}
#ifdef VERBOSE
fprintf (stderr, "%d: %d \n", i, tids[i]);
#endif
}

/* Now we check if several loop regions in one parallel region have the
* same logical assignement of chunks to threads. We use the nowait
* clause to increase the probability to get an error. */

/* First we allocate some more memmory */
free (tids);
tids = (int *) malloc (sizeof (int) * LOOPCOUNT);
tids2 = (int *) malloc (sizeof (int) * LOOPCOUNT);

#pragma omp parallel
{
{
int n;
#pragma omp for schedule(static) nowait
for (n = 0; n < LOOPCOUNT; n++) {
if (LOOPCOUNT == n + 1 )
my_sleep(SLEEPTIME);

tids[n] = omp_get_thread_num();
}
}
{
int m;
#pragma omp for schedule(static) nowait
for (m = 1; m <= LOOPCOUNT; m++) {
tids2[m-1] = omp_get_thread_num();
}
}
}

for (i = 0; i < LOOPCOUNT; i++)
if (tids[i] != tids2[i]) {
fprintf (stderr, "Chunk no. %d was assigned once to thread %d and"
" later to thread %d.\n", i, tids[i],tids2[i]);
result = 0;
}

free (tids);
free (tids2);
return result;
}

int main()
{
int i;
int num_failed=0;

for (i = 0; i < REPETITIONS; i++) {
if(!test_omp_for_schedule_static_3()) {
num_failed++;
}
}
return num_failed;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_parallel_for_firstprivate()
{
int sum ;
int i2;
int i;
int known_sum;

sum=0;
i2=3;

#pragma omp parallel for reduction(+:sum) private(i) firstprivate(i2)
for (i = 1; i <= LOOPCOUNT; i++) {
sum = sum + (i + i2);
}

known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 + i2 * LOOPCOUNT;
return (known_sum == sum);
} /* end of check_parallel_for_fistprivate */

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_for_firstprivate()) {
num_failed++;
}
}
return num_failed;
}
42 changes: 42 additions & 0 deletions openmp/runtime/test/worksharing/for/omp_parallel_for_if.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"

int test_omp_parallel_for_if()
{
int known_sum;
int num_threads;
int sum, sum2;
int i;
int control;

control = 0;
num_threads=0;
sum = 0;
sum2 = 0;

#pragma omp parallel for private(i) if (control==1)
for (i=0; i <= LOOPCOUNT; i++) {
num_threads = omp_get_num_threads();
sum = sum + i;
}

known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
fprintf(stderr, "Number of threads determined by"
" omp_get_num_threads: %d\n", num_threads);
return (known_sum == sum && num_threads == 1);
} /* end of check_parallel_for_private */

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_for_if()) {
num_failed++;
}
}
return num_failed;
}
37 changes: 37 additions & 0 deletions openmp/runtime/test/worksharing/for/omp_parallel_for_lastprivate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_parallel_for_lastprivate()
{
int sum;
int i;
int i0;
int known_sum;

sum =0;
i0 = -1;

#pragma omp parallel for reduction(+:sum) \
schedule(static,7) private(i) lastprivate(i0)
for (i = 1; i <= LOOPCOUNT; i++) {
sum = sum + i;
i0 = i;
} /* end of parallel for */

known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
return ((known_sum == sum) && (i0 == LOOPCOUNT));
} /* end of check_parallel_for_lastprivate */

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_for_lastprivate()) {
num_failed++;
}
}
return num_failed;
}
64 changes: 64 additions & 0 deletions openmp/runtime/test/worksharing/for/omp_parallel_for_ordered.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

static int last_i = 0;

int i;
#pragma omp threadprivate(i)

/* Variable ii is used to avoid problems with a threadprivate variable used as a loop
* index. See test omp_threadprivate_for.
*/
static int ii;
#pragma omp threadprivate(ii)

/*!
Utility function: returns true if the passed argument is larger than
the argument of the last call of this function.
*/
static int check_i_islarger2(int i)
{
int islarger;
islarger = (i > last_i);
last_i = i;
return (islarger);
}

int test_omp_parallel_for_ordered()
{
int sum;
int is_larger;
int known_sum;
int i;

sum = 0;
is_larger = 1;
last_i = 0;
#pragma omp parallel for schedule(static,1) private(i) ordered
for (i = 1; i < 100; i++) {
ii = i;
#pragma omp ordered
{
is_larger = check_i_islarger2 (ii) && is_larger;
sum = sum + ii;
}
}
known_sum = (99 * 100) / 2;
fprintf (stderr," known_sum = %d , sum = %d \n", known_sum, sum);
fprintf (stderr," is_larger = %d\n", is_larger);
return (known_sum == sum) && is_larger;
}

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_for_ordered()) {
num_failed++;
}
}
return num_failed;
}
50 changes: 50 additions & 0 deletions openmp/runtime/test/worksharing/for/omp_parallel_for_private.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"

/*! Utility function to spend some time in a loop */
static void do_some_work (void)
{
int i;
double sum = 0;
for(i = 0; i < 1000; i++){
sum += sqrt (i);
}
}

int test_omp_parallel_for_private()
{
int sum;
int i;
int i2;
int known_sum;

sum =0;
i2=0;

#pragma omp parallel for reduction(+:sum) schedule(static,1) private(i) private(i2)
for (i=1;i<=LOOPCOUNT;i++)
{
i2 = i;
#pragma omp flush
do_some_work ();
#pragma omp flush
sum = sum + i2;
} /*end of for*/
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
return (known_sum == sum);
} /* end of check_parallel_for_private */

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_for_private()) {
num_failed++;
}
}
return num_failed;
}
266 changes: 266 additions & 0 deletions openmp/runtime/test/worksharing/for/omp_parallel_for_reduction.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"

#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
#define MAX_FACTOR 10
#define KNOWN_PRODUCT 3628800 /* 10! */

int test_omp_parallel_for_reduction()
{
int sum;
int known_sum;
double dsum;
double dknown_sum;
double dt=0.5; /* base of geometric row for + and - test*/
double rounding_error= 1.E-9;
int diff;
double ddiff;
int product;
int known_product;
int logic_and;
int logic_or;
int bit_and;
int bit_or;
int exclusiv_bit_or;
int logics[LOOPCOUNT];
int i;
double dpt;
int result;

sum =0;
dsum=0;
dt = 1./3.;
result = 0;
product = 1;
logic_and=1;
logic_or=0;
bit_and=1;
bit_or=0;
exclusiv_bit_or=0;

/* Tests for integers */
known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2;
#pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:sum)
for (i=1;i<=LOOPCOUNT;i++) {
sum=sum+i;
}
if(known_sum!=sum) {
result++;
fprintf(stderr,"Error in sum with integers: Result was %d"
" instead of %d\n",sum,known_sum);
}

diff = (LOOPCOUNT*(LOOPCOUNT+1))/2;
#pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:diff)
for (i=1;i<=LOOPCOUNT;++i) {
diff=diff-i;
}
if(diff != 0) {
result++;
fprintf(stderr,"Error in difference with integers: Result was %d"
" instead of 0.\n",diff);
}

/* Tests for doubles */
dsum=0;
dpt=1;
for (i=0;i<DOUBLE_DIGITS;++i) {
dpt*=dt;
}
dknown_sum = (1-dpt)/(1-dt);
#pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:dsum)
for (i=0;i<DOUBLE_DIGITS;++i) {
dsum += pow(dt,i);
}
if( fabs(dsum-dknown_sum) > rounding_error ) {
result++;
fprintf(stderr,"Error in sum with doubles: Result was %f"
" instead of %f (Difference: %E)\n",
dsum, dknown_sum, dsum-dknown_sum);
}

dpt=1;

for (i=0;i<DOUBLE_DIGITS;++i) {
dpt*=dt;
}
fprintf(stderr,"\n");
ddiff = (1-dpt)/(1-dt);
#pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:ddiff)
for (i=0;i<DOUBLE_DIGITS;++i) {
ddiff -= pow(dt,i);
}
if( fabs(ddiff) > rounding_error) {
result++;
fprintf(stderr,"Error in Difference with doubles: Result was %E"
" instead of 0.0\n",ddiff);
}

/* Tests for integers */
#pragma omp parallel for schedule(dynamic,1) private(i) reduction(*:product)
for(i=1;i<=MAX_FACTOR;i++) {
product *= i;
}
known_product = KNOWN_PRODUCT;
if(known_product != product) {
result++;
fprintf(stderr,"Error in Product with integers: Result was %d"
" instead of %d\n\n",product,known_product);
}

/* Tests for logic AND */
for(i=0;i<LOOPCOUNT;i++) {
logics[i]=1;
}

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(&&:logic_and)
for(i=0;i<LOOPCOUNT;++i) {
logic_and = (logic_and && logics[i]);
}
if(!logic_and) {
result++;
fprintf(stderr,"Error in logic AND part 1.\n");
}

logic_and = 1;
logics[LOOPCOUNT/2]=0;

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(&&:logic_and)
for(i=0;i<LOOPCOUNT;++i) {
logic_and = logic_and && logics[i];
}
if(logic_and) {
result++;
fprintf(stderr,"Error in logic AND part 2.\n");
}

/* Tests for logic OR */
for(i=0;i<LOOPCOUNT;i++) {
logics[i]=0;
}

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(||:logic_or)
for(i=0;i<LOOPCOUNT;++i) {
logic_or = logic_or || logics[i];
}
if(logic_or) {
result++;
fprintf(stderr,"Error in logic OR part 1.\n");
}
logic_or = 0;
logics[LOOPCOUNT/2]=1;

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(||:logic_or)
for(i=0;i<LOOPCOUNT;++i) {
logic_or = logic_or || logics[i];
}
if(!logic_or) {
result++;
fprintf(stderr,"Error in logic OR part 2.\n");
}

/* Tests for bitwise AND */
for(i=0;i<LOOPCOUNT;++i) {
logics[i]=1;
}

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(&:bit_and)
for(i=0;i<LOOPCOUNT;++i) {
bit_and = (bit_and & logics[i]);
}
if(!bit_and) {
result++;
fprintf(stderr,"Error in BIT AND part 1.\n");
}

bit_and = 1;
logics[LOOPCOUNT/2]=0;

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(&:bit_and)
for(i=0;i<LOOPCOUNT;++i) {
bit_and = bit_and & logics[i];
}
if(bit_and) {
result++;
fprintf(stderr,"Error in BIT AND part 2.\n");
}

/* Tests for bitwise OR */
for(i=0;i<LOOPCOUNT;i++) {
logics[i]=0;
}

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(|:bit_or)
for(i=0;i<LOOPCOUNT;++i) {
bit_or = bit_or | logics[i];
}
if(bit_or) {
result++;
fprintf(stderr,"Error in BIT OR part 1\n");
}
bit_or = 0;
logics[LOOPCOUNT/2]=1;

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(|:bit_or)
for(i=0;i<LOOPCOUNT;++i) {
bit_or = bit_or | logics[i];
}
if(!bit_or) {
result++;
fprintf(stderr,"Error in BIT OR part 2\n");
}

/* Tests for bitwise XOR */
for(i=0;i<LOOPCOUNT;i++) {
logics[i]=0;
}

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(^:exclusiv_bit_or)
for(i=0;i<LOOPCOUNT;++i) {
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
if(exclusiv_bit_or) {
result++;
fprintf(stderr,"Error in EXCLUSIV BIT OR part 1\n");
}

exclusiv_bit_or = 0;
logics[LOOPCOUNT/2]=1;

#pragma omp parallel for schedule(dynamic,1) private(i) \
reduction(^:exclusiv_bit_or)
for(i=0;i<LOOPCOUNT;++i) {
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
if(!exclusiv_bit_or) {
result++;
fprintf(stderr,"Error in EXCLUSIV BIT OR part 2\n");
}

/*printf("\nResult:%d\n",result);*/
return (result==0);
}

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_for_reduction()) {
num_failed++;
}
}
return num_failed;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_parallel_sections_firstprivate()
{
int sum;
int sum0;
int known_sum;

sum =7;
sum0=11;

#pragma omp parallel sections firstprivate(sum0)
{
#pragma omp section
{
#pragma omp critical
{
sum= sum+sum0;
}
}
#pragma omp section
{
#pragma omp critical
{
sum= sum+sum0;
}
}
#pragma omp section
{
#pragma omp critical
{
sum= sum+sum0;
}
}
}

known_sum=11*3+7;
return (known_sum==sum);
} /* end of check_section_firstprivate*/

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_sections_firstprivate()) {
num_failed++;
}
}
return num_failed;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_parallel_sections_lastprivate()
{
int sum;
int sum0;
int i;
int i0;
int known_sum;
sum =0;
sum0 = 0;
i0 = -1;

#pragma omp parallel sections private(i,sum0) lastprivate(i0)
{
#pragma omp section
{
sum0=0;
for (i=1;i<400;i++) {
sum0=sum0+i;
i0=i;
}
#pragma omp critical
{
sum= sum+sum0;
}
}
#pragma omp section
{
sum0=0;
for(i=400;i<700;i++) {
sum0=sum0+i;
i0=i;
}
#pragma omp critical
{
sum= sum+sum0;
}
}
#pragma omp section
{
sum0=0;
for(i=700;i<1000;i++) {
sum0=sum0+i;
i0=i;
}
#pragma omp critical
{
sum= sum+sum0;
}
}
}

known_sum=(999*1000)/2;
return ((known_sum==sum) && (i0==999) );
}

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_sections_lastprivate()) {
num_failed++;
}
}
return num_failed;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_parallel_sections_private()
{
int sum;
int sum0;
int i;
int known_sum;

sum = 7;
sum0=0;

#pragma omp parallel sections private(sum0, i)
{
#pragma omp section
{
sum0=0;
for (i=1;i<400;i++)
sum0=sum0+i;
#pragma omp critical
{
sum= sum+sum0;
}
}
#pragma omp section
{
sum0=0;
for(i=400;i<700;i++)
sum0=sum0+i;
#pragma omp critical
{
sum= sum+sum0;
}
}
#pragma omp section
{
sum0=0;
for(i=700;i<1000;i++)
sum0=sum0+i;
#pragma omp critical
{
sum= sum+sum0;
}
}
}

known_sum=(999*1000)/2+7;
return (known_sum==sum);
} /* end of check_section_private*/

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_parallel_sections_private()) {
num_failed++;
}
}
return num_failed;
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_section_firstprivate()
{
int sum;
int sum0;
int known_sum;

sum0 = 11;
sum = 7;
#pragma omp parallel
{
#pragma omp sections firstprivate(sum0)
{
#pragma omp section
{
#pragma omp critical
{
sum = sum + sum0;
}
}
#pragma omp section
{
#pragma omp critical
{
sum = sum + sum0;
}
}
#pragma omp section
{
#pragma omp critical
{
sum = sum + sum0;
}
}
}
}
known_sum = 11 * 3 + 7;
return (known_sum == sum);
} /* end of check_section_firstprivate*/

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_section_firstprivate()) {
num_failed++;
}
}
return num_failed;
}
76 changes: 76 additions & 0 deletions openmp/runtime/test/worksharing/sections/omp_section_lastprivate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_section_lastprivate()
{
int i0 = -1;
int sum = 0;
int i;
int sum0 = 0;
int known_sum;

i0 = -1;
sum = 0;

#pragma omp parallel
{
#pragma omp sections lastprivate(i0) private(i,sum0)
{
#pragma omp section
{
sum0 = 0;
for (i = 1; i < 400; i++)
{
sum0 = sum0 + i;
i0 = i;
}
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical*/
} /* end of section */
#pragma omp section
{
sum0 = 0;
for(i = 400; i < 700; i++)
{
sum0 = sum0 + i;
i0 = i;
}
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical*/
}
#pragma omp section
{
sum0 = 0;
for(i = 700; i < 1000; i++)
{
sum0 = sum0 + i;
i0 = i;
}
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical*/
} /* end of section */
} /* end of sections*/
} /* end of parallel*/
known_sum = (999 * 1000) / 2;
return ((known_sum == sum) && (i0 == 999) );
}

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_section_lastprivate()) {
num_failed++;
}
}
return num_failed;
}
66 changes: 66 additions & 0 deletions openmp/runtime/test/worksharing/sections/omp_section_private.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_section_private()
{
int sum;
int sum0;
int i;
int known_sum;

sum = 7;
sum0 = 0;

#pragma omp parallel
{
#pragma omp sections private(sum0,i)
{
#pragma omp section
{
sum0 = 0;
for (i = 1; i < 400; i++)
sum0 = sum0 + i;
#pragma omp critical
{
sum = sum + sum0;
}
}
#pragma omp section
{
sum0 = 0;
for (i = 400; i < 700; i++)
sum0 = sum0 + i;
#pragma omp critical
{
sum = sum + sum0;
}
}
#pragma omp section
{
sum0 = 0;
for (i = 700; i < 1000; i++)
sum0 = sum0 + i;
#pragma omp critical
{
sum = sum + sum0;
}
}
} /*end of sections*/
} /* end of parallel */
known_sum = (999 * 1000) / 2 + 7;
return (known_sum == sum);
} /* end of check_section_private*/

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_section_private()) {
num_failed++;
}
}
return num_failed;
}
69 changes: 69 additions & 0 deletions openmp/runtime/test/worksharing/sections/omp_sections_nowait.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"

int test_omp_sections_nowait()
{
int result;
int count;
int j;

result = 0;
count = 0;

#pragma omp parallel
{
int rank;
rank = omp_get_thread_num ();
#pragma omp sections nowait
{
#pragma omp section
{
fprintf(stderr, "Thread nr %d enters first section"
" and gets sleeping.\n", rank);
my_sleep(SLEEPTIME);
count = 1;
fprintf(stderr, "Thread nr %d woke up an set"
" count to 1.\n", rank);
#pragma omp flush(count)
}
#pragma omp section
{
fprintf(stderr, "Thread nr %d executed work in the"
" first section.\n", rank);
}
}
/* Begin of second sections environment */
#pragma omp sections
{
#pragma omp section
{
fprintf(stderr, "Thread nr %d executed work in the"
" second section.\n", rank);
}
#pragma omp section
{
fprintf(stderr, "Thread nr %d executed work in the"
" second section and controls the value of count\n", rank);
if (count == 0)
result = 1;
fprintf(stderr, "count was %d\n", count);
}
}
}
return result;
}

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_sections_nowait()) {
num_failed++;
}
}
return num_failed;
}
543 changes: 543 additions & 0 deletions openmp/runtime/test/worksharing/sections/omp_sections_reduction.c

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions openmp/runtime/test/worksharing/single/omp_single.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int test_omp_single()
{
int nr_threads_in_single;
int result;
int nr_iterations;
int i;

nr_threads_in_single = 0;
result = 0;
nr_iterations = 0;

#pragma omp parallel private(i)
{
for (i = 0; i < LOOPCOUNT; i++) {
#pragma omp single
{
#pragma omp flush
nr_threads_in_single++;
#pragma omp flush
nr_iterations++;
nr_threads_in_single--;
result = result + nr_threads_in_single;
}
}
}
return ((result == 0) && (nr_iterations == LOOPCOUNT));
} /* end of check_single*/

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_single()) {
num_failed++;
}
}
return num_failed;
}
60 changes: 60 additions & 0 deletions openmp/runtime/test/worksharing/single/omp_single_copyprivate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// RUN: %libomp-compile-and-run
#include "omp_testsuite.h"

#define DEBUG_TEST 0

int j;
#pragma omp threadprivate(j)

int test_omp_single_copyprivate()
{
int result;
int nr_iterations;

result = 0;
nr_iterations = 0;
#pragma omp parallel
{
int i;
for (i = 0; i < LOOPCOUNT; i++)
{
#if DEBUG_TEST
int thread;
thread = omp_get_thread_num ();
#endif
#pragma omp single copyprivate(j)
{
nr_iterations++;
j = i;
#if DEBUG_TEST
printf ("thread %d assigns, j = %d, i = %d\n", thread, j, i);
#endif
}
#if DEBUG_TEST
#pragma omp barrier
#endif
#pragma omp critical
{
#if DEBUG_TEST
printf ("thread = %d, j = %d, i = %d\n", thread, j, i);
#endif
result = result + j - i;
}
#pragma omp barrier
} /* end of for */
} /* end of parallel */
return ((result == 0) && (nr_iterations == LOOPCOUNT));
}

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_single_copyprivate()) {
num_failed++;
}
}
return num_failed;
}
57 changes: 57 additions & 0 deletions openmp/runtime/test/worksharing/single/omp_single_nowait.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int my_iterations;
#pragma omp threadprivate(my_iterations)

int test_omp_single_nowait()
{
int nr_iterations;
int total_iterations = 0;
int i;

nr_iterations = 0;
my_iterations = 0;

#pragma omp parallel private(i)
{
for (i = 0; i < LOOPCOUNT; i++) {
#pragma omp single nowait
{
#pragma omp atomic
nr_iterations++;
}
}
}

#pragma omp parallel private(i)
{
my_iterations = 0;
for (i = 0; i < LOOPCOUNT; i++) {
#pragma omp single nowait
{
my_iterations++;
}
}
#pragma omp critical
{
total_iterations += my_iterations;
}

}
return ((nr_iterations == LOOPCOUNT) && (total_iterations == LOOPCOUNT));
} /* end of check_single_nowait*/

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_single_nowait()) {
num_failed++;
}
}
return num_failed;
}
57 changes: 57 additions & 0 deletions openmp/runtime/test/worksharing/single/omp_single_private.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#include "omp_testsuite.h"

int myit = 0;
#pragma omp threadprivate(myit)
int myresult = 0;
#pragma omp threadprivate(myresult)

int test_omp_single_private()
{
int nr_threads_in_single;
int result;
int nr_iterations;
int i;

myit = 0;
nr_threads_in_single = 0;
nr_iterations = 0;
result = 0;

#pragma omp parallel private(i)
{
myresult = 0;
myit = 0;
for (i = 0; i < LOOPCOUNT; i++) {
#pragma omp single private(nr_threads_in_single) nowait
{
nr_threads_in_single = 0;
#pragma omp flush
nr_threads_in_single++;
#pragma omp flush
myit++;
myresult = myresult + nr_threads_in_single;
}
}
#pragma omp critical
{
result += nr_threads_in_single;
nr_iterations += myit;
}
}
return ((result == 0) && (nr_iterations == LOOPCOUNT));
} /* end of check_single private */

int main()
{
int i;
int num_failed=0;

for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_single_private()) {
num_failed++;
}
}
return num_failed;
}