| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> |