Add testsuite from OpenUH

llvm-svn: 208472
This commit is contained in:
Jim Cownie
2014-05-10 17:02:09 +00:00
parent 281f9d0e97
commit 18d8473f18
151 changed files with 14672 additions and 8 deletions

View File

@@ -8,10 +8,33 @@ beautification by scripts. The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
(S).
N: Sunita Chandrasekaran
D: Contributor to testsuite from OpenUH
N: Barbara Chapman
D: Contributor to testsuite from OpenUH
N: University of Houston
W: http://web.cs.uh.edu/~openuh/download/
D: OpenUH test suite
N: Intel Corporation OpenMP runtime team
W: http://openmprtl.org
D: Created the runtime.
N: Matthias Muller
D: Contributor to testsuite from OpenUH
N: Pavel Neytchev
D: Contributor to testsuite from OpenUH
N: Steven Noonan
E: steven@uplinklabs.net
D: Patches for the ARM architecture and several inconsistency removal.
D: Patches for the ARM architecture and removal of several inconsistencies.
N: Alp Toker
E: alp@nuanti.com
D: Making build work for FreeBSD.
N: Cheng Wang
D: Contributor to testsuite from OpenUH

34
openmp/testsuite/LICENSE Normal file
View File

@@ -0,0 +1,34 @@
Copyright (c) 2011, 2012
University of Houston System
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
o Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
o Neither the name of the University of Houston System nor the names of its
contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

222
openmp/testsuite/Makefile Normal file
View File

@@ -0,0 +1,222 @@
# General Makefile containing all the necessary compiler flags for the tests
# modify CC and CFLAGS for OpenMP C compilers
# modify FC and FFLAGS for OpenMP Fortran compilers
# Content:
#########################################################
# 1. Basic usage
# 2. General testsuite settings
# 3. Compiler selection and Flags
#########################################################
#########################################################
# 1. Basic usage
#########################################################
# make ctest generate c test "ctest"
# make ftest generate fortran test "ftest"
# make clean removes all sources and binaries
# make cleanall removes sources,binaries and logfiles
#########################################################
# 2. General testsuite settings
#########################################################
# For general testsuite settings see the configuration file
# ompts.conf
#########################################################
# 3. Compiler selection and Flags
#########################################################
# GNU Compiler
CC = gcc
CFLAGS = -fopenmp -lm -O3
CFLAGS = -fopenmp -lm -O3
FC = gfortran
FFLAGS = -fopenmp -lm
FFLAGS = -fopenmp -lm -O3
# Fujitsu Compilers:
#CC = fcc
#CFLAGS = -KOMP,fast_GP2=2
#FC=frt
#FFLAGS=-KOMP,fast_GP2=2 -w -Am -X9 -Fixed
# PGI compilers
#CC = pgcc
#CFLAGS = -mp
#CFLAGS = -mp -DVERBOSE
#CFLAGS = -fast -mp
#FC = pgf90
#FFLAGS = -fast -mp
#FFLAGS = -mp -g
# Intel compilers:
#CC = icc
#CFLAGS = -O3 -ip -openmp
#CFLAGS = -Wall -O0 -openmp
#CFLAGS = -openmp -lm
#CFLAGS = -openmp -lm -DVERBOSE
#FC = ifort
#FFLAGS = -openmp -lm -fpp
# Omni compilers:
#CC = ompcc
#CFLAGS = -O3 -lm
# Assure compilers:
#CC = assurec
#CFLAGS = -O3 -WApname=project -DUSE_ASSURE=1
#FC =
#FFLAGS =
# NEC:
#CC = c++
#CC = sxc++
#CFLAGS = -Popenmp
#FC=sxf90
#FFLAGS= -Popenmp
# Hitachi:
#CC = xcc
#CFLAGS = -O4 -pvec +Op -parallel -omp
#FC =
#FFLAGS =
# SGI:
#CC = cc
#CFLAGS = -mp -lm
#FC =
#FFLAGS =
# IBM compilers:
#CC = xlc_r
#CFLAGS = -qsmp=omp -lm
#FC=xlf90_r
#FFLAGS=-qsmp=omp -qfixed=132 -qlanglvl=extended
# SUN compilers
#CC = cc
#CFLAGS = -fast -xopenmp -lm
#FC =f90
#FFLAGS = -xopenmp -fast -lm
# open64 compilers
# remark: -I. was a workaround because the installation came without omp.h file
#CC = opencc
#CFLAGS = -O0 -openmp -lm -I. -lomp -lpthread
#CFLAGS = -O0 -openmp -lm -I /home/matthew/opt/usr/include -lpthread
#CFLAGS = -openmp -lm
#FC = openf90
#FFLAGS = -O0 -openmp -lm -lomp -lpthread
#Pathscale Compiler
#CC = pathcc
#CFLAGS = -mp -Ofast -lm
#FC=pathf90
#FFLAGS= -mp -Ofast -lm
#OpenUH Compiler
#CC = uhcc
#CFLAGS = -mp
#FC = uhf90
#FFLAGS = -mp
#########################################################################
help:
@echo "OpenMP Validation Suite, v3.0"
@echo "(C) University of Stuttgart, University of Houston"
@echo ""
@echo "Do make [rule], where rule may be one of:"
@echo " ctest"
@echo " Build and run the OpenMP/C validation tests."
@echo " ftest"
@echo " Build and run the OpenMP/Fortran validation tests."
@echo " print_compile_options"
@echo " Display the default compiler and compiler options being tested"
@echo " cleansrcs"
@echo " Remove sources generated from the templates"
@echo " cleanbins"
@echo " Remove executables from bin/ directory"
@echo " cleanouts"
@echo " Remove all *.out files from bin/ directory"
@echo " cleanlogs"
@echo " Remove all *.log files from bin/ directory"
@echo " clean"
@echo " Remove all sources and executables from bin/ directory"
@echo " cleanall"
@echo " Remove the entire bin/ directory"
omp_my_sleep:
mkdir -p bin/c
cp omp_my_sleep.h bin/c/
omp_testsuite: omp_testsuite.h
mkdir -p bin/c
cp omp_testsuite.h bin/c/
omp_testsuite.h: ompts-c.conf c/*
./ompts_makeHeader.pl -f=ompts-c.conf -t=c
.c.o: omp_testsuite omp_my_sleep
$(CC) $(CFLAGS) -c $<
ctest: omp_my_sleep omp_testsuite
./runtest.pl --lang=c testlist-c.txt
ftest:
mkdir -p bin/fortran
cp omp_testsuite.f bin/fortran
cp omp_my_sleep.f bin/fortran
./runtest.pl --lang=fortran testlist-f.txt
print_compile_options:
@echo "-------------------"
@echo "C compiler"
@echo "-------------------"
@echo "compilation: $(CC) $(CFLAGS)"
@$(CC) --version
@echo "-------------------"
@echo "Fortran compiler"
@echo "-------------------"
@echo "compilation: $(FC) $(FFLAGS)"
@$(FC) --version
cleansrcs:
find bin/ -iname "*.[cf]" -exec rm {} \;
cleanbins:
find bin/ -perm /a+x -type f -exec rm {} \;
cleanouts:
find bin/ -iname "*.out" -exec rm {} \;
cleanlogs:
find bin/ -iname "*.log" -exec rm {} \;
clean: cleansrcs cleanbins
cleanall:
rm -rf bin/

334
openmp/testsuite/README Normal file
View File

@@ -0,0 +1,334 @@
============================================================================
| OpenMP Validation Suite V 3.0 |
| High Performance Computing Center, Stuttgart |
| High Performance Computing and Tools, University of Houston |
| Jan. 2012 |
============================================================================
TABLE OF CONTENTS
I INTRODUCTION
I.1. Aims and general function
I.2. Files and directories
II USAGE
II.1. First run with make
II.2 Where to search for results
II.3. Using the runtest script
III Adding and modifying tests
III.1. The template structure
IV Known Issues and Workaround
V Contact and Support
------------------------------------------------------------------------------
I. INTRODUCTION
==============================================================================
I.1. Aims and general function
--------------------------------
The OpenMP validation suite is designed to verify the correct implementation
of OpenMP in compilers. It is capable of checking Fortran as well as c
compiler.
Testing the implementation is based on statistics. Each directive is tested
by computing and verifying the result with the already known value. In most
cases a wrong implementation can result in the right values. So the tests are
run several times.
Additionally, the validation suite creates so called crosstests for each
directive. These are tests in which either the directive is missing or used
with different arguments. If this so called crosstest fails, this indicates
strongly that the previous test is capable of testing the directive.
Lastly, an orphaned test is also run to determine if the directive being
tested is able to correctly run when 'orphaned' from the main function.
Essentially, the directive's code is placed into its own function which is
called during execution of the main function and often inside a parallel
region.
I.2. Files and directories
----------------------------
d c directory containing the templates for the c tests
d fortran directory containing the templates for the Fortran
tests
Makefile Makefile containing options for compilation
common_utility.f
omp_my_sleep.h thread save sleep function
omp_testsuite.f Fortran header file
omp_testsuite.h autogenerated c-header file
ompts-c.conf configuration file for the c tests about how often
the tests shall be executed or how large the loop size
is
ompts_makeHeader.pl perl module for automatically generation of an up
to date header file
ompts_parserFunctions.pm perl module containing general functions for
the parser.pl script
ompts_parser.pl script for generating the source code out of the templates
ompts_standaloneProc.c framework for the c tests
ompts_standaloneProc.f framework for the Fortran tests
README the README file you've already found ;-)
LICENSE contains license information
runtest.pl the frame program of the test suite
testlist-f.txt test list containing the available tests for Fortran
testlist-c.txt test list containing the available tests for c
------------------------------------------------------------------------------
II. USAGE
==============================================================================
II.1. First run with make
--------------------------
You can do a first simple run of the testsuite only after one step of
configuration:
1) Modify the ompts.conf and ompts-c.conf file, change the number of threads
and number of repetitions of each test.
2) Modify the Makefile, uncommenting the CC/FC and CFLAGS/FFLAGS variables for
the compiler of your choice.
And now you can run the testsuite either for a C compiler with:
> make ctest
or for a Fortran compiler with:
> make ftest
II.2. Running custom tests
--------------------------
In order to run single tests or custom groups of tests, two make commmands
are defined: make stest and make fstest. These two command reference the file
customtest.txt when looking for a testlist to use. Simply edit customtest.txt
to include the desired test or tests. If customtest.txt contains c tests,
> make stest
or for fortran tests
> make fstest
In order to change the number of threads used in the tests, simply edit the
Makefile variables MINTHREADS and MAXTHREADS. By default, they are configured
to use 2 threads. To change the number of times each test is run, for c tests
edit the REPETITIONS variable in the file ompts-c.conf. The LOOPCOUNT and
SLEEPTIME variables can also be changed here. For fortran tests, edit the file
omp_testsuite.f to change both the LOOPCOUNT and the number of times each test
is run.
II.3. Understanding the results
---------------------------------
When running the testsuite the results will be shown on the screen.
If you need the results for further purpose you can use the results.txt, which
is a simple list containing the results for each directive
in a single line. Each line starts with the name of the directive. Then follows
the result of the test given in the percentage of the passed tests. If 100% of
the tests passed successfully, the second number gives the result of the
corresponding crosstest. Crosstests will only be run if the normal test passes
with 100% accuracy. If a crosstest was not run or a test does not exist, it is
denotated by a "-".
After the results of the normal tests, there follow a series of tests in the
orphaned mode. If there were no orphaned tests available this is shown by a "-".
If you run the testsuite with different numbers of threads (e.g. using the
runtest.pl script) the results are shown in blocks of 4 columns for each number
of threads.
If a test fails you can find more detailed information in the ompts.log,
bin/c/*.out and *.log files. While the ompts.log file contains all compiler
error messages for all tests, the *.out and *.log files contain detailed inforamtion
on the execution process of the single tests.
In the *.out files there are listed all the results of the single executions of
the tests. In the *.log files there are error messages of the tests itself.
II.4. Cleaning Up
-----------------
Because many files are generated for each tested directive, it is often necessary
to clean the main directory after a battery of tests. To clean all generated files
in the main directory including the results and log files,
> make clean
To clean only the logs and out files,
> make cleanlogs
To clean only the results,
> make cleanresults
II.4. Using the runtest script
-------------------------------
So for special purpose you can use the runtest.pl script, which allows a lot
more options for the execution process than the execution with make.
Using the runtest.pl script is rather easy. You can use the the test suite only
after two steps of modifications:
1.) Modify the Makefile to your wishes choosing your compiler and the necessary
compiler flags.
2.) If necessary edit one of the test lists (testlist-c.txt) and comment out the
tests you do not want to run using # at the beginning of a line. Testlists for Fortran end
with -f.txt while test lists for c with -c.txt.
And now you can run the test suite either for Fortran using
# > ./runtest.pl -lang=fortran -d=fortran testlist-f.txt
or for c
# > ./runtest.pl -lang=c -d=c testlist-c.txt
With the --help option you can show the complete list of options and their
explanations.
The test results are summarized in cresults or fresults.txt while *.log keep
details for individual tests. There is also a file (ompts.log) keeping
compilation information. (see section II.2 )
If you don't want to test the directives in orphaned mode you can use the
-norphan option. You also can use the runtest.pl script either to compile all
tests or run compiled tests e.g. for cross compilation on other platforms. For
this there are the options -norun and -nocompile.
Happy testing!
------------------------------------------------------------------------------
III. How to add new tests / The structure of test templates
==============================================================================
III.1 The template structure
------------------------------
The test suite is based on templates so that you only have one file for test,
crosstest and the orphaned versions of them.
A) Description of the template structure
The syntax of the templates is much like xml. So each test begins with
'<ompts:test>' and ends with '</ompts:test>'.
In between there are several other blocks holding information:
- <ompts:testdescription> </ompts:testdescription> In between this tag you can
give a description on what the test checks and how it works.
- <ompts:ompversion> </ompts:version> This tag is used to specify the
OpenMP-version which includes the tested directive.
- <ompts:directive> </ompts:directive> Used to specify the directive how it is
called in the programming language.
- <ompts:dependences> </ompts:dependences> With this tag you can specify other
omp directives which are necessary for the correct execution of your test.
The directives have to be listed by their directive names as it is called in
the programming language. Multiple directives are separated by ','.
- <ompts:testcode> </ompts:testcode> In this tag stands the whole source code
for the test / crosstest. Each test has to be written as a function. The
syntax of the functions differs between C and Fortran: In C it has to take a
file pointer 'FILE * logFile' and return an int. If the test has been passed
successful it has to return a value unequal to 0. The file pointer can be used
to write information into a log file. In Fortran the function takes no
argument and the function name must not exceed XX characters. The return value
has to be specified using the '<testfunctionname>' tags. It has to be 1 if the
test succeeded and 0 if the test failed. For details see the example.
To tell the test suite the name of your test function you have to enclose it
into the '<ompts:testcode:functionname> </ompts:testcode:functionname>' tag.
If there are differences between test and crosstest you can use the
<ompts:check> </ompts:check> and <ompts:crosscheck> </ompts:crosscheck> tag.
When generating the test the parser will use the code enclosed in
<ompts:check> tags and cut out the code written in <ompts:crosscheck> tags. So
you have two possibilities to write your template for test and crosstest: The
first way you can write the complete code is to write the test in one
<ompts:check> tag and later the crosstest in one <ompts:crosscheck> tag. The
second way is to write both tests only by enclosing differing parts in
corresponding tags.
The first method should be preferred if test and crosstest differ much from
each other. The second e.g. if you only want to change a few options like
replacing an omp singleprivate clause by an omp private clause or to cut out
a directive like omp flush. When you use the first way you have to take care
of the function name! You have to declare it twice with
<ompts:testcode:functionname>!
- <ompts:orphan> </ompts:orphan> This tag can be used if you want to enable
your test to check the directive in orphan regions, too. The code enclosed
in this part will be written to a separate function which will be called
instead. If you have variables which are used outside this region you have to
declare them as global variables enclosed in an <ompts:orphan:vars> tag. For
further information see the description of the <ompts:orphan:vars> tag.
- <ompts:orphan:vars> </ompts:orphan:vars> This tag is used to specify global
variables for an orphan region which allow the exchange of values between
the main program and the orphaned functions. The usage differs between C and
Fortran. In C you have to use a single declaration for each variable. You can
either declare all variables in one single or in several different regions. You
must not initialize the variables inside! In Fortran you have to put all
declarations in one single tag. Because there exist no global variables as in
C you have to use common blocks. For further information see the examples.
III.2. Adding tests to the test lists
--------------------------------------
After you have created a new test you have to add them to a testlist. Simply
add the function name in a new Line into a file.
------------------------------------------------------------------------------
IV. Known Issues and Workaround
==============================================================================
The Sun OS has a problem with the -maxdepth option on the 'make cleanall'
command. This prevents the tests from being removed from the working directory
and can cause problems with future tests. To remedy, edit the makefile line
under the clean command:
-rm [cf]test*.[cf] [cf]crosstest*.[cf] [cf]ctest*.[cf] [cf]orphan*.[cf]
Change to:
-rm [cf]test* [cf]crosstest* [cf]ctest* [cf]orphan*
------------------------------------------------------------------------------
V. Contact and Support
==============================================================================
Contact: http://www.cs.uh.edu/~hpctools

View File

@@ -0,0 +1,30 @@
<ompts:test>
<ompts:testdescription>Test which checks the OpenMp support.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>_OPENMP</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>has_openmp</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int rvalue = 0;
</ompts:orphan:vars>
<ompts:orphan>
<ompts:check>
#ifdef _OPENMP
rvalue = 1;
#endif
</ompts:check>
<ompts:crosscheck>
#if 0
rvalue = 1;
#endif
</ompts:crosscheck>
</ompts:orphan>
return (rvalue);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,434 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp atomic directive by counting up a variable in a parallelized loop with an atomic directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp atomic</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_atomic</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int sum;
int diff;
double dsum = 0;
double dt = 0.5; /* base of geometric row for + and - test*/
double ddiff;
int product;
int x;
int *logics;
int bit_and = 1;
int bit_or = 0;
int exclusiv_bit_or = 0;
</ompts:orphan:vars>
#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
#define MAX_FACTOR 10
#define KNOWN_PRODUCT 3628800 /* 10! */
int j;
int known_sum;
int known_diff;
int known_product;
int result = 0;
int logic_and = 1;
int logic_or = 0;
double dknown_sum;
double rounding_error = 1.E-9;
double dpt, div;
int logicsArray[LOOPCOUNT];
logics = logicsArray;
sum = 0;
diff = 0;
product = 1;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 1; i <= LOOPCOUNT; i++)
{
<ompts:check>#pragma omp atomic</ompts:check>
sum += i;
}
</ompts:orphan>
}
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
if (known_sum != sum)
{
fprintf (logFile,
"Error in sum with integers: Result was %d instead of %d.\n",
sum, known_sum);
result++;
}
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; i++)
{
<ompts:check>#pragma omp atomic</ompts:check>
diff -= i;
}
</ompts:orphan>
}
known_diff = ((LOOPCOUNT - 1) * LOOPCOUNT) / 2 * -1;
if (diff != known_diff)
{
fprintf (logFile,
"Error in difference with integers: Result was %d instead of 0.\n",
diff);
result++;
}
/* Tests for doubles */
dsum = 0;
dpt = 1;
for (j = 0; j < DOUBLE_DIGITS; ++j)
{
dpt *= dt;
}
dknown_sum = (1 - dpt) / (1 -dt);
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < DOUBLE_DIGITS; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
dsum += pow (dt, i);
}
</ompts:orphan>
}
if (dsum != dknown_sum && (fabs (dsum - dknown_sum) > rounding_error))
{
fprintf (logFile,
"Error in sum with doubles: Result was %f instead of: %f (Difference: %E)\n",
dsum, dknown_sum, dsum - dknown_sum);
result++;
}
dpt = 1;
for (j = 0; j < DOUBLE_DIGITS; ++j)
{
dpt *= dt;
}
ddiff = (1 - dpt) / (1 - dt);
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < DOUBLE_DIGITS; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
ddiff -= pow (dt, i);
}
</ompts:orphan>
}
if (fabs (ddiff) > rounding_error)
{
fprintf (logFile,
"Error in difference with doubles: Result was %E instead of 0.0\n",
ddiff);
result++;
}
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 1; i <= MAX_FACTOR; i++)
{
<ompts:check>#pragma omp atomic</ompts:check>
product *= i;
}
</ompts:orphan>
}
known_product = KNOWN_PRODUCT;
if (known_product != product)
{
fprintf (logFile,
"Error in product with integers: Result was %d instead of %d\n",
product, known_product);
result++;
}
product = KNOWN_PRODUCT;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 1; i <= MAX_FACTOR; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
product /= i;
}
</ompts:orphan>
}
if (product != 1)
{
fprintf (logFile,
"Error in product division with integers: Result was %d instead of 1\n",
product);
result++;
}
div = 5.0E+5;
#pragma omp parallel
{
int i;
#pragma omp for
for (i = 1; i <= MAX_FACTOR; i++)
{
<ompts:check>#pragma omp atomic</ompts:check>
div /= i;
}
}
if (fabs(div-0.137787) >= 1.0E-4 )
{
result++;
fprintf (logFile,
"Error in division with double: Result was %f instead of 0.137787\n", div);
}
x = 0;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
x++;
}
</ompts:orphan>
}
if (x != LOOPCOUNT)
{
result++;
fprintf (logFile, "Error in ++\n");
}
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
x--;
}
</ompts:orphan>
}
if (x != 0)
{
result++;
fprintf (logFile, "Error in --\n");
}
for (j = 0; j < LOOPCOUNT; ++j)
{
logics[j] = 1;
}
bit_and = 1;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
bit_and &= logics[i];
}
</ompts:orphan>
}
if (!bit_and)
{
result++;
fprintf (logFile, "Error in BIT AND part 1\n");
}
bit_and = 1;
logics[LOOPCOUNT / 2] = 0;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
bit_and &= logics[i];
}
</ompts:orphan>
}
if (bit_and)
{
result++;
fprintf (logFile, "Error in BIT AND part 2\n");
}
for (j = 0; j < LOOPCOUNT; j++)
{
logics[j] = 0;
}
bit_or = 0;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
bit_or |= logics[i];
}
</ompts:orphan>
}
if (bit_or)
{
result++;
fprintf (logFile, "Error in BIT OR part 1\n");
}
bit_or = 0;
logics[LOOPCOUNT / 2] = 1;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
bit_or |= logics[i];
}
</ompts:orphan>
}
if (!bit_or)
{
result++;
fprintf (logFile, "Error in BIT OR part 2\n");
}
for (j = 0; j < LOOPCOUNT; j++)
{
logics[j] = 0;
}
exclusiv_bit_or = 0;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
exclusiv_bit_or ^= logics[i];
}
</ompts:orphan>
}
if (exclusiv_bit_or)
{
result++;
fprintf (logFile, "Error in EXCLUSIV BIT OR part 1\n");
}
exclusiv_bit_or = 0;
logics[LOOPCOUNT / 2] = 1;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < LOOPCOUNT; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
exclusiv_bit_or ^= logics[i];
}
</ompts:orphan>
}
if (!exclusiv_bit_or)
{
result++;
fprintf (logFile, "Error in EXCLUSIV BIT OR part 2\n");
}
x = 1;
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < 10; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
x <<= 1;
}
</ompts:orphan>
}
if ( x != 1024)
{
result++;
fprintf (logFile, "Error in <<\n");
x = 1024;
}
#pragma omp parallel
{
<ompts:orphan>
int i;
#pragma omp for
for (i = 0; i < 10; ++i)
{
<ompts:check>#pragma omp atomic</ompts:check>
x >>= 1;
}
</ompts:orphan>
}
if (x != 1)
{
result++;
fprintf (logFile, "Error in >>\n");
}
return (result == 0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,41 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp barrier directive. The test creates several threads and sends one of them sleeping before setting a flag. After the barrier the other ones do some littel work depending on the flag.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp barrier</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_barrier</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int result1;
int result2;
</ompts:orphan:vars>
result1 = 0;
result2 = 0;
#pragma omp parallel
{
<ompts:orphan>
int rank;
rank = omp_get_thread_num ();
if (rank ==1) {
my_sleep(SLEEPTIME_LONG);
result2 = 3;
}
<ompts:check>#pragma omp barrier</ompts:check>
if (rank == 2) {
result1 = result2;
}
</ompts:orphan>
}
printf("result1=%d\n",result1);
return (result1 == 3);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,42 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp critical directive by counting up a variable in a parallelized loop within a critical section.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp critical</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_critical</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int sum;
</ompts:orphan:vars>
sum=0;
int known_sum;
<ompts:orphan>
#pragma omp parallel
{
int mysum=0;
int i;
#pragma omp for
for (i = 0; i < 1000; i++)
mysum = mysum + i;
<ompts:check>#pragma omp critical</ompts:check>
sum = mysum +sum;
} /* end of parallel */
</ompts:orphan>
printf("sum=%d\n",sum);
known_sum = 999 * 1000 / 2;
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,50 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp flush directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp flush</ompts:directive>
<ompts:dependences>omp barrier</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_flush</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int result1;
int result2;
int dummy;
</ompts:orphan:vars>
result1 = 0;
result2 = 0;
#pragma omp parallel
{
int rank;
rank = omp_get_thread_num ();
#pragma omp barrier
if (rank == 1) {
result2 = 3;
<ompts:orphan>
<ompts:check>#pragma omp flush (result2)</ompts:check>
dummy = result2;
</ompts:orphan>
}
if (rank == 0) {
<ompts:check>my_sleep(SLEEPTIME_LONG);</ompts:check>
<ompts:orphan>
<ompts:check>#pragma omp flush (result2)</ompts:check>
result1 = result2;
</ompts:orphan>
}
} /* end of parallel */
return ((result1 == result2) && (result2 == dummy) && (result2 == 3));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,56 @@
<ompts:test>
<ompts:testdescription>Test with omp for collapse clause. Bind with two loops. Without the collapse clause, the first loop will not be ordered</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp for collapse</ompts:directive>
<ompts:dependences>omp critical,omp for schedule</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
/* Utility function to check that i is increasing monotonically
with each call */
static int check_i_islarger (int i)
{
static int last_i;
int islarger;
if (i==1)
last_i=0;
islarger = ((i >= last_i)&&(i - last_i<=1));
last_i = i;
return (islarger);
}
int <ompts:testcode:functionname>omp_for_collapse</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int is_larger = 1;
</ompts:orphan:vars>
#pragma omp parallel
{
<ompts:orphan>
int i,j;
int my_islarger = 1;
#pragma omp for private(i,j) schedule(static,1) <ompts:check>collapse(2)</ompts:check> ordered
for (i = 1; i < 100; i++){
<ompts:crosscheck>my_islarger = check_i_islarger(i)&& my_islarger;</ompts:crosscheck>
for (j =1; j <100; j++)
{
<ompts:check>
#pragma omp ordered
my_islarger = check_i_islarger(i)&&my_islarger;
</ompts:check>
} /* end of for */
}
#pragma omp critical
is_larger = is_larger && my_islarger;
</ompts:orphan>
}
return (is_larger);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,55 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp for firstprivate clause by counting up a variable in a parallelized loop. Each thread has a firstprivate variable (1) and an variable (2) declared by for firstprivate. First it stores the result of its last iteration in variable (2). Then it stores the value of the variable (2) in its firstprivate variable (1). At the end all firstprivate variables (1) are added to a total sum in a critical section and compared with the correct result.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp for firstprivate</ompts:directive>
<ompts:dependences>omp critical,omp parallel firstprivate</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int sum1;
#pragma omp threadprivate(sum1)
int <ompts:testcode:functionname>omp_for_firstprivate</ompts:testcode:functionname> (FILE * logFile)
{
int sum;
<ompts:orphan:vars>
int sum0;
</ompts:orphan:vars>
int known_sum;
int threadsnum;
sum = 0;
sum0 = 12345;
sum1 = 0;
#pragma omp parallel
{
#pragma omp single
{
threadsnum=omp_get_num_threads();
}
/* sum0 = 0; */
<ompts:orphan>
int i;
#pragma omp for <ompts:check>firstprivate(sum0)</ompts:check><ompts:crosscheck>private(sum0)</ompts:crosscheck>
for (i = 1; i <= LOOPCOUNT; i++)
{
sum0 = sum0 + i;
sum1 = sum0;
} /* end of for */
</ompts:orphan>
#pragma omp critical
{
sum = sum + sum1;
} /* end of critical */
} /* end of parallel */
known_sum = 12345* threadsnum+ (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,52 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp for lastprivate clause by counting up a variable in a parallelized loop. Each thread saves the next summand in a lastprivate variable i0. At the end i0 is compared to the value of the expected last summand.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp for lastprivate</ompts:directive>
<ompts:dependences>omp critical,omp parallel firstprivate,omp schedule</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int sum0;
#pragma omp threadprivate(sum0)
int <ompts:testcode:functionname>omp_for_lastprivate</ompts:testcode:functionname> (FILE * logFile)
{
int sum = 0;
int known_sum;
<ompts:orphan:vars>
int i0;
</ompts:orphan:vars>
i0 = -1;
#pragma omp parallel
{
sum0 = 0;
{ /* Begin of orphaned block */
<ompts:orphan>
int i;
#pragma omp for schedule(static,7) <ompts:check>lastprivate(i0)</ompts:check>
for (i = 1; i <= LOOPCOUNT; i++)
{
sum0 = sum0 + i;
i0 = i;
} /* end of for */
</ompts:orphan>
} /* end of orphaned block */
#pragma omp critical
{
sum = sum + sum0;
} /* end of critical */
} /* end of parallel */
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
fprintf(logFile," known_sum = %d , sum = %d \n",known_sum,sum);
fprintf(logFile," LOOPCOUNT = %d , i0 = %d \n",LOOPCOUNT,i0);
return ((known_sum == sum) && (i0 == LOOPCOUNT) );
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,57 @@
<ompts:test>
<ompts:description>Test which checks the omp parallel for nowait directive. It fills an array with values and operates on these in the following.</ompts:description>
<ompts:directive>omp parallel for nowait</ompts:directive>
<ompts:version>1.0</ompts:version>
<ompts:dependences>omp parallel for, omp flush</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_for_nowait</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int result;
int count;
</ompts:orphan:vars>
int j;
int myarray[LOOPCOUNT];
result = 0;
count = 0;
#pragma omp parallel
{
<ompts:orphan>
int rank;
int i;
rank = omp_get_thread_num();
#pragma omp for <ompts:check>nowait</ompts:check>
for (i = 0; i < LOOPCOUNT; i++) {
if (i == 0) {
fprintf (logFile, "Thread nr %d entering for loop and going to sleep.\n", rank);
my_sleep(SLEEPTIME);
count = 1;
#pragma omp flush(count)
fprintf (logFile, "Thread nr %d woke up and set count = 1.\n", rank);
}
}
fprintf (logFile, "Thread nr %d exited first for loop and enters the second.\n", rank);
#pragma omp for
for (i = 0; i < LOOPCOUNT; i++)
{
#pragma omp flush(count)
if (count == 0)
result = 1;
}
</ompts:orphan>
}
return result;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,60 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp ordered directive by counting up an variable in an parallelized loop and watching each iteration if the sumand is larger as the last one.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp for ordered</ompts:directive>
<ompts:dependences>omp critical,omp for schedule</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
static int last_i = 0;
/* Utility function to check that i is increasing monotonically
with each call */
static int check_i_islarger (int i)
{
int islarger;
islarger = (i > last_i);
last_i = i;
return (islarger);
}
int <ompts:testcode:functionname>omp_for_ordered</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int sum;
int is_larger = 1;
</ompts:orphan:vars>
int known_sum;
last_i = 0;
sum = 0;
#pragma omp parallel
{
<ompts:orphan>
int i;
int my_islarger = 1;
#pragma omp for schedule(static,1) ordered
for (i = 1; i < 100; i++)
{
<ompts:check>#pragma omp ordered</ompts:check>
{
my_islarger = check_i_islarger(i) && my_islarger;
sum = sum + i;
} /* end of ordered */
} /* end of for */
#pragma omp critical
{
is_larger = is_larger && my_islarger;
} /* end of critical */
</ompts:orphan>
}
known_sum=(99 * 100) / 2;
return ((known_sum == sum) && is_larger);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,64 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp for private clause by counting up a variable in a parallelized loop. Each thread has a private variable (1) and a variable (2) declared by for private. First it stores the result of its last iteration in variable (2). Then this thread waits some time before it stores the value of the variable (2) in its private variable (1). At the beginning of the next iteration the value of (1) is assigned to (2). At the end all private variables (1) are added to a total sum in a critical section and compared with the correct result.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp for private</ompts:directive>
<ompts:dependences>omp parallel,omp flush,omp critical,omp threadprivate</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
/* Utility function do spend some time in a loop */
static void do_some_work (){
int i;
double sum = 0;
for(i = 0; i < 1000; i++){
sum += sqrt ((double) i);
}
}
int sum1;
#pragma omp threadprivate(sum1)
int <ompts:testcode:functionname>omp_for_private</ompts:testcode:functionname> (FILE * logFile)
{
int sum = 0;
<ompts:orphan:vars>
int sum0;
</ompts:orphan:vars>
int known_sum;
sum0 = 0; /* setting (global) sum0 = 0 */
#pragma omp parallel
{
sum1 = 0; /* setting sum1 in each thread to 0 */
{ /* begin of orphaned block */
<ompts:orphan>
int i;
#pragma omp for <ompts:check>private(sum0)</ompts:check> schedule(static,1)
for (i = 1; i <= LOOPCOUNT; i++)
{
sum0 = sum1;
#pragma omp flush
sum0 = sum0 + i;
do_some_work ();
#pragma omp flush
sum1 = sum0;
} /* end of for */
</ompts:orphan>
} /* end of orphaned block */
#pragma omp critical
{
sum = sum + sum1;
} /*end of critical*/
} /* end of parallel*/
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,429 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp for reduction directive wich all its options.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp for reduction</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_for_reduction</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
double dt;
int sum;
int diff;
int product = 1;
double dsum;
double dknown_sum;
double ddiff;
int logic_and;
int logic_or;
int bit_and;
int bit_or;
int exclusiv_bit_or;
int *logics;
</ompts:orphan:vars>
#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
#define MAX_FACTOR 10
#define KNOWN_PRODUCT 3628800 /* 10! */
int i;
int known_sum;
int known_product;
double rounding_error = 1.E-9; /* over all rounding error to be ignored in the double tests */
double dpt;
int result = 0;
int logicsArray[LOOPCOUNT];
/* Variables for integer tests */
sum = 0;
product = 1;
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
/* variabels for double tests */
dt = 1. / 3.; /* base of geometric row for + and - test*/
dsum = 0.;
/* Variabeles for logic tests */
logics = logicsArray;
logic_and = 1;
logic_or = 0;
/* Variabeles for bit operators tests */
bit_and = 1;
bit_or = 0;
/* Variables for exclusiv bit or */
exclusiv_bit_or = 0;
/****************************************************************************/
/** Tests for integers **/
/****************************************************************************/
/**** Testing integer addition ****/
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(+:sum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (j = 1; j <= LOOPCOUNT; j++)
{
sum = sum + j;
}
</ompts:orphan>
}
if (known_sum != sum) {
result++;
fprintf (logFile, "Error in sum with integers: Result was %d instead of %d.\n", sum, known_sum);
}
/**** Testing integer subtracton ****/
diff = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(-:diff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (j = 1; j <= LOOPCOUNT; j++)
{
diff = diff - j;
}
</ompts:orphan>
}
if (diff != 0) {
result++;
fprintf (logFile, "Error in difference with integers: Result was %d instead of 0.\n", diff);
}
/**** Testing integer multiplication ****/
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(*:product)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (j = 1; j <= MAX_FACTOR; j++)
{
product *= j;
}
</ompts:orphan>
}
known_product = KNOWN_PRODUCT;
if(known_product != product)
{
result++;
fprintf (logFile,"Error in Product with integers: Result was %d instead of %d\n",product,known_product);
}
/****************************************************************************/
/** Tests for doubles **/
/****************************************************************************/
/**** Testing double addition ****/
dsum = 0.;
dpt = 1.;
for (i = 0; i < DOUBLE_DIGITS; ++i)
{
dpt *= dt;
}
dknown_sum = (1 - dpt) / (1 - dt);
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(+:dsum)</ompts:check>
for (j = 0; j < DOUBLE_DIGITS; j++)
{
dsum += pow (dt, j);
}
</ompts:orphan>
}
if (fabs (dsum - dknown_sum) > rounding_error) {
result++;
fprintf (logFile, "\nError in sum with doubles: Result was %f instead of: %f (Difference: %E)\n", dsum, dknown_sum, dsum-dknown_sum);
}
#if 0
dpt = 1.;
for (i = 0; i < DOUBLE_DIGITS; ++i)
{
dpt *= dt;
}
#endif
/**** Testing double subtraction ****/
ddiff = (1 - dpt) / (1 - dt);
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(-:ddiff)</ompts:check>
for (j = 0; j < DOUBLE_DIGITS; ++j)
{
ddiff -= pow (dt, j);
}
</ompts:orphan>
}
if (fabs (ddiff) > rounding_error) {
result++;
fprintf (logFile, "Error in Difference with doubles: Result was %E instead of 0.0\n", ddiff);
}
/****************************************************************************/
/** Tests for logical values **/
/****************************************************************************/
/**** Testing logic and ****/
for (i = 0; i < LOOPCOUNT; i++)
{
logics[i] = 1;
}
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(&&:logic_and)</ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
logic_and = (logic_and && logics[j]);
}
</ompts:orphan>
}
if(!logic_and) {
result++;
fprintf (logFile, "Error in logic AND part 1\n");
}
logic_and = 1;
logics[LOOPCOUNT / 2] = 0;
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (j = 0; j < LOOPCOUNT; ++j)
{
logic_and = logic_and && logics[j];
}
</ompts:orphan>
}
if(logic_and) {
result++;
fprintf (logFile, "Error in logic AND part 2\n");
}
/**** Testing logic or ****/
for (i = 0; i < LOOPCOUNT; i++)
{
logics[i] = 0;
}
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(||:logic_or) </ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
logic_or = logic_or || logics[j];
}
</ompts:orphan>
}
if (logic_or) {
result++;
fprintf (logFile, "Error in logic OR part 1\n");
}
logic_or = 0;
logics[LOOPCOUNT / 2] = 1;
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(||:logic_or)</ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
logic_or = logic_or || logics[j];
}
</ompts:orphan>
}
if(!logic_or) {
result++;
fprintf (logFile, "Error in logic OR part 2\n");
}
/****************************************************************************/
/** Tests for bit values **/
/****************************************************************************/
/**** Testing bit and ****/
for (i = 0; i < LOOPCOUNT; ++i)
{
logics[i] = 1;
}
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(&:bit_and) </ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
bit_and = (bit_and & logics[j]);
}
</ompts:orphan>
}
if (!bit_and) {
result++;
fprintf (logFile, "Error in BIT AND part 1\n");
}
bit_and = 1;
logics[LOOPCOUNT / 2] = 0;
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(&:bit_and)</ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
bit_and = bit_and & logics[j];
}
</ompts:orphan>
}
if (bit_and) {
result++;
fprintf (logFile, "Error in BIT AND part 2\n");
}
/**** Testing bit or ****/
for (i = 0; i < LOOPCOUNT; i++)
{
logics[i] = 0;
}
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(|:bit_or)</ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
bit_or = bit_or | logics[j];
}
</ompts:orphan>
}
if (bit_or) {
result++;
fprintf (logFile, "Error in BIT OR part 1\n");
}
bit_or = 0;
logics[LOOPCOUNT / 2] = 1;
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(|:bit_or)</ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
bit_or = bit_or | logics[j];
}
</ompts:orphan>
}
if (!bit_or) {
result++;
fprintf (logFile, "Error in BIT OR part 2\n");
}
/**** Testing exclusive bit or ****/
for (i = 0; i < LOOPCOUNT; i++)
{
logics[i] = 0;
}
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[j];
}
</ompts:orphan>
}
if (exclusiv_bit_or) {
result++;
fprintf (logFile, "Error in EXCLUSIV BIT OR part 1\n");
}
exclusiv_bit_or = 0;
logics[LOOPCOUNT / 2] = 1;
#pragma omp parallel
{
<ompts:orphan>
int j;
#pragma omp for schedule(dynamic,1) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check>
for (j = 0; j < LOOPCOUNT; ++j)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[j];
}
</ompts:orphan>
}
if (!exclusiv_bit_or) {
result++;
fprintf (logFile, "Error in EXCLUSIV BIT OR part 2\n");
}
/*fprintf ("\nResult:%d\n", result);*/
return (result == 0);
free (logics);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,55 @@
<ompts:test>
<ompts:testdescription>Test with omp for schedule auto</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp for auto</ompts:directive>
<ompts:dependences>omp critical,omp parallel firstprivate</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int sum1;
#pragma omp threadprivate(sum1)
int <ompts:testcode:functionname>omp_for_auto</ompts:testcode:functionname> (FILE * logFile)
{
int sum;
<ompts:orphan:vars>
int sum0;
</ompts:orphan:vars>
int known_sum;
int threadsnum;
sum = 0;
sum0 = 12345;
sum1 = 0;
#pragma omp parallel
{
#pragma omp single
{
threadsnum=omp_get_num_threads();
}
/* sum0 = 0; */
<ompts:orphan>
int i;
#pragma omp for <ompts:check>firstprivate(sum0) schedule(auto)</ompts:check><ompts:crosscheck>private(sum0)</ompts:crosscheck>
for (i = 1; i <= LOOPCOUNT; i++)
{
sum0 = sum0 + i;
sum1 = sum0;
} /* end of for */
</ompts:orphan>
#pragma omp critical
{
sum = sum + sum1;
} /* end of critical */
} /* end of parallel */
known_sum = 12345* threadsnum+ (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,111 @@
<ompts:test>
<ompts:testdescription>Test which checks the dynamic option of the omp for schedule directive</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp for schedule(dynamic)</ompts:directive>
<ompts:dependences>omp flush,omp for nowait,omp critical,omp single</ompts:dependences>
<ompts:testcode>
/*
* Test for dynamic scheduling with chunk size
* Method: caculate how many times the iteration space is dispatched
* and judge if each dispatch has the requested chunk size
* unless it is the last one.
* It is possible for two adjacent chunks are assigned to the same thread
* Modifyied by Chunhua Liao
*/
#include <stdio.h>
#include <omp.h>
#include <unistd.h>
#include <stdlib.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
#define CFDMAX_SIZE 100
const int chunk_size = 7;
int <ompts:testcode:functionname>omp_for_schedule_dynamic</ompts:testcode:functionname> (FILE * logFile)
{
int tid;
<ompts:orphan:vars>
int *tids;
int i;
</ompts:orphan:vars>
int tidsArray[CFDMAX_SIZE];
int count = 0;
int tmp_count = 0; /*dispatch times*/
int *tmp; /*store chunk size for each dispatch*/
int result = 0;
tids = tidsArray;
#pragma omp parallel private(tid) shared(tids)
{ /* begin of parallel */
<ompts:orphan>
int tid;
tid = omp_get_thread_num ();
#pragma omp for <ompts:check>schedule(dynamic,chunk_size)</ompts:check>
for (i = 0; i < CFDMAX_SIZE; i++)
{
tids[i] = tid;
}
</ompts:orphan>
} /* end of parallel */
for (i = 0; i < CFDMAX_SIZE - 1; ++i)
{
if (tids[i] != tids[i + 1])
{
count++;
}
}
tmp = (int *) malloc (sizeof (int) * (count + 1));
tmp[0] = 1;
for (i = 0; i < CFDMAX_SIZE - 1; ++i)
{
if (tmp_count > count)
{
printf ("--------------------\nTestinternal Error: List too small!!!\n--------------------\n"); /* Error handling */
break;
}
if (tids[i] != tids[i + 1])
{
tmp_count++;
tmp[tmp_count] = 1;
}
else
{
tmp[tmp_count]++;
}
}
/*
printf("debug----\n");
for (i = 0; i < CFDMAX_SIZE; ++i)
printf("%d ",tids[i]);
printf("debug----\n");
*/
/* is dynamic statement working? */
for (i = 0; i < count; i++)
{
if ((tmp[i]%chunk_size)!=0)
/*it is possible for 2 adjacent chunks assigned to a same thread*/
{
result++;
fprintf(logFile,"The intermediate dispatch has wrong chunksize.\n");
/*result += ((tmp[i] / chunk_size) - 1);*/
}
}
if ((tmp[count]%chunk_size)!=(CFDMAX_SIZE%chunk_size))
{
result++;
fprintf(logFile,"the last dispatch has wrong chunksize.\n");
}
/* for (int i=0;i<count+1;++i) printf("%d\t:=\t%d\n",i+1,tmp[i]); */
return (result==0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,225 @@
<ompts:test>
<ompts:testdescription>Test which checks the guided option of the omp for schedule directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp for schedule(guided)</ompts:directive>
<ompts:dependences>omp flush,omp for nowait,omp critical,omp single</ompts:dependences>
<ompts:testcode>
/* 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 NUMBER_OF_THREADS 10
#define CFSMAX_SIZE 1000
#define MAX_TIME 0.005
#ifdef SLEEPTIME
#undef SLEEPTIME
#define SLEEPTIME 0.0001
#endif
int <ompts:testcode:functionname>omp_for_schedule_guided</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int * tids;
int * chunksizes;
int notout;
int maxiter;
</ompts:orphan:vars>
int threads;
int i;
int result;
tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
maxiter = 0;
result = 1;
notout = 1;
/* Testing if enought threads are available for this check. */
#pragma omp parallel
{
#pragma omp single
{
threads = omp_get_num_threads ();
} /* end of single */
} /* end of parallel */
if (threads < 2) {
printf ("This test only works with at least two threads .\n");
fprintf (logFile, "This test only works with at least two threads. Available were only %d thread(s).\n", threads);
return (0);
} /* end if */
/* Now the real parallel work:
*
* Each thread will start immediately with the first chunk.
*/
#pragma omp parallel shared(tids,maxiter)
{ /* begin of parallel */
<ompts:orphan>
double count;
int tid;
int j;
tid = omp_get_thread_num ();
#pragma omp for nowait <ompts:check>schedule(guided)</ompts:check>
for(j = 0; j < CFSMAX_SIZE; ++j)
{
count = 0.;
#pragma omp flush(maxiter)
if (j > maxiter)
{
#pragma omp critical
{
maxiter = j;
} /* end of critical */
}
/*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)
</ompts:orphan>
} /* end of parallel */
/*******************************************************
* evaluation of the values *
*******************************************************/
{
int determined_chunksize = 1;
int last_threadnr = tids[0];
int global_chunknr = 0;
int local_chunknr[NUMBER_OF_THREADS];
int openwork = CFSMAX_SIZE;
int expected_chunk_size;
double c = 1;
for (i = 0; i < NUMBER_OF_THREADS; i++)
local_chunknr[i] = 0;
tids[CFSMAX_SIZE] = -1;
/*
* determine the number of global chunks
*/
/*fprintf(logFile,"# global_chunknr thread local_chunknr chunksize\n"); */
for(i = 1; i <= CFSMAX_SIZE; ++i)
{
if (last_threadnr==tids[i]) {
determined_chunksize++;
}
else
{
/* fprintf (logFile, "%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 (logFile, "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 (logFile, "%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 (logFile, "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 (logFile, "Chunksize did not decrease: %d instead of %d\n", chunksizes[i],expected_chunk_size);
#endif
/* calculating the remaining ammount of work */
openwork -= chunksizes[i];
}
}
return result;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,165 @@
<ompts:test>
<ompts:testdescription>Test which checks the static option of the omp for schedule directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp for schedule(static)</ompts:directive>
<ompts:dependences>omp for nowait,omp flush,omp critical,omp single</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
#define NUMBER_OF_THREADS 10
#define CFSMAX_SIZE 1000
#define MAX_TIME 0.01
#ifdef SLEEPTIME
#undef SLEEPTIME
#define SLEEPTIME 0.0005
#endif
int <ompts:testcode:functionname>omp_for_schedule_static</ompts:testcode:functionname> (FILE * logFile)
{
int threads;
int i,lasttid;
<ompts:orphan:vars>
int * tids;
int notout;
int maxiter;
int chunk_size;
</ompts:orphan:vars>
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)
{
printf ("This test only works with at least two threads");
fprintf (logFile,"This test only works with at least two threads");
return 0;
}
else
{
fprintf (logFile,"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 */
<ompts:orphan>
double count;
int tid;
int j;
tid = omp_get_thread_num ();
#pragma omp for nowait <ompts:check>schedule(static,chunk_size)</ompts:check>
for(j = 0; j < CFSMAX_SIZE; ++j)
{
count = 0.;
#pragma omp flush(maxiter)
if (j > maxiter)
{
#pragma omp critical
{
maxiter = j;
} /* end of critical */
}
/*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)
</ompts:orphan>
} /* 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 (logFile, "%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 (logFile, "OK\n");
#endif
}
/* If the chunk size was wrong, check if the end was reached */
else {
if (tids[i] == -1) {
if (i == CFSMAX_SIZE) {
fprintf (logFile, "Last thread had chunk size %d\n", tmp_count);
break;
}
else {
fprintf (logFile, "ERROR: Last thread (thread with number -1) was found before the end.\n");
result = 0;
}
}
else {
fprintf (logFile, "ERROR: chunk size was %d. (assigned was %d)\n", tmp_count, chunk_size);
result = 0;
}
}
}
else {
fprintf(logFile, "ERROR: Found thread with number %d (should be inbetween 0 and %d).", tids[i], threads - 1);
result = 0;
}
#ifdef VERBOSE
fprintf (logFile, "%d: %d \n", i, tids[i]);
#endif
}
}
return result;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,212 @@
<ompts:test>
<ompts:testdescription>Test which checks the static option of the omp for schedule directive considering the specifications for the chunk distribution of several loop regions is the same as specified in the Open MP standard version 3.0.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp for schedule(static)</ompts:directive>
<ompts:dependences>omp for nowait,omp flush,omp critical,omp single</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
#define NUMBER_OF_THREADS 10
#define CFSMAX_SIZE 1000
#define MAX_TIME 0.01
#ifdef SLEEPTIME
#undef SLEEPTIME
#define SLEEPTIME 0.0005
#endif
#define VERBOSE 0
int <ompts:testcode:functionname>omp_for_schedule_static_3</ompts:testcode:functionname> (FILE * logFile)
{
int threads;
int i,lasttid;
<ompts:orphan:vars>
int * tids;
int * tids2;
int notout;
int maxiter;
int chunk_size;
</ompts:orphan:vars>
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)
{
printf ("This test only works with at least two threads");
fprintf (logFile,"This test only works with at least two threads");
return 0;
}
else
{
fprintf (logFile,"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 */
<ompts:orphan>
double count;
int tid;
int j;
tid = omp_get_thread_num ();
#pragma omp for nowait <ompts:check>schedule(static,chunk_size)</ompts:check>
for(j = 0; j < CFSMAX_SIZE; ++j)
{
count = 0.;
#pragma omp flush(maxiter)
if (j > maxiter)
{
#pragma omp critical
{
maxiter = j;
} /* end of critical */
}
/*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)
</ompts:orphan>
} /* 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 (logFile, "%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 (logFile, "OK\n");
#endif
}
/* If the chunk size was wrong, check if the end was reached */
else {
if (tids[i] == -1) {
if (i == CFSMAX_SIZE) {
fprintf (logFile, "Last thread had chunk size %d\n", tmp_count);
break;
}
else {
fprintf (logFile, "ERROR: Last thread (thread with number -1) was found before the end.\n");
result = 0;
}
}
else {
fprintf (logFile, "ERROR: chunk size was %d. (assigned was %d)\n", tmp_count, chunk_size);
result = 0;
}
}
}
else {
fprintf(logFile, "ERROR: Found thread with number %d (should be inbetween 0 and %d).", tids[i], threads - 1);
result = 0;
}
#ifdef VERBOSE
fprintf (logFile, "%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
{
<ompts:orphan>
{
int n;
#pragma omp for <ompts:check>schedule(static)</ompts:check> nowait
for (n = 0; n < LOOPCOUNT; n++)
{
if (LOOPCOUNT == n + 1 )
my_sleep(SLEEPTIME);
tids[n] = omp_get_thread_num();
}
}
</ompts:orphan>
<ompts:orphan>
{
int m;
#pragma omp for <ompts:check>schedule(static)</ompts:check> nowait
for (m = 1; m <= LOOPCOUNT; m++)
{
tids2[m-1] = omp_get_thread_num();
}
}
</ompts:orphan>
}
for (i = 0; i < LOOPCOUNT; i++)
if (tids[i] != tids2[i]) {
fprintf (logFile, "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;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,39 @@
<ompts:test>
<ompts:testdescription>Test which checks that the omp_get_num_threads returns the correct number of threads. Therefor it counts up a variable in a parallelized section and compars this value with the result of the omp_get_num_threads function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_get_num_threads</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_get_num_threads</ompts:testcode:functionname> (FILE * logFile)
{
/* checks that omp_get_num_threads is equal to the number of
threads */
<ompts:orphan:vars>
int nthreads_lib;
</ompts:orphan:vars>
int nthreads = 0;
nthreads_lib = -1;
#pragma omp parallel
{
#pragma omp critical
{
nthreads++;
} /* end of critical */
#pragma omp single
{
<ompts:orphan>
<ompts:check>nthreads_lib = omp_get_num_threads ();</ompts:check>
</ompts:orphan>
} /* end of single */
} /* end of parallel */
fprintf (logFile, "Counted %d threads. get_num_threads returned %d.\n", nthreads, nthreads_lib);
return (nthreads == nthreads_lib);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,24 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_get_wtick function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_get_wtick</ompts:directive>
<ompts:testcode>
#include<stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_get_wtick</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
double tick;
</ompts:orphan:vars>
tick = -1.;
<ompts:orphan>
<ompts:check>tick = omp_get_wtick ();</ompts:check>
</ompts:orphan>
fprintf (logFile, "Work took %lf sec. time.\n", tick);
return ((tick > 0.0) && (tick < 0.01));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,38 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_get_wtime function. It compares the time with which is called a sleep function with the time it took by messuring the difference between the call of the sleep function and its end.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_get_wtime</ompts:directive>
<ompts:testcode>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_get_wtime</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
double start;
double end;
</ompts:orphan:vars>
double measured_time;
int wait_time = 1;
start = 0;
end = 0;
<ompts:orphan>
<ompts:check>start = omp_get_wtime ();</ompts:check>
</ompts:orphan>
my_sleep (wait_time);
<ompts:orphan>
<ompts:check>end = omp_get_wtime ();</ompts:check>
</ompts:orphan>
measured_time = end-start;
fprintf(logFile, "Work took %lf sec. time.\n", measured_time);
return ((measured_time > 0.99 * wait_time) && (measured_time < 1.01 * wait_time)) ;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,51 @@
<ompts:test>
<ompts:testdescription>Test which checks that omp_in_parallel returns false when called from a serial region and true when called within a parallel region.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_in_parallel</ompts:directive>
<ompts:testcode>
/*
* Checks that false is returned when called from serial region
* and true is returned when called within parallel region.
*/
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_in_parallel</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int serial;
int isparallel;
</ompts:orphan:vars>
serial = 1;
isparallel = 0;
<ompts:check>
<ompts:orphan>
serial = omp_in_parallel ();
</ompts:orphan>
#pragma omp parallel
{
#pragma omp single
{
<ompts:orphan>
isparallel = omp_in_parallel ();
</ompts:orphan>
}
}
</ompts:check>
<ompts:crosscheck>
#pragma omp parallel
{
#pragma omp single
{
}
}
</ompts:crosscheck>
return (!(serial) && isparallel);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,45 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_set_lock and the omp_unset_lock function by counting the threads entering and exiting a single region with locks.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_lock</ompts:directive>
<ompts:dependences>omp flush</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
omp_lock_t lck;
int <ompts:testcode:functionname>omp_lock</ompts:testcode:functionname>(FILE * logFile)
{
int nr_threads_in_single = 0;
int result = 0;
int nr_iterations = 0;
int i;
omp_init_lock (&lck);
#pragma omp parallel shared(lck)
{
#pragma omp for
for(i = 0; i < LOOPCOUNT; i++)
{
<ompts:orphan>
<ompts:check>omp_set_lock (&lck);</ompts:check>
</ompts:orphan>
#pragma omp flush
nr_threads_in_single++;
#pragma omp flush
nr_iterations++;
nr_threads_in_single--;
result = result + nr_threads_in_single;
<ompts:orphan>
<ompts:check>omp_unset_lock(&lck);</ompts:check>
</ompts:orphan>
}
}
omp_destroy_lock (&lck);
return ((result == 0) && (nr_iterations == LOOPCOUNT));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,37 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp master directive by counting up a variable in a omp master section.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp master</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_master</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int nthreads;
int executing_thread;
</ompts:orphan:vars>
nthreads = 0;
executing_thread = -1;
#pragma omp parallel
{
<ompts:orphan>
<ompts:check>#pragma omp master </ompts:check>
{
#pragma omp critical
{
nthreads++;
}
executing_thread = omp_get_thread_num ();
} /* end of master*/
</ompts:orphan>
} /* end of parallel*/
return ((nthreads == 1) && (executing_thread == 0));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,44 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp master directive by counting up a variable in a omp master section. It also checks that the master thread has the thread number 0 as specified in the Open MP standard version 3.0.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp master</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_master_3</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int nthreads;
int executing_thread;
int tid_result = 0; /* counts up the number of wrong thread no. for
the master thread. (Must be 0) */
</ompts:orphan:vars>
nthreads = 0;
executing_thread = -1;
#pragma omp parallel
{
<ompts:orphan>
<ompts:check>#pragma omp master </ompts:check>
{
int tid = omp_get_thread_num();
if (tid != 0) {
#pragma omp critical
{ tid_result++; }
}
#pragma omp critical
{
nthreads++;
}
executing_thread = omp_get_thread_num ();
} /* end of master*/
</ompts:orphan>
} /* end of parallel*/
return ((nthreads == 1) && (executing_thread == 0) && (tid_result == 0));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,45 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_set_nest_lock and the omp_unset_nest_lock function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_nest_lock</ompts:directive>
<ompts:dependences>omp flush</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
omp_nest_lock_t lck;
int <ompts:testcode:functionname>omp_nest_lock</ompts:testcode:functionname>(FILE * logFile)
{
int nr_threads_in_single = 0;
int result = 0;
int nr_iterations = 0;
int i;
omp_init_nest_lock (&lck);
#pragma omp parallel shared(lck)
{
#pragma omp for
for(i = 0; i < LOOPCOUNT; i++)
{
<ompts:orphan>
<ompts:check>omp_set_nest_lock (&lck);</ompts:check>
</ompts:orphan>
#pragma omp flush
nr_threads_in_single++;
#pragma omp flush
nr_iterations++;
nr_threads_in_single--;
result = result + nr_threads_in_single;
<ompts:orphan>
<ompts:check>omp_unset_nest_lock (&lck);</ompts:check>
</ompts:orphan>
}
}
omp_destroy_nest_lock (&lck);
return ((result == 0) && (nr_iterations == LOOPCOUNT));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,42 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_nested function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_nested</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
/*
* Test if the compiler supports nested parallelism
* By Chunhua Liao, University of Houston
* Oct. 2005
*/
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_nested</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int counter = 0;
</ompts:orphan:vars>
#ifdef _OPENMP
<ompts:check>omp_set_nested(1);</ompts:check>
<ompts:crosscheck>omp_set_nested(0);</ompts:crosscheck>
#endif
#pragma omp parallel shared(counter)
{
<ompts:orphan>
#pragma omp critical
counter ++;
#pragma omp parallel
{
#pragma omp critical
counter --;
}
</ompts:orphan>
}
return (counter != 0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,47 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel copyin directive.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp parallel copyin</ompts:directive>
<ompts:dependences>omp critical,omp threadprivate</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <stdlib.h>
#include "omp_testsuite.h"
static int sum1 = 789;
#pragma omp threadprivate(sum1)
int <ompts:testcode:functionname>omp_parallel_copyin</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int sum, num_threads;
</ompts:orphan:vars>
int known_sum;
sum = 0;
sum1 = 7;
num_threads = 0;
#pragma omp parallel <ompts:check>copyin(sum1)</ompts:check>
{
/*printf("sum1=%d\n",sum1);*/
<ompts:orphan>
int i;
#pragma omp for
for (i = 1; i < 1000; i++)
{
sum1 = sum1 + i;
} /*end of for*/
#pragma omp critical
{
sum = sum + sum1;
num_threads++;
} /*end of critical*/
</ompts:orphan>
} /* end of parallel*/
known_sum = (999 * 1000) / 2 + 7 * num_threads;
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,44 @@
<ompts:test>
<ompts:testdescription>Test which checks the default option of the parallel construct.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp parallel default</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_default</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int i;
int sum;
int mysum;
</ompts:orphan:vars>
int known_sum;
sum =0;
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 ;
<ompts:orphan>
#pragma omp parallel <ompts:check>default(shared)</ompts:check> private(i) private(mysum<ompts:crosscheck>,sum</ompts:crosscheck>)
{
mysum = 0;
#pragma omp for
for (i = 1; i <= LOOPCOUNT; i++)
{
mysum = mysum + i;
}
#pragma omp critical
{
sum = sum + mysum;
} /* end of critical */
} /* end of parallel */
</ompts:orphan>
if (known_sum != sum) {
fprintf(logFile, "KNOWN_SUM = %d; SUM = %d\n", known_sum, sum);
}
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,48 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel firstprivate directive.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp parallel firstprivate</ompts:directive>
<ompts:dependences>omp for omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <stdlib.h>
#include "omp_testsuite.h"
//static int sum1 = 789;
int <ompts:testcode:functionname>omp_parallel_firstprivate</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int sum, num_threads,sum1;
</ompts:orphan:vars>
int known_sum;
sum = 0;
sum1=7;
num_threads = 0;
#pragma omp parallel <ompts:check>firstprivate(sum1)</ompts:check><ompts:crosscheck>private(sum1)</ompts:crosscheck>
{
/*printf("sum1=%d\n",sum1);*/
<ompts:orphan>
int i;
#pragma omp for
for (i = 1; i < 1000; i++)
{
sum1 = sum1 + i;
} /*end of for*/
#pragma omp critical
{
sum = sum + sum1;
num_threads++;
} /*end of critical*/
</ompts:orphan>
} /* end of parallel*/
known_sum = (999 * 1000) / 2 + 7 * num_threads;
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,36 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel for firstprivate directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel for firstprivate</ompts:directive>
<ompts:dependences>omp parallel for reduction,omp parallel for private</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_for_firstprivate</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int sum ;
int i2;
int i;
</ompts:orphan:vars>
sum=0;
i2=3;
int known_sum;
#pragma omp parallel for reduction(+:sum) private(i) <ompts:check>firstprivate(i2)</ompts:check><ompts:crosscheck>private(i2)</ompts:crosscheck>
<ompts:orphan>
for (i = 1; i <= LOOPCOUNT; i++)
{
sum = sum + (i + i2);
} /*end of for*/
</ompts:orphan>
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 + i2 * LOOPCOUNT;
return (known_sum == sum);
} /* end of check_parallel_for_fistprivate */
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,38 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel for if directive. Needs at least two threads.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel for if</ompts:directive>
<ompts:dependences></ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_for_if</ompts:testcode:functionname>(FILE * logFile){
int known_sum;
<ompts:orphan:vars>
int num_threads;
int sum, sum2;
int i;
int control;
</ompts:orphan:vars>
control = 0;
num_threads=0;
sum = 0;
sum2 = 0;
#pragma omp parallel for private(i) <ompts:check>if (control==1)</ompts:check>
<ompts:orphan>
for (i=0; i <= LOOPCOUNT; i++)
{
num_threads = omp_get_num_threads();
sum = sum + i;
} /*end of for*/
</ompts:orphan>
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
fprintf (logFile, "Number of threads determined by omp_get_num_threads: %d\n", num_threads);
return (known_sum == sum && num_threads == 1);
} /* end of check_paralel_for_private */
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,34 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel for lastprivate directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel for lastprivate</ompts:directive>
<ompts:dependences>omp parallel for reduction,omp parallel for private</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_for_lastprivate</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int i;
int i0;
</ompts:orphan:vars>
sum =0;
i0 = -1;
int known_sum;
#pragma omp parallel for reduction(+:sum) schedule(static,7) private(i) <ompts:check>lastprivate(i0)</ompts:check><ompts:crosscheck>private(i0)</ompts:crosscheck>
<ompts:orphan>
for (i = 1; i <= LOOPCOUNT; i++)
{
sum = sum + i;
i0 = i;
} /*end of for*/
/* end of parallel*/
</ompts:orphan>
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
return ((known_sum == sum) && (i0 == LOOPCOUNT));
} /* end of check_parallel_for_lastprivate */
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,62 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel for ordered directive</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel for ordered</ompts:directive>
<ompts:dependences>omp parallel schedule(static)</ompts:dependences>
<ompts:testcode>
#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 <ompts:testcode:functionname>omp_parallel_for_ordered</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int is_larger;
</ompts:orphan:vars>
int known_sum;
int i;
sum = 0;
is_larger = 1;
last_i = 0;
#pragma omp parallel for schedule(static,1) private(i) <ompts:check>ordered</ompts:check>
for (i = 1; i < 100; i++)
{
ii = i;
<ompts:orphan>
<ompts:check>#pragma omp ordered</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
is_larger = check_i_islarger2 (ii) && is_larger;
sum = sum + ii;
}
</ompts:orphan>
}
known_sum = (99 * 100) / 2;
fprintf (logFile," known_sum = %d , sum = %d \n", known_sum, sum);
fprintf (logFile," is_larger = %d\n", is_larger);
return (known_sum == sum) && is_larger;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,48 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel for private directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel for private</ompts:directive>
<ompts:dependences>omp parallel for reduction,omp flush</ompts:dependences>
<ompts:testcode>
#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 <ompts:testcode:functionname>omp_parallel_for_private</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int i;
int i2;
</ompts:orphan:vars>
sum =0;
i2=0;
int known_sum;
#pragma omp parallel for reduction(+:sum) schedule(static,1) private(i) <ompts:check>private(i2)</ompts:check>
<ompts:orphan>
for (i=1;i<=LOOPCOUNT;i++)
{
i2 = i;
#pragma omp flush
do_some_work ();
#pragma omp flush
sum = sum + i2;
} /*end of for*/
</ompts:orphan>
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
return (known_sum == sum);
} /* end of check_paralel_for_private */
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,280 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel for reduction directive with all its options.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel for reduction</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_for_reduction</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
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;
#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
int diff;
double ddiff;
int product;
int known_product;
#define MAX_FACTOR 10
#define KNOWN_PRODUCT 3628800 /* 10! */
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;
</ompts:orphan:vars>
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;
known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2;
<ompts:orphan>
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(+:sum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (i=1;i<=LOOPCOUNT;i++)
{
sum=sum+i;
}
if(known_sum!=sum)
{
result++;
fprintf(logFile,"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) <ompts:check>reduction(-:diff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (i=1;i<=LOOPCOUNT;++i)
{
diff=diff-i;
}
if(diff != 0)
{
result++;
fprintf(logFile,"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) <ompts:check>reduction(+:dsum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (i=0;i<DOUBLE_DIGITS;++i)
{
dsum += pow(dt,i);
}
if( fabs(dsum-dknown_sum) > rounding_error )
{
result++;
fprintf(logFile,"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(logFile,"\n");
ddiff = (1-dpt)/(1-dt);
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(-:ddiff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (i=0;i<DOUBLE_DIGITS;++i)
{
ddiff -= pow(dt,i);
}
if( fabs(ddiff) > rounding_error)
{
result++;
fprintf(logFile,"Error in Difference with doubles: Result was %E instead of 0.0\n",ddiff);
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(*:product)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=1;i<=MAX_FACTOR;i++)
{
product *= i;
}
known_product = KNOWN_PRODUCT;
if(known_product != product)
{
result++;
fprintf(logFile,"Error in Product with integers: Result was %d instead of %d\n\n",product,known_product);
}
for(i=0;i<LOOPCOUNT;i++)
{
logics[i]=1;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
logic_and = (logic_and && logics[i]);
}
if(!logic_and)
{
result++;
fprintf(logFile,"Error in logic AND part 1.\n");
}
logic_and = 1;
logics[LOOPCOUNT/2]=0;
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
logic_and = logic_and && logics[i];
}
if(logic_and)
{
result++;
fprintf(logFile,"Error in logic AND part 2.\n");
}
for(i=0;i<LOOPCOUNT;i++)
{
logics[i]=0;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(||:logic_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
logic_or = logic_or || logics[i];
}
if(logic_or)
{
result++;
fprintf(logFile,"Error in logic OR part 1.\n");
}
logic_or = 0;
logics[LOOPCOUNT/2]=1;
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(||:logic_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
logic_or = logic_or || logics[i];
}
if(!logic_or)
{
result++;
fprintf(logFile,"Error in logic OR part 2.\n");
}
for(i=0;i<LOOPCOUNT;++i)
{
logics[i]=1;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(&:bit_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
bit_and = (bit_and & logics[i]);
}
if(!bit_and)
{
result++;
fprintf(logFile,"Error in BIT AND part 1.\n");
}
bit_and = 1;
logics[LOOPCOUNT/2]=0;
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(&:bit_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
bit_and = bit_and & logics[i];
}
if(bit_and)
{
result++;
fprintf(logFile,"Error in BIT AND part 2.\n");
}
for(i=0;i<LOOPCOUNT;i++)
{
logics[i]=0;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(|:bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
bit_or = bit_or | logics[i];
}
if(bit_or)
{
result++;
fprintf(logFile,"Error in BIT OR part 1\n");
}
bit_or = 0;
logics[LOOPCOUNT/2]=1;
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(|:bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
bit_or = bit_or | logics[i];
}
if(!bit_or)
{
result++;
fprintf(logFile,"Error in BIT OR part 2\n");
}
for(i=0;i<LOOPCOUNT;i++)
{
logics[i]=0;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
if(exclusiv_bit_or)
{
result++;
fprintf(logFile,"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) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
if(!exclusiv_bit_or)
{
result++;
fprintf(logFile,"Error in EXCLUSIV BIT OR part 2\n");
}
</ompts:orphan>
/*printf("\nResult:%d\n",result);*/
return (result==0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,40 @@
<ompts:test>
<ompts:testdescription>Test which checks the if option of the parallel construct.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp parallel if</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_if</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int i;
int sum;
int known_sum;
int mysum;
int control=1;
</ompts:orphan:vars>
sum =0;
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 ;
#pragma omp parallel private(i) <ompts:check>if(control==0)</ompts:check>
{
<ompts:orphan>
mysum = 0;
for (i = 1; i <= LOOPCOUNT; i++)
{
mysum = mysum + i;
}
#pragma omp critical
{
sum = sum + mysum;
} /* end of critical */
</ompts:orphan>
} /* end of parallel */
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,46 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_parallel_num_threads directive by counting the threads in a parallel region which was started with an explicitly stated number of threads.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp parellel num_threads</ompts:directive>
<ompts:dependences>omp master,omp parallel reduction,omp atomic</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_num_threads</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int failed;
int threads;
int nthreads;
</ompts:orphan:vars>
int max_threads = 0;
failed = 0;
/* first we check how many threads are available */
#pragma omp parallel
{
#pragma omp master
max_threads = omp_get_num_threads ();
}
/* we increase the number of threads from one to maximum:*/
for (threads = 1; threads <= max_threads; threads++)
{
nthreads = 0;
<ompts:orphan>
#pragma omp parallel reduction(+:failed) <ompts:check>num_threads(threads)</ompts:check>
{
failed = failed + !(threads == omp_get_num_threads ());
#pragma omp atomic
nthreads += 1;
}
</ompts:orphan>
failed = failed + !(nthreads == threads);
}
return (!failed);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,50 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel private directive.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp parallel private</ompts:directive>
<ompts:dependences>omp for omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <stdlib.h>
#include "omp_testsuite.h"
//static int sum1 = 789;
int <ompts:testcode:functionname>omp_parallel_private</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int sum, num_threads,sum1;
</ompts:orphan:vars>
int known_sum;
sum = 0;
<ompts:crosscheck> sum1=0; </ompts:crosscheck>
num_threads = 0;
#pragma omp parallel <ompts:check>private(sum1)</ompts:check>
{
<ompts:check>
sum1 = 7;
</ompts:check>
/*printf("sum1=%d\n",sum1);*/
<ompts:orphan>
int i;
#pragma omp for
for (i = 1; i < 1000; i++)
{
sum1 = sum1 + i;
} /*end of for*/
#pragma omp critical
{
sum = sum + sum1;
num_threads++;
} /*end of critical*/
</ompts:orphan>
} /* end of parallel*/
known_sum = (999 * 1000) / 2 + 7 * num_threads;
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,278 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel reduction directive with all its options.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp parallel reduction</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_reduction</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
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;
#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
int diff;
double ddiff;
int product;
int known_product;
#define MAX_FACTOR 10
#define KNOWN_PRODUCT 3628800 /* 10! */
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;
</ompts:orphan:vars>
sum =0;
dsum=0;
product=1;
logic_and=1;
logic_or=0;
bit_and=1;
bit_or=0;
exclusiv_bit_or=0;
result=0;
dt = 1./3.;
known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2;
<ompts:orphan>
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(+:sum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (i=1;i<=LOOPCOUNT;i++)
{
sum=sum+i;
}
if(known_sum!=sum)
{
result++;
fprintf(logFile,"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) <ompts:check>reduction(-:diff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (i=1;i<=LOOPCOUNT;++i)
{
diff=diff-i;
}
if(diff != 0)
{
result++;
fprintf(logFile,"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) <ompts:check>reduction(+:dsum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (i=0;i<DOUBLE_DIGITS;++i)
{
dsum += pow(dt,i);
}
if( fabs(dsum-dknown_sum) > rounding_error )
{
result++;
fprintf(logFile,"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(logFile,"\n");
ddiff = (1-dpt)/(1-dt);
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(-:ddiff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for (i=0;i<DOUBLE_DIGITS;++i)
{
ddiff -= pow(dt,i);
}
if( fabs(ddiff) > rounding_error)
{
result++;
fprintf(logFile,"Error in Difference with doubles: Result was %E instead of 0.0\n",ddiff);
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(*:product)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=1;i<=MAX_FACTOR;i++)
{
product *= i;
}
known_product = KNOWN_PRODUCT;
if(known_product != product)
{
result++;
fprintf(logFile,"Error in Product with integers: Result was %d instead of %d\n\n",product,known_product);
}
for(i=0;i<LOOPCOUNT;i++)
{
logics[i]=1;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
logic_and = (logic_and && logics[i]);
}
if(!logic_and)
{
result++;
fprintf(logFile,"Error in logic AND part 1.\n");
}
logic_and = 1;
logics[LOOPCOUNT/2]=0;
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
logic_and = logic_and && logics[i];
}
if(logic_and)
{
result++;
fprintf(logFile,"Error in logic AND part 2.\n");
}
for(i=0;i<LOOPCOUNT;i++)
{
logics[i]=0;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(||:logic_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
logic_or = logic_or || logics[i];
}
if(logic_or)
{
result++;
fprintf(logFile,"Error in logic OR part 1.\n");
}
logic_or = 0;
logics[LOOPCOUNT/2]=1;
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(||:logic_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
logic_or = logic_or || logics[i];
}
if(!logic_or)
{
result++;
fprintf(logFile,"Error in logic OR part 2.\n");
}
for(i=0;i<LOOPCOUNT;++i)
{
logics[i]=1;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(&:bit_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
bit_and = (bit_and & logics[i]);
}
if(!bit_and)
{
result++;
fprintf(logFile,"Error in BIT AND part 1.\n");
}
bit_and = 1;
logics[LOOPCOUNT/2]=0;
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(&:bit_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
bit_and = bit_and & logics[i];
}
if(bit_and)
{
result++;
fprintf(logFile,"Error in BIT AND part 2.\n");
}
for(i=0;i<LOOPCOUNT;i++)
{
logics[i]=0;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(|:bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
bit_or = bit_or | logics[i];
}
if(bit_or)
{
result++;
fprintf(logFile,"Error in BIT OR part 1\n");
}
bit_or = 0;
logics[LOOPCOUNT/2]=1;
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(|:bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
bit_or = bit_or | logics[i];
}
if(!bit_or)
{
result++;
fprintf(logFile,"Error in BIT OR part 2\n");
}
for(i=0;i<LOOPCOUNT;i++)
{
logics[i]=0;
}
#pragma omp parallel for schedule(dynamic,1) private(i) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
if(exclusiv_bit_or)
{
result++;
fprintf(logFile,"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) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
for(i=0;i<LOOPCOUNT;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
if(!exclusiv_bit_or)
{
result++;
fprintf(logFile,"Error in EXCLUSIV BIT OR part 2\n");
}
</ompts:orphan>
/*printf("\nResult:%d\n",result);*/
return (result==0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,49 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel sections firstprivate directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel sections firstprivate</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_sections_firstprivate</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int sum0;
</ompts:orphan:vars>
int known_sum;
sum =7;
sum0=11;
<ompts:orphan>
#pragma omp parallel sections <ompts:check>firstprivate(sum0)</ompts:check><ompts:crosscheck>private(sum0)</ompts:crosscheck>
{
#pragma omp section
{
#pragma omp critical
{
sum= sum+sum0;
} /*end of critical */
}
#pragma omp section
{
#pragma omp critical
{
sum= sum+sum0;
} /*end of critical */
}
#pragma omp section
{
#pragma omp critical
{
sum= sum+sum0;
} /*end of critical */
}
} /*end of parallel sections*/
</ompts:orphan>
known_sum=11*3+7;
return (known_sum==sum);
} /* end of check_section_firstprivate*/
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,70 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel sections lastprivate directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel sections lastprivate</ompts:directive>
<ompts:dependences>omp critical,omp parallel sections private</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_sections_lastprivate</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int sum0;
int i;
int i0;
</ompts:orphan:vars>
int known_sum;
sum =0;
sum0 = 0;
i0 = -1;
<ompts:orphan>
#pragma omp parallel sections private(i,sum0) <ompts:check>lastprivate(i0)</ompts:check><ompts:crosscheck>private(i0)</ompts:crosscheck>
{
#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; /*end of for*/
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 parallel sections*/
</ompts:orphan>
known_sum=(999*1000)/2;
return ((known_sum==sum) && (i0==999) );
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,65 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel sections private directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel sections private</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_sections_private</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int sum0;
int i;
</ompts:orphan:vars>
int known_sum;
sum = 7;
sum0=0;
<ompts:orphan>
#pragma omp parallel sections private(<ompts:check>sum0,</ompts:check> i)
{
#pragma omp section
{
<ompts:check>
sum0=0;
</ompts:check>
for (i=1;i<400;i++)
sum0=sum0+i;
#pragma omp critical
{
sum= sum+sum0;
} /*end of critical */
}
#pragma omp section
{
<ompts:check>
sum0=0;
</ompts:check>
for(i=400;i<700;i++)
sum0=sum0+i;
#pragma omp critical
{
sum= sum+sum0;
} /*end of critical */
}
#pragma omp section
{
<ompts:check>
sum0=0;
</ompts:check>
for(i=700;i<1000;i++)
sum0=sum0+i;
#pragma omp critical
{
sum= sum+sum0;
} /*end of critical */
}
} /*end of paralell sections*/
</ompts:orphan>
known_sum=(999*1000)/2+7;
return (known_sum==sum);
} /* end of check_section_private*/
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,568 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel sections reduction directive with all its option.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel sections reduction</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_sections_reduction</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int known_sum;
double dpt;
double dsum;
double dknown_sum;
double dt=0.5; /* base of geometric row for + and - test*/
double rounding_error= 1.E-5;
int diff;
double ddiff;
int product;
int known_product;
int logic_and;
int bit_and;
int logic_or;
int bit_or;
int exclusiv_bit_or;
int logics[1000];
int i;
int result;
</ompts:orphan:vars>
sum = 7;
dsum=0;
product =1;
dpt = 1;
logic_and=1;
bit_and=1;
logic_or=0;
bit_or=0;
exclusiv_bit_or=0;
result =0;
/* int my_islarger;*/
/*int is_larger=1;*/
known_sum = (999*1000)/2+7;
<ompts:orphan>
#pragma omp parallel sections private(i) <ompts:check>reduction(+:sum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
sum=sum+i;
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
sum=sum+i;
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
sum=sum+i;
}
}
}
if(known_sum!=sum)
{
result++;
fprintf(logFile,"Error in sum with integers: Result was %d instead of %d.\n",sum, known_sum);
}
diff = (999*1000)/2;
#pragma omp parallel sections private(i) <ompts:check>reduction(-:diff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
diff=diff-i;
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
diff=diff-i;
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
diff=diff-i;
}
}
}
if(diff != 0)
{
result++;
fprintf(logFile,"Error in Difference with integers: Result was %d instead of 0.\n",diff);
}
for (i=0;i<20;++i)
{
dpt*=dt;
}
dknown_sum = (1-dpt)/(1-dt);
#pragma omp parallel sections private(i) <ompts:check>reduction(+:dsum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=0;i<6;++i)
{
dsum += pow(dt,i);
}
}
#pragma omp section
{
for (i=6;i<12;++i)
{
dsum += pow(dt,i);
}
}
#pragma omp section
{
for (i=12;i<20;++i)
{
dsum += pow(dt,i);
}
}
}
if( fabs(dsum-dknown_sum) > rounding_error )
{
result++;
fprintf(logFile,"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<20;++i)
{
dpt*=dt;
}
fprintf(logFile,"\n");
ddiff = (1-dpt)/(1-dt);
#pragma omp parallel sections private(i) <ompts:check>reduction(-:ddiff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=0;i<6;++i)
{
ddiff -= pow(dt,i);
}
}
#pragma omp section
{
for (i=6;i<12;++i)
{
ddiff -= pow(dt,i);
}
}
#pragma omp section
{
for (i=12;i<20;++i)
{
ddiff -= pow(dt,i);
}
}
}
if( fabs(ddiff) > rounding_error)
{
result++;
fprintf(logFile,"Error in Difference with doubles: Result was %E instead of 0.0\n",ddiff);
}
known_product = 3628800;
#pragma omp parallel sections private(i) <ompts:check>reduction(*:product)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=1;i<3;i++)
{
product *= i;
}
}
#pragma omp section
{
for(i=3;i<7;i++)
{
product *= i;
}
}
#pragma omp section
{
for(i=7;i<11;i++)
{
product *= i;
}
}
}
if(known_product != product)
{
result++;
fprintf(logFile,"Error in Product with integers: Result was %d instead of %d\n",product,known_product);
}
for(i=0;i<1000;i++)
{
logics[i]=1;
}
#pragma omp parallel sections private(i) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
logic_and = (logic_and && logics[i]);
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
logic_and = (logic_and && logics[i]);
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
logic_and = (logic_and && logics[i]);
}
}
}
if(!logic_and)
{
result++;
fprintf(logFile,"Error in logic AND part 1\n");
}
logic_and = 1;
logics[501] = 0;
#pragma omp parallel sections private(i) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
logic_and = (logic_and && logics[i]);
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
logic_and = (logic_and && logics[i]);
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
logic_and = (logic_and && logics[i]);
}
}
}
if(logic_and)
{
result++;
fprintf(logFile,"Error in logic AND part 2");
}
for(i=0;i<1000;i++)
{
logics[i]=0;
}
#pragma omp parallel sections private(i) <ompts:check>reduction(||:logic_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
logic_or = (logic_or || logics[i]);
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
logic_or = (logic_or || logics[i]);
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
logic_or = (logic_or || logics[i]);
}
}
}
if(logic_or)
{
result++;
fprintf(logFile,"Error in logic OR part 1\n");
}
logic_or = 0;
logics[501]=1;
#pragma omp parallel sections private(i) <ompts:check>reduction(||:logic_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
logic_or = (logic_or || logics[i]);
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
logic_or = (logic_or || logics[i]);
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
logic_or = (logic_or || logics[i]);
}
}
}
if(!logic_or)
{
result++;
fprintf(logFile,"Error in logic OR part 2\n");
}
for(i=0;i<1000;++i)
{
logics[i]=1;
}
#pragma omp parallel sections private(i) <ompts:check>reduction(&:bit_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
bit_and = (bit_and & logics[i]);
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
bit_and = (bit_and & logics[i]);
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
bit_and = (bit_and & logics[i]);
}
}
}
if(!bit_and)
{
result++;
fprintf(logFile,"Error in BIT AND part 1\n");
}
bit_and = 1;
logics[501]=0;
#pragma omp parallel sections private(i) <ompts:check>reduction(&:bit_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
bit_and = bit_and & logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
bit_and = bit_and & logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
bit_and = bit_and & logics[i];
}
}
}
if(bit_and)
{
result++;
fprintf(logFile,"Error in BIT AND part 2");
}
for(i=0;i<1000;i++)
{
logics[i]=0;
}
#pragma omp parallel sections private(i) <ompts:check>reduction(|:bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
bit_or = bit_or | logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
bit_or = bit_or | logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
bit_or = bit_or | logics[i];
}
}
}
if(bit_or)
{
result++;
fprintf(logFile,"Error in BIT OR part 1\n");
}
bit_or = 0;
logics[501]=1;
#pragma omp parallel sections private(i) <ompts:check>reduction(|:bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
bit_or = bit_or | logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
bit_or = bit_or | logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
bit_or = bit_or | logics[i];
}
}
}
if(!bit_or)
{
result++;
fprintf(logFile,"Error in BIT OR part 2\n");
}
for(i=0;i<1000;i++)
{
logics[i]=0;
}
#pragma omp parallel sections private(i) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
}
if(exclusiv_bit_or)
{
result++;
fprintf(logFile,"Error in EXCLUSIV BIT OR part 1\n");
}
exclusiv_bit_or = 0;
logics[501]=1;
#pragma omp parallel sections private(i) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
}
if(!exclusiv_bit_or)
{
result++;
fprintf(logFile,"Error in EXCLUSIV BIT OR part 2\n");
}
</ompts:orphan>
/*printf("\nResult:%d\n",result);*/
return (result==0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,43 @@
<ompts:test>
<ompts:testdescription>Test which checks the shared option of the parallel construct.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp parallel shared</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <unistd.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_parallel_shared</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int i;
int sum;
</ompts:orphan:vars>
sum = 0;
int known_sum;
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 ;
#pragma omp parallel private(i) <ompts:check>shared(sum)</ompts:check> <ompts:crosscheck>firstprivate(sum)</ompts:crosscheck>
{
<ompts:orphan>
int mysum = 0;
#pragma omp for
for (i = 1; i <= LOOPCOUNT; i++)
{
mysum = mysum + i;
}
#pragma omp critical
{
sum = sum + mysum;
} /* end of critical */
</ompts:orphan>
} /* end of parallel */
if (known_sum != sum) {
fprintf(logFile, "KNOWN_SUM = %d; SUM = %d\n", known_sum, sum);
}
return (known_sum == sum);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,52 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp section firstprivate directive by adding a variable which is defined before the parallel region.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp firstprivate</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_section_firstprivate</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int sum0;
</ompts:orphan:vars>
int known_sum;
sum0 = 11;
sum = 7;
#pragma omp parallel
{
<ompts:orphan>
#pragma omp sections <ompts:check>firstprivate(sum0)</ompts:check><ompts:crosscheck>private(sum0)</ompts:crosscheck>
{
#pragma omp section
{
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical */
}
#pragma omp section
{
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical */
}
#pragma omp section
{
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical */
}
} /*end of sections*/
</ompts:orphan>
} /* end of parallel */
known_sum = 11 * 3 + 7;
return (known_sum == sum);
} /* end of check_section_firstprivate*/
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,73 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp section lastprivate directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp section lastprivate</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_section_lastprivate</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int i0 = -1;
int sum = 0;
int i;
int sum0 = 0;
</ompts:orphan:vars>
int known_sum;
i0 = -1;
sum = 0;
#pragma omp parallel
{
<ompts:orphan>
#pragma omp sections <ompts:check>lastprivate(i0)</ompts:check><ompts:crosscheck>private(i0)</ompts:crosscheck> 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 sections*/
</ompts:orphan>
} /* end of parallel*/
known_sum = (999 * 1000) / 2;
return ((known_sum == sum) && (i0 == 999) );
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,69 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp section private directive by upcounting a variable in a to several sections splitted loop.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp section private</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_section_private</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int sum0;
int i;
</ompts:orphan:vars>
int known_sum;
sum = 7;
sum0 = 0;
#pragma omp parallel
{
<ompts:orphan>
#pragma omp sections <ompts:check>private(sum0,i)</ompts:check><ompts:crosscheck>private(i)</ompts:crosscheck>
{
#pragma omp section
{
<ompts:check>
sum0 = 0;
</ompts:check>
for (i = 1; i < 400; i++)
sum0 = sum0 + i;
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical */
}
#pragma omp section
{
<ompts:check>
sum0 = 0;
</ompts:check>
for (i = 400; i < 700; i++)
sum0 = sum0 + i;
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical */
}
#pragma omp section
{
<ompts:check>
sum0 = 0;
</ompts:check>
for (i = 700; i < 1000; i++)
sum0 = sum0 + i;
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical */
}
} /*end of sections*/
</ompts:orphan>
} /* end of parallel */
known_sum = (999 * 1000) / 2 + 7;
return (known_sum == sum);
} /* end of check_section_private*/
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,66 @@
<ompts:test>
<ompts:description>Test which checks the omp parallel for nowait directive. It fills an array with values and operates on these in the following.</ompts:description>
<ompts:directive>omp parallel sections nowait</ompts:directive>
<ompts:version>1.0</ompts:version>
<ompts:dependences>omp parallel sections, omp flush</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_sections_nowait</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int result;
int count;
</ompts:orphan:vars>
int j;
result = 0;
count = 0;
#pragma omp parallel
{
<ompts:orphan>
int rank;
rank = omp_get_thread_num ();
#pragma omp sections <ompts:check>nowait</ompts:check>
{
#pragma omp section
{
fprintf (logFile, "Thread nr %d enters first section and gets sleeping.\n", rank);
my_sleep(SLEEPTIME);
count = 1;
fprintf (logFile, "Thread nr %d woke up an set count to 1.\n", rank);
#pragma omp flush(count)
}
#pragma omp section
{
fprintf (logFile, "Thread nr %d executed work in the first section.\n", rank);
}
}
/* Begin of second sections environment */
#pragma omp sections
{
#pragma omp section
{
fprintf (logFile, "Thread nr %d executed work in the second section.\n", rank);
}
#pragma omp section
{
fprintf (logFile, "Thread nr %d executed work in the second section and controls the value of count\n", rank);
if (count == 0)
result = 1;
fprintf (logFile, "cout was %d", count);
}
}
</ompts:orphan>
}
return result;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,613 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp sections reduction directive with all its options.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp sections reduction</ompts:directive>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_sections_reduction</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int sum;
int known_sum;
double dpt,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 bit_and;
int logic_or;
int bit_or;
int exclusiv_bit_or;
int logics[1000];
int i;
int result;
</ompts:orphan:vars>
/* int my_islarger;*/
/*int is_larger=1;*/
sum =7;
dpt =1;
dsum=0;
product =1;
logic_and=1;
bit_and=1;
logic_or=0;
bit_or=0;
exclusiv_bit_or=0;
result = 0;
dt = 1./3.;
known_sum = (999*1000)/2+7;
<ompts:orphan>
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(+:sum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
sum=sum+i;
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
sum=sum+i;
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
sum=sum+i;
}
}
}
}
if(known_sum!=sum)
{
++result;
fprintf(logFile,"Error in sum with integers: Result was %d instead of %d\n", sum,known_sum);
}
diff = (999*1000)/2;
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(-:diff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
diff=diff-i;
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
diff=diff-i;
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
diff=diff-i;
}
}
}
}
if(diff != 0)
{
result++;
fprintf(logFile,"Error in Difference with integers: Result was %d instead of 0.\n",diff);
}
for (i=0;i<20;++i)
{
dpt*=dt;
}
dknown_sum = (1-dpt)/(1-dt);
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(+:dsum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=0;i<6;++i)
{
dsum += pow(dt,i);
}
}
#pragma omp section
{
for (i=6;i<12;++i)
{
dsum += pow(dt,i);
}
}
#pragma omp section
{
for (i=12;i<20;++i)
{
dsum += pow(dt,i);
}
}
}
}
if( fabs(dsum-dknown_sum) > rounding_error )
{
result++;
fprintf(logFile,"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<20;++i)
{
dpt*=dt;
}
fprintf(logFile,"\n");
ddiff = (1-dpt)/(1-dt);
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(-:ddiff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=0;i<6;++i)
{
ddiff -= pow(dt,i);
}
}
#pragma omp section
{
for (i=6;i<12;++i)
{
ddiff -= pow(dt,i);
}
}
#pragma omp section
{
for (i=12;i<20;++i)
{
ddiff -= pow(dt,i);
}
}
}
}
if( fabs(ddiff) > rounding_error)
{
result++;
fprintf(logFile,"Error in Difference with doubles: Result was %E instead of 0.0\n",ddiff);
}
known_product = 3628800;
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(*:product)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=1;i<3;i++)
{
product *= i;
}
}
#pragma omp section
{
for(i=3;i<7;i++)
{
product *= i;
}
}
#pragma omp section
{
for(i=7;i<11;i++)
{
product *= i;
}
}
}
}
if(known_product != product)
{
result++;
fprintf(logFile,"Error in Product with integers: Result was %d instead of %d\n",product,known_product);
}
for(i=0;i<1000;i++)
{
logics[i]=1;
}
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
logic_and = (logic_and && logics[i]);
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
logic_and = (logic_and && logics[i]);
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
logic_and = (logic_and && logics[i]);
}
}
}
}
if(!logic_and)
{
result++;
fprintf(logFile,"Error in logic AND part 1\n");
}
logic_and = 1;
logics[501] = 0;
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
logic_and = (logic_and && logics[i]);
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
logic_and = (logic_and && logics[i]);
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
logic_and = (logic_and && logics[i]);
}
}
}
}
if(logic_and)
{
result++;
fprintf(logFile,"Error in logic AND part 2\n");
}
for(i=0;i<1000;i++)
{
logics[i]=0;
}
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(||:logic_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
logic_or = (logic_or || logics[i]);
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
logic_or = (logic_or || logics[i]);
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
logic_or = (logic_or || logics[i]);
}
}
}
}
if(logic_or)
{
result++;
fprintf(logFile,"\nError in logic OR part 1\n");
}
logic_or = 0;
logics[501]=1;
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(||:logic_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for (i=1;i<300;i++)
{
logic_or = (logic_or || logics[i]);
}
}
#pragma omp section
{
for (i=300;i<700;i++)
{
logic_or = (logic_or || logics[i]);
}
}
#pragma omp section
{
for (i=700;i<1000;i++)
{
logic_or = (logic_or || logics[i]);
}
}
}
}
if(!logic_or)
{
result++;
fprintf(logFile,"Error in logic OR part 2\n");
}
for(i=0;i<1000;++i)
{
logics[i]=1;
}
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(&:bit_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
bit_and = (bit_and & logics[i]);
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
bit_and = (bit_and & logics[i]);
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
bit_and = (bit_and & logics[i]);
}
}
}
}
if(!bit_and)
{
result++;
fprintf(logFile,"Error in BIT AND part 1\n");
}
bit_and = 1;
logics[501]=0;
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(&:bit_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
bit_and = bit_and & logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
bit_and = bit_and & logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
bit_and = bit_and & logics[i];
}
}
}
}
if(bit_and)
{
result++;
fprintf(logFile,"Error in BIT AND part 2\n");
}
for(i=0;i<1000;i++)
{
logics[i]=0;
}
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(|:bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
bit_or = bit_or | logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
bit_or = bit_or | logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
bit_or = bit_or | logics[i];
}
}
}
}
if(bit_or)
{
result++;
fprintf(logFile,"Error in BIT OR part 1\n");
}
bit_or = 0;
logics[501]=1;
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(|:bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
bit_or = bit_or | logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
bit_or = bit_or | logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
bit_or = bit_or | logics[i];
}
}
}
}
if(!bit_or)
{
result++;
fprintf(logFile,"Error in BIT OR part 2\n");
}
for(i=0;i<1000;i++)
{
logics[i]=0;
}
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
}
}
if(exclusiv_bit_or)
{
result++;
fprintf(logFile,"Error in EXCLUSIV BIT OR part 1\n");
}
exclusiv_bit_or = 0;
logics[501]=1;
#pragma omp parallel
{
#pragma omp sections private(i) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check><ompts:crosscheck></ompts:crosscheck>
{
#pragma omp section
{
for(i=0;i<300;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
#pragma omp section
{
for(i=300;i<700;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
#pragma omp section
{
for(i=700;i<1000;++i)
{
exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
}
}
}
}
if(!exclusiv_bit_or)
{
result++;
fprintf(logFile,"Error in EXCLUSIV BIT OR part 2\n");
}
</ompts:orphan>
/*printf("\nResult:%d\n",result);*/
return (result==0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,43 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp single directive by controling how often a directive is called in an omp single region.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp single</ompts:directive>
<ompts:dependences>omp parallel private,omp flush</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_single</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int nr_threads_in_single;
int result;
int nr_iterations;
int i;
</ompts:orphan:vars>
nr_threads_in_single = 0;
result = 0;
nr_iterations = 0;
#pragma omp parallel private(i)
{
for (i = 0; i < LOOPCOUNT; i++)
{
<ompts:orphan>
<ompts:check>#pragma omp single </ompts:check>
{
#pragma omp flush
nr_threads_in_single++;
#pragma omp flush
nr_iterations++;
nr_threads_in_single--;
result = result + nr_threads_in_single;
} /* end of single */
</ompts:orphan>
} /* end of for */
} /* end of parallel */
return ((result == 0) && (nr_iterations == LOOPCOUNT));
} /* end of check_single*/
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,50 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp single copyprivate directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp single copyprivate</ompts:directive>
<ompts:dependences>omp parllel,omp critical</ompts:dependences>
<ompts:testcode>
#include "omp_testsuite.h"
int j;
#pragma omp threadprivate(j)
int <ompts:testcode:functionname>omp_single_copyprivate</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int result;
int nr_iterations;
</ompts:orphan:vars>
result = 0;
nr_iterations = 0;
#pragma omp parallel
{
<ompts:orphan>
int i;
for (i = 0; i < LOOPCOUNT; i++)
{
/*
int thread;
thread = omp_get_thread_num ();
*/
#pragma omp single <ompts:check>copyprivate(j)</ompts:check>
{
nr_iterations++;
j = i;
/*printf ("thread %d assigns, j = %d, i = %d\n", thread, j, i);*/
}
/* #pragma omp barrier*/
#pragma omp critical
{
/*printf ("thread = %d, j = %d, i = %d\n", thread, j, i);*/
result = result + j - i;
}
#pragma omp barrier
} /* end of for */
</ompts:orphan>
} /* end of parallel */
return ((result == 0) && (nr_iterations == LOOPCOUNT));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,60 @@
<ompts:test>
<ompts:testdescription></ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp single nowait</ompts:directive>
<ompts:dependences>omp critical,omp atomic</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int my_iterations;
#pragma omp threadprivate(my_iterations)
int <ompts:testcode:functionname>omp_single_nowait</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int nr_iterations;
</ompts:orphan:vars>
int total_iterations = 0;
int i;
nr_iterations = 0;
my_iterations = 0;
#pragma omp parallel private(i)
{
for (i = 0; i < LOOPCOUNT; i++)
{
<ompts:orphan>
<ompts:check>#pragma omp single nowait</ompts:check>
{
#pragma omp atomic
nr_iterations++;
} /* end of single*/
</ompts:orphan>
} /* end of for */
} /* end of parallel */
#pragma omp parallel private(i)
{
my_iterations = 0;
for (i = 0; i < LOOPCOUNT; i++)
{
<ompts:orphan>
<ompts:check>#pragma omp single nowait</ompts:check>
{
my_iterations++;
} /* end of single*/
</ompts:orphan>
} /* end of for */
#pragma omp critical
{
total_iterations += my_iterations;
}
} /* end of parallel */
return ((nr_iterations == LOOPCOUNT) && (total_iterations == LOOPCOUNT));
} /* end of check_single_nowait*/
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,56 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp single private directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp singel private</ompts:directive>
<ompts:dependences>omp critical,omp flush,omp single nowait</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
int myit = 0;
#pragma omp threadprivate(myit)
int myresult = 0;
#pragma omp threadprivate(myresult)
int <ompts:testcode:functionname>omp_single_private</ompts:testcode:functionname>(FILE * logFile)
{
<ompts:orphan:vars>
int nr_threads_in_single;
int result;
int nr_iterations;
</ompts:orphan:vars>
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++)
{
<ompts:orphan>
#pragma omp single <ompts:check>private(nr_threads_in_single) </ompts:check>nowait
{
nr_threads_in_single = 0;
#pragma omp flush
nr_threads_in_single++;
#pragma omp flush
myit++;
myresult = myresult + nr_threads_in_single;
} /* end of single */
</ompts:orphan>
} /* end of for */
#pragma omp critical
{
result += nr_threads_in_single;
nr_iterations += myit;
}
} /* end of parallel */
return ((result == 0) && (nr_iterations == LOOPCOUNT));
} /* end of check_single private */
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,52 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp task directive. The idea of the tests is to generate a set of tasks in a single region. We let pause the tasks generated so that other threads get sheduled to the newly opened tasks.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp task</ompts:directive>
<ompts:dependences>omp single</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_task</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int tids[NUM_TASKS];
int i;
</ompts:orphan:vars>
#pragma omp parallel
{
#pragma omp single
{
for (i = 0; i < NUM_TASKS; i++) {
<ompts:orphan>
/* First we have to store the value of the loop index in a new variable
* which will be private for each task because otherwise it will be overwritten
* if the execution of the task takes longer than the time which is needed to
* enter the next step of the loop!
*/
int myi;
myi = i;
<ompts:check>#pragma omp task</ompts:check>
{
my_sleep (SLEEPTIME);
tids[myi] = omp_get_thread_num();
} /* end of omp task */
</ompts:orphan>
} /* end of for */
} /* end of single */
} /*end of parallel */
/* Now we ckeck if more than one thread executed the tasks. */
for (i = 1; i < NUM_TASKS; i++) {
if (tids[0] != tids[i])
return 1;
}
return 0;
} /* end of check_paralel_for_private */
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,52 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp task directive. The idea of the tests is to generate a set of tasks in a single region. We let pause the tasks generated so that other threads get sheduled to the newly opened tasks.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp task final</ompts:directive>
<ompts:dependences>omp single</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_task_final</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int tids[NUM_TASKS];
int i;
</ompts:orphan:vars>
int error;
#pragma omp parallel
{
#pragma omp single
{
for (i = 0; i < NUM_TASKS; i++) {
<ompts:orphan>
/* First we have to store the value of the loop index in a new variable
* which will be private for each task because otherwise it will be overwritten
* if the execution of the task takes longer than the time which is needed to
* enter the next step of the loop!
*/
int myi;
myi = i;
#pragma omp task <ompts:check>final(i>=10)</ompts:check>
{
my_sleep (SLEEPTIME);
tids[myi] = omp_get_thread_num();
} /* end of omp task */
</ompts:orphan>
} /* end of for */
} /* end of single */
} /*end of parallel */
/* Now we ckeck if more than one thread executed the tasks. */
for (i = 10; i < NUM_TASKS; i++) {
if (tids[10] != tids[i])
error++;
}
return (error==0);
} /* end of check_paralel_for_private */
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,51 @@
<ompts:test>
<ompts:testdescription>Test which checks the firstprivate clause of the task directive. We create a set of tasks in a single region. We defines a variable named sum unequal zero which gets declared firstprivate for each task. Now each task calcualtes a sum using this private variable. Before each calcualation step we introduce a flush command so that maybe the private variabel gets bad. At the end we check if the calculated sum was right.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp task firstprivate</ompts:directive>
<ompts:dependences>omp single,omp flush,omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
int <ompts:testcode:functionname>omp_task_firstprivate</ompts:testcode:functionname> (FILE * logFile)
{
int i;
<ompts:orphan:vars>
int sum = 1234;
int known_sum;
int result = 0; /* counts the wrong sums from tasks */
</ompts:orphan:vars>
known_sum = 1234 + (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
#pragma omp parallel
{
#pragma omp single
{
for (i = 0; i < NUM_TASKS; i++)
{
<ompts:orphan>
#pragma omp task <ompts:check>firstprivate(sum)</ompts:check>
{
int j;
for (j = 0; j <= LOOPCOUNT; j++) {
#pragma omp flush
sum += j;
}
/* check if calculated sum was right */
if (sum != known_sum) {
#pragma omp critical
{ result++; }
}
} /* end of omp task */
</ompts:orphan>
} /* end of for */
} /* end of single */
} /* end of parallel*/
return (result == 0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,43 @@
<ompts:test>
<ompts:testdescription>Test which checks the if clause of the omp task directive. The idear of the tests is to generate a tasks in a single region and pause it immediately. The parent thread now shall set a counter variable which the paused task shall evaluate when woke up.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp task if</ompts:directive>
<ompts:dependences>omp single,omp flush</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_task_if</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int condition_false;
int count;
int result;
</ompts:orphan:vars>
count=0;
condition_false = (logFile == NULL);
#pragma omp parallel
{
#pragma omp single
{
<ompts:orphan>
#pragma omp task <ompts:check>if (condition_false)</ompts:check> shared(count, result)
{
my_sleep (SLEEPTIME_LONG);
//#pragma omp flush (count)
result = (0 == count);
} /* end of omp task */
</ompts:orphan>
count = 1;
//#pragma omp flush (count)
} /* end of single */
} /*end of parallel */
return result;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,51 @@
<ompts:test>
<ompts:testdescription> Test to see if implied private works properly</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp task</ompts:directive>
<ompts:dependences>omp single</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
/* Utility function do spend some time in a loop */
int <ompts:testcode:functionname>omp_task_imp_firstprivate</ompts:testcode:functionname> (FILE * logFile)
{
int i=5;
int k = 0;
int result = 0;
int task_result = 1;
#pragma omp parallel firstprivate(i)
{
#pragma omp single
{
for (k = 0; k < NUM_TASKS; k++)
{
#pragma omp task shared(result , task_result<ompts:crosscheck>, i</ompts:crosscheck>)
{
int j;
//check if i is private
if(i != 5)
task_result = 0;
for(j = 0; j < NUM_TASKS; j++)
i++;
//this should be firstprivate implicitly
}
}
#pragma omp taskwait
result = (task_result && i==5);
}
}
return result;
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,53 @@
<ompts:test>
<ompts:testdescription>Test which checks the private clause of the task directive. We create a set of tasks in a single region. We defines a variable named sum which gets declared private for each task. Now each task calcualtes a sum using this private variable. Before each calcualation step we introduce a flush command so that maybe the private variabel gets bad. At the end we check if the calculated sum was right.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp task private</ompts:directive>
<ompts:dependences>omp single,omp flush,omp critical</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
/* Utility function do spend some time in a loop */
int <ompts:testcode:functionname>omp_task_private</ompts:testcode:functionname> (FILE * logFile)
{
int i;
<ompts:orphan:vars>
int known_sum;
int sum = 0;
int result = 0; /* counts the wrong sums from tasks */
</ompts:orphan:vars>
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
#pragma omp parallel
{
#pragma omp single
{
for (i = 0; i < NUM_TASKS; i++)
{
<ompts:orphan>
#pragma omp task <ompts:check>private(sum)</ompts:check> shared(result, known_sum)
{
int j;
//if sum is private, initialize to 0
<ompts:check>sum = 0;</ompts:check>
for (j = 0; j <= LOOPCOUNT; j++) {
#pragma omp flush
sum += j;
}
/* check if calculated sum was right */
if (sum != known_sum) {
#pragma omp critical
result++;
}
} /* end of omp task */
</ompts:orphan>
} /* end of for */
} /* end of single */
} /* end of parallel*/
return (result == 0);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,47 @@
<ompts:test>
<ompts:testdescription> Test to see if implied shared works correctly</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp task</ompts:directive>
<ompts:dependences>omp single, omp task firstprivate</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
/* Utility function do spend some time in a loop */
int <ompts:testcode:functionname>omp_task_imp_shared</ompts:testcode:functionname> (FILE * logFile)
{
<ompts:orphan:vars>
int i;
</ompts:orphan:vars>
i=0;
int k = 0;
int result = 0;
#pragma omp parallel
{
#pragma omp single
for (k = 0; k < NUM_TASKS; k++)
{
<ompts:orphan>
#pragma omp task <ompts:crosscheck> firstprivate(i) </ompts:crosscheck> <ompts:check> shared(i)</ompts:check>
{
#pragma omp atomic
i++;
//this should be shared implicitly
}
</ompts:orphan>
}
}
result = i;
return ((result == NUM_TASKS));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,69 @@
<ompts:test>
<ompts:testdescription>Test for untied clause. First generate a set of tasks and pause it immediately. Then we resume half of them and check whether they are scheduled by different threads</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp task untied</ompts:directive>
<ompts:dependences>omp taskwait</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_task_untied</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int i;
int count;
int start_tid[NUM_TASKS];
int current_tid[NUM_TASKS];
</ompts:orphan:vars>
count = 0;
/*initialization*/
for (i=0; i< NUM_TASKS; i++){
start_tid[i]=0;
current_tid[i]=0;
}
#pragma omp parallel firstprivate(i)
{
#pragma omp single
{
for (i = 0; i < NUM_TASKS; i++) {
<ompts:orphan>
int myi = i;
#pragma omp task <ompts:check>untied</ompts:check>
{
my_sleep(SLEEPTIME);
start_tid[myi] = omp_get_thread_num();
current_tid[myi] = omp_get_thread_num();
#pragma omp taskwait
<ompts:check>if((start_tid[myi] %2) !=0){</ompts:check>
my_sleep(SLEEPTIME);
current_tid[myi] = omp_get_thread_num();
<ompts:check>
} /* end of if */
else {
current_tid[myi] = omp_get_thread_num();
}
</ompts:check>
} /*end of omp task */
</ompts:orphan>
} /* end of for */
} /* end of single */
} /* end of parallel */
for (i=0;i<NUM_TASKS; i++)
{
printf("start_tid[%d]=%d, current_tid[%d]=%d\n",i, start_tid[i], i , current_tid[i]);
if (current_tid[i] == start_tid[i])
count++;
}
return (count<NUM_TASKS);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,75 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp taskwait directive. First we generate a set of tasks, which set the elements of an array to a specific value. Then we do a taskwait and check if all tasks finished meaning all array elements contain the right value. Then we generate a second set setting the array elements to another value. After the parallel region we check if all tasks of the second set finished and were executed after the tasks of the first set.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp taskwait</ompts:directive>
<ompts:dependences>omp single,omp task</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_taskwait</ompts:testcode:functionname>(FILE * logFile){
int result1 = 0; /* Stores number of not finished tasks after the taskwait */
int result2 = 0; /* Stores number of wrong array elements at the end */
int array[NUM_TASKS];
int i;
/* fill array */
for (i = 0; i < NUM_TASKS; i++)
array[i] = 0;
#pragma omp parallel
{
#pragma omp single
{
for (i = 0; i < NUM_TASKS; i++) {
/* First we have to store the value of the loop index in a new variable
* which will be private for each task because otherwise it will be overwritten
* if the execution of the task takes longer than the time which is needed to
* enter the next step of the loop!
*/
int myi;
myi = i;
#pragma omp task
{
my_sleep (SLEEPTIME);
array[myi] = 1;
} /* end of omp task */
} /* end of for */
<ompts:orphan>
<ompts:check>#pragma omp taskwait</ompts:check>
</ompts:orphan>
/* check if all tasks were finished */
for (i = 0; i < NUM_TASKS; i++)
if (array[i] != 1)
result1++;
/* generate some more tasks which now shall overwrite
* the values in the tids array */
for (i = 0; i < NUM_TASKS; i++) {
int myi;
myi = i;
#pragma omp task
{
array[myi] = 2;
} /* end of omp task */
} /* end of for */
} /* end of single */
} /*end of parallel */
/* final check, if all array elements contain the right values: */
for (i = 0; i < NUM_TASKS; i++) {
if (array[i] != 2)
result2++;
}
return ((result1 == 0) && (result2 == 0));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,59 @@
<ompts:test>
<ompts:testdescription>Test taskyield directive. First generate a set of tasks and pause it immediately. Then we resume half of them and check whether they are scheduled by different threads</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp taskyield</ompts:directive>
<ompts:dependences>omp taskwait</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include <math.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
int <ompts:testcode:functionname>omp_taskyield</ompts:testcode:functionname>(FILE * logFile){
<ompts:orphan:vars>
int i;
int count = 0;
int start_tid[NUM_TASKS];
int current_tid[NUM_TASKS];
</ompts:orphan:vars>
for (i=0; i< NUM_TASKS; i++){
start_tid[i]=0;
current_tid[i]=0;
}
#pragma omp parallel
{
#pragma omp single
{
for (i = 0; i < NUM_TASKS; i++) {
<ompts:orphan>
int myi = i;
<ompts:check>#pragma omp task untied</ompts:check>
{
my_sleep(SLEEPTIME);
start_tid[myi] = omp_get_thread_num();
#pragma omp taskyield
if((start_tid[myi] %2) ==0){
my_sleep(SLEEPTIME);
current_tid[myi] = omp_get_thread_num();
} /*end of if*/
} /* end of omp task */
</ompts:orphan>
} /* end of for */
} /* end of single */
} /* end of parallel */
for (i=0;i<NUM_TASKS; i++)
{
//printf("start_tid[%d]=%d, current_tid[%d]=%d\n",i, start_tid[i], i , current_tid[i]);
if (current_tid[i] == start_tid[i])
count++;
}
return (count<NUM_TASKS);
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,47 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_testlock function. The test counts the threads entering and exiting a single region which is build with a test_lock in an endless loop.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_test_lock</ompts:directive>
<ompts:dependences>omp flush</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
omp_lock_t lck;
int <ompts:testcode:functionname>omp_test_lock</ompts:testcode:functionname>(FILE * logFile)
{
int nr_threads_in_single = 0;
int result = 0;
int nr_iterations = 0;
int i;
omp_init_lock (&lck);
#pragma omp parallel shared(lck)
{
#pragma omp for
for (i = 0; i < LOOPCOUNT; i++)
{
/*omp_set_lock(&lck);*/
<ompts:orphan>
<ompts:check>while (!omp_test_lock (&lck))
{};</ompts:check>
</ompts:orphan>
#pragma omp flush
nr_threads_in_single++;
#pragma omp flush
nr_iterations++;
nr_threads_in_single--;
result = result + nr_threads_in_single;
<ompts:check>omp_unset_lock (&lck);</ompts:check>
}
}
omp_destroy_lock(&lck);
return ((result == 0) && (nr_iterations == LOOPCOUNT));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,48 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_test_nest_lock function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_test_nest_lock</ompts:directive>
<ompts:dependences>omp flush</ompts:dependences>
<ompts:testcode>
#include <stdio.h>
#include "omp_testsuite.h"
static omp_nest_lock_t lck;
int <ompts:testcode:functionname>omp_test_nest_lock</ompts:testcode:functionname>(FILE * logFile)
{
int nr_threads_in_single = 0;
int result = 0;
int nr_iterations = 0;
int i;
omp_init_nest_lock (&lck);
#pragma omp parallel shared(lck)
{
#pragma omp for
for (i = 0; i < LOOPCOUNT; i++)
{
/*omp_set_lock(&lck);*/
<ompts:orphan>
<ompts:check>while(!omp_test_nest_lock (&lck))
{};</ompts:check>
</ompts:orphan>
#pragma omp flush
nr_threads_in_single++;
#pragma omp flush
nr_iterations++;
nr_threads_in_single--;
result = result + nr_threads_in_single;
<ompts:check>omp_unset_nest_lock (&lck);</ompts:check>
}
}
omp_destroy_nest_lock (&lck);
return ((result == 0) && (nr_iterations == LOOPCOUNT));
}
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,97 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp threadprivate directive by filling an array with random numbers in an parallelised region. Each thread generates one number of the array and saves this in a temporary threadprivate variable. In a second parallelised region the test controls, that the temporary variable contains still the former value by comparing it with the one in the array.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp threadprivate</ompts:directive>
<ompts:dependences>omp critical,omp_set_dynamic,omp_get_num_threads</ompts:dependences>
<ompts:testcode>
/*
* Threadprivate is tested in 2 ways:
* 1. The global variable declared as threadprivate should have
* local copy for each thread. Otherwise race condition and
* wrong result.
* 2. If the value of local copy is retained for the two adjacent
* parallel regions
*/
#include "omp_testsuite.h"
#include <stdlib.h>
#include <stdio.h>
static int sum0=0;
static int myvalue = 0;
<ompts:check>#pragma omp threadprivate(sum0)</ompts:check>
<ompts:check>#pragma omp threadprivate(myvalue)</ompts:check>
int <ompts:testcode:functionname>omp_threadprivate</ompts:testcode:functionname>(FILE * logFile)
{
int sum = 0;
int known_sum;
int i;
int iter;
int *data;
int size;
int failed = 0;
int my_random;
omp_set_dynamic(0);
#pragma omp parallel private(i)
{
sum0 = 0;
#pragma omp for
for (i = 1; i <= LOOPCOUNT; i++)
{
sum0 = sum0 + i;
} /*end of for*/
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical */
} /* end of parallel */
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
if (known_sum != sum ) {
fprintf (logFile, " known_sum = %d, sum = %d\n", known_sum, sum);
}
/* the next parallel region is just used to get the number of threads*/
omp_set_dynamic(0);
#pragma omp parallel
{
#pragma omp master
{
size=omp_get_num_threads();
data=(int*) malloc(size*sizeof(int));
}
}/* end parallel*/
srand(45);
for (iter = 0; iter < 100; iter++){
my_random = rand(); /* random number generator is called inside serial region*/
/* the first parallel region is used to initialiye myvalue and the array with my_random+rank*/
#pragma omp parallel
{
int rank;
rank = omp_get_thread_num ();
myvalue = data[rank] = my_random + rank;
}
/* the second parallel region verifies that the value of "myvalue" is retained */
#pragma omp parallel reduction(+:failed)
{
int rank;
rank = omp_get_thread_num ();
failed = failed + (myvalue != data[rank]);
if(myvalue != data[rank]){
fprintf (logFile, " myvalue = %d, data[rank]= %d\n", myvalue, data[rank]);
}
}
}
free (data);
return (known_sum == sum) && !failed;
} /* end of check_threadprivate*/
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,44 @@
<ompts:test>
<ompts:testdescription>Test which checks if a variable declared as threadprivate can be used as a loopindex.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp threadprivate</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
#include "omp_testsuite.h"
#include <stdlib.h>
#include <stdio.h>
static int i;
<ompts:check>#pragma omp threadprivate(i)</ompts:check>
int <ompts:testcode:functionname>omp_threadprivate_for</ompts:testcode:functionname>(FILE * logFile)
{
int known_sum;
int sum;
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
sum = 0;
#pragma omp parallel
{
int sum0 = 0;
#pragma omp for
for (i = 1; i <= LOOPCOUNT; i++)
{
sum0 = sum0 + i;
} /*end of for*/
#pragma omp critical
{
sum = sum + sum0;
} /*end of critical */
} /* end of parallel */
if (known_sum != sum ) {
fprintf (logFile, " known_sum = %d, sum = %d\n", known_sum, sum);
}
return (known_sum == sum);
} /* end of check_threadprivate*/
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,57 @@
subroutine print_result(s,crossfailed,M,name)
implicit none
character (len=*)::name
real cert
integer M,crossfailed
integer s
character (len=11) :: c
character (len=18) :: c2
cert=100.0*crossfailed/M
! print *, "cert", cert, "cross ", crossfailed
! test1=hundred*crossfailed
c="% certainty"
c2=" ... verified with "
if(s.eq.1) then
write (*,"(A, A, F7.2, A)") name, c2, cert, c
else
write (*,"(A,A)") name," ... FAILED"
endif
end
subroutine do_test(test_func,cross_test_func,name,N,failed,
x num_tests,crosschecked)
implicit none
integer succeed
integer crossfail
integer failed
integer, external::test_func
integer, external::cross_test_func
character (len=*)::name
integer fail
integer N,i
integer num_tests,crosschecked
num_tests=num_tests+1
succeed=1
crossfail=0
fail=0
do i=1,N
if(test_func().eq.0) then
succeed=0
fail=fail+1
exit
end if
if(cross_test_func().eq.0) then
! print *, crossfail
crossfail=crossfail+1.0
end if
enddo
if (fail .ne. 0) then
failed=failed+1
else
if(crossfail .ne. 0) then
crosschecked=crosschecked+1
end if
endif
call print_result(succeed,crossfail,N,name)
end

View File

@@ -0,0 +1,2 @@
# Add custom tests in this list
omp_parallel_copyin

View File

@@ -0,0 +1,36 @@
has_openmp
omp_nested
omp_get_num_threads
omp_in_parallel
do_ordered
do_reduction
do_private
do_firstprivate
do_lastprivate
section_reduction
section_private
section_firstprivate
section_lastprivate
single
single_private
single_nowait
par_do_ordered
par_do_reduction
par_do_private
par_do_firstprivate
par_do_lastprivate
par_section_reduction
par_section_private
par_section_firstprivate
par_section_lastprivate
omp_master_thread
omp_critical
omp_atomic
omp_barrier
omp_flush
omp_threadprivate
omp_copyin
omp_lock
omp_testlock
omp_nest_lock
omp_nest_testlock

View File

@@ -0,0 +1,5 @@
omp_num_threads
omp_workshare
omp_time
omp_ticks_time
single_copyprivate

View File

@@ -0,0 +1,57 @@
subroutine print_result(s,crossfailed,M,name)
implicit none
character (len=*)::name
real cert
integer M,crossfailed
integer s
character (len=11) :: c
character (len=18) :: c2
cert=100.0*crossfailed/M
! print *, "cert", cert, "cross ", crossfailed
! test1=hundred*crossfailed
c="% certainty"
c2=" ... verified with "
if(s.eq.1) then
write (*,"(A, A, F7.2, A)") name, c2, cert, c
else
write (*,"(A,A)") name," ... FAILED"
endif
end
subroutine do_test(test_func,cross_test_func,name,N,failed,
x num_tests,crosschecked)
implicit none
integer succeed
integer crossfail
integer failed
integer, external::test_func
integer, external::cross_test_func
character (len=*)::name
integer fail
integer N,i
integer num_tests,crosschecked
num_tests=num_tests+1
succeed=1
crossfail=0
fail=0
do i=1,N
if(test_func().eq.0) then
succeed=0
fail=fail+1
exit
end if
if(cross_test_func().eq.0) then
! print *, crossfail
crossfail=crossfail+1.0
end if
enddo
if (fail .ne. 0) then
failed=failed+1
else
if(crossfail .ne. 0) then
crosschecked=crosschecked+1
end if
endif
call print_result(succeed,crossfail,N,name)
end

View File

@@ -0,0 +1,67 @@
<ompts:test>
<ompts:testdescription>Test with omp for collapse clause. Bind with two loops. Without the collapse clause, the first loop will not be ordered</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp do collapse</ompts:directive>
<ompts:dependences>omp critical,omp do schedule</ompts:dependences>
<ompts:testcode>
LOGICAL FUNCTION check_is_larger(i)
implicit none
INTEGER :: i
INTEGER, save :: last_i
LOGICAL :: is_larger
if (i .eq. 1) last_i = 0
is_larger = (i .ge. last_i) .and. ((i-last_i) .le. 1)
last_i = i
check_is_larger = is_larger
END FUNCTION check_is_larger
INTEGER FUNCTION <ompts:testcode:functionname>do_collapse</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER i, j
<ompts:orphan:vars>
LOGICAL check_is_larger
LOGICAL my_is_larger
LOGICAL is_larger
COMMON /orphvars/ is_larger
</ompts:orphan:vars>
INCLUDE "omp_testsuite.f"
is_larger = .true.
!$omp parallel private(my_is_larger)
<ompts:orphan>
my_is_larger = .true.
!$omp do private(i,j) schedule(static,1) <ompts:check>collapse(2)</ompts:check>
!$omp+ ordered
DO i=1,100
<ompts:crosscheck>
my_is_larger = check_is_larger(i) .and. my_is_larger
</ompts:crosscheck>
DO j=1,00
<ompts:check>
!$omp ordered
my_is_larger = check_is_larger(i) .and. my_is_larger
!$omp end ordered
</ompts:check>
END DO
END DO
!$omp end do
!$omp critical
is_larger = is_larger .and. my_is_larger
!$omp end critical
</ompts:orphan>
!$omp end parallel
if (is_larger) then
<testfunctionname></testfunctionname> = 1
else
<testfunctionname></testfunctionname> = 0
end if
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,56 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp do firstprivate clause by counting up a variable in a parallelized loop. Each thread has a firstprivate variable (1) and an variable (2) declared by do firstprivate. First it stores the result of its last iteration in variable (2). Then it stores the value of the variable (2) in its firstprivate variable (1). At the end all firstprivate variables (1) are added to a total sum in a critical section and compared with the correct result.</ompts:testdescription>
<ompts:version>2.0</ompts:version>
<ompts:directive>omp do firstprivate</ompts:directive>
<ompts:dependences>omp parallel private, omp critical</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>do_firstprivate</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER sum, known_sum
INTEGER numthreads
INTEGER omp_get_num_threads
<ompts:orphan:vars>
INTEGER sum0, sum1, i
COMMON /orphvars/ sum0, sum1, i
</ompts:orphan:vars>
INCLUDE "omp_testsuite.f"
sum = 0
sum0 = 12345
sum1 = 0
!$omp parallel firstprivate(sum1)
!$omp single
numthreads = omp_get_num_threads()
!$omp end single
<ompts:orphan>
!$omp do <ompts:check>firstprivate(sum0)</ompts:check><ompts:crosscheck>private (sum0)</ompts:crosscheck>
DO i=1,LOOPCOUNT
sum0 = sum0 + i
sum1 = sum0
END DO
!$omp end do
</ompts:orphan>
!$omp critical
WRITE (1,*) sum0
sum = sum + sum1
!$omp end critical
!$omp end parallel
known_sum=12345*numthreads+ (LOOPCOUNT*(LOOPCOUNT+1))/2
IF ( known_sum .EQ. sum ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
WRITE (1,*) "Found sum was", sum, "instead of", known_sum
<testfunctionname></testfunctionname> = 0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,39 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp do lastprivate clause by counting up a variable in a parallelized loop. Each thread saves the next summand in a lastprivate variable i0. At the end i0 is compared to the value of the expected last summand.</ompts:testdescription>
<ompts:version>2.0</ompts:version>
<ompts:directive>omp do private</ompts:directive>
<ompts:dependences>omp parallel firstprivate, omp critical</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>do_lastprivate</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER sum,known_sum
<ompts:orphan:vars>
INTEGER sum0,i0,i
COMMON /orphvars/ sum0,i0,i
</ompts:orphan:vars>
INCLUDE "omp_testsuite.f"
sum = 0
sum0 = 0
i0 = -1
!$omp parallel firstprivate(sum0)
<ompts:orphan>
!$omp do schedule(static,7) <ompts:check>lastprivate(i0)</ompts:check>
DO i=1, LOOPCOUNT
sum0 = sum0 + i
i0 = i
END DO
<ompts:check>!$omp end do</ompts:check>
</ompts:orphan>
!$omp critical
sum = sum + sum0
!$omp end critical
!$omp end parallel
known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2
IF ( known_sum .EQ. sum .AND. i0 .EQ. LOOPCOUNT ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,73 @@
<ompts:test>
<ompts:directive>do ordered</ompts:directive>
<ompts:version>2.0</ompts:version>
<ompts:dependences>parallel private, critical</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION i_islarger(i)
IMPLICIT NONE
INTEGER i, islarger
INTEGER last_i
COMMON /mycom/ last_i
IF ( i .GT. last_i) THEN
islarger = 1
ELSE
islarger = 0
END If
last_i = i
i_islarger = islarger
END
INTEGER FUNCTION <ompts:testcode:functionname>do_ordered</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER known_sum, is_larger
INTEGER last_i
INTEGER i_islarger
COMMON /mycom/ last_i
<ompts:orphan:parms> i </ompts:orphan:parms>
<ompts:orphan:vars>
INTEGER sum, i, my_islarger
COMMON /orphvars/ my_islarger, sum
</ompts:orphan:vars>
sum = 0
is_larger = 1
last_i = 0
!$omp parallel private(my_islarger)
my_islarger = 1
!$omp do schedule(static,1) ordered
DO i=1, 99
<ompts:orphan>
<ompts:check>
!$omp ordered
</ompts:check>
IF (i_islarger(i) .EQ. 1 .AND. my_islarger .EQ. 1) THEN
my_islarger = 1
ELSE
my_islarger = 0
END IF
sum = sum + i
<ompts:check>
!$omp end ordered
</ompts:check>
</ompts:orphan>
END DO
!$omp end do
!$omp critical
IF (is_larger .EQ. 1 .AND. my_islarger .EQ. 1 ) THEN
is_larger = 1
ELSE
is_larger = 0
END IF
!$omp end critical
!$omp end parallel
known_sum = (99*100)/2
IF ( known_sum .EQ. sum .AND. is_larger .EQ. 1) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,67 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp do private clause by counting up a variable in a parallelized loop. Each thread has a private variable (1) and an variable (2) declared by for private. First it stores the result of its last iteration in variable (2). Then this thread waits some time before it stores the value of the variable (2) in its private variable (1). At the beginning of the next iteration the value of (1) is assigned to (2). At the end all private variables (1) are added to a total sum in a critical section and compared with the correct result.</ompts:testdescription>
<ompts:version>2.0</ompts:version>
<ompts:directive>omp do private</ompts:directive>
<ompts:dependences>omp parallel private, omp flush, omp critical</ompts:dependences>
<ompts:testcode>
SUBROUTINE do_some_work()
IMPLICIT NONE
INTEGER i
INTRINSIC sqrt
DOUBLE PRECISION sum
INCLUDE "omp_testsuite.f"
sum=0.0
DO i=0, LOOPCOUNT-1
sum = sum + sqrt(REAL(i))
ENDDO
END
INTEGER FUNCTION <ompts:testcode:functionname>do_private</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER sum, known_sum
<ompts:orphan:vars>
INTEGER sum0, sum1, i
COMMON /orphvars/ sum0, sum1, i
</ompts:orphan:vars>
INCLUDE "omp_testsuite.f"
sum = 0
sum0 = 0
sum1 = 0
!$omp parallel private(sum1)
sum0 = 0
sum1 = 0
<ompts:orphan>
!$omp do <ompts:check>private(sum0)</ompts:check> schedule(static,1)
DO i=1, LOOPCOUNT
sum0 = sum1
!$omp flush
sum0 = sum0 + i
CALL do_some_work()
!$omp flush
! print *, sum0
sum1 = sum0
END DO
!$omp end do
</ompts:orphan>
!$omp critical
sum = sum + sum1
!$omp end critical
!$omp end parallel
known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2
! print *, "sum:", sum, "known_sum", known_sum
IF ( known_sum .EQ. sum) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,514 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp do reduction directive wich all its options.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp do reduction</ompts:directive>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>do_reduction</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER sum2, known_sum
INTEGER known_product
DOUBLE PRECISION rounding_error, dpt
INTEGER double_DIGITS
DOUBLE PRECISION dknown_sum
INTEGER result
INCLUDE "omp_testsuite.f"
PARAMETER (known_product=3628800)
PARAMETER (rounding_error=1.E-6)
<ompts:orphan:vars>
INTEGER sum,diff,product,i
DOUBLE PRECISION dsum,ddiff,dt
LOGICAL logic_and, logic_or, logic_eqv,logic_neqv
LOGICAL logics(LOOPCOUNT)
INTEGER bit_and, bit_or
INTEGER exclusiv_bit_or
INTEGER min_value, max_value
INTEGER int_array(LOOPCOUNT)
DOUBLE PRECISION d_array(LOOPCOUNT)
DOUBLE PRECISION dmin, dmax
COMMON /orphvars/ sum,product,diff,i,dsum,ddiff,dt,logic_and,
& logic_or,logic_eqv,logic_neqv,logics,bit_and,bit_or,int_array,
& exclusiv_bit_or,min_value,dmin,dmax,d_array,max_value
INTEGER MAX_FACTOR
PARAMETER (double_DIGITS=20,MAX_FACTOR=10)
</ompts:orphan:vars>
dt = 1./3.
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2
product = 1
sum2 = 0
sum = 0
dsum = 0.
result =0
logic_and = .true.
logic_or = .false.
bit_and = 1
bit_or = 0
exclusiv_bit_or = 0
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic, 1) <ompts:check>reduction(+:sum)</ompts:check>
DO i = 1, LOOPCOUNT
sum = sum + i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (known_sum .NE. sum) THEN
result = result + 1
WRITE(1,*) "Error in sum with integers: Result was ",
& sum,"instead of ", known_sum
END IF
diff = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic, 1) <ompts:check>reduction (-: diff)</ompts:check>
DO i = 1, LOOPCOUNT
diff = diff - i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( diff .NE. 0 ) THEN
result = result + 1
WRITE(1,*) "Error in difference with integers: Result was ",
& sum,"instead of 0."
END IF
!... Test for doubles
dsum =0.
dpt = 1
DO i=1, DOUBLE_DIGITS
dpt= dpt * dt
END DO
dknown_sum = (1-dpt)/(1-dt)
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(+:dsum)</ompts:check>
DO i=0,DOUBLE_DIGITS-1
dsum = dsum + dt**i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF(dsum .NE. dknown_sum .AND.
& ABS(dsum - dknown_sum) .GT. rounding_error ) THEN
result = result + 1
WRITE(1,*) "Error in sum with doubles: Result was ",
& dsum,"instead of ",dknown_sum,"(Difference: ",
& dsum - dknown_sum,")"
END IF
dpt = 1
DO i=1, DOUBLE_DIGITS
dpt = dpt*dt
END DO
ddiff = ( 1-dpt)/(1-dt)
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(-:ddiff)</ompts:check>
DO i=0, DOUBLE_DIGITS-1
ddiff = ddiff - dt**i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( ABS(ddiff) .GT. rounding_error ) THEN
result = result + 1
WRITE(1,*) "Error in Difference with doubles: Result was ",
& ddiff,"instead of 0.0"
END IF
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(*:product)</ompts:check>
DO i=1,MAX_FACTOR
product = product * i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (known_product .NE. product) THEN
result = result + 1
write(1,*) "Error in Product with integers: Result was ",
& product," instead of",known_product
END IF
DO i=1,LOOPCOUNT
logics(i) = .TRUE.
END DO
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(.AND.:logic_and)</ompts:check>
DO i=1,LOOPCOUNT
logic_and = logic_and .AND. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (.NOT. logic_and) THEN
result = result + 1
WRITE(1,*) "Error in logic AND part 1"
END IF
logic_and = .TRUE.
logics(LOOPCOUNT/2) = .FALSE.
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(.AND.:logic_and)</ompts:check>
DO i=1,LOOPCOUNT
logic_and = logic_and .AND. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (logic_and) THEN
result = result + 1
WRITE(1,*) "Error in logic AND pass 2"
END IF
DO i=1, LOOPCOUNT
logics(i) = .FALSE.
END DO
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(.OR.:logic_or)</ompts:check>
DO i = 1, LOOPCOUNT
logic_or = logic_or .OR. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (logic_or) THEN
result = result + 1
WRITE(1,*) "Error in logic OR part 1"
END IF
logic_or = .FALSE.
logics(LOOPCOUNT/2) = .TRUE.
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(.OR.:logic_or)</ompts:check>
DO i=1,LOOPCOUNT
logic_or = logic_or .OR. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( .NOT. logic_or ) THEN
result = result + 1
WRITE(1,*) "Error in logic OR part 2"
END IF
!... Test logic EQV, unique in Fortran
DO i=1, LOOPCOUNT
logics(i) = .TRUE.
END DO
logic_eqv = .TRUE.
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(.EQV.:logic_eqv)</ompts:check>
DO i = 1, LOOPCOUNT
logic_eqv = logic_eqv .EQV. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (.NOT. logic_eqv) THEN
result = result + 1
WRITE(1,*) "Error in logic EQV part 1"
END IF
logic_eqv = .TRUE.
logics(LOOPCOUNT/2) = .FALSE.
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(.EQV.:logic_eqv)</ompts:check>
DO i=1,LOOPCOUNT
logic_eqv = logic_eqv .EQV. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( logic_eqv ) THEN
result = result + 1
WRITE(1,*) "Error in logic EQV part 2"
END IF
!... Test logic NEQV, which is unique in Fortran
DO i=1, LOOPCOUNT
logics(i) = .FALSE.
END DO
logic_neqv = .FALSE.
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(.NEQV.:logic_neqv)</ompts:check>
DO i = 1, LOOPCOUNT
logic_neqv = logic_neqv .NEQV. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (logic_neqv) THEN
result = result + 1
WRITE(1,*) "Error in logic NEQV part 1"
END IF
logic_neqv = .FALSE.
logics(LOOPCOUNT/2) = .TRUE.
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(.neqv.:logic_neqv)</ompts:check>
DO i=1,LOOPCOUNT
logic_neqv = logic_neqv .NEQV. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( .NOT. logic_neqv ) THEN
result = result + 1
WRITE(1,*) "Error in logic NEQV part 2"
END IF
DO i=1, LOOPCOUNT
int_array(i) = 1
END DO
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(IAND:bit_and)</ompts:check>
DO i=1, LOOPCOUNT
!... iand(I,J): Returns value resulting from boolean AND of
!... pair of bits in each of I and J.
bit_and = IAND(bit_and,int_array(i))
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( bit_and .LT. 1 ) THEN
result = result + 1
WRITE(1,*) "Error in IAND part 1"
END IF
bit_and = 1
int_array(LOOPCOUNT/2) = 0
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(IAND:bit_and)</ompts:check>
DO i=1, LOOPCOUNT
bit_and = IAND ( bit_and, int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF( bit_and .GE. 1) THEN
result = result + 1
WRITE(1,*) "Error in IAND part 2"
END IF
DO i=1, LOOPCOUNT
int_array(i) = 0
END DO
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(IOR:bit_or)</ompts:check>
DO i=1, LOOPCOUNT
!... Ior(I,J): Returns value resulting from boolean OR of
!... pair of bits in each of I and J.
bit_or = IOR(bit_or, int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( bit_or .GE. 1) THEN
result = result + 1
WRITE(1,*) "Error in Ior part 1"
END IF
bit_or = 0
int_array(LOOPCOUNT/2) = 1
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(IOR:bit_or)</ompts:check>
DO i=1, LOOPCOUNT
bit_or = IOR(bit_or, int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( bit_or .LE. 0) THEN
result = result + 1
WRITE(1,*) "Error in Ior part 2"
END IF
DO i=1, LOOPCOUNT
int_array(i) = 0
END DO
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(IEOR:exclusiv_bit_or)</ompts:check>
DO i = 1, LOOPCOUNT
exclusiv_bit_or = ieor(exclusiv_bit_or, int_array(i))
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( exclusiv_bit_or .ge. 1) THEN
result = result + 1
WRITE(1,*) "Error in Ieor part 1"
END IF
exclusiv_bit_or = 0
int_array(LOOPCOUNT/2) = 1
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(IEOR:exclusiv_bit_or)</ompts:check>
DO i = 1, LOOPCOUNT
exclusiv_bit_or = IEOR(exclusiv_bit_or, int_array(i))
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( exclusiv_bit_or .LE. 0) THEN
result = result + 1
WRITE(1,*) "Error in Ieor part 2"
END IF
DO i=1,LOOPCOUNT
int_array(i) = 10 - i
END DO
min_value = 65535
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(MIN:min_value)</ompts:check>
DO i = 1, LOOPCOUNT
min_value = MIN(min_value,int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( min_value .GT. (10-LOOPCOUNT) )THEN
result = result + 1
WRITE(1,*) "Error in integer MIN"
END IF
DO i=1,LOOPCOUNT
int_array(i) = i
END DO
max_value = -32768
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(MAX:max_value)</ompts:check>
DO i = 1, LOOPCOUNT
max_value = MAX(max_value,int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( max_value .LT. LOOPCOUNT )THEN
result = result + 1
WRITE(1,*) "Error in integer MAX"
END IF
!... test double min, max
DO i=1,LOOPCOUNT
d_array(i) = 10 - i*dt
END DO
dmin = 2**10
dt = 0.5
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(MIN:dmin)</ompts:check>
DO i = 1, LOOPCOUNT
dmin= MIN(dmin,d_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( dmin .GT. (10-dt) )THEN
result = result + 1
WRITE(1,*) "Error in double MIN"
END IF
DO i=1,LOOPCOUNT
d_array(i) = i * dt
END DO
dmax= - (2**10)
!$omp parallel
<ompts:orphan>
!$omp do schedule(dynamic,1) <ompts:check>reduction(MAX:dmax)</ompts:check>
DO i = 1, LOOPCOUNT
dmax= MAX(dmax,d_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( dmax .LT. LOOPCOUNT*dt )THEN
result = result + 1
WRITE(1,*) "Error in double MAX"
END IF
IF ( result .EQ. 0 ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,90 @@
<ompts:test>
<ompts:testdescription>Test which checks the dynamic option of the omp do schedule directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp do schedule(dynamic)</ompts:directive>
<ompts:dependences>omp flush,omp do nowait,omp critical,omp single</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>do_schedule_dynamic</ompts:testcode:functionname>()
IMPLICIT NONE
CHARACTER*30 logfile
INTEGER omp_get_thread_num,omp_get_num_threads
INTEGER threads
INTEGER count, tmp_count
INTEGER,ALLOCATABLE:: tmp(:)
INTEGER ii
INTEGER result
<ompts:orphan:vars>
INTEGER CFDMAX_SIZE
PARAMETER (CFDMAX_SIZE = 1000)
INTEGER i,tids(0:CFDMAX_SIZE-1),tid,chunk_size
COMMON /orphvars/ i,tids,tid,chunk_size
</ompts:orphan:vars>
chunk_size = 7
count = 0
tmp_count = 0
result = 0
ii = 0
!$omp parallel private(tid)
tid = omp_get_thread_num()
<ompts:orphan>
!$omp do <ompts:check>schedule(dynamic,chunk_size)</ompts:check>
DO i=0, CFDMAX_SIZE-1
tids(i) = tid
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
DO i=0, CFDMAX_SIZE - 2
IF ( tids(i) .ne. tids(i+1) ) THEN
count = count + 1
END IF
END DO
ALLOCATE( tmp(0:count) )
tmp(0) = 1
DO i = 0, CFDMAX_SIZE - 2
IF ( tmp_count .GT. count ) THEN
WRITE(*,*) "--------------------"
WRITE(*,*) "Testinternal Error: List too small!!!"
WRITE(*,*) "--------------------"
GOTO 10
END If
IF ( tids(i) .NE. tids(i+1) ) then
tmp_count = tmp_count + 1
tmp(tmp_count) = 1
ELSE
tmp(tmp_count) = tmp(tmp_count) +1
END IF
END DO
!... is dynamic statement working?
10 DO i=0, count -1
IF ( MOD(tmp(i),chunk_size) .ne. 0 ) THEN
! ... it is possible for 2 adjacent chunks assigned to a same thread
result = result + 1
WRITE(1,*) "The intermediate dispatch has wrong chunksize."
END IF
END DO
IF ( MOD(tmp(count), chunk_size) .NE.
& MOD (CFDMAX_SIZE, chunk_size) ) THEN
result = result + 1
WRITE(1,*) "the last dispatch has wrong chunksize."
END IF
IF ( result .eq. 0) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,174 @@
<ompts:test>
<ompts:testdescription>Test which checks the guided option of the omp do schedule directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp do schedule(guided)</ompts:directive>
<ompts:dependences>omp flush,omp do nowait,omp critical,omp single</ompts:dependences>
<ompts:testcode>
! TODO:
! C. Niethammer:
! Find check to decide if the test was run as schedule(static) because
! this also can pass the test if the work is devided into thread-counts
INTEGER FUNCTION <ompts:testcode:functionname>do_schedule_guided</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER omp_get_thread_num,omp_get_num_threads
CHARACTER*20 logfile
INTEGER threads
INTEGER tmp_count
INTEGER, allocatable :: tmp(:)
INTEGER ii, flag
INTEGER result
INTEGER expected
INTEGER openwork
DOUBLE PRECISION c
<ompts:orphan:vars>
INTEGER i
INTEGER tid
INTEGER count
INTEGER DELAY
INTEGER MAX_TIME
INTEGER CFSMAX_SIZE
! ... choose small iteration space for small sync. overhead
PARAMETER (DELAY = 1)
PARAMETER (MAX_TIME = 5)
PARAMETER (CFSMAX_SIZE = 150)
INTEGER notout
INTEGER maxiter
INTEGER tids(0:CFSMAX_SIZE-1)
COMMON /orphvars/ notout,maxiter,tids
</ompts:orphan:vars>
result = 0
notout = 1
maxiter = 0
count = 0
tmp_count = 0
openwork = CFSMAX_SIZE
<ompts:check>
! Determine the number of available threads
!$omp parallel
!$omp single
threads = omp_get_num_threads()
!$omp end single
!$omp end parallel
IF ( threads .LT. 2) THEN
PRINT *,"This test only works with at least two threads"
WRITE(1,*) "This test only works with at least two threads"
<testfunctionname></testfunctionname> = 0
STOP
END IF
! ... Now the real parallel work:
! ... Each thread will start immediately with the first chunk.
!$omp parallel private(tid,count) shared(tids,maxiter)
tid = omp_get_thread_num()
<ompts:orphan>
!$omp do schedule(guided)
DO i = 0 , CFSMAX_SIZE-1
count = 0
!$omp flush(maxiter)
IF ( i .GT. maxiter ) THEN
!$omp critical
maxiter = i
!$omp end critical
END IF
!.. if it is not our turn we wait
! a) until another thread executed an iteration
! with a higher iteration count
! b) we are at the end of the loop (first thread finished
! and set notout=0 OR
! c) timeout arrived
!$omp flush(maxiter,notout)
IF ( notout .GE. 1 .AND. count .LT. MAX_TIME
& .AND. maxiter .EQ. i ) THEN
DO WHILE ( notout .GE. 1 .AND. count .LT. MAX_TIME
& .AND. maxiter .EQ. i )
CALL sleep(DELAY)
count = count + DELAY
END DO
END IF
tids(i) = tid
END DO
!$omp end do nowait
</ompts:orphan>
notout = 0
!$omp flush(notout)
!$omp end parallel
!*******************************************************!
! evaluation of the values
!*******************************************************!
count = 0
DO i=0, CFSMAX_SIZE - 2
IF ( tids(i) .NE. tids(i+1) ) THEN
count = count + 1
END IF
END DO
ALLOCATE( tmp(0:count) )
tmp_count = 0
tmp(0) = 1
! ... calculate the chunksize for each dispatch
DO i=0, CFSMAX_SIZE - 2
IF ( tids(i) .EQ. tids(i+1) ) THEN
tmp(tmp_count) = tmp(tmp_count) + 1
ELSE
tmp_count = tmp_count + 1
tmp(tmp_count) = 1
END IF
END DO
! ... Check if chunk sizes are decreased until equals to
! ... the specified one, ignore the last dispatch
! ... for possible smaller remainder
! Determine the constant
expected = openwork / threads
c = real(tmp(0)) / real(expected)
WRITE(1,*) "Found constant to be ", c
DO i = 0, count - 2
WRITE(1,*) "open:", openwork, "size:", tmp(i)
IF (expected .GT. 1) THEN
expected = c * openwork / threads
END IF
IF (abs(tmp(i) - expected) .GE. 2 ) THEN
result = 1
WRITE(1,*) "Chunksize differed from expected ",
& "value: ",tmp(i), "instead ", expected
END IF
IF (i .GT. 0 .AND. (tmp(i-1) - tmp(i)) .LT. 0) THEN
WRITE(1,*) "Chunksize did not decrease: ", tmp(i),
& "instead",tmp(i-1)
END IF
openwork = openwork - tmp(i)
END DO
IF ( result .EQ. 0 ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:check>
<ompts:crosscheck>
<testfunctionname></testfunctionname> = 0
END
</ompts:crosscheck>
</ompts:testcode>
</omtps:test>

View File

@@ -0,0 +1,70 @@
<ompts:test>
<ompts:testdescription>Test which checks the static option of the omp do schedule directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp do schedule(static)</ompts:directive>
<ompts:dependences>omp do nowait,omp flush,omp critical,omp single</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>do_schedule_static</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER omp_get_thread_num,omp_get_num_threads
CHARACTER*30 logfile
INTEGER threads
INTEGER count
INTEGER ii
INTEGER result
<ompts:orphan:vars>
INTEGER CFSMAX_SIZE
PARAMETER (CFSMAX_SIZE = 1000)
INTEGER i,tids(0:CFSMAX_SIZE-1), tid, chunk_size
COMMON /orphvars/ i,tid,tids,chunk_size
</ompts:orphan:vars>
chunk_size = 7
result = 0
ii = 0
!$omp parallel
!$omp single
threads = omp_get_num_threads()
!$omp end single
!$omp end parallel
IF ( threads .LT. 2) THEN
PRINT *,"This test only works with at least two threads"
WRITE(1,*) "This test only works with at least two threads"
<testfunctionname></testfunctionname> = 0
STOP
ELSE
WRITE(1,*) "Using an internal count of ",CFSMAX_SIZE
WRITE(1,*) "Using a specified chunksize of ",chunk_size
!$omp parallel private(tid) shared(tids)
tid = omp_get_thread_num()
<ompts:orphan>
!$omp do <ompts:check>schedule(static,chunk_size)</ompts:check>
DO i = 0 ,CFSMAX_SIZE -1
tids(i) = tid
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
DO i = 0, CFSMAX_SIZE-1
!... round-robin for static chunk
ii = mod( i/chunk_size,threads)
IF (tids(i) .NE. ii ) THEN
result = result + 1
WRITE(1,*)"Iteration ",i,"should be assigned to ",
& ii,"instead of ",tids(i)
END IF
END DO
IF ( result .EQ. 0 )THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,25 @@
<ompts:test>
<ompts:version>2.0</ompts:version>
<ompts:testdescription>Testing if the conditional compilation is supported or not.
Yi Wen at 05032004: Do we want to write two versions of has_omp? both C23456789
and #ifdef formats are supposed to work. At least Sun's compiler cannot deal with
the second format (#ifdef)</ompts:testdescription>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>has_openmp</ompts:testcode:functionname>()
<testfunctionname></testfunctionname> = 0
<ompts:check>
!version 1.
!C23456789
!$ <testfunctionname></testfunctionname> = 1
! version 2.
!#ifdef _OPENMP
<testfunctionname></testfunctionname> = 1
!#endif
</ompts:check>
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,588 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp atomic directive by counting up a variable in a parallelized loop with an atomic directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp atomic</ompts:directive>
<ompts:testcode>
!********************************************************************
! Functions: omp_atomic
! change "character*20" into "character (LEN=20)::"
! get rid of the "tab" key by Zhenying Liu, on Oct. 16, 2005.
!********************************************************************
INTEGER FUNCTION <ompts:testcode:functionname>omp_atomic</ompts:testcode:functionname>()
IMPLICIT NONE
INCLUDE "omp_testsuite.f"
INTEGER sum2, known_sum
INTEGER known_product, int_const
DOUBLE PRECISION rounding_error, dpt
INTEGER double_DIGITS
DOUBLE PRECISION dknown_sum
INTEGER result
PARAMETER (int_const=10,known_product=3628800)
PARAMETER (rounding_error=1.E-2)
<ompts:orphan:vars>
INTEGER sum,i,diff,product
DOUBLE PRECISION dsum,dt,ddiff
LOGICAL logic_and, logic_or, logic_eqv,logic_neqv
INTEGER bit_and, bit_or
INTEGER exclusiv_bit_or
INTEGER min_value, max_value
DOUBLE PRECISION dmin, dmax
LOGICAL logics(LOOPCOUNT)
INTEGER int_array(LOOPCOUNT)
DOUBLE PRECISION d_array(LOOPCOUNT)
COMMON /orphvars/ sum,product,diff,i,dsum,ddiff,dt,logic_and,
& logic_or,logic_eqv,logic_neqv,logics,bit_and,bit_or,int_array,
& exclusiv_bit_or,min_value,dmin,dmax,d_array,max_value
INTEGER MAX_FACTOR
PARAMETER (double_DIGITS=20,MAX_FACTOR=10)
</ompts:orphan:vars>
dt = 1./3.
known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2
product = 1
sum2 = 0
sum = 0
dsum = 0.
result =0
logic_and = .true.
logic_or = .false.
bit_and = 1
bit_or = 0
exclusiv_bit_or = 0
!$omp parallel
<ompts:orphan>
!$omp do
DO i =1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
sum = sum + i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (known_sum .NE. sum) THEN
result = result + 1
WRITE(1,*) "Error in sum with integers: Result was ",
& sum,"instead of ", known_sum
END If
diff = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2
!$omp parallel
<ompts:orphan>
!$omp do
DO i =1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
diff = diff - i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( diff .NE. 0 ) THEN
result = result + 1
WRITE(1,*) "Error in difference with integers: Result was ",
& diff,"instead of 0."
END IF
!... Test for doubles
dsum = 0.
dpt = 1
DO i=1, DOUBLE_DIGITS
dpt= dpt * dt
END DO
dknown_sum = (1-dpt)/(1-dt)
!$omp parallel
<ompts:orphan>
!$omp do
DO i=0,DOUBLE_DIGITS-1
<ompts:check>
!$omp atomic
</ompts:check>
dsum = dsum + dt**i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (dsum .NE. dknown_sum .AND.
& ABS(dsum - dknown_sum) .GT. rounding_error ) THEN
result = result + 1
WRITE(1,*) "Error in sum with doubles: Result was ",
& dsum,"instead of ",dknown_sum,"(Difference: ",
& dsum - dknown_sum,")"
END IF
dpt = 1
DO i=1, DOUBLE_DIGITS
dpt = dpt*dt
END DO
ddiff = ( 1-dpt)/(1-dt)
!$omp parallel
<ompts:orphan>
!$omp do
DO i=0, DOUBLE_DIGITS-1
<ompts:check>
!$omp atomic
</ompts:check>
ddiff = ddiff - dt**i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( ABS(ddiff) .GT. rounding_error ) THEN
result = result + 1
WRITE(1,*) "Error in Difference with doubles: Result was ",
& ddiff,"instead of 0.0"
END IF
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1,MAX_FACTOR
<ompts:check>
!$omp atomic
</ompts:check>
product = product * i
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (known_product .NE. product) THEN
result = result + 1
WRITE(1,*) "Error in Product with integers: Result was ",
& product," instead of",known_product
END IF
DO i=1,LOOPCOUNT
logics(i) = .TRUE.
END DO
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1,LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
logic_and = logic_and .AND. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (.NOT. logic_and) THEN
result = result + 1
WRITE(1,*) "Error in logic AND part 1"
END IF
logic_and = .TRUE.
logics(LOOPCOUNT/2) = .FALSE.
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1,LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
logic_and = logic_and .AND. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (logic_and) THEN
result = result + 1
WRITE(1,*) "Error in logic AND pass 2"
END IF
DO i=1, LOOPCOUNT
logics(i) = .FALSE.
END DO
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
logic_or = logic_or .OR. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (logic_or) THEN
result = result + 1
WRITE(1,*) "Error in logic OR part 1"
END IF
logic_or = .FALSE.
logics(LOOPCOUNT/2) = .TRUE.
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1,LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
logic_or = logic_or .OR. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( .NOT. logic_or ) THEN
result = result + 1
WRITE(1,*) "Error in logic OR part 2"
END IF
!... Test logic EQV, unique in Fortran
DO i=1, LOOPCOUNT
logics(i) = .TRUE.
END DO
logic_eqv = .TRUE.
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
logic_eqv = logic_eqv .EQV. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (.NOT. logic_eqv) THEN
result = result + 1
WRITE(1,*) "Error in logic EQV part 1"
END IF
logic_eqv = .TRUE.
logics(LOOPCOUNT/2) = .FALSE.
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1,LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
logic_eqv = logic_eqv .EQV. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( logic_eqv ) THEN
result = result + 1
WRITE(1,*) "Error in logic EQV part 2"
END IF
!... Test logic NEQV, which is unique in Fortran
DO i=1, LOOPCOUNT
logics(i) = .FALSE.
END DO
logic_neqv = .FALSE.
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
logic_neqv = logic_neqv .OR. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF (logic_neqv) THEN
result = result + 1
WRITE(1,*) "Error in logic NEQV part 1"
END IF
logic_neqv = .FALSE.
logics(LOOPCOUNT/2) = .TRUE.
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1,LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
logic_neqv = logic_neqv .OR. logics(i)
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( .NOT. logic_neqv ) THEN
result = result + 1
WRITE(1,*) "Error in logic NEQV part 2"
END IF
DO i=1, LOOPCOUNT
int_array(i) = 1
END DO
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1, LOOPCOUNT
!... iand(I,J): Returns value resulting from boolean AND of
!... pair of bits in each of I and J.
<ompts:check>
!$omp atomic
</ompts:check>
bit_and = IAND(bit_and,int_array(i))
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( bit_and .LT. 1 ) THEN
result = result + 1
WRITE(1,*) "Error in IAND part 1"
END If
bit_and = 1
int_array(LOOPCOUNT/2) = 0
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
bit_and = IAND ( bit_and, int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF( bit_and .GE. 1) THEN
result = result + 1
WRITE(1,*) "Error in IAND part 2"
END IF
DO i=1, LOOPCOUNT
int_array(i) = 0
END DO
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1, LOOPCOUNT
!... Ior(I,J): Returns value resulting from boolean OR of
!... pair of bits in each of I and J.
<ompts:check>
!$omp atomic
</ompts:check>
bit_or = Ior(bit_or, int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( bit_or .GE. 1) THEN
result = result + 1
WRITE(1,*) "Error in Ior part 1"
END IF
bit_or = 0
int_array(LOOPCOUNT/2) = 1
!$omp parallel
<ompts:orphan>
!$omp do
DO i=1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
bit_or = IOR(bit_or, int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( bit_or .le. 0) THEN
result = result + 1
WRITE(1,*) "Error in Ior part 2"
END IF
DO i=1, LOOPCOUNT
int_array(i) = 0
END DO
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
exclusiv_bit_or = IEOR(exclusiv_bit_or, int_array(i))
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( exclusiv_bit_or .GE. 1) THEN
result = result + 1
WRITE(1,*) "Error in Ieor part 1"
END IF
exclusiv_bit_or = 0
int_array(LOOPCOUNT/2) = 1
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
exclusiv_bit_or = ieor(exclusiv_bit_or, int_array(i))
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( exclusiv_bit_or .LE. 0) THEN
result = result + 1
WRITE(1,*) "Error in Ieor part 2"
END IF
DO i=1,LOOPCOUNT
int_array(i) = 10 - i
END DO
min_value = 65535
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
min_value = min(min_value,int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( min_value .GT. (10-LOOPCOUNT) )THEN
result = result + 1
WRITE(1,*) "Error in integer MIN"
END IF
DO i=1,LOOPCOUNT
int_array(i) = i
END DO
max_value = -32768
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
max_value = max(max_value,int_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( max_value .LT. LOOPCOUNT )THEN
result = result + 1
WRITE(1,*) "Error in integer MAX"
END IF
!... test double min, max
DO i=1,LOOPCOUNT
d_array(i) = 10 - i*dt
END DO
dmin = 2**10
dt = 0.5
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
dmin= MIN(dmin,d_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( dmin .GT. (10-dt) )THEN
result = result + 1
WRITE(1,*) "Error in double MIN"
END IF
DO i=1,LOOPCOUNT
d_array(i) = i * dt
END DO
dmax= - (2**10)
!$omp parallel
<ompts:orphan>
!$omp do
DO i = 1, LOOPCOUNT
<ompts:check>
!$omp atomic
</ompts:check>
dmax= max(dmax,d_array(i) )
END DO
!$omp end do
</ompts:orphan>
!$omp end parallel
IF ( dmax .LT. LOOPCOUNT*dt )THEN
result = result + 1
WRITE(1,*) "Error in double MAX"
END IF
IF ( result .EQ. 0 ) THEN
<testfunctionname></testfunctionname>= 1
ELSE
<testfunctionname></testfunctionname>= 0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,50 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp barrier directive. The test creates several threads and sends one of them sleeping before setting a flag. After the barrier the other ones do some littel work depending on the flag.</ ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp barrier</ompts:directive>
<ompts:testcode>
SUBROUTINE do_some_work3()
REAL i
INTRINSIC sqrt
DOUBLE PRECISION sum
INCLUDE "omp_testsuite.f"
sum = 0.0
DO WHILE (i < LOOPCOUNT-1)
sum = sum + sqrt(i)
i = i + 1
END DO
END
INTEGER FUNCTION <ompts:testcode:functionname>omp_barrier</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER sleeptime
INTEGER omp_get_thread_num
INTEGER result1, result2, rank
result1 = 0
result2 = 0
sleeptime = 1
!$omp parallel private(rank)
rank = omp_get_thread_num()
! PRINT *, "rank", rank
IF ( rank .EQ. 1 ) THEN
CALL sleep(sleeptime)
result2 = 3
END IF
<ompts:orphan>
<ompts:check>
!$omp barrier
</ompts:check>
</ompts:orphan>
IF ( rank .EQ. 0 ) THEN
result1 = result2
END IF
!$omp end parallel
IF ( result1 .EQ. 3 ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,47 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp parallel copyin directive.</ ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp parallel copyin</ompts:directive>
<ompts:dependences>omp critical,omp threadprivate</ompts:dependences>
<ompts:testcode>
! Changelog:
INTEGER FUNCTION <ompts:testcode:functionname>omp_copyin</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER known_sum
<ompts:orphan:vars>
! INTEGER, SAVE::sum1
! implicitly by omp_threadprivate, see spec25 Chap. 2.8.2
INTEGER sum1
COMMON /csum1/ sum1
INTEGER sum, i, threads
COMMON /orphvars/ sum, i, threads
! C. Niethammer 30.11.06: moved threadprivate statement into the orphaned
! function
!$omp threadprivate(/csum1/)
</ompts:orphan:vars>
sum = 0
sum1 = 7
threads = 0
<ompts:orphan>
!$omp parallel <ompts:check>copyin(sum1)</ompts:check>
! print *,"sum1",sum1
!$omp do
DO i=1, 999
sum1 = sum1 + i
END DO
!$omp critical
sum = sum + sum1
threads = threads + 1
!$omp end critical
!$omp end parallel
</ompts:orphan>
known_sum = 999*1000/2 + 7*threads
IF ( known_sum .EQ. sum ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,59 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp critical directive by counting up a variable in a parallelized region within a critical section.
</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp critical</ompts:directive>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_critical</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER known_sum
<ompts:orphan:vars>
INTEGER i,j,myi,myj, sum
COMMON /orphvars/ sum, myi, myj
</ompts:orphan:vars>
sum = 0
myi = 0
myj = 500
!$omp parallel
!$omp sections
!$omp section
DO i = 0 , 499
<ompts:orphan>
<ompts:check>
!$omp critical
</ompts:check>
sum = sum + myi
myi = myi + 1
<ompts:check>
!$omp end critical
</ompts:check>
</ompts:orphan>
END DO
!$omp section
DO j = 500 , 999
<ompts:orphan>
<ompts:check>
!$omp critical
</ompts:check>
sum = sum + myj
myj = myj + 1
<ompts:check>
!$omp end critical
</ompts:check>
</ompts:orphan>
END DO
!$omp end sections
!$omp end parallel
known_sum = 999*1000/2
IF ( known_sum .EQ. sum ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
WRITE (1,*) "Found sum was", sum, "instead", known_sum
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,49 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp flush directive.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp flush</ompts:directive>
<ompts:dependences>omp barrier</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_flush</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER result1, dummy, rank
INTEGER omp_get_thread_num
<ompts:orphan:vars>
INTEGER result2
COMMON /orphvars/ result2
</ompts:orphan:vars>
result1=0
result2=0
!$omp parallel private(rank)
rank = omp_get_thread_num()
!$omp barrier
IF ( rank .EQ. 1 ) THEN
result2 = 3
<ompts:orphan>
<ompts:check>
!$omp flush(result2)
</ompts:check>
</ompts:orphan>
dummy = result2
END IF
IF ( rank .EQ. 0 ) THEN
call sleep(1)
<ompts:orphan>
<ompts:check>
!$omp flush(result2)
</ompts:check>
</ompts:orphan>
result1 = result2
END IF
!$omp end parallel
! PRINT *,"1:", result1, "2:", result2, "dummy", dummy
IF ( (result1 .EQ. result2) .AND. (result2 .EQ. dummy) .AND.
& (result2 .EQ. 3) ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,37 @@
<ompts:test>
<ompts:testdescription>Test which checks that the omp_get_num_threads returns the correct number of threads. Therefor it counts up a variable in a parallelized section and compars this value with the result of the omp_get_num_threads function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_get_num_threads</ompts:directive>
<ompts:dependences>omp critical,somp single</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_get_num_threads</ompts:testcode:functionname>()
INTEGER nthreads
INTEGER omp_get_num_threads
<ompts:orphan:vars>
INTEGER nthreads_lib
COMMON /orphvars/ nthreads_lib
</ompts:orphan:vars>
nthreads=0
nthreads_lib=-1
!$omp parallel
!shared(nthreads,nthreads_lib)
!$omp critical
nthreads = nthreads + 1
!$omp end critical
!$omp single
<ompts:orphan>
<ompts:check>
nthreads_lib=omp_get_num_threads()
</ompts:check>
</ompts:orphan>
!$omp end single
!$omp end parallel
IF (nthreads .EQ. nthreads_lib) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,28 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_get_wtick function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_get_wtick</ompts:directive>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_get_wticks</ompts:testcode:functionname>()
IMPLICIT NONE
<ompts:orphan:vars>
DOUBLE PRECISION tick
COMMON /orphvars/ tick
include "omp_lib.h"
</ompts:orphan:vars>
! DOUBLE PRECISION omp_get_wtick
tick = 1
<ompts:orphan>
<ompts:check>
tick=omp_get_wticK()
</ompts:check>
</ompts:orphan>
WRITE(1,*) "work took",tick,"sec. time."
IF(tick .GT. 0. .AND. tick .LT. 0.01) THEN
<testfunctionname></testfunctionname>=1
ELSE
<testfunctionname></testfunctionname>=0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,41 @@
<ompts:test>
<ompts:testdescription>Test which checks that omp_in_parallel returns false when called from a serial region and true when called within a parallel region.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_in_parallel</ompts:directive>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_in_parallel</ompts:testcode:functionname>()
! checks that false is returned when called from serial region
! and true is returned when called within parallel region
LOGICAL omp_in_parallel
<ompts:orphan:vars>
! LOGICAL omp_in_parallel
LOGICAL serial, parallel
COMMON /orphvars/ serial, parallel
</ompts:orphan:vars>
serial=.TRUE.
parallel=.FALSE.
<ompts:orphan>
<ompts:check>
serial=omp_in_parallel()
</ompts:check>
</ompts:orphan>
!$omp parallel
!$omp single
<ompts:orphan>
<ompts:check>
parallel=omp_in_parallel();
</ompts:check>
</ompts:orphan>
!$omp end single
!$omp end parallel
IF ( (.NOT. serial) .AND. (parallel) ) THEN
<testfunctionname></testfunctionname>=1
ELSE
<testfunctionname></testfunctionname>=0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,58 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_set_lock and the omp_unset_lock function by counting the threads entering and exiting a single region with locks.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp_lock</ompts:directive>
<ompts:dependences>omp flush</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_lock</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER result
INTEGER nr_threads_in_single
INTEGER nr_iterations
INTEGER i
!lock variable
<ompts:orphan:vars>
INCLUDE "omp_lib.h"
INTEGER (KIND=OMP_LOCK_KIND) :: lock
COMMON /orphvars/ lock
</ompts:orphan:vars>
INCLUDE "omp_testsuite.f"
!result is:
! 0 -- if the test fails
! 1 -- if the test succeeds
CALL omp_init_lock(lock)
nr_iterations=0
nr_threads_in_single=0
result=0
!$omp parallel shared(lock,nr_threads_in_single,nr_iterations,result)
!$omp do
DO i=1,LOOPCOUNT
<ompts:orphan>
<ompts:check>
CALL omp_set_lock(lock)
</ompts:check>
</ompts:orphan>
!$omp flush
nr_threads_in_single=nr_threads_in_single+1
!$omp flush
nr_iterations=nr_iterations+1
nr_threads_in_single=nr_threads_in_single-1
result=result+nr_threads_in_single
<ompts:orphan>
<ompts:check>
CALL omp_unset_lock(lock)
</ompts:check>
</ompts:orphan>
END DO
!$omp end do
!$omp end parallel
CALL omp_destroy_lock(lock)
IF(result.EQ.0 .AND. nr_iterations .EQ. LOOPCOUNT) THEN
<testfunctionname></testfunctionname>=1
ELSE
<testfunctionname></testfunctionname>=0
ENDIf
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,39 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp master directive by counting up a variable in a omp master section.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp master</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_master</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER omp_get_thread_num
<ompts:orphan:vars>
INTEGER nthreads, executing_thread
COMMON /orphvars/ nthreads, executing_thread
</ompts:orphan:vars>
nthreads=0
executing_thread=-1
!$omp parallel
<ompts:orphan>
<ompts:check>
!$omp master
</ompts:check>
!$omp critical
nthreads = nthreads + 1
!$omp end critical
executing_thread=omp_get_thread_num()
<ompts:check>
!$omp end master
</ompts:check>
</ompts:orphan>
!$omp end parallel
IF ( (nthreads .EQ. 1) .AND. (executing_thread .EQ. 0) ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,49 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp master directive by counting up a variable in a omp master section. It also checks that the master thread has the thread number 0 as specified in the OpenMP standard version 3.0.</ompts:testdescription>
<ompts:ompversion>3.0</ompts:ompversion>
<ompts:directive>omp master</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_master_3</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER omp_get_thread_num
<ompts:orphan:vars>
INTEGER nthreads, executing_thread
INTEGER tid_result ! counts up the number of wrong thread no.
! for the master thread
COMMON /orphvars/ nthreads, executing_thread, tid_result
</ompts:orphan:vars>
tid_result = 0
nthreads=0
executing_thread=-1
!$omp parallel
<ompts:orphan>
<ompts:check>
!$omp master
</ompts:check>
if (omp_get_thread_num() .ne. 0) then
!$omp critical
tid_result = tid_result + 1
!$omp end critical
end if
!$omp critical
nthreads = nthreads + 1
!$omp end critical
executing_thread=omp_get_thread_num()
<ompts:check>
!$omp end master
</ompts:check>
</ompts:orphan>
!$omp end parallel
IF ( (nthreads .EQ. 1) .AND. (executing_thread .EQ. 0) .AND.
& (tid_result .EQ. 0) ) THEN
<testfunctionname></testfunctionname> = 1
ELSE
<testfunctionname></testfunctionname> = 0
END IF
END
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,59 @@
<ompts:test>
<ompts:testdescription>Test which checks the omp_set_nest_lock and the omp_unset_nest_lock function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_nest_lock</ompts:directive>
<ompts:dependences>omp flush</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_nest_lock</ompts:testcode:functionname>()
IMPLICIT NONE
!result is:
! 0 -- if the test fails
! 1 -- if the test succeeds
INTEGER result
INTEGER nr_threads_in_single
INTEGER nr_iterations
INTEGER i
<ompts:orphan:vars>
INCLUDE "omp_lib.h"
INTEGER (KIND=OMP_NEST_LOCK_KIND) :: lock
COMMON /orphvars/ lock
</ompts:orphan:vars>
INCLUDE "omp_testsuite.f"
nr_iterations=0
nr_threads_in_single=0
CALL omp_init_nest_lock(lock)
result=0
!$omp parallel shared(lock,nr_threads_in_single,nr_iterations,result)
!$omp do
DO i=1,LOOPCOUNT
<ompts:orphan>
<ompts:check>
CALL omp_set_nest_lock(lock)
</ompts:check>
</ompts:orphan>
!$omp flush
nr_threads_in_single=nr_threads_in_single+1
!$omp flush
nr_iterations=nr_iterations+1
nr_threads_in_single=nr_threads_in_single-1
result=result+nr_threads_in_single
<ompts:orphan>
<ompts:check>
CALL omp_unset_nest_lock(lock)
</ompts:check>
</ompts:orphan>
END DO
!$omp end do
!$omp end parallel
CALL omp_destroy_nest_lock(lock)
! PRINT *, result, nr_iterations
IF(result.EQ.0 .AND. nr_iterations .EQ. LOOPCOUNT) THEN
<testfunctionname></testfunctionname>=1
ELSE
<testfunctionname></testfunctionname>=0
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,53 @@
<ompts:test>
<ompts:testdescription>Test if the compiler support nested parallelism.</ompts:testdescription>
<ompts:version>2.5</ompts:version>
<ompts:directive>nestedtest</ompts:directive>
<ompts:dependences>omp critical</ompts:dependences>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_nested</ompts:testcode:functionname>()
IMPLICIT NONE
INCLUDE "omp_testsuite.f"
<ompts:orphan:vars>
INTEGER counter
COMMON /orphvars/ counter
</ompts:orphan:vars>
counter =0
<ompts:check>
!$ CALL OMP_SET_NESTED(.TRUE.)
!#ifdef _OPENMP
! CALL OMP_SET_NESTED(.TRUE.)
!#endif
</ompts:check>
<ompts:crosscheck>
!$ CALL OMP_SET_NESTED(.FALSE.)
!#ifdef _OPENMP
! CALL OMP_SET_NESTED(.FALSE.)
!#endif
</ompts:crosscheck>
!$omp parallel
<ompts:orphan>
!$omp critical
counter = counter + 1
!$omp end critical
!$omp parallel
!$omp critical
counter = counter - 1
!$omp end critical
!$omp end parallel
</ompts:orphan>
!$omp end parallel
IF (counter .EQ. 0 ) THEN
WRITE (1,*) "Counter was 0"
<testfunctionname></testfunctionname> = 0
ELSE
WRITE (1,*) "Counter was", counter
<testfunctionname></testfunctionname> = 1
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

View File

@@ -0,0 +1,60 @@
<ompts:test>
<ompts:testdescription>Test which checks that the omp_get_num_threads returns the correct number of threads. Therefor it counts up a variable in a parallelized section and compars this value with the result of the omp_get_num_threads function.</ompts:testdescription>
<ompts:ompversion>2.0</ompts:ompversion>
<ompts:directive>omp_get_num_threads</ompts:directive>
<ompts:testcode>
INTEGER FUNCTION <ompts:testcode:functionname>omp_num_threads</ompts:testcode:functionname>()
IMPLICIT NONE
INTEGER i, max_threads
INTEGER omp_get_num_threads
<ompts:orphan:vars>
INTEGER failed,threads,nthreads,tmp
COMMON /orphvars/ failed,threads,nthreads
</ompts:orphan:vars>
failed = 0
max_threads = 0
!$omp parallel
!$omp master
max_threads = OMP_GET_NUM_THREADS()
!$omp end master
!$omp end parallel
! print *, "max threads:",max_threads
!Yi Wen added omp_Set_dynamics here to make sure num_threads clause work
!Thanks to Dr. Yin Ma in Absoft. should be not be called before the test loop
!becuase it allows the dynamic adjustment of the number of threads at runtime
!instead of using the max_threads set.
!CALL OMP_SET_DYNAMIC(.TRUE.)
DO threads = 1, max_threads
nthreads = 0
<ompts:orphan>
!$omp parallel num_threads(threads) reduction(+:failed)
! print *, threads, omp_get_num_threads()
tmp = omp_get_num_threads()
IF ( threads .NE. tmp ) THEN
failed = failed + 1
WRITE (1,*) "Error: found ", tmp, " instead of ",
& threads, " threads"
END IF
!$omp atomic
nthreads = nthreads + 1
!$omp end parallel
</ompts:orphan>
! print *, threads, nthreads
<ompts:check>IF ( nthreads .NE. threads ) THEN</ompts:check>
<ompts:crosscheck>IF ( nthreads .EQ. threads ) THEN</ompts:crosscheck>
failed = failed + 1
END IF
END DO
IF(failed .NE. 0) THEN
<testfunctionname></testfunctionname> = 0
ELSE
<testfunctionname></testfunctionname> = 1
END IF
END FUNCTION
</ompts:testcode>
</ompts:test>

Some files were not shown because too many files have changed in this diff Show More