summaryrefslogtreecommitdiffstats
path: root/openmp/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'openmp/runtime')
-rw-r--r--openmp/runtime/CMakeLists.txt2
-rw-r--r--openmp/runtime/src/CMakeLists.txt20
-rw-r--r--openmp/runtime/test/CMakeLists.txt70
-rw-r--r--openmp/runtime/test/api/has_openmp.c23
-rw-r--r--openmp/runtime/test/api/omp_get_num_threads.c39
-rw-r--r--openmp/runtime/test/api/omp_get_wtick.c24
-rw-r--r--openmp/runtime/test/api/omp_get_wtime.c33
-rw-r--r--openmp/runtime/test/api/omp_in_parallel.c39
-rw-r--r--openmp/runtime/test/atomic/omp_atomic.c366
-rw-r--r--openmp/runtime/test/barrier/omp_barrier.c40
-rw-r--r--openmp/runtime/test/critical/omp_critical.c37
-rw-r--r--openmp/runtime/test/flush/omp_flush.c45
-rw-r--r--openmp/runtime/test/lit.cfg54
-rw-r--r--openmp/runtime/test/lit.site.cfg.in13
-rw-r--r--openmp/runtime/test/lock/omp_lock.c45
-rw-r--r--openmp/runtime/test/lock/omp_nest_lock.c45
-rw-r--r--openmp/runtime/test/lock/omp_test_lock.c45
-rw-r--r--openmp/runtime/test/lock/omp_test_nest_lock.c47
-rw-r--r--openmp/runtime/test/master/omp_master.c38
-rw-r--r--openmp/runtime/test/master/omp_master_3.c44
-rw-r--r--openmp/runtime/test/omp_my_sleep.h33
-rw-r--r--openmp/runtime/test/omp_testsuite.h22
-rw-r--r--openmp/runtime/test/parallel/omp_nested.c41
-rw-r--r--openmp/runtime/test/parallel/omp_parallel_copyin.c47
-rw-r--r--openmp/runtime/test/parallel/omp_parallel_default.c43
-rw-r--r--openmp/runtime/test/parallel/omp_parallel_firstprivate.c46
-rw-r--r--openmp/runtime/test/parallel/omp_parallel_if.c40
-rw-r--r--openmp/runtime/test/parallel/omp_parallel_num_threads.c46
-rw-r--r--openmp/runtime/test/parallel/omp_parallel_private.c46
-rw-r--r--openmp/runtime/test/parallel/omp_parallel_reduction.c254
-rw-r--r--openmp/runtime/test/parallel/omp_parallel_shared.c46
-rw-r--r--openmp/runtime/test/tasking/omp_task.c52
-rw-r--r--openmp/runtime/test/tasking/omp_task_final.c65
-rw-r--r--openmp/runtime/test/tasking/omp_task_firstprivate.c51
-rw-r--r--openmp/runtime/test/tasking/omp_task_if.c43
-rw-r--r--openmp/runtime/test/tasking/omp_task_imp_firstprivate.c47
-rw-r--r--openmp/runtime/test/tasking/omp_task_private.c53
-rw-r--r--openmp/runtime/test/tasking/omp_task_shared.c41
-rw-r--r--openmp/runtime/test/tasking/omp_taskwait.c74
-rw-r--r--openmp/runtime/test/tasking/omp_taskyield.c58
-rw-r--r--openmp/runtime/test/threadprivate/omp_threadprivate.c102
-rw-r--r--openmp/runtime/test/threadprivate/omp_threadprivate_for.c47
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_collapse.c51
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_firstprivate.c55
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_lastprivate.c52
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_nowait.c53
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_ordered.c60
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_private.c63
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_reduction.c339
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_schedule_auto.c69
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_schedule_dynamic.c90
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_schedule_guided.c218
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_schedule_static.c155
-rw-r--r--openmp/runtime/test/worksharing/for/omp_for_schedule_static_3.c203
-rw-r--r--openmp/runtime/test/worksharing/for/omp_parallel_for_firstprivate.c35
-rw-r--r--openmp/runtime/test/worksharing/for/omp_parallel_for_if.c42
-rw-r--r--openmp/runtime/test/worksharing/for/omp_parallel_for_lastprivate.c37
-rw-r--r--openmp/runtime/test/worksharing/for/omp_parallel_for_ordered.c64
-rw-r--r--openmp/runtime/test/worksharing/for/omp_parallel_for_private.c50
-rw-r--r--openmp/runtime/test/worksharing/for/omp_parallel_for_reduction.c266
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_parallel_sections_firstprivate.c54
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_parallel_sections_lastprivate.c71
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_parallel_sections_private.c64
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_parallel_sections_reduction.c508
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_section_firstprivate.c55
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_section_lastprivate.c76
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_section_private.c66
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_sections_nowait.c69
-rw-r--r--openmp/runtime/test/worksharing/sections/omp_sections_reduction.c543
-rw-r--r--openmp/runtime/test/worksharing/single/omp_single.c44
-rw-r--r--openmp/runtime/test/worksharing/single/omp_single_copyprivate.c60
-rw-r--r--openmp/runtime/test/worksharing/single/omp_single_nowait.c57
-rw-r--r--openmp/runtime/test/worksharing/single/omp_single_private.c57
73 files changed, 5992 insertions, 0 deletions
diff --git a/openmp/runtime/CMakeLists.txt b/openmp/runtime/CMakeLists.txt
index 28920ae0072..4ca5450b966 100644
--- a/openmp/runtime/CMakeLists.txt
+++ b/openmp/runtime/CMakeLists.txt
@@ -206,6 +206,7 @@ set(LIBOMP_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LIBOMP_SRC_DIR ${LIBOMP_BASE_DIR}/src)
set(LIBOMP_TOOLS_DIR ${LIBOMP_BASE_DIR}/tools)
set(LIBOMP_INC_DIR ${LIBOMP_SRC_DIR}/include/${LIBOMP_OMP_VERSION})
+set(LIBOMP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
# Enabling Fortran if it is needed
if(${LIBOMP_FORTRAN_MODULES})
@@ -324,4 +325,5 @@ if(${LIBOMP_STANDALONE_BUILD})
endif()
add_subdirectory(src)
+add_subdirectory(test)
diff --git a/openmp/runtime/src/CMakeLists.txt b/openmp/runtime/src/CMakeLists.txt
index ce6b2600a62..d0c1183ac82 100644
--- a/openmp/runtime/src/CMakeLists.txt
+++ b/openmp/runtime/src/CMakeLists.txt
@@ -141,6 +141,26 @@ set_target_properties(omp PROPERTIES
SKIP_BUILD_RPATH true # have Mac linker -install_name just be "-install_name libomp.dylib"
)
+# Get the library's location within the build tree for the unit tester
+get_target_property(LIBOMP_LIBRARY_DIR omp LIBRARY_OUTPUT_DIRECTORY)
+if(NOT LIBOMP_LIBRARY_DIR)
+ set(LIBOMP_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+ set(LIBOMP_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
+else()
+ set(LIBOMP_LIBRARY_DIR ${LIBOMP_LIBRARY_DIR} PARENT_SCOPE)
+endif()
+
+# Add symbolic links to libomp
+if(NOT WIN32)
+ add_custom_command(TARGET omp POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIBOMP_LIB_FILE}
+ libgomp${CMAKE_SHARED_LIBRARY_SUFFIX}
+ COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIBOMP_LIB_FILE}
+ libiomp5${CMAKE_SHARED_LIBRARY_SUFFIX}
+ WORKING_DIRECTORY ${LIBOMP_LIBRARY_DIR}
+ )
+endif()
+
# Linking command will include libraries in LIBOMP_CONFIGURED_LIBFLAGS
libomp_get_libflags(LIBOMP_CONFIGURED_LIBFLAGS)
target_link_libraries(omp ${LIBOMP_CONFIGURED_LIBFLAGS} ${CMAKE_DL_LIBS})
diff --git a/openmp/runtime/test/CMakeLists.txt b/openmp/runtime/test/CMakeLists.txt
new file mode 100644
index 00000000000..c5877cff13c
--- /dev/null
+++ b/openmp/runtime/test/CMakeLists.txt
@@ -0,0 +1,70 @@
+# CMakeLists.txt file for unit testing OpenMP Library
+include(FindPythonInterp)
+include(CheckTypeSize)
+if(NOT PYTHONINTERP_FOUND)
+ libomp_warning_say("Could not find Python.")
+ libomp_warning_say("The check-libomp target will not be available!")
+ return()
+endif()
+
+set(LIBOMP_TEST_CFLAGS "" CACHE STRING
+ "Extra compiler flags to send to the test compiler")
+
+if(${LIBOMP_STANDALONE_BUILD})
+ # Make sure we can use the console pool for recent cmake and ninja > 1.5
+ if(CMAKE_VERSION VERSION_LESS 3.1.20141117)
+ set(cmake_3_2_USES_TERMINAL)
+ else()
+ set(cmake_3_2_USES_TERMINAL USES_TERMINAL)
+ endif()
+ set(LIBOMP_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE STRING
+ "Compiler to use for testing OpenMP library")
+ set(LIBOMP_TEST_OPENMP_FLAG -fopenmp CACHE STRING
+ "OpenMP compiler flag to use for testing OpenMP library")
+ set(LIBOMP_LLVM_LIT_EXECUTABLE "" CACHE STRING
+ "Path to llvm-lit")
+ find_program(LIT_EXECUTABLE NAMES llvm-lit ${LIBOMP_LLVM_LIT_EXECUTABLE})
+ if(NOT LIT_EXECUTABLE)
+ libomp_say("Cannot find llvm-lit.")
+ libomp_say("Please put llvm-lit in your PATH or set LIBOMP_LLVM_LIT_EXECUTABLE to its full path")
+ libomp_warning_say("The check-libomp target will not be available!")
+ return()
+ endif()
+ # Set lit arguments
+ # The -j 1 lets the actual tests run with the entire machine.
+ # We have one test thread that spawns the tests serially. This allows
+ # Each test to use the entire machine.
+ set(LIBOMP_LIT_ARGS_DEFAULT "-sv --show-unsupported --show-xfail -j 1")
+ if(MSVC OR XCODE)
+ set(LIBOMP_LIT_ARGS_DEFAULT "${LIBOMP_LIT_ARGS_DEFAULT} --no-progress-bar")
+ endif()
+ set(LIBOMP_LIT_ARGS "${LIBOMP_LIT_ARGS_DEFAULT}" CACHE STRING
+ "Default options for lit")
+ separate_arguments(LIBOMP_LIT_ARGS)
+ add_custom_target(check-libomp
+ COMMAND ${PYTHON_EXECUTABLE} ${LIT_EXECUTABLE} ${LIBOMP_LIT_ARGS} ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS omp
+ COMMENT "Running libomp tests"
+ ${cmake_3_2_USES_TERMINAL}
+ )
+else()
+ # LLVM source tree build, test just-built clang
+ if(NOT MSVC)
+ set(LIBOMP_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
+ else()
+ set(LIBOMP_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe)
+ endif()
+ set(LIBOMP_TEST_OPENMP_FLAG -fopenmp=libomp)
+ # Use add_lit_testsuite() from LLVM CMake.
+ add_lit_testsuite(check-libomp
+ "Running libomp tests"
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ARGS "-j 1"
+ DEPENDS omp
+ )
+endif()
+
+# Configure the lit.site.cfg.in file
+set(AUTO_GEN_COMMENT "## Autogenerated by libomp configuration.\n# Do not edit!")
+configure_file(lit.site.cfg.in lit.site.cfg @ONLY)
+
diff --git a/openmp/runtime/test/api/has_openmp.c b/openmp/runtime/test/api/has_openmp.c
new file mode 100644
index 00000000000..da95f595fb9
--- /dev/null
+++ b/openmp/runtime/test/api/has_openmp.c
@@ -0,0 +1,23 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+
+int test_has_openmp()
+{
+ int rvalue = 0;
+#ifdef _OPENMP
+ rvalue = 1;
+#endif
+ return (rvalue);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+ if(!test_has_openmp()) {
+ num_failed++;
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/api/omp_get_num_threads.c b/openmp/runtime/test/api/omp_get_num_threads.c
new file mode 100644
index 00000000000..38a1434a031
--- /dev/null
+++ b/openmp/runtime/test/api/omp_get_num_threads.c
@@ -0,0 +1,39 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_get_num_threads()
+{
+ /* checks that omp_get_num_threads is equal to the number of
+ threads */
+ int nthreads_lib;
+ int nthreads = 0;
+
+ nthreads_lib = -1;
+
+ #pragma omp parallel
+ {
+ #pragma omp critical
+ {
+ nthreads++;
+ } /* end of critical */
+ #pragma omp single
+ {
+ nthreads_lib = omp_get_num_threads ();
+ } /* end of single */
+ } /* end of parallel */
+ return (nthreads == nthreads_lib);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_get_num_threads()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/api/omp_get_wtick.c b/openmp/runtime/test/api/omp_get_wtick.c
new file mode 100644
index 00000000000..8b35226a01f
--- /dev/null
+++ b/openmp/runtime/test/api/omp_get_wtick.c
@@ -0,0 +1,24 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_get_wtick()
+{
+ double tick;
+ tick = -1.;
+ tick = omp_get_wtick ();
+ return ((tick > 0.0) && (tick < 0.01));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_get_wtick()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/api/omp_get_wtime.c b/openmp/runtime/test/api/omp_get_wtime.c
new file mode 100644
index 00000000000..f7be1faef5a
--- /dev/null
+++ b/openmp/runtime/test/api/omp_get_wtime.c
@@ -0,0 +1,33 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_get_wtime()
+{
+ double start;
+ double end;
+ double measured_time;
+ double wait_time = 0.25;
+ start = 0;
+ end = 0;
+ start = omp_get_wtime();
+ my_sleep (wait_time);
+ end = omp_get_wtime();
+ measured_time = end-start;
+ return ((measured_time > 0.99 * wait_time) && (measured_time < 1.01 * wait_time)) ;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_get_wtime()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/api/omp_in_parallel.c b/openmp/runtime/test/api/omp_in_parallel.c
new file mode 100644
index 00000000000..40cc3859c50
--- /dev/null
+++ b/openmp/runtime/test/api/omp_in_parallel.c
@@ -0,0 +1,39 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+/*
+ * Checks that false is returned when called from serial region
+ * and true is returned when called within parallel region.
+ */
+int test_omp_in_parallel()
+{
+ int serial;
+ int isparallel;
+
+ serial = 1;
+ isparallel = 0;
+ serial = omp_in_parallel();
+
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ isparallel = omp_in_parallel();
+ }
+ }
+ return (!(serial) && isparallel);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_in_parallel()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/atomic/omp_atomic.c b/openmp/runtime/test/atomic/omp_atomic.c
new file mode 100644
index 00000000000..966660ee207
--- /dev/null
+++ b/openmp/runtime/test/atomic/omp_atomic.c
@@ -0,0 +1,366 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
+#define MAX_FACTOR 10
+#define KNOWN_PRODUCT 3628800 /* 10! */
+
+int test_omp_atomic()
+{
+ int sum;
+ int diff;
+ double dsum = 0;
+ double dt = 0.5; /* base of geometric row for + and - test*/
+ double ddiff;
+ int product;
+ int x;
+ int *logics;
+ int bit_and = 1;
+ int bit_or = 0;
+ int exclusiv_bit_or = 0;
+ int j;
+ int known_sum;
+ int known_diff;
+ int known_product;
+ int result = 0;
+ int logic_and = 1;
+ int logic_or = 0;
+ double dknown_sum;
+ double rounding_error = 1.E-9;
+ double dpt, div;
+ int logicsArray[LOOPCOUNT];
+ logics = logicsArray;
+
+ sum = 0;
+ diff = 0;
+ product = 1;
+
+ // sum of integers test
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ #pragma omp atomic
+ sum += i;
+ }
+
+ }
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ if (known_sum != sum)
+ {
+ fprintf(stderr,
+ "Error in sum with integers: Result was %d instead of %d.\n",
+ sum, known_sum);
+ result++;
+ }
+
+ // difference of integers test
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; i++) {
+ #pragma omp atomic
+ diff -= i;
+ }
+ }
+ known_diff = ((LOOPCOUNT - 1) * LOOPCOUNT) / 2 * -1;
+ if (diff != known_diff)
+ {
+ fprintf (stderr,
+ "Error in difference with integers: Result was %d instead of 0.\n",
+ diff);
+ result++;
+ }
+
+ // sum of doubles test
+ dsum = 0;
+ dpt = 1;
+ for (j = 0; j < DOUBLE_DIGITS; ++j) {
+ dpt *= dt;
+ }
+ dknown_sum = (1 - dpt) / (1 -dt);
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < DOUBLE_DIGITS; ++i) {
+ #pragma omp atomic
+ dsum += pow (dt, i);
+ }
+ }
+ if (dsum != dknown_sum && (fabs (dsum - dknown_sum) > rounding_error)) {
+ fprintf (stderr, "Error in sum with doubles: Result was %f"
+ " instead of: %f (Difference: %E)\n",
+ dsum, dknown_sum, dsum - dknown_sum);
+ result++;
+ }
+
+ // difference of doubles test
+ dpt = 1;
+ for (j = 0; j < DOUBLE_DIGITS; ++j) {
+ dpt *= dt;
+ }
+ ddiff = (1 - dpt) / (1 - dt);
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < DOUBLE_DIGITS; ++i) {
+ #pragma omp atomic
+ ddiff -= pow (dt, i);
+ }
+ }
+ if (fabs (ddiff) > rounding_error) {
+ fprintf (stderr,
+ "Error in difference with doubles: Result was %E instead of 0.0\n",
+ ddiff);
+ result++;
+ }
+
+ // product of integers test
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 1; i <= MAX_FACTOR; i++) {
+ #pragma omp atomic
+ product *= i;
+ }
+ }
+ known_product = KNOWN_PRODUCT;
+ if (known_product != product) {
+ fprintf (stderr,
+ "Error in product with integers: Result was %d instead of %d\n",
+ product, known_product);
+ result++;
+ }
+
+ // division of integers test
+ product = KNOWN_PRODUCT;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 1; i <= MAX_FACTOR; ++i) {
+ #pragma omp atomic
+ product /= i;
+ }
+ }
+ if (product != 1) {
+ fprintf (stderr,
+ "Error in product division with integers: Result was %d"
+ " instead of 1\n",
+ product);
+ result++;
+ }
+
+ // division of doubles test
+ div = 5.0E+5;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 1; i <= MAX_FACTOR; i++) {
+ #pragma omp atomic
+ div /= i;
+ }
+ }
+ if (fabs(div-0.137787) >= 1.0E-4 ) {
+ result++;
+ fprintf (stderr, "Error in division with double: Result was %f"
+ " instead of 0.137787\n", div);
+ }
+
+ // ++ test
+ x = 0;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ #pragma omp atomic
+ x++;
+ }
+ }
+ if (x != LOOPCOUNT) {
+ result++;
+ fprintf (stderr, "Error in ++\n");
+ }
+
+ // -- test
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ #pragma omp atomic
+ x--;
+ }
+ }
+ if (x != 0) {
+ result++;
+ fprintf (stderr, "Error in --\n");
+ }
+
+ // bit-and test part 1
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ logics[j] = 1;
+ }
+ bit_and = 1;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ #pragma omp atomic
+ bit_and &= logics[i];
+ }
+ }
+ if (!bit_and) {
+ result++;
+ fprintf (stderr, "Error in BIT AND part 1\n");
+ }
+
+ // bit-and test part 2
+ bit_and = 1;
+ logics[LOOPCOUNT / 2] = 0;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ #pragma omp atomic
+ bit_and &= logics[i];
+ }
+ }
+ if (bit_and) {
+ result++;
+ fprintf (stderr, "Error in BIT AND part 2\n");
+ }
+
+ // bit-or test part 1
+ for (j = 0; j < LOOPCOUNT; j++) {
+ logics[j] = 0;
+ }
+ bit_or = 0;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ #pragma omp atomic
+ bit_or |= logics[i];
+ }
+ }
+ if (bit_or) {
+ result++;
+ fprintf (stderr, "Error in BIT OR part 1\n");
+ }
+
+ // bit-or test part 2
+ bit_or = 0;
+ logics[LOOPCOUNT / 2] = 1;
+ #pragma omp parallel
+ {
+
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ #pragma omp atomic
+ bit_or |= logics[i];
+ }
+ }
+ if (!bit_or) {
+ result++;
+ fprintf (stderr, "Error in BIT OR part 2\n");
+ }
+
+ // bit-xor test part 1
+ for (j = 0; j < LOOPCOUNT; j++) {
+ logics[j] = 0;
+ }
+ exclusiv_bit_or = 0;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ #pragma omp atomic
+ exclusiv_bit_or ^= logics[i];
+ }
+ }
+ if (exclusiv_bit_or) {
+ result++;
+ fprintf (stderr, "Error in EXCLUSIV BIT OR part 1\n");
+ }
+
+ // bit-xor test part 2
+ exclusiv_bit_or = 0;
+ logics[LOOPCOUNT / 2] = 1;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ #pragma omp atomic
+ exclusiv_bit_or ^= logics[i];
+ }
+
+ }
+ if (!exclusiv_bit_or) {
+ result++;
+ fprintf (stderr, "Error in EXCLUSIV BIT OR part 2\n");
+ }
+
+ // left shift test
+ x = 1;
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < 10; ++i) {
+ #pragma omp atomic
+ x <<= 1;
+ }
+
+ }
+ if ( x != 1024) {
+ result++;
+ fprintf (stderr, "Error in <<\n");
+ x = 1024;
+ }
+
+ // right shift test
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < 10; ++i) {
+ #pragma omp atomic
+ x >>= 1;
+ }
+ }
+ if (x != 1) {
+ result++;
+ fprintf (stderr, "Error in >>\n");
+ }
+
+ return (result == 0);
+} // test_omp_atomic()
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_atomic()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/barrier/omp_barrier.c b/openmp/runtime/test/barrier/omp_barrier.c
new file mode 100644
index 00000000000..5bb8c3ab126
--- /dev/null
+++ b/openmp/runtime/test/barrier/omp_barrier.c
@@ -0,0 +1,40 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_barrier()
+{
+ int result1;
+ int result2;
+ result1 = 0;
+ result2 = 0;
+
+ #pragma omp parallel
+ {
+ int rank;
+ rank = omp_get_thread_num ();
+ if (rank ==1) {
+ my_sleep(SLEEPTIME);
+ result2 = 3;
+ }
+ #pragma omp barrier
+ if (rank == 2) {
+ result1 = result2;
+ }
+ }
+ return (result1 == 3);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_barrier()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/critical/omp_critical.c b/openmp/runtime/test/critical/omp_critical.c
new file mode 100644
index 00000000000..e07dbcb7442
--- /dev/null
+++ b/openmp/runtime/test/critical/omp_critical.c
@@ -0,0 +1,37 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_critical()
+{
+ int sum;
+ int known_sum;
+
+ sum=0;
+ #pragma omp parallel
+ {
+ int mysum=0;
+ int i;
+ #pragma omp for
+ for (i = 0; i < 1000; i++)
+ mysum = mysum + i;
+
+ #pragma omp critical
+ sum = mysum +sum;
+ }
+ known_sum = 999 * 1000 / 2;
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_critical()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/flush/omp_flush.c b/openmp/runtime/test/flush/omp_flush.c
new file mode 100644
index 00000000000..3fd3cdfbc21
--- /dev/null
+++ b/openmp/runtime/test/flush/omp_flush.c
@@ -0,0 +1,45 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_flush()
+{
+ int result1;
+ int result2;
+ int dummy;
+
+ result1 = 0;
+ result2 = 0;
+
+ #pragma omp parallel
+ {
+ int rank;
+ rank = omp_get_thread_num ();
+ #pragma omp barrier
+ if (rank == 1) {
+ result2 = 3;
+ #pragma omp flush (result2)
+ dummy = result2;
+ }
+ if (rank == 0) {
+ my_sleep(SLEEPTIME);
+ #pragma omp flush (result2)
+ result1 = result2;
+ }
+ } /* end of parallel */
+ return ((result1 == result2) && (result2 == dummy) && (result2 == 3));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for (i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_flush()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/lit.cfg b/openmp/runtime/test/lit.cfg
new file mode 100644
index 00000000000..b86c86f9063
--- /dev/null
+++ b/openmp/runtime/test/lit.cfg
@@ -0,0 +1,54 @@
+# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
+# Configuration file for the 'lit' test runner.
+
+import os
+import lit.formats
+
+# Tell pylint that we know config and lit_config exist somewhere.
+if 'PYLINT_IMPORT' in os.environ:
+ config = object()
+ lit_config = object()
+
+def append_dynamic_library_path(name, value, sep):
+ if name in config.environment:
+ config.environment[name] = value + sep + config.environment[name]
+ else:
+ config.environment[name] = value
+
+# name: The name of this test suite.
+config.name = 'libomp'
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root object directory where output is placed
+config.test_exec_root = config.libomp_obj_root
+
+# test format
+config.test_format = lit.formats.ShTest()
+
+# compiler flags
+config.test_cflags = config.test_openmp_flag + \
+ " -I " + config.test_source_root + \
+ " -I " + config.omp_header_directory + \
+ " -L " + config.library_dir + \
+ " " + config.test_extra_cflags
+
+# Setup environment to find dynamic library at runtime
+if config.operating_system == 'Windows':
+ append_dynamic_library_path('PATH', config.library_dir, ";")
+elif config.operating_system == 'Darwin':
+ append_dynamic_library_path('DYLD_LIBRARY_PATH', config.library_dir, ":")
+else: # Unices
+ append_dynamic_library_path('LD_LIBRARY_PATH', config.library_dir, ":")
+
+# substitutions
+config.substitutions.append(("%libomp-compile-and-run", \
+ "%clang %cflags %s -o %t -lm && %t"))
+config.substitutions.append(("%clang", config.test_compiler))
+config.substitutions.append(("%openmp_flag", config.test_openmp_flag))
+config.substitutions.append(("%cflags", config.test_cflags))
+
diff --git a/openmp/runtime/test/lit.site.cfg.in b/openmp/runtime/test/lit.site.cfg.in
new file mode 100644
index 00000000000..c9cd7e78ba9
--- /dev/null
+++ b/openmp/runtime/test/lit.site.cfg.in
@@ -0,0 +1,13 @@
+@AUTO_GEN_COMMENT@
+
+config.test_compiler = "@LIBOMP_TEST_COMPILER@"
+config.test_openmp_flag = "@LIBOMP_TEST_OPENMP_FLAG@"
+config.test_extra_cflags = "@LIBOMP_TEST_CFLAGS@"
+config.libomp_obj_root = "@CMAKE_CURRENT_BINARY_DIR@"
+config.library_dir = "@LIBOMP_LIBRARY_DIR@"
+config.omp_header_directory = "@LIBOMP_BINARY_DIR@/src"
+config.operating_system = "@CMAKE_SYSTEM_NAME@"
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@LIBOMP_BASE_DIR@/test/lit.cfg")
+
diff --git a/openmp/runtime/test/lock/omp_lock.c b/openmp/runtime/test/lock/omp_lock.c
new file mode 100644
index 00000000000..028c461db6a
--- /dev/null
+++ b/openmp/runtime/test/lock/omp_lock.c
@@ -0,0 +1,45 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+omp_lock_t lck;
+
+int test_omp_lock()
+{
+ int nr_threads_in_single = 0;
+ int result = 0;
+ int nr_iterations = 0;
+ int i;
+
+ omp_init_lock(&lck);
+ #pragma omp parallel shared(lck)
+ {
+ #pragma omp for
+ for(i = 0; i < LOOPCOUNT; i++) {
+ omp_set_lock(&lck);
+ #pragma omp flush
+ nr_threads_in_single++;
+ #pragma omp flush
+ nr_iterations++;
+ nr_threads_in_single--;
+ result = result + nr_threads_in_single;
+ omp_unset_lock(&lck);
+ }
+ }
+ omp_destroy_lock(&lck);
+
+ return ((result == 0) && (nr_iterations == LOOPCOUNT));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_lock()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/lock/omp_nest_lock.c b/openmp/runtime/test/lock/omp_nest_lock.c
new file mode 100644
index 00000000000..f9cf4480647
--- /dev/null
+++ b/openmp/runtime/test/lock/omp_nest_lock.c
@@ -0,0 +1,45 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+omp_nest_lock_t lck;
+
+int test_omp_nest_lock()
+{
+ int nr_threads_in_single = 0;
+ int result = 0;
+ int nr_iterations = 0;
+ int i;
+
+ omp_init_nest_lock(&lck);
+ #pragma omp parallel shared(lck)
+ {
+ #pragma omp for
+ for(i = 0; i < LOOPCOUNT; i++) {
+ omp_set_nest_lock(&lck);
+ #pragma omp flush
+ nr_threads_in_single++;
+ #pragma omp flush
+ nr_iterations++;
+ nr_threads_in_single--;
+ result = result + nr_threads_in_single;
+ omp_unset_nest_lock(&lck);
+ }
+ }
+ omp_destroy_nest_lock(&lck);
+
+ return ((result == 0) && (nr_iterations == LOOPCOUNT));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_nest_lock()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/lock/omp_test_lock.c b/openmp/runtime/test/lock/omp_test_lock.c
new file mode 100644
index 00000000000..dcaae0fca6a
--- /dev/null
+++ b/openmp/runtime/test/lock/omp_test_lock.c
@@ -0,0 +1,45 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+omp_lock_t lck;
+
+int test_omp_test_lock()
+{
+ 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++) {
+ while (!omp_test_lock (&lck))
+ {};
+ #pragma omp flush
+ nr_threads_in_single++;
+ #pragma omp flush
+ nr_iterations++;
+ nr_threads_in_single--;
+ result = result + nr_threads_in_single;
+ omp_unset_lock (&lck);
+ }
+ }
+ omp_destroy_lock(&lck);
+ return ((result == 0) && (nr_iterations == LOOPCOUNT));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_test_lock()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/lock/omp_test_nest_lock.c b/openmp/runtime/test/lock/omp_test_nest_lock.c
new file mode 100644
index 00000000000..d9c5dde0f5d
--- /dev/null
+++ b/openmp/runtime/test/lock/omp_test_nest_lock.c
@@ -0,0 +1,47 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+static omp_nest_lock_t lck;
+
+int test_omp_test_nest_lock()
+{
+ int nr_threads_in_single = 0;
+ int result = 0;
+ int nr_iterations = 0;
+ int i;
+
+ omp_init_nest_lock (&lck);
+ #pragma omp parallel shared(lck)
+ {
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; i++)
+ {
+ /*omp_set_lock(&lck);*/
+ while(!omp_test_nest_lock (&lck))
+ {};
+ #pragma omp flush
+ nr_threads_in_single++;
+ #pragma omp flush
+ nr_iterations++;
+ nr_threads_in_single--;
+ result = result + nr_threads_in_single;
+ omp_unset_nest_lock (&lck);
+ }
+ }
+ omp_destroy_nest_lock (&lck);
+ return ((result == 0) && (nr_iterations == LOOPCOUNT));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_test_nest_lock()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/master/omp_master.c b/openmp/runtime/test/master/omp_master.c
new file mode 100644
index 00000000000..29c42d63a3f
--- /dev/null
+++ b/openmp/runtime/test/master/omp_master.c
@@ -0,0 +1,38 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_master()
+{
+ int nthreads;
+ int executing_thread;
+
+ nthreads = 0;
+ executing_thread = -1;
+
+ #pragma omp parallel
+ {
+ #pragma omp master
+ {
+ #pragma omp critical
+ {
+ nthreads++;
+ }
+ executing_thread = omp_get_thread_num();
+ } /* end of master*/
+ } /* end of parallel*/
+ return ((nthreads == 1) && (executing_thread == 0));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_master()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/master/omp_master_3.c b/openmp/runtime/test/master/omp_master_3.c
new file mode 100644
index 00000000000..1d1132e34d5
--- /dev/null
+++ b/openmp/runtime/test/master/omp_master_3.c
@@ -0,0 +1,44 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_master_3()
+{
+ int nthreads;
+ int executing_thread;
+ int tid_result = 0; /* counts up the number of wrong thread no. for
+ the master thread. (Must be 0) */
+ nthreads = 0;
+ executing_thread = -1;
+
+ #pragma omp parallel
+ {
+ #pragma omp master
+ {
+ 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*/
+ } /* end of parallel*/
+ return ((nthreads == 1) && (executing_thread == 0) && (tid_result == 0));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_master_3()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/omp_my_sleep.h b/openmp/runtime/test/omp_my_sleep.h
new file mode 100644
index 00000000000..138d930ca64
--- /dev/null
+++ b/openmp/runtime/test/omp_my_sleep.h
@@ -0,0 +1,33 @@
+#ifndef MY_SLEEP_H
+#define MY_SLEEP_H
+
+/*! Utility function to have a sleep function with better resolution and
+ * which only stops one thread. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+
+#if defined(_WIN32)
+# include <windows.h>
+// Windows version of my_sleep() function
+static void my_sleep(double sleeptime) {
+ DWORD ms = (DWORD) (sleeptime * 1000.0);
+ Sleep(ms);
+}
+
+
+#else // _WIN32
+
+// Unices version of my_sleep() function
+static void my_sleep(double sleeptime) {
+ struct timespec ts;
+ ts.tv_sec = (time_t)sleeptime;
+ ts.tv_nsec = (long)((sleeptime - (double)ts.tv_sec) * 1E9);
+ nanosleep(&ts, NULL);
+}
+
+#endif // _WIN32
+
+#endif // MY_SLEEP_H
diff --git a/openmp/runtime/test/omp_testsuite.h b/openmp/runtime/test/omp_testsuite.h
new file mode 100644
index 00000000000..53e0b78b6cf
--- /dev/null
+++ b/openmp/runtime/test/omp_testsuite.h
@@ -0,0 +1,22 @@
+/* Global headerfile of the OpenMP Testsuite */
+
+#ifndef OMP_TESTSUITE_H
+#define OMP_TESTSUITE_H
+
+#include <stdio.h>
+#include <omp.h>
+
+/* General */
+/**********************************************************/
+#define LOOPCOUNT 1000 /* Number of iterations to slit amongst threads */
+#define REPETITIONS 10 /* Number of times to run each test */
+
+/* following times are in seconds */
+#define SLEEPTIME 0.1
+
+/* Definitions for tasks */
+/**********************************************************/
+#define NUM_TASKS 25
+#define MAX_TASKS_PER_THREAD 5
+
+#endif
diff --git a/openmp/runtime/test/parallel/omp_nested.c b/openmp/runtime/test/parallel/omp_nested.c
new file mode 100644
index 00000000000..f73e072b38d
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_nested.c
@@ -0,0 +1,41 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+/*
+ * Test if the compiler supports nested parallelism
+ * By Chunhua Liao, University of Houston
+ * Oct. 2005
+ */
+int test_omp_nested()
+{
+ int counter = 0;
+#ifdef _OPENMP
+ omp_set_nested(1);
+#endif
+
+ #pragma omp parallel shared(counter)
+ {
+ #pragma omp critical
+ counter++;
+ #pragma omp parallel
+ {
+ #pragma omp critical
+ counter--;
+ }
+ }
+ return (counter != 0);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_nested()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/parallel/omp_parallel_copyin.c b/openmp/runtime/test/parallel/omp_parallel_copyin.c
new file mode 100644
index 00000000000..f14933b9869
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_parallel_copyin.c
@@ -0,0 +1,47 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+
+static int sum1 = 789;
+#pragma omp threadprivate(sum1)
+
+int test_omp_parallel_copyin()
+{
+ int sum, num_threads;
+ int known_sum;
+
+ sum = 0;
+ sum1 = 7;
+ num_threads = 0;
+
+ #pragma omp parallel copyin(sum1)
+ {
+ /*printf("sum1=%d\n",sum1);*/
+ 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*/
+ } /* end of parallel*/
+ known_sum = (999 * 1000) / 2 + 7 * num_threads;
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_copyin()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/parallel/omp_parallel_default.c b/openmp/runtime/test/parallel/omp_parallel_default.c
new file mode 100644
index 00000000000..171d0f585ce
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_parallel_default.c
@@ -0,0 +1,43 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_default()
+{
+ int i;
+ int sum;
+ int mysum;
+ int known_sum;
+ sum =0;
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 ;
+
+ #pragma omp parallel default(shared) private(i) private(mysum)
+ {
+ 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 */
+ if (known_sum != sum) {
+ fprintf(stderr, "KNOWN_SUM = %d; SUM = %d\n", known_sum, sum);
+ }
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_default()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/parallel/omp_parallel_firstprivate.c b/openmp/runtime/test/parallel/omp_parallel_firstprivate.c
new file mode 100644
index 00000000000..355a8b7bd2b
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_parallel_firstprivate.c
@@ -0,0 +1,46 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+
+//static int sum1 = 789;
+
+int test_omp_parallel_firstprivate()
+{
+ int sum, num_threads,sum1;
+ int known_sum;
+
+ sum = 0;
+ sum1=7;
+ num_threads = 0;
+
+ #pragma omp parallel firstprivate(sum1)
+ {
+ /*printf("sum1=%d\n",sum1);*/
+ 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*/
+ } /* end of parallel*/
+ known_sum = (999 * 1000) / 2 + 7 * num_threads;
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_firstprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/parallel/omp_parallel_if.c b/openmp/runtime/test/parallel/omp_parallel_if.c
new file mode 100644
index 00000000000..0f52f11c721
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_parallel_if.c
@@ -0,0 +1,40 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_if()
+{
+ int i;
+ int sum;
+ int known_sum;
+ int mysum;
+ int control=1;
+
+ sum =0;
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 ;
+ #pragma omp parallel private(i) if(control==0)
+ {
+ mysum = 0;
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ mysum = mysum + i;
+ }
+ #pragma omp critical
+ {
+ sum = sum + mysum;
+ }
+ }
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_if()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/parallel/omp_parallel_num_threads.c b/openmp/runtime/test/parallel/omp_parallel_num_threads.c
new file mode 100644
index 00000000000..8af1f9d674a
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_parallel_num_threads.c
@@ -0,0 +1,46 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_num_threads()
+{
+ int num_failed;
+ int threads;
+ int nthreads;
+ int max_threads = 0;
+
+ num_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;
+ #pragma omp parallel reduction(+:num_failed) num_threads(threads)
+ {
+ num_failed = num_failed + !(threads == omp_get_num_threads());
+ #pragma omp atomic
+ nthreads += 1;
+ }
+ num_failed = num_failed + !(nthreads == threads);
+ }
+ return (!num_failed);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_num_threads()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/parallel/omp_parallel_private.c b/openmp/runtime/test/parallel/omp_parallel_private.c
new file mode 100644
index 00000000000..24a47a15dca
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_parallel_private.c
@@ -0,0 +1,46 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+
+//static int sum1 = 789;
+
+int test_omp_parallel_private()
+{
+ int sum, num_threads,sum1;
+ int known_sum;
+
+ sum = 0;
+ num_threads = 0;
+
+ #pragma omp parallel private(sum1)
+ {
+ int i;
+ sum1 = 7;
+ /*printf("sum1=%d\n",sum1);*/
+ #pragma omp for
+ for (i = 1; i < 1000; i++) {
+ sum1 = sum1 + i;
+ }
+ #pragma omp critical
+ {
+ sum = sum + sum1;
+ num_threads++;
+ }
+ }
+ known_sum = (999 * 1000) / 2 + 7 * num_threads;
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_private()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/parallel/omp_parallel_reduction.c b/openmp/runtime/test/parallel/omp_parallel_reduction.c
new file mode 100644
index 00000000000..12783f28616
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_parallel_reduction.c
@@ -0,0 +1,254 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
+#define MAX_FACTOR 10
+#define KNOWN_PRODUCT 3628800 /* 10! */
+
+int test_omp_parallel_reduction()
+{
+ int sum;
+ int known_sum;
+ double dsum;
+ double dknown_sum;
+ double dt=0.5; /* base of geometric row for + and - test*/
+ double rounding_error= 1.E-9;
+ int diff;
+ double ddiff;
+ int product;
+ int known_product;
+ int logic_and;
+ int logic_or;
+ int bit_and;
+ int bit_or;
+ int exclusiv_bit_or;
+ int logics[LOOPCOUNT];
+ int i;
+ double dpt;
+ int result;
+
+ sum =0;
+ dsum=0;
+ product=1;
+ logic_and=1;
+ logic_or=0;
+ bit_and=1;
+ bit_or=0;
+ exclusiv_bit_or=0;
+ result=0;
+ dt = 1./3.;
+ known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2;
+
+ /* Tests for integers */
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:sum)
+ for (i=1;i<=LOOPCOUNT;i++) {
+ sum=sum+i;
+ }
+
+ if(known_sum!=sum) {
+ result++;
+ fprintf(stderr,"Error in sum with integers: Result was %d instead of %d\n",sum,known_sum);
+ }
+
+ diff = (LOOPCOUNT*(LOOPCOUNT+1))/2;
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:diff)
+ for (i=1;i<=LOOPCOUNT;++i) {
+ diff=diff-i;
+ }
+
+ if(diff != 0) {
+ result++;
+ fprintf(stderr,"Error in difference with integers: Result was %d instead of 0.\n",diff);
+ }
+
+ /* Tests for doubles */
+ dsum=0;
+ dpt=1;
+ for (i=0;i<DOUBLE_DIGITS;++i) {
+ dpt*=dt;
+ }
+ dknown_sum = (1-dpt)/(1-dt);
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:dsum)
+ for (i=0;i<DOUBLE_DIGITS;++i) {
+ dsum += pow(dt,i);
+ }
+
+ if( fabs(dsum-dknown_sum) > rounding_error ) {
+ result++;
+ fprintf(stderr,"Error in sum with doubles: Result was %f instead of %f (Difference: %E)\n",dsum,dknown_sum, dsum-dknown_sum);
+ }
+
+ dpt=1;
+
+ for (i=0;i<DOUBLE_DIGITS;++i) {
+ dpt*=dt;
+ }
+ fprintf(stderr,"\n");
+ ddiff = (1-dpt)/(1-dt);
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:ddiff)
+ for (i=0;i<DOUBLE_DIGITS;++i) {
+ ddiff -= pow(dt,i);
+ }
+ if( fabs(ddiff) > rounding_error) {
+ result++;
+ fprintf(stderr,"Error in Difference with doubles: Result was %E instead of 0.0\n",ddiff);
+ }
+
+ /* Tests for product of integers */
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(*:product)
+ for(i=1;i<=MAX_FACTOR;i++) {
+ product *= i;
+ }
+
+ known_product = KNOWN_PRODUCT;
+ if(known_product != product) {
+ result++;
+ fprintf(stderr,"Error in Product with integers: Result was %d instead of %d\n\n",product,known_product);
+ }
+
+ /* Tests for logical and */
+ for(i=0;i<LOOPCOUNT;i++) {
+ logics[i]=1;
+ }
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&&:logic_and)
+ for(i=0;i<LOOPCOUNT;++i) {
+ logic_and = (logic_and && logics[i]);
+ }
+ if(!logic_and) {
+ result++;
+ fprintf(stderr,"Error in logic AND part 1.\n");
+ }
+
+ logic_and = 1;
+ logics[LOOPCOUNT/2]=0;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&&:logic_and)
+ for(i=0;i<LOOPCOUNT;++i) {
+ logic_and = logic_and && logics[i];
+ }
+ if(logic_and) {
+ result++;
+ fprintf(stderr,"Error in logic AND part 2.\n");
+ }
+
+ /* Tests for logical or */
+ for(i=0;i<LOOPCOUNT;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(||:logic_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ logic_or = logic_or || logics[i];
+ }
+ if(logic_or) {
+ result++;
+ fprintf(stderr,"Error in logic OR part 1.\n");
+ }
+ logic_or = 0;
+ logics[LOOPCOUNT/2]=1;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(||:logic_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ logic_or = logic_or || logics[i];
+ }
+ if(!logic_or) {
+ result++;
+ fprintf(stderr,"Error in logic OR part 2.\n");
+ }
+
+ /* Tests for bitwise and */
+ for(i=0;i<LOOPCOUNT;++i) {
+ logics[i]=1;
+ }
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&:bit_and)
+ for(i=0;i<LOOPCOUNT;++i) {
+ bit_and = (bit_and & logics[i]);
+ }
+ if(!bit_and) {
+ result++;
+ fprintf(stderr,"Error in BIT AND part 1.\n");
+ }
+
+ bit_and = 1;
+ logics[LOOPCOUNT/2]=0;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&:bit_and)
+ for(i=0;i<LOOPCOUNT;++i) {
+ bit_and = bit_and & logics[i];
+ }
+ if(bit_and) {
+ result++;
+ fprintf(stderr,"Error in BIT AND part 2.\n");
+ }
+
+ for(i=0;i<LOOPCOUNT;i++) {
+ logics[i]=0;
+ }
+
+ /* Tests for bitwise or */
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(|:bit_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ if(bit_or) {
+ result++;
+ fprintf(stderr,"Error in BIT OR part 1\n");
+ }
+ bit_or = 0;
+ logics[LOOPCOUNT/2]=1;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(|:bit_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ if(!bit_or) {
+ result++;
+ fprintf(stderr,"Error in BIT OR part 2\n");
+ }
+
+ for(i=0;i<LOOPCOUNT;i++) {
+ logics[i]=0;
+ }
+
+ /* Tests for bitwise xor */
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(^:exclusiv_bit_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ if(exclusiv_bit_or) {
+ result++;
+ fprintf(stderr,"Error in EXCLUSIV BIT OR part 1\n");
+ }
+
+ exclusiv_bit_or = 0;
+ logics[LOOPCOUNT/2]=1;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(^:exclusiv_bit_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ if(!exclusiv_bit_or) {
+ result++;
+ fprintf(stderr,"Error in EXCLUSIV BIT OR part 2\n");
+ }
+
+ /*printf("\nResult:%d\n",result);*/
+ return (result==0);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_reduction()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/parallel/omp_parallel_shared.c b/openmp/runtime/test/parallel/omp_parallel_shared.c
new file mode 100644
index 00000000000..a6a37060bbe
--- /dev/null
+++ b/openmp/runtime/test/parallel/omp_parallel_shared.c
@@ -0,0 +1,46 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_shared()
+{
+ int i;
+ int sum;
+ int known_sum;
+
+ sum = 0;
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 ;
+
+ #pragma omp parallel private(i) shared(sum)
+ {
+
+ int mysum = 0;
+ #pragma omp for
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ mysum = mysum + i;
+ }
+ #pragma omp critical
+ {
+ sum = sum + mysum;
+ }
+
+
+ }
+ if (known_sum != sum) {
+ fprintf(stderr, "KNOWN_SUM = %d; SUM = %d\n", known_sum, sum);
+ }
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_shared()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/tasking/omp_task.c b/openmp/runtime/test/tasking/omp_task.c
new file mode 100644
index 00000000000..d2e28aad1a8
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_task.c
@@ -0,0 +1,52 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_task()
+{
+ int tids[NUM_TASKS];
+ int i;
+
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ for (i = 0; i < NUM_TASKS; i++) {
+ /* First we have to store the value of the loop index in a new variable
+ * which will be private for each task because otherwise it will be overwritten
+ * if the execution of the task takes longer than the time which is needed to
+ * enter the next step of the loop!
+ */
+ int myi;
+ myi = i;
+ #pragma omp task
+ {
+ my_sleep (SLEEPTIME);
+ tids[myi] = omp_get_thread_num();
+ } /* end of omp task */
+ } /* end of for */
+ } /* end of single */
+ } /*end of parallel */
+
+ /* Now we ckeck if more than one thread executed the tasks. */
+ for (i = 1; i < NUM_TASKS; i++) {
+ if (tids[0] != tids[i])
+ return 1;
+ }
+ return 0;
+} /* end of check_parallel_for_private */
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_task()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/tasking/omp_task_final.c b/openmp/runtime/test/tasking/omp_task_final.c
new file mode 100644
index 00000000000..aa9f90d5ecf
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_task_final.c
@@ -0,0 +1,65 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_task_final()
+{
+ int tids[NUM_TASKS];
+ int includedtids[NUM_TASKS];
+ int i;
+ int error;
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ for (i = 0; i < NUM_TASKS; i++) {
+ /* First we have to store the value of the loop index in a new variable
+ * which will be private for each task because otherwise it will be overwritten
+ * if the execution of the task takes longer than the time which is needed to
+ * enter the next step of the loop!
+ */
+ int myi;
+ myi = i;
+
+ #pragma omp task final(i>=10)
+ {
+ tids[myi] = omp_get_thread_num();
+ /* we generate included tasks for final tasks */
+ if(myi >= 10) {
+ int included = myi;
+ #pragma omp task
+ {
+ my_sleep (SLEEPTIME);
+ includedtids[included] = omp_get_thread_num();
+ } /* end of omp included task of the final task */
+ my_sleep (SLEEPTIME);
+ } /* end of if it is a final task*/
+ } /* end of omp task */
+ } /* end of for */
+ } /* end of single */
+ } /*end of parallel */
+
+ /* Now we ckeck if more than one thread executed the final task and its included task. */
+ for (i = 10; i < NUM_TASKS; i++) {
+ if (tids[i] != includedtids[i]) {
+ error++;
+ }
+ }
+ return (error==0);
+} /* end of check_paralel_for_private */
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_task_final()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
+
diff --git a/openmp/runtime/test/tasking/omp_task_firstprivate.c b/openmp/runtime/test/tasking/omp_task_firstprivate.c
new file mode 100644
index 00000000000..b5f4d234bfb
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_task_firstprivate.c
@@ -0,0 +1,51 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+int test_omp_task_firstprivate()
+{
+ int i;
+ int sum = 1234;
+ int known_sum;
+ int result = 0; /* counts the wrong sums from tasks */
+
+ known_sum = 1234 + (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ for (i = 0; i < NUM_TASKS; i++) {
+ #pragma omp task firstprivate(sum)
+ {
+ int j;
+ for (j = 0; j <= LOOPCOUNT; j++) {
+ #pragma omp flush
+ sum += j;
+ }
+
+ /* check if calculated sum was right */
+ if (sum != known_sum) {
+ #pragma omp critical
+ { result++; }
+ }
+ } /* omp task */
+ } /* for loop */
+ } /* omp single */
+ } /* omp parallel */
+ return (result == 0);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_task_firstprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/tasking/omp_task_if.c b/openmp/runtime/test/tasking/omp_task_if.c
new file mode 100644
index 00000000000..7bb7525ebda
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_task_if.c
@@ -0,0 +1,43 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_task_if()
+{
+ int condition_false;
+ int count;
+ int result;
+
+ count=0;
+ condition_false = (count == 1);
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ #pragma omp task if (condition_false) shared(count, result)
+ {
+ my_sleep (SLEEPTIME);
+ #pragma omp critical
+ result = (0 == count);
+ } /* end of omp task */
+ #pragma omp critical
+ count = 1;
+ } /* end of single */
+ } /*end of parallel */
+ return result;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_task_if()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/tasking/omp_task_imp_firstprivate.c b/openmp/runtime/test/tasking/omp_task_imp_firstprivate.c
new file mode 100644
index 00000000000..905ab9ac766
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_task_imp_firstprivate.c
@@ -0,0 +1,47 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+/* Utility function do spend some time in a loop */
+int test_omp_task_imp_firstprivate()
+{
+ int i=5;
+ int k = 0;
+ int result = 0;
+ int task_result = 1;
+ #pragma omp parallel firstprivate(i)
+ {
+ #pragma omp single
+ {
+ for (k = 0; k < NUM_TASKS; k++) {
+ #pragma omp task shared(result , task_result)
+ {
+ int j;
+ //check if i is private
+ if(i != 5)
+ task_result = 0;
+ for(j = 0; j < NUM_TASKS; j++)
+ i++;
+ //this should be firstprivate implicitly
+ }
+ }
+ #pragma omp taskwait
+ result = (task_result && i==5);
+ }
+ }
+ return result;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_task_imp_firstprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/tasking/omp_task_private.c b/openmp/runtime/test/tasking/omp_task_private.c
new file mode 100644
index 00000000000..dd164475ed1
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_task_private.c
@@ -0,0 +1,53 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+/* Utility function do spend some time in a loop */
+int test_omp_task_private()
+{
+ int i;
+ int known_sum;
+ int sum = 0;
+ int result = 0; /* counts the wrong sums from tasks */
+
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ for (i = 0; i < NUM_TASKS; i++) {
+ #pragma omp task private(sum) shared(result, known_sum)
+ {
+ int j;
+ //if sum is private, initialize to 0
+ sum = 0;
+ for (j = 0; j <= LOOPCOUNT; j++) {
+ #pragma omp flush
+ sum += j;
+ }
+ /* check if calculated sum was right */
+ if (sum != known_sum) {
+ #pragma omp critical
+ result++;
+ }
+ } /* end of omp task */
+ } /* end of for */
+ } /* end of single */
+ } /* end of parallel*/
+ return (result == 0);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_task_private()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/tasking/omp_task_shared.c b/openmp/runtime/test/tasking/omp_task_shared.c
new file mode 100644
index 00000000000..03040261064
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_task_shared.c
@@ -0,0 +1,41 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+/* Utility function do spend some time in a loop */
+int test_omp_task_imp_shared()
+{
+ int i;
+ int k = 0;
+ int result = 0;
+ i=0;
+
+ #pragma omp parallel
+ {
+ #pragma omp single
+ for (k = 0; k < NUM_TASKS; k++) {
+ #pragma omp task shared(i)
+ {
+ #pragma omp atomic
+ i++;
+ //this should be shared implicitly
+ }
+ }
+ }
+ result = i;
+ return ((result == NUM_TASKS));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_task_imp_shared()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/tasking/omp_taskwait.c b/openmp/runtime/test/tasking/omp_taskwait.c
new file mode 100644
index 00000000000..ddcaa77e518
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_taskwait.c
@@ -0,0 +1,74 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_taskwait()
+{
+ int result1 = 0; /* Stores number of not finished tasks after the taskwait */
+ int result2 = 0; /* Stores number of wrong array elements at the end */
+ int array[NUM_TASKS];
+ int i;
+
+ /* fill array */
+ for (i = 0; i < NUM_TASKS; i++)
+ array[i] = 0;
+
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ for (i = 0; i < NUM_TASKS; i++) {
+ /* First we have to store the value of the loop index in a new variable
+ * which will be private for each task because otherwise it will be overwritten
+ * if the execution of the task takes longer than the time which is needed to
+ * enter the next step of the loop!
+ */
+ int myi;
+ myi = i;
+ #pragma omp task
+ {
+ my_sleep (SLEEPTIME);
+ array[myi] = 1;
+ } /* end of omp task */
+ } /* end of for */
+ #pragma omp taskwait
+ /* check if all tasks were finished */
+ for (i = 0; i < NUM_TASKS; i++)
+ if (array[i] != 1)
+ result1++;
+
+ /* generate some more tasks which now shall overwrite
+ * the values in the tids array */
+ for (i = 0; i < NUM_TASKS; i++) {
+ int myi;
+ myi = i;
+ #pragma omp task
+ {
+ array[myi] = 2;
+ } /* end of omp task */
+ } /* end of for */
+ } /* end of single */
+ } /*end of parallel */
+
+ /* final check, if all array elements contain the right values: */
+ for (i = 0; i < NUM_TASKS; i++) {
+ if (array[i] != 2)
+ result2++;
+ }
+ return ((result1 == 0) && (result2 == 0));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_taskwait()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/tasking/omp_taskyield.c b/openmp/runtime/test/tasking/omp_taskyield.c
new file mode 100644
index 00000000000..5bb69844518
--- /dev/null
+++ b/openmp/runtime/test/tasking/omp_taskyield.c
@@ -0,0 +1,58 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_taskyield()
+{
+ int i;
+ int count = 0;
+ int start_tid[NUM_TASKS];
+ int current_tid[NUM_TASKS];
+
+ for (i=0; i< NUM_TASKS; i++) {
+ start_tid[i]=0;
+ current_tid[i]=0;
+ }
+
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ for (i = 0; i < NUM_TASKS; i++) {
+ int myi = i;
+ #pragma omp task untied
+ {
+ my_sleep(SLEEPTIME);
+ start_tid[myi] = omp_get_thread_num();
+ #pragma omp taskyield
+ if((start_tid[myi] %2) ==0){
+ my_sleep(SLEEPTIME);
+ current_tid[myi] = omp_get_thread_num();
+ } /*end of if*/
+ } /* end of omp task */
+ } /* end of for */
+ } /* end of single */
+ } /* end of parallel */
+ for (i=0;i<NUM_TASKS; i++) {
+ //printf("start_tid[%d]=%d, current_tid[%d]=%d\n",
+ //i, start_tid[i], i , current_tid[i]);
+ if (current_tid[i] == start_tid[i])
+ count++;
+ }
+ return (count<NUM_TASKS);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_taskyield()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/threadprivate/omp_threadprivate.c b/openmp/runtime/test/threadprivate/omp_threadprivate.c
new file mode 100644
index 00000000000..5dabadb4637
--- /dev/null
+++ b/openmp/runtime/test/threadprivate/omp_threadprivate.c
@@ -0,0 +1,102 @@
+// RUN: %libomp-compile-and-run
+/*
+ * Threadprivate is tested in 2 ways:
+ * 1. The global variable declared as threadprivate should have
+ * local copy for each thread. Otherwise race condition and
+ * wrong result.
+ * 2. If the value of local copy is retained for the two adjacent
+ * parallel regions
+ */
+#include "omp_testsuite.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+static int sum0=0;
+static int myvalue = 0;
+
+#pragma omp threadprivate(sum0)
+#pragma omp threadprivate(myvalue)
+
+int test_omp_threadprivate()
+{
+ int sum = 0;
+ int known_sum;
+ int i;
+ int iter;
+ int *data;
+ int size;
+ int num_failed = 0;
+ int my_random;
+ omp_set_dynamic(0);
+
+ #pragma omp parallel private(i)
+ {
+ sum0 = 0;
+ #pragma omp for
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ sum0 = sum0 + i;
+ } /*end of for*/
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ } /*end of critical */
+ } /* end of parallel */
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ if (known_sum != sum ) {
+ fprintf (stderr, " known_sum = %d, sum = %d\n", known_sum, sum);
+ }
+
+ /* the next parallel region is just used to get the number of threads*/
+ omp_set_dynamic(0);
+ #pragma omp parallel
+ {
+ #pragma omp master
+ {
+ size=omp_get_num_threads();
+ data=(int*) malloc(size*sizeof(int));
+ }
+ }/* end parallel*/
+
+ srand(45);
+ for (iter = 0; iter < 100; iter++) {
+ my_random = rand(); /* random number generator is
+ called inside serial region*/
+
+ /* the first parallel region is used to initialiye myvalue
+ and the array with my_random+rank */
+ #pragma omp parallel
+ {
+ int rank;
+ rank = omp_get_thread_num ();
+ myvalue = data[rank] = my_random + rank;
+ }
+
+ /* the second parallel region verifies that the
+ value of "myvalue" is retained */
+ #pragma omp parallel reduction(+:num_failed)
+ {
+ int rank;
+ rank = omp_get_thread_num ();
+ num_failed = num_failed + (myvalue != data[rank]);
+ if(myvalue != data[rank]) {
+ fprintf (stderr, " myvalue = %d, data[rank]= %d\n",
+ myvalue, data[rank]);
+ }
+ }
+ }
+ free (data);
+ return (known_sum == sum) && !num_failed;
+} /* end of check_threadprivate*/
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_threadprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/threadprivate/omp_threadprivate_for.c b/openmp/runtime/test/threadprivate/omp_threadprivate_for.c
new file mode 100644
index 00000000000..abfe52b00d0
--- /dev/null
+++ b/openmp/runtime/test/threadprivate/omp_threadprivate_for.c
@@ -0,0 +1,47 @@
+// RUN: %libomp-compile-and-run
+#include "omp_testsuite.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+static int i;
+#pragma omp threadprivate(i)
+
+int test_omp_threadprivate_for()
+{
+ int known_sum;
+ int sum;
+
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ sum = 0;
+
+ #pragma omp parallel
+ {
+ int sum0 = 0;
+ #pragma omp for
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ sum0 = sum0 + i;
+ }
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ }
+ } /* end of parallel */
+
+ if (known_sum != sum ) {
+ fprintf(stderr, " known_sum = %d, sum = %d\n", known_sum, sum);
+ }
+ return (known_sum == sum);
+} /* end of check_threadprivate*/
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_threadprivate_for()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_collapse.c b/openmp/runtime/test/worksharing/for/omp_for_collapse.c
new file mode 100644
index 00000000000..2d79e468783
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_collapse.c
@@ -0,0 +1,51 @@
+// RUN: %libomp-compile-and-run
+#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 test_omp_for_collapse()
+{
+ int is_larger = 1;
+
+ #pragma omp parallel
+ {
+ int i,j;
+ int my_islarger = 1;
+ #pragma omp for private(i,j) schedule(static,1) collapse(2) ordered
+ for (i = 1; i < 100; i++) {
+ for (j =1; j <100; j++) {
+ #pragma omp ordered
+ my_islarger = check_i_islarger(i)&&my_islarger;
+ }
+ }
+ #pragma omp critical
+ is_larger = is_larger && my_islarger;
+ }
+ return (is_larger);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_collapse()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_firstprivate.c b/openmp/runtime/test/worksharing/for/omp_for_firstprivate.c
new file mode 100644
index 00000000000..feceb525130
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_firstprivate.c
@@ -0,0 +1,55 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+int sum1;
+#pragma omp threadprivate(sum1)
+
+int test_omp_for_firstprivate()
+{
+ int sum;
+ int sum0;
+ int known_sum;
+ int threadsnum;
+
+ sum = 0;
+ sum0 = 12345;
+ sum1 = 0;
+
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ threadsnum=omp_get_num_threads();
+ }
+ /* sum0 = 0; */
+
+ int i;
+ #pragma omp for firstprivate(sum0)
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ sum0 = sum0 + i;
+ sum1 = sum0;
+ } /* end of for */
+
+ #pragma omp critical
+ {
+ sum = sum + sum1;
+ } /* end of critical */
+ } /* end of parallel */
+ known_sum = 12345* threadsnum+ (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_firstprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_lastprivate.c b/openmp/runtime/test/worksharing/for/omp_for_lastprivate.c
new file mode 100644
index 00000000000..de89729ae33
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_lastprivate.c
@@ -0,0 +1,52 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+int sum0;
+#pragma omp threadprivate(sum0)
+
+int test_omp_for_lastprivate()
+{
+ int sum = 0;
+ int known_sum;
+ int i0;
+
+ i0 = -1;
+
+ #pragma omp parallel
+ {
+ sum0 = 0;
+ { /* Begin of orphaned block */
+ int i;
+ #pragma omp for schedule(static,7) lastprivate(i0)
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ sum0 = sum0 + i;
+ i0 = i;
+ } /* end of for */
+ } /* end of orphaned block */
+
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ } /* end of critical */
+ } /* end of parallel */
+
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ fprintf(stderr, "known_sum = %d , sum = %d\n",known_sum,sum);
+ fprintf(stderr, "LOOPCOUNT = %d , i0 = %d\n",LOOPCOUNT,i0);
+ return ((known_sum == sum) && (i0 == LOOPCOUNT));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for (i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_lastprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_nowait.c b/openmp/runtime/test/worksharing/for/omp_for_nowait.c
new file mode 100644
index 00000000000..0e85f1e0d32
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_nowait.c
@@ -0,0 +1,53 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_for_nowait()
+{
+ int result;
+ int count;
+ int j;
+ int myarray[LOOPCOUNT];
+
+ result = 0;
+ count = 0;
+
+ #pragma omp parallel
+ {
+ int rank;
+ int i;
+
+ rank = omp_get_thread_num();
+
+ #pragma omp for nowait
+ for (i = 0; i < LOOPCOUNT; i++) {
+ if (i == 0) {
+ my_sleep(SLEEPTIME);
+ count = 1;
+ #pragma omp flush(count)
+ }
+ }
+
+ #pragma omp for
+ for (i = 0; i < LOOPCOUNT; i++) {
+ #pragma omp flush(count)
+ if (count == 0)
+ result = 1;
+ }
+ }
+ return result;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_nowait()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_ordered.c b/openmp/runtime/test/worksharing/for/omp_for_ordered.c
new file mode 100644
index 00000000000..6bf0ed22a93
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_ordered.c
@@ -0,0 +1,60 @@
+// RUN: %libomp-compile-and-run
+#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 test_omp_for_ordered()
+{
+ int sum;
+ int is_larger = 1;
+ int known_sum;
+
+ last_i = 0;
+ sum = 0;
+
+ #pragma omp parallel
+ {
+ int i;
+ int my_islarger = 1;
+ #pragma omp for schedule(static,1) ordered
+ for (i = 1; i < 100; i++) {
+ #pragma omp ordered
+ {
+ my_islarger = check_i_islarger(i) && my_islarger;
+ sum = sum + i;
+ }
+ }
+ #pragma omp critical
+ {
+ is_larger = is_larger && my_islarger;
+ }
+ }
+
+ known_sum=(99 * 100) / 2;
+ return ((known_sum == sum) && is_larger);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_ordered()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_private.c b/openmp/runtime/test/worksharing/for/omp_for_private.c
new file mode 100644
index 00000000000..981698eb667
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_private.c
@@ -0,0 +1,63 @@
+// RUN: %libomp-compile-and-run
+#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 test_omp_for_private()
+{
+ int sum = 0;
+ int sum0;
+ 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 */
+ int i;
+ #pragma omp for private(sum0) 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 orphaned block */
+
+ #pragma omp critical
+ {
+ sum = sum + sum1;
+ } /*end of critical*/
+ } /* end of parallel*/
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_private()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_reduction.c b/openmp/runtime/test/worksharing/for/omp_for_reduction.c
new file mode 100644
index 00000000000..df690b28450
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_reduction.c
@@ -0,0 +1,339 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
+#define MAX_FACTOR 10
+#define KNOWN_PRODUCT 3628800 /* 10! */
+
+int test_omp_for_reduction ()
+{
+ double dt;
+ int sum;
+ int diff;
+ int product = 1;
+ double dsum;
+ double dknown_sum;
+ double ddiff;
+ int logic_and;
+ int logic_or;
+ int bit_and;
+ int bit_or;
+ int exclusiv_bit_or;
+ int *logics;
+ int i;
+ int known_sum;
+ int known_product;
+ double rounding_error = 1.E-9; /* over all rounding error to be
+ ignored in the double tests */
+ double dpt;
+ int result = 0;
+ int logicsArray[LOOPCOUNT];
+
+ /* Variables for integer tests */
+ sum = 0;
+ product = 1;
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ /* variabels for double tests */
+ dt = 1. / 3.; /* base of geometric row for + and - test*/
+ dsum = 0.;
+ /* Variabeles for logic tests */
+ logics = logicsArray;
+ logic_and = 1;
+ logic_or = 0;
+ /* Variabeles for bit operators tests */
+ bit_and = 1;
+ bit_or = 0;
+ /* Variables for exclusiv bit or */
+ exclusiv_bit_or = 0;
+
+ /************************************************************************/
+ /** Tests for integers **/
+ /************************************************************************/
+
+ /**** Testing integer addition ****/
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(+:sum)
+ for (j = 1; j <= LOOPCOUNT; j++) {
+ sum = sum + j;
+ }
+ }
+ if (known_sum != sum) {
+ result++;
+ fprintf (stderr, "Error in sum with integers: Result was %d"
+ " instead of %d.\n", sum, known_sum);
+ }
+
+ /**** Testing integer subtracton ****/
+ diff = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(-:diff)
+ for (j = 1; j <= LOOPCOUNT; j++) {
+ diff = diff - j;
+ }
+ }
+ if (diff != 0) {
+ result++;
+ fprintf (stderr, "Error in difference with integers: Result was %d"
+ " instead of 0.\n", diff);
+ }
+
+ /**** Testing integer multiplication ****/
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(*:product)
+ for (j = 1; j <= MAX_FACTOR; j++) {
+ product *= j;
+ }
+ }
+ known_product = KNOWN_PRODUCT;
+ if(known_product != product) {
+ result++;
+ fprintf (stderr,"Error in Product with integers: Result was %d"
+ " instead of %d\n",product,known_product);
+ }
+
+ /************************************************************************/
+ /** Tests for doubles **/
+ /************************************************************************/
+
+ /**** Testing double addition ****/
+ dsum = 0.;
+ dpt = 1.;
+ for (i = 0; i < DOUBLE_DIGITS; ++i) {
+ dpt *= dt;
+ }
+ dknown_sum = (1 - dpt) / (1 - dt);
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(+:dsum)
+ for (j = 0; j < DOUBLE_DIGITS; j++) {
+ dsum += pow (dt, j);
+ }
+ }
+ if (fabs (dsum - dknown_sum) > rounding_error) {
+ result++;
+ fprintf (stderr, "\nError in sum with doubles: Result was %f"
+ " instead of: %f (Difference: %E)\n",
+ dsum, dknown_sum, dsum-dknown_sum);
+ }
+
+ /**** Testing double subtraction ****/
+ ddiff = (1 - dpt) / (1 - dt);
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(-:ddiff)
+ for (j = 0; j < DOUBLE_DIGITS; ++j) {
+ ddiff -= pow (dt, j);
+ }
+ }
+ if (fabs (ddiff) > rounding_error) {
+ result++;
+ fprintf (stderr, "Error in Difference with doubles: Result was %E"
+ " instead of 0.0\n", ddiff);
+ }
+
+
+ /************************************************************************/
+ /** Tests for logical values **/
+ /************************************************************************/
+
+ /**** Testing logic and ****/
+ for (i = 0; i < LOOPCOUNT; i++) {
+ logics[i] = 1;
+ }
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(&&:logic_and)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ logic_and = (logic_and && logics[j]);
+ }
+ }
+ if(!logic_and) {
+ result++;
+ fprintf (stderr, "Error in logic AND part 1\n");
+ }
+
+ logic_and = 1;
+ logics[LOOPCOUNT / 2] = 0;
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(&&:logic_and)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ logic_and = logic_and && logics[j];
+ }
+ }
+ if(logic_and) {
+ result++;
+ fprintf (stderr, "Error in logic AND part 2\n");
+ }
+
+ /**** Testing logic or ****/
+ for (i = 0; i < LOOPCOUNT; i++) {
+ logics[i] = 0;
+ }
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(||:logic_or)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ logic_or = logic_or || logics[j];
+ }
+ }
+ if (logic_or) {
+ result++;
+ fprintf (stderr, "Error in logic OR part 1\n");
+ }
+
+ logic_or = 0;
+ logics[LOOPCOUNT / 2] = 1;
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(||:logic_or)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ logic_or = logic_or || logics[j];
+ }
+ }
+ if(!logic_or) {
+ result++;
+ fprintf (stderr, "Error in logic OR part 2\n");
+ }
+
+ /************************************************************************/
+ /** Tests for bit values **/
+ /************************************************************************/
+
+ /**** Testing bit and ****/
+ for (i = 0; i < LOOPCOUNT; ++i) {
+ logics[i] = 1;
+ }
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(&:bit_and)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ bit_and = (bit_and & logics[j]);
+ }
+ }
+ if (!bit_and) {
+ result++;
+ fprintf (stderr, "Error in BIT AND part 1\n");
+ }
+
+ bit_and = 1;
+ logics[LOOPCOUNT / 2] = 0;
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(&:bit_and)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ bit_and = bit_and & logics[j];
+ }
+ }
+ if (bit_and) {
+ result++;
+ fprintf (stderr, "Error in BIT AND part 2\n");
+ }
+
+ /**** Testing bit or ****/
+ for (i = 0; i < LOOPCOUNT; i++) {
+ logics[i] = 0;
+ }
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(|:bit_or)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ bit_or = bit_or | logics[j];
+ }
+ }
+ if (bit_or) {
+ result++;
+ fprintf (stderr, "Error in BIT OR part 1\n");
+ }
+
+ bit_or = 0;
+ logics[LOOPCOUNT / 2] = 1;
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(|:bit_or)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ bit_or = bit_or | logics[j];
+ }
+ }
+ if (!bit_or) {
+ result++;
+ fprintf (stderr, "Error in BIT OR part 2\n");
+ }
+
+ /**** Testing exclusive bit or ****/
+ for (i = 0; i < LOOPCOUNT; i++) {
+ logics[i] = 0;
+ }
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(^:exclusiv_bit_or)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[j];
+ }
+ }
+ if (exclusiv_bit_or) {
+ result++;
+ fprintf (stderr, "Error in EXCLUSIV BIT OR part 1\n");
+ }
+
+ exclusiv_bit_or = 0;
+ logics[LOOPCOUNT / 2] = 1;
+
+ #pragma omp parallel
+ {
+ int j;
+ #pragma omp for schedule(dynamic,1) reduction(^:exclusiv_bit_or)
+ for (j = 0; j < LOOPCOUNT; ++j) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[j];
+ }
+ }
+ if (!exclusiv_bit_or) {
+ result++;
+ fprintf (stderr, "Error in EXCLUSIV BIT OR part 2\n");
+ }
+
+ return (result == 0);
+ free (logics);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_reduction()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_schedule_auto.c b/openmp/runtime/test/worksharing/for/omp_for_schedule_auto.c
new file mode 100644
index 00000000000..67c2d21e28c
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_schedule_auto.c
@@ -0,0 +1,69 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+int sum1;
+#pragma omp threadprivate(sum1)
+
+int test_omp_for_auto()
+{
+ int j;
+ int sum;
+ int sum0;
+ int known_sum;
+ int threadsnum;
+
+ sum = 0;
+ sum0 = 12345;
+ sum1 = 0;
+
+ // array which keeps track of which threads participated in the for loop
+ // e.g., given 4 threads, [ 0 | 1 | 1 | 0 ] implies
+ // threads 0 and 3 did not, threads 1 and 2 did
+ int max_threads = omp_get_max_threads();
+ int* active_threads = (int*)malloc(sizeof(int)*max_threads);
+ for(j = 0; j < max_threads; j++)
+ active_threads[j] = 0;
+
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp for firstprivate(sum0) schedule(auto)
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ active_threads[omp_get_thread_num()] = 1;
+ sum0 = sum0 + i;
+ sum1 = sum0;
+ }
+
+ #pragma omp critical
+ {
+ sum = sum + sum1;
+ }
+ }
+
+ // count the threads that participated (sum is stored in threadsnum)
+ threadsnum=0;
+ for(j = 0; j < max_threads; j++) {
+ if(active_threads[j])
+ threadsnum++;
+ }
+ free(active_threads);
+
+ known_sum = 12345 * threadsnum + (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ return (known_sum == sum);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_auto()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_schedule_dynamic.c b/openmp/runtime/test/worksharing/for/omp_for_schedule_dynamic.c
new file mode 100644
index 00000000000..92a6d098e1e
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_schedule_dynamic.c
@@ -0,0 +1,90 @@
+// RUN: %libomp-compile-and-run
+/*
+ * 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
+ * Modified by Chunhua Liao
+ */
+#include <stdio.h>
+#include <omp.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+
+#define CFDMAX_SIZE 100
+const int chunk_size = 7;
+
+int test_omp_for_schedule_dynamic()
+{
+ int tid;
+ int *tids;
+ int i;
+ 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 */
+ int tid;
+ tid = omp_get_thread_num ();
+ #pragma omp for schedule(dynamic,chunk_size)
+ for (i = 0; i < CFDMAX_SIZE; i++) {
+ tids[i] = tid;
+ }
+ }
+
+ 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]++;
+ }
+ }
+ /* 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(stderr,"The intermediate dispatch has wrong chunksize.\n");
+ /* result += ((tmp[i] / chunk_size) - 1); */
+ }
+ }
+ if ((tmp[count]%chunk_size)!=(CFDMAX_SIZE%chunk_size)) {
+ result++;
+ fprintf(stderr,"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);
+}
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_schedule_dynamic()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_schedule_guided.c b/openmp/runtime/test/worksharing/for/omp_for_schedule_guided.c
new file mode 100644
index 00000000000..5cc2b47711c
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_schedule_guided.c
@@ -0,0 +1,218 @@
+// RUN: %libomp-compile-and-run
+
+/* Test for guided scheduling
+ * Ensure threads get chunks interleavely first
+ * Then judge the chunk sizes are decreasing to a stable value
+ * Modified by Chunhua Liao
+ * For example, 100 iteration on 2 threads, chunksize 7
+ * one line for each dispatch, 0/1 means thread id
+ * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24
+ * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 18
+ * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14
+ * 1 1 1 1 1 1 1 1 1 1 10
+ * 0 0 0 0 0 0 0 0 8
+ * 1 1 1 1 1 1 1 7
+ * 0 0 0 0 0 0 0 7
+ * 1 1 1 1 1 1 1 7
+ * 0 0 0 0 0 5
+*/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+#define CFSMAX_SIZE 1000
+#define MAX_TIME 0.005
+
+#ifdef SLEEPTIME
+#undef SLEEPTIME
+#define SLEEPTIME 0.0001
+#endif
+
+int test_omp_for_schedule_guided()
+{
+ int * tids;
+ int * chunksizes;
+ int notout;
+ int maxiter;
+ int threads;
+ int i;
+ int result;
+
+ tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
+ maxiter = 0;
+ result = 1;
+ notout = 1;
+
+ /* Testing if enough threads are available for this check. */
+ #pragma omp parallel
+ {
+ #pragma omp single
+ {
+ threads = omp_get_num_threads();
+ }
+ }
+
+ /* ensure there are at least two threads */
+ if (threads < 2) {
+ omp_set_num_threads(2);
+ threads = 2;
+ }
+
+ /* Now the real parallel work:
+ * Each thread will start immediately with the first chunk.
+ */
+ #pragma omp parallel shared(tids,maxiter)
+ { /* begin of parallel */
+ double count;
+ int tid;
+ int j;
+
+ tid = omp_get_thread_num ();
+
+ #pragma omp for nowait schedule(guided)
+ for(j = 0; j < CFSMAX_SIZE; ++j) {
+ count = 0.;
+ #pragma omp flush(maxiter)
+ if (j > maxiter) {
+ #pragma omp critical
+ {
+ maxiter = j;
+ }
+ }
+ /*printf ("thread %d sleeping\n", tid);*/
+ #pragma omp flush(maxiter,notout)
+ while (notout && (count < MAX_TIME) && (maxiter == j)) {
+ #pragma omp flush(maxiter,notout)
+ my_sleep (SLEEPTIME);
+ count += SLEEPTIME;
+#ifdef VERBOSE
+ printf(".");
+#endif
+ }
+#ifdef VERBOSE
+ if (count > 0.) printf(" waited %lf s\n", count);
+#endif
+ /*printf ("thread %d awake\n", tid);*/
+ tids[j] = tid;
+#ifdef VERBOSE
+ printf("%d finished by %d\n",j,tid);
+#endif
+ } /* end of for */
+ notout = 0;
+ #pragma omp flush(maxiter,notout)
+ } /* end of parallel */
+
+ /*******************************************************
+ * evaluation of the values *
+ *******************************************************/
+ {
+ int determined_chunksize = 1;
+ int last_threadnr = tids[0];
+ int global_chunknr = 0;
+ int openwork = CFSMAX_SIZE;
+ int expected_chunk_size;
+ int* local_chunknr = (int*)malloc(threads * sizeof(int));
+ double c = 1;
+
+ for (i = 0; i < threads; i++)
+ local_chunknr[i] = 0;
+
+ tids[CFSMAX_SIZE] = -1;
+
+ /*
+ * determine the number of global chunks
+ */
+ // fprintf(stderr,"# global_chunknr thread local_chunknr chunksize\n");
+ for(i = 1; i <= CFSMAX_SIZE; ++i) {
+ if (last_threadnr==tids[i]) {
+ determined_chunksize++;
+ } else {
+ /* fprintf(stderr, "%d\t%d\t%d\t%d\n", global_chunknr,
+ last_threadnr, local_chunknr[last_threadnr], m); */
+ global_chunknr++;
+ local_chunknr[last_threadnr]++;
+ last_threadnr = tids[i];
+ determined_chunksize = 1;
+ }
+ }
+ /* now allocate the memory for saving the sizes of the global chunks */
+ chunksizes = (int*)malloc(global_chunknr * sizeof(int));
+
+ /*
+ * Evaluate the sizes of the global chunks
+ */
+ global_chunknr = 0;
+ determined_chunksize = 1;
+ last_threadnr = tids[0];
+ for (i = 1; i <= CFSMAX_SIZE; ++i) {
+ /* If the threadnumber was the same as before increase the
+ * detected chunksize for this chunk otherwise set the detected
+ * chunksize again to one and save the number of the next
+ * thread in last_threadnr.
+ */
+ if (last_threadnr == tids[i]) {
+ determined_chunksize++;
+ } else {
+ chunksizes[global_chunknr] = determined_chunksize;
+ global_chunknr++;
+ local_chunknr[last_threadnr]++;
+ last_threadnr = tids[i];
+ determined_chunksize = 1;
+ }
+ }
+
+#ifdef VERBOSE
+ fprintf(stderr, "found\texpected\tconstant\n");
+#endif
+
+ /* identify the constant c for the exponential
+ decrease of the chunksize */
+ expected_chunk_size = openwork / threads;
+ c = (double) chunksizes[0] / expected_chunk_size;
+
+ for (i = 0; i < global_chunknr; i++) {
+ /* calculate the new expected chunksize */
+ if (expected_chunk_size > 1)
+ expected_chunk_size = c * openwork / threads;
+#ifdef VERBOSE
+ fprintf(stderr, "%8d\t%8d\t%lf\n", chunksizes[i],
+ expected_chunk_size, c * chunksizes[i]/expected_chunk_size);
+#endif
+ /* check if chunksize is inside the rounding errors */
+ if (abs (chunksizes[i] - expected_chunk_size) >= 2) {
+ result = 0;
+#ifndef VERBOSE
+ fprintf(stderr, "Chunksize differed from expected "
+ "value: %d instead of %d\n", chunksizes[i],
+ expected_chunk_size);
+ return 0;
+#endif
+ } /* end if */
+
+#ifndef VERBOSE
+ if (expected_chunk_size - chunksizes[i] < 0)
+ fprintf(stderr, "Chunksize did not decrease: %d"
+ " instead of %d\n", chunksizes[i],expected_chunk_size);
+#endif
+
+ /* calculating the remaining amount of work */
+ openwork -= chunksizes[i];
+ }
+ }
+ return result;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_schedule_guided()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_schedule_static.c b/openmp/runtime/test/worksharing/for/omp_for_schedule_static.c
new file mode 100644
index 00000000000..30b8bffb6cb
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_schedule_static.c
@@ -0,0 +1,155 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+#define CFSMAX_SIZE 1000
+#define MAX_TIME 0.01
+
+#ifdef SLEEPTIME
+#undef SLEEPTIME
+#define SLEEPTIME 0.0005
+#endif
+
+int test_omp_for_schedule_static()
+{
+ int threads;
+ int i,lasttid;
+ int * tids;
+ int notout;
+ int maxiter;
+ int chunk_size;
+ int counter = 0;
+ int tmp_count=1;
+ int lastthreadsstarttid = -1;
+ int result = 1;
+
+ chunk_size = 7;
+ tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
+ notout = 1;
+ maxiter = 0;
+
+ #pragma omp parallel shared(tids,counter)
+ { /* begin of parallel*/
+ #pragma omp single
+ {
+ threads = omp_get_num_threads ();
+ } /* end of single */
+ } /* end of parallel */
+
+ if (threads < 2) {
+ omp_set_num_threads(2);
+ threads = 2;
+ }
+ fprintf (stderr,"Using an internal count of %d\nUsing a specified"
+ " chunksize of %d\n", CFSMAX_SIZE, chunk_size);
+ tids[CFSMAX_SIZE] = -1; /* setting endflag */
+ #pragma omp parallel shared(tids)
+ { /* begin of parallel */
+ double count;
+ int tid;
+ int j;
+
+ tid = omp_get_thread_num ();
+
+ #pragma omp for nowait schedule(static,chunk_size)
+ for(j = 0; j < CFSMAX_SIZE; ++j) {
+ count = 0.;
+ #pragma omp flush(maxiter)
+ if (j > maxiter) {
+ #pragma omp critical
+ {
+ maxiter = j;
+ }
+ }
+ /*printf ("thread %d sleeping\n", tid);*/
+ while (notout && (count < MAX_TIME) && (maxiter == j)) {
+ #pragma omp flush(maxiter,notout)
+ my_sleep (SLEEPTIME);
+ count += SLEEPTIME;
+ printf(".");
+ }
+#ifdef VERBOSE
+ if (count > 0.) printf(" waited %lf s\n", count);
+#endif
+ /*printf ("thread %d awake\n", tid);*/
+ tids[j] = tid;
+#ifdef VERBOSE
+ printf("%d finished by %d\n",j,tid);
+#endif
+ } /* end of for */
+ notout = 0;
+ #pragma omp flush(maxiter,notout)
+ } /* end of parallel */
+
+ /**** analysing the data in array tids ****/
+
+ lasttid = tids[0];
+ tmp_count = 0;
+
+ for (i = 0; i < CFSMAX_SIZE + 1; ++i) {
+ /* If the work was done by the same thread increase tmp_count by one. */
+ if (tids[i] == lasttid) {
+ tmp_count++;
+#ifdef VERBOSE
+ fprintf (stderr, "%d: %d \n", i, tids[i]);
+#endif
+ continue;
+ }
+
+ /* Check if the next thread had has the right thread number. When finding
+ * threadnumber -1 the end should be reached.
+ */
+ if (tids[i] == (lasttid + 1) % threads || tids[i] == -1) {
+ /* checking for the right chunk size */
+ if (tmp_count == chunk_size) {
+ tmp_count = 1;
+ lasttid = tids[i];
+#ifdef VERBOSE
+ fprintf (stderr, "OK\n");
+#endif
+ } else {
+ /* If the chunk size was wrong, check if the end was reached */
+ if (tids[i] == -1) {
+ if (i == CFSMAX_SIZE) {
+ fprintf (stderr, "Last thread had chunk size %d\n",
+ tmp_count);
+ break;
+ } else {
+ fprintf (stderr, "ERROR: Last thread (thread with"
+ " number -1) was found before the end.\n");
+ result = 0;
+ }
+ } else {
+ fprintf (stderr, "ERROR: chunk size was %d. (assigned"
+ " was %d)\n", tmp_count, chunk_size);
+ result = 0;
+ }
+ }
+ } else {
+ fprintf(stderr, "ERROR: Found thread with number %d (should be"
+ " inbetween 0 and %d).", tids[i], threads - 1);
+ result = 0;
+ }
+#ifdef VERBOSE
+ fprintf (stderr, "%d: %d \n", i, tids[i]);
+#endif
+ }
+
+ return result;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_schedule_static()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_for_schedule_static_3.c b/openmp/runtime/test/worksharing/for/omp_for_schedule_static_3.c
new file mode 100644
index 00000000000..99980d41dd9
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_for_schedule_static_3.c
@@ -0,0 +1,203 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+#define CFSMAX_SIZE 1000
+#define MAX_TIME 0.01
+
+#ifdef SLEEPTIME
+#undef SLEEPTIME
+#define SLEEPTIME 0.0005
+#endif
+
+#define VERBOSE 0
+
+int test_omp_for_schedule_static_3()
+{
+ int threads;
+ int i,lasttid;
+
+ int * tids;
+ int * tids2;
+ int notout;
+ int maxiter;
+ int chunk_size;
+
+ int counter = 0;
+ int tmp_count=1;
+ int lastthreadsstarttid = -1;
+ int result = 1;
+ chunk_size = 7;
+
+ tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
+ notout = 1;
+ maxiter = 0;
+
+ #pragma omp parallel shared(tids,counter)
+ { /* begin of parallel*/
+ #pragma omp single
+ {
+ threads = omp_get_num_threads ();
+ } /* end of single */
+ } /* end of parallel */
+
+ /* Ensure that at least two threads are created */
+ if (threads < 2) {
+ omp_set_num_threads(2);
+ threads = 2;
+ }
+ fprintf (stderr,"Using an internal count of %d\nUsing a"
+ " specified chunksize of %d\n", CFSMAX_SIZE, chunk_size);
+ tids[CFSMAX_SIZE] = -1; /* setting endflag */
+
+ #pragma omp parallel shared(tids)
+ { /* begin of parallel */
+ double count;
+ int tid;
+ int j;
+
+ tid = omp_get_thread_num ();
+
+ #pragma omp for nowait schedule(static,chunk_size)
+ for(j = 0; j < CFSMAX_SIZE; ++j) {
+ count = 0.;
+ #pragma omp flush(maxiter)
+ if (j > maxiter) {
+ #pragma omp critical
+ {
+ maxiter = j;
+ }
+ }
+ /*printf ("thread %d sleeping\n", tid);*/
+ while (notout && (count < MAX_TIME) && (maxiter == j)) {
+ #pragma omp flush(maxiter,notout)
+ my_sleep (SLEEPTIME);
+ count += SLEEPTIME;
+ printf(".");
+ }
+#ifdef VERBOSE
+ if (count > 0.) printf(" waited %lf s\n", count);
+#endif
+ /*printf ("thread %d awake\n", tid);*/
+ tids[j] = tid;
+#ifdef VERBOSE
+ printf("%d finished by %d\n",j,tid);
+#endif
+ } /* end of omp parallel for */
+
+ notout = 0;
+ #pragma omp flush(maxiter,notout)
+ } /* end of parallel */
+
+ /**** analysing the data in array tids ****/
+
+ lasttid = tids[0];
+ tmp_count = 0;
+
+ for (i = 0; i < CFSMAX_SIZE + 1; ++i) {
+ /* If the work was done by the same thread
+ increase tmp_count by one. */
+ if (tids[i] == lasttid) {
+ tmp_count++;
+#ifdef VERBOSE
+ fprintf (stderr, "%d: %d \n", i, tids[i]);
+#endif
+ continue;
+ }
+
+ /* Check if the next thread had has the right thread number.
+ * When finding threadnumber -1 the end should be reached.
+ */
+ if (tids[i] == (lasttid + 1) % threads || tids[i] == -1) {
+ /* checking for the right chunk size */
+ if (tmp_count == chunk_size) {
+ tmp_count = 1;
+ lasttid = tids[i];
+#ifdef VERBOSE
+ fprintf (stderr, "OK\n");
+#endif
+ } else {
+ /* If the chunk size was wrong, check if the end was reached */
+ if (tids[i] == -1) {
+ if (i == CFSMAX_SIZE) {
+ fprintf (stderr, "Last thread had chunk size %d\n",
+ tmp_count);
+ break;
+ } else {
+ fprintf (stderr, "ERROR: Last thread (thread with"
+ " number -1) was found before the end.\n");
+ result = 0;
+ }
+ } else {
+ fprintf (stderr, "ERROR: chunk size was %d. (assigned"
+ " was %d)\n", tmp_count, chunk_size);
+ result = 0;
+ }
+ }
+ } else {
+ fprintf(stderr, "ERROR: Found thread with number %d (should be"
+ " inbetween 0 and %d).", tids[i], threads - 1);
+ result = 0;
+ }
+#ifdef VERBOSE
+ fprintf (stderr, "%d: %d \n", i, tids[i]);
+#endif
+ }
+
+ /* Now we check if several loop regions in one parallel region have the
+ * same logical assignement of chunks to threads. We use the nowait
+ * clause to increase the probability to get an error. */
+
+ /* First we allocate some more memmory */
+ free (tids);
+ tids = (int *) malloc (sizeof (int) * LOOPCOUNT);
+ tids2 = (int *) malloc (sizeof (int) * LOOPCOUNT);
+
+ #pragma omp parallel
+ {
+ {
+ int n;
+ #pragma omp for schedule(static) nowait
+ for (n = 0; n < LOOPCOUNT; n++) {
+ if (LOOPCOUNT == n + 1 )
+ my_sleep(SLEEPTIME);
+
+ tids[n] = omp_get_thread_num();
+ }
+ }
+ {
+ int m;
+ #pragma omp for schedule(static) nowait
+ for (m = 1; m <= LOOPCOUNT; m++) {
+ tids2[m-1] = omp_get_thread_num();
+ }
+ }
+ }
+
+ for (i = 0; i < LOOPCOUNT; i++)
+ if (tids[i] != tids2[i]) {
+ fprintf (stderr, "Chunk no. %d was assigned once to thread %d and"
+ " later to thread %d.\n", i, tids[i],tids2[i]);
+ result = 0;
+ }
+
+ free (tids);
+ free (tids2);
+ return result;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for (i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_for_schedule_static_3()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_parallel_for_firstprivate.c b/openmp/runtime/test/worksharing/for/omp_parallel_for_firstprivate.c
new file mode 100644
index 00000000000..3b3bf7d887c
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_parallel_for_firstprivate.c
@@ -0,0 +1,35 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_for_firstprivate()
+{
+ int sum ;
+ int i2;
+ int i;
+ int known_sum;
+
+ sum=0;
+ i2=3;
+
+ #pragma omp parallel for reduction(+:sum) private(i) firstprivate(i2)
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ sum = sum + (i + i2);
+ }
+
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2 + i2 * LOOPCOUNT;
+ return (known_sum == sum);
+} /* end of check_parallel_for_fistprivate */
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_for_firstprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_parallel_for_if.c b/openmp/runtime/test/worksharing/for/omp_parallel_for_if.c
new file mode 100644
index 00000000000..57fe498c2ba
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_parallel_for_if.c
@@ -0,0 +1,42 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_for_if()
+{
+ int known_sum;
+ int num_threads;
+ int sum, sum2;
+ int i;
+ int control;
+
+ control = 0;
+ num_threads=0;
+ sum = 0;
+ sum2 = 0;
+
+ #pragma omp parallel for private(i) if (control==1)
+ for (i=0; i <= LOOPCOUNT; i++) {
+ num_threads = omp_get_num_threads();
+ sum = sum + i;
+ }
+
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ fprintf(stderr, "Number of threads determined by"
+ " omp_get_num_threads: %d\n", num_threads);
+ return (known_sum == sum && num_threads == 1);
+} /* end of check_parallel_for_private */
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_for_if()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_parallel_for_lastprivate.c b/openmp/runtime/test/worksharing/for/omp_parallel_for_lastprivate.c
new file mode 100644
index 00000000000..a53cfb26303
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_parallel_for_lastprivate.c
@@ -0,0 +1,37 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_for_lastprivate()
+{
+ int sum;
+ int i;
+ int i0;
+ int known_sum;
+
+ sum =0;
+ i0 = -1;
+
+ #pragma omp parallel for reduction(+:sum) \
+ schedule(static,7) private(i) lastprivate(i0)
+ for (i = 1; i <= LOOPCOUNT; i++) {
+ sum = sum + i;
+ i0 = i;
+ } /* end of parallel for */
+
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ return ((known_sum == sum) && (i0 == LOOPCOUNT));
+} /* end of check_parallel_for_lastprivate */
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_for_lastprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_parallel_for_ordered.c b/openmp/runtime/test/worksharing/for/omp_parallel_for_ordered.c
new file mode 100644
index 00000000000..82cc97bfefb
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_parallel_for_ordered.c
@@ -0,0 +1,64 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+static int last_i = 0;
+
+int i;
+#pragma omp threadprivate(i)
+
+/* Variable ii is used to avoid problems with a threadprivate variable used as a loop
+ * index. See test omp_threadprivate_for.
+ */
+static int ii;
+#pragma omp threadprivate(ii)
+
+/*!
+ Utility function: returns true if the passed argument is larger than
+ the argument of the last call of this function.
+ */
+static int check_i_islarger2(int i)
+{
+ int islarger;
+ islarger = (i > last_i);
+ last_i = i;
+ return (islarger);
+}
+
+int test_omp_parallel_for_ordered()
+{
+ int sum;
+ int is_larger;
+ int known_sum;
+ int i;
+
+ sum = 0;
+ is_larger = 1;
+ last_i = 0;
+ #pragma omp parallel for schedule(static,1) private(i) ordered
+ for (i = 1; i < 100; i++) {
+ ii = i;
+ #pragma omp ordered
+ {
+ is_larger = check_i_islarger2 (ii) && is_larger;
+ sum = sum + ii;
+ }
+ }
+ known_sum = (99 * 100) / 2;
+ fprintf (stderr," known_sum = %d , sum = %d \n", known_sum, sum);
+ fprintf (stderr," is_larger = %d\n", is_larger);
+ return (known_sum == sum) && is_larger;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_for_ordered()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_parallel_for_private.c b/openmp/runtime/test/worksharing/for/omp_parallel_for_private.c
new file mode 100644
index 00000000000..1231d360d3c
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_parallel_for_private.c
@@ -0,0 +1,50 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+/*! Utility function to spend some time in a loop */
+static void do_some_work (void)
+{
+ int i;
+ double sum = 0;
+ for(i = 0; i < 1000; i++){
+ sum += sqrt (i);
+ }
+}
+
+int test_omp_parallel_for_private()
+{
+ int sum;
+ int i;
+ int i2;
+ int known_sum;
+
+ sum =0;
+ i2=0;
+
+ #pragma omp parallel for reduction(+:sum) schedule(static,1) private(i) private(i2)
+ for (i=1;i<=LOOPCOUNT;i++)
+ {
+ i2 = i;
+ #pragma omp flush
+ do_some_work ();
+ #pragma omp flush
+ sum = sum + i2;
+ } /*end of for*/
+ known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+ return (known_sum == sum);
+} /* end of check_parallel_for_private */
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_for_private()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/for/omp_parallel_for_reduction.c b/openmp/runtime/test/worksharing/for/omp_parallel_for_reduction.c
new file mode 100644
index 00000000000..05f85557ae7
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/omp_parallel_for_reduction.c
@@ -0,0 +1,266 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
+#define MAX_FACTOR 10
+#define KNOWN_PRODUCT 3628800 /* 10! */
+
+int test_omp_parallel_for_reduction()
+{
+ int sum;
+ int known_sum;
+ double dsum;
+ double dknown_sum;
+ double dt=0.5; /* base of geometric row for + and - test*/
+ double rounding_error= 1.E-9;
+ int diff;
+ double ddiff;
+ int product;
+ int known_product;
+ int logic_and;
+ int logic_or;
+ int bit_and;
+ int bit_or;
+ int exclusiv_bit_or;
+ int logics[LOOPCOUNT];
+ int i;
+ double dpt;
+ int result;
+
+ sum =0;
+ dsum=0;
+ dt = 1./3.;
+ result = 0;
+ product = 1;
+ logic_and=1;
+ logic_or=0;
+ bit_and=1;
+ bit_or=0;
+ exclusiv_bit_or=0;
+
+ /* Tests for integers */
+ known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2;
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:sum)
+ for (i=1;i<=LOOPCOUNT;i++) {
+ sum=sum+i;
+ }
+ if(known_sum!=sum) {
+ result++;
+ fprintf(stderr,"Error in sum with integers: Result was %d"
+ " instead of %d\n",sum,known_sum);
+ }
+
+ diff = (LOOPCOUNT*(LOOPCOUNT+1))/2;
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:diff)
+ for (i=1;i<=LOOPCOUNT;++i) {
+ diff=diff-i;
+ }
+ if(diff != 0) {
+ result++;
+ fprintf(stderr,"Error in difference with integers: Result was %d"
+ " instead of 0.\n",diff);
+ }
+
+ /* Tests for doubles */
+ dsum=0;
+ dpt=1;
+ for (i=0;i<DOUBLE_DIGITS;++i) {
+ dpt*=dt;
+ }
+ dknown_sum = (1-dpt)/(1-dt);
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:dsum)
+ for (i=0;i<DOUBLE_DIGITS;++i) {
+ dsum += pow(dt,i);
+ }
+ if( fabs(dsum-dknown_sum) > rounding_error ) {
+ result++;
+ fprintf(stderr,"Error in sum with doubles: Result was %f"
+ " instead of %f (Difference: %E)\n",
+ dsum, dknown_sum, dsum-dknown_sum);
+ }
+
+ dpt=1;
+
+ for (i=0;i<DOUBLE_DIGITS;++i) {
+ dpt*=dt;
+ }
+ fprintf(stderr,"\n");
+ ddiff = (1-dpt)/(1-dt);
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:ddiff)
+ for (i=0;i<DOUBLE_DIGITS;++i) {
+ ddiff -= pow(dt,i);
+ }
+ if( fabs(ddiff) > rounding_error) {
+ result++;
+ fprintf(stderr,"Error in Difference with doubles: Result was %E"
+ " instead of 0.0\n",ddiff);
+ }
+
+ /* Tests for integers */
+ #pragma omp parallel for schedule(dynamic,1) private(i) reduction(*:product)
+ for(i=1;i<=MAX_FACTOR;i++) {
+ product *= i;
+ }
+ known_product = KNOWN_PRODUCT;
+ if(known_product != product) {
+ result++;
+ fprintf(stderr,"Error in Product with integers: Result was %d"
+ " instead of %d\n\n",product,known_product);
+ }
+
+ /* Tests for logic AND */
+ for(i=0;i<LOOPCOUNT;i++) {
+ logics[i]=1;
+ }
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(&&:logic_and)
+ for(i=0;i<LOOPCOUNT;++i) {
+ logic_and = (logic_and && logics[i]);
+ }
+ if(!logic_and) {
+ result++;
+ fprintf(stderr,"Error in logic AND part 1.\n");
+ }
+
+ logic_and = 1;
+ logics[LOOPCOUNT/2]=0;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(&&:logic_and)
+ for(i=0;i<LOOPCOUNT;++i) {
+ logic_and = logic_and && logics[i];
+ }
+ if(logic_and) {
+ result++;
+ fprintf(stderr,"Error in logic AND part 2.\n");
+ }
+
+ /* Tests for logic OR */
+ for(i=0;i<LOOPCOUNT;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(||:logic_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ logic_or = logic_or || logics[i];
+ }
+ if(logic_or) {
+ result++;
+ fprintf(stderr,"Error in logic OR part 1.\n");
+ }
+ logic_or = 0;
+ logics[LOOPCOUNT/2]=1;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(||:logic_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ logic_or = logic_or || logics[i];
+ }
+ if(!logic_or) {
+ result++;
+ fprintf(stderr,"Error in logic OR part 2.\n");
+ }
+
+ /* Tests for bitwise AND */
+ for(i=0;i<LOOPCOUNT;++i) {
+ logics[i]=1;
+ }
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(&:bit_and)
+ for(i=0;i<LOOPCOUNT;++i) {
+ bit_and = (bit_and & logics[i]);
+ }
+ if(!bit_and) {
+ result++;
+ fprintf(stderr,"Error in BIT AND part 1.\n");
+ }
+
+ bit_and = 1;
+ logics[LOOPCOUNT/2]=0;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(&:bit_and)
+ for(i=0;i<LOOPCOUNT;++i) {
+ bit_and = bit_and & logics[i];
+ }
+ if(bit_and) {
+ result++;
+ fprintf(stderr,"Error in BIT AND part 2.\n");
+ }
+
+ /* Tests for bitwise OR */
+ for(i=0;i<LOOPCOUNT;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(|:bit_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ if(bit_or) {
+ result++;
+ fprintf(stderr,"Error in BIT OR part 1\n");
+ }
+ bit_or = 0;
+ logics[LOOPCOUNT/2]=1;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(|:bit_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ if(!bit_or) {
+ result++;
+ fprintf(stderr,"Error in BIT OR part 2\n");
+ }
+
+ /* Tests for bitwise XOR */
+ for(i=0;i<LOOPCOUNT;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(^:exclusiv_bit_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ if(exclusiv_bit_or) {
+ result++;
+ fprintf(stderr,"Error in EXCLUSIV BIT OR part 1\n");
+ }
+
+ exclusiv_bit_or = 0;
+ logics[LOOPCOUNT/2]=1;
+
+ #pragma omp parallel for schedule(dynamic,1) private(i) \
+ reduction(^:exclusiv_bit_or)
+ for(i=0;i<LOOPCOUNT;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ if(!exclusiv_bit_or) {
+ result++;
+ fprintf(stderr,"Error in EXCLUSIV BIT OR part 2\n");
+ }
+
+ /*printf("\nResult:%d\n",result);*/
+ return (result==0);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_for_reduction()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_parallel_sections_firstprivate.c b/openmp/runtime/test/worksharing/sections/omp_parallel_sections_firstprivate.c
new file mode 100644
index 00000000000..364a5d0bc6a
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_parallel_sections_firstprivate.c
@@ -0,0 +1,54 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_sections_firstprivate()
+{
+ int sum;
+ int sum0;
+ int known_sum;
+
+ sum =7;
+ sum0=11;
+
+ #pragma omp parallel sections firstprivate(sum0)
+ {
+ #pragma omp section
+ {
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ #pragma omp section
+ {
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ #pragma omp section
+ {
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ }
+
+ known_sum=11*3+7;
+ return (known_sum==sum);
+} /* end of check_section_firstprivate*/
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_sections_firstprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_parallel_sections_lastprivate.c b/openmp/runtime/test/worksharing/sections/omp_parallel_sections_lastprivate.c
new file mode 100644
index 00000000000..592735e2405
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_parallel_sections_lastprivate.c
@@ -0,0 +1,71 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_sections_lastprivate()
+{
+ int sum;
+ int sum0;
+ int i;
+ int i0;
+ int known_sum;
+ sum =0;
+ sum0 = 0;
+ i0 = -1;
+
+ #pragma omp parallel sections private(i,sum0) lastprivate(i0)
+ {
+ #pragma omp section
+ {
+ sum0=0;
+ for (i=1;i<400;i++) {
+ sum0=sum0+i;
+ i0=i;
+ }
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ #pragma omp section
+ {
+ sum0=0;
+ for(i=400;i<700;i++) {
+ sum0=sum0+i;
+ i0=i;
+ }
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ #pragma omp section
+ {
+ sum0=0;
+ for(i=700;i<1000;i++) {
+ sum0=sum0+i;
+ i0=i;
+ }
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ }
+
+ known_sum=(999*1000)/2;
+ return ((known_sum==sum) && (i0==999) );
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_sections_lastprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_parallel_sections_private.c b/openmp/runtime/test/worksharing/sections/omp_parallel_sections_private.c
new file mode 100644
index 00000000000..494d61ea724
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_parallel_sections_private.c
@@ -0,0 +1,64 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_sections_private()
+{
+ int sum;
+ int sum0;
+ int i;
+ int known_sum;
+
+ sum = 7;
+ sum0=0;
+
+ #pragma omp parallel sections private(sum0, i)
+ {
+ #pragma omp section
+ {
+ sum0=0;
+ for (i=1;i<400;i++)
+ sum0=sum0+i;
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ #pragma omp section
+ {
+ sum0=0;
+ for(i=400;i<700;i++)
+ sum0=sum0+i;
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ #pragma omp section
+ {
+ sum0=0;
+ for(i=700;i<1000;i++)
+ sum0=sum0+i;
+ #pragma omp critical
+ {
+ sum= sum+sum0;
+ }
+ }
+ }
+
+ known_sum=(999*1000)/2+7;
+ return (known_sum==sum);
+} /* end of check_section_private*/
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_sections_private()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_parallel_sections_reduction.c b/openmp/runtime/test/worksharing/sections/omp_parallel_sections_reduction.c
new file mode 100644
index 00000000000..4ad5ce335a1
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_parallel_sections_reduction.c
@@ -0,0 +1,508 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+int test_omp_parallel_sections_reduction()
+{
+ int sum;
+ int known_sum;
+ double dpt;
+ double dsum;
+ double dknown_sum;
+ double dt=0.5; /* base of geometric row for + and - test*/
+ double rounding_error= 1.E-5;
+ int diff;
+ double ddiff;
+ int product;
+ int known_product;
+ int logic_and;
+ int bit_and;
+ int logic_or;
+ int bit_or;
+ int exclusiv_bit_or;
+ int logics[1000];
+ int i;
+ int result;
+
+ sum = 7;
+ dsum=0;
+ product =1;
+ dpt = 1;
+ logic_and=1;
+ bit_and=1;
+ logic_or=0;
+ bit_or=0;
+ exclusiv_bit_or=0;
+ result =0;
+ /* int my_islarger;*/
+ /*int is_larger=1;*/
+
+ // Test summation of integers
+ known_sum = (999*1000)/2+7;
+ #pragma omp parallel sections private(i) reduction(+:sum)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ sum=sum+i;
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ sum=sum+i;
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ sum=sum+i;
+ }
+ }
+ }
+ if(known_sum!=sum) {
+ result++;
+ fprintf(stderr,"Error in sum with integers: Result was %d"
+ " instead of %d.\n",sum, known_sum);
+ }
+
+ // Test differences of integers
+ diff = (999*1000)/2;
+ #pragma omp parallel sections private(i) reduction(-:diff)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ diff=diff-i;
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ diff=diff-i;
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ diff=diff-i;
+ }
+ }
+ }
+ if(diff != 0) {
+ result++;
+ fprintf(stderr,"Error in Difference with integers: Result was %d"
+ " instead of 0.\n",diff);
+ }
+
+ // Test summation of doubles
+ for (i=0;i<20;++i) {
+ dpt*=dt;
+ }
+ dknown_sum = (1-dpt)/(1-dt);
+ #pragma omp parallel sections private(i) reduction(+:dsum)
+ {
+ #pragma omp section
+ {
+ for (i=0;i<6;++i) {
+ dsum += pow(dt,i);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=6;i<12;++i) {
+ dsum += pow(dt,i);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=12;i<20;++i) {
+ dsum += pow(dt,i);
+ }
+ }
+ }
+ if( fabs(dsum-dknown_sum) > rounding_error ) {
+ result++;
+ fprintf(stderr,"Error in sum with doubles: Result was %f"
+ " instead of %f (Difference: %E)\n",
+ dsum, dknown_sum, dsum-dknown_sum);
+ }
+
+ // Test differences of doubles
+ dpt=1;
+ for (i=0;i<20;++i) {
+ dpt*=dt;
+ }
+ fprintf(stderr,"\n");
+ ddiff = (1-dpt)/(1-dt);
+ #pragma omp parallel sections private(i) reduction(-:ddiff)
+ {
+ #pragma omp section
+ {
+ for (i=0;i<6;++i) {
+ ddiff -= pow(dt,i);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=6;i<12;++i) {
+ ddiff -= pow(dt,i);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=12;i<20;++i) {
+ ddiff -= pow(dt,i);
+ }
+ }
+ }
+ if( fabs(ddiff) > rounding_error) {
+ result++;
+ fprintf(stderr,"Error in Difference with doubles: Result was %E"
+ " instead of 0.0\n",ddiff);
+ }
+
+ // Test product of integers
+ known_product = 3628800;
+ #pragma omp parallel sections private(i) reduction(*:product)
+ {
+ #pragma omp section
+ {
+ for(i=1;i<3;i++) {
+ product *= i;
+ }
+ }
+ #pragma omp section
+ {
+ for(i=3;i<7;i++) {
+ product *= i;
+ }
+ }
+ #pragma omp section
+ {
+ for(i=7;i<11;i++) {
+ product *= i;
+ }
+ }
+ }
+ if(known_product != product) {
+ result++;
+ fprintf(stderr,"Error in Product with integers: Result was %d"
+ " instead of %d\n",product,known_product);
+ }
+
+ // Test logical AND
+ for(i=0;i<1000;i++) {
+ logics[i]=1;
+ }
+
+ #pragma omp parallel sections private(i) reduction(&&:logic_and)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ }
+ if(!logic_and) {
+ result++;
+ fprintf(stderr,"Error in logic AND part 1\n");
+ }
+ logic_and = 1;
+ logics[501] = 0;
+
+ #pragma omp parallel sections private(i) reduction(&&:logic_and)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ }
+ if(logic_and) {
+ result++;
+ fprintf(stderr,"Error in logic AND part 2");
+ }
+
+ // Test logical OR
+ for(i=0;i<1000;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel sections private(i) reduction(||:logic_or)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ }
+ if(logic_or) {
+ result++;
+ fprintf(stderr,"Error in logic OR part 1\n");
+ }
+
+ logic_or = 0;
+ logics[501]=1;
+
+ #pragma omp parallel sections private(i) reduction(||:logic_or)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ }
+ if(!logic_or) {
+ result++;
+ fprintf(stderr,"Error in logic OR part 2\n");
+ }
+
+ // Test bitwise AND
+ for(i=0;i<1000;++i) {
+ logics[i]=1;
+ }
+
+ #pragma omp parallel sections private(i) reduction(&:bit_and)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ bit_and = (bit_and & logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ bit_and = (bit_and & logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ bit_and = (bit_and & logics[i]);
+ }
+ }
+ }
+ if(!bit_and) {
+ result++;
+ fprintf(stderr,"Error in BIT AND part 1\n");
+ }
+
+ bit_and = 1;
+ logics[501]=0;
+
+ #pragma omp parallel sections private(i) reduction(&:bit_and)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ bit_and = bit_and & logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ bit_and = bit_and & logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ bit_and = bit_and & logics[i];
+ }
+ }
+ }
+ if(bit_and) {
+ result++;
+ fprintf(stderr,"Error in BIT AND part 2");
+ }
+
+ // Test bitwise OR
+ for(i=0;i<1000;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel sections private(i) reduction(|:bit_or)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ }
+ if(bit_or) {
+ result++;
+ fprintf(stderr,"Error in BIT OR part 1\n");
+ }
+ bit_or = 0;
+ logics[501]=1;
+
+ #pragma omp parallel sections private(i) reduction(|:bit_or)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ }
+ if(!bit_or) {
+ result++;
+ fprintf(stderr,"Error in BIT OR part 2\n");
+ }
+
+ // Test bitwise XOR
+ for(i=0;i<1000;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel sections private(i) reduction(^:exclusiv_bit_or)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ }
+ if(exclusiv_bit_or) {
+ result++;
+ fprintf(stderr,"Error in EXCLUSIV BIT OR part 1\n");
+ }
+
+ exclusiv_bit_or = 0;
+ logics[501]=1;
+
+ #pragma omp parallel sections private(i) reduction(^:exclusiv_bit_or)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ }
+ if(!exclusiv_bit_or) {
+ result++;
+ fprintf(stderr,"Error in EXCLUSIV BIT OR part 2\n");
+ }
+
+ /*printf("\nResult:%d\n",result);*/
+ return (result==0);
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_parallel_sections_reduction()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_section_firstprivate.c b/openmp/runtime/test/worksharing/sections/omp_section_firstprivate.c
new file mode 100644
index 00000000000..4dd2267cbda
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_section_firstprivate.c
@@ -0,0 +1,55 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_section_firstprivate()
+{
+ int sum;
+ int sum0;
+ int known_sum;
+
+ sum0 = 11;
+ sum = 7;
+ #pragma omp parallel
+ {
+ #pragma omp sections firstprivate(sum0)
+ {
+ #pragma omp section
+ {
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ }
+ }
+ #pragma omp section
+ {
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ }
+ }
+ #pragma omp section
+ {
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ }
+ }
+ }
+ }
+ known_sum = 11 * 3 + 7;
+ return (known_sum == sum);
+} /* end of check_section_firstprivate*/
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_section_firstprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_section_lastprivate.c b/openmp/runtime/test/worksharing/sections/omp_section_lastprivate.c
new file mode 100644
index 00000000000..64ebd2f05e0
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_section_lastprivate.c
@@ -0,0 +1,76 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_section_lastprivate()
+{
+ int i0 = -1;
+ int sum = 0;
+ int i;
+ int sum0 = 0;
+ int known_sum;
+
+ i0 = -1;
+ sum = 0;
+
+ #pragma omp parallel
+ {
+ #pragma omp sections lastprivate(i0) private(i,sum0)
+ {
+ #pragma omp section
+ {
+ sum0 = 0;
+ for (i = 1; i < 400; i++)
+ {
+ sum0 = sum0 + i;
+ i0 = i;
+ }
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ } /*end of critical*/
+ } /* end of section */
+ #pragma omp section
+ {
+ sum0 = 0;
+ for(i = 400; i < 700; i++)
+ {
+ sum0 = sum0 + i;
+ i0 = i;
+ }
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ } /*end of critical*/
+ }
+ #pragma omp section
+ {
+ sum0 = 0;
+ for(i = 700; i < 1000; i++)
+ {
+ sum0 = sum0 + i;
+ i0 = i;
+ }
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ } /*end of critical*/
+ } /* end of section */
+ } /* end of sections*/
+ } /* end of parallel*/
+ known_sum = (999 * 1000) / 2;
+ return ((known_sum == sum) && (i0 == 999) );
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_section_lastprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_section_private.c b/openmp/runtime/test/worksharing/sections/omp_section_private.c
new file mode 100644
index 00000000000..ebf3f1cb99d
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_section_private.c
@@ -0,0 +1,66 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_section_private()
+{
+ int sum;
+ int sum0;
+ int i;
+ int known_sum;
+
+ sum = 7;
+ sum0 = 0;
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(sum0,i)
+ {
+ #pragma omp section
+ {
+ sum0 = 0;
+ for (i = 1; i < 400; i++)
+ sum0 = sum0 + i;
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ }
+ }
+ #pragma omp section
+ {
+ sum0 = 0;
+ for (i = 400; i < 700; i++)
+ sum0 = sum0 + i;
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ }
+ }
+ #pragma omp section
+ {
+ sum0 = 0;
+ for (i = 700; i < 1000; i++)
+ sum0 = sum0 + i;
+ #pragma omp critical
+ {
+ sum = sum + sum0;
+ }
+ }
+ } /*end of sections*/
+ } /* end of parallel */
+ known_sum = (999 * 1000) / 2 + 7;
+ return (known_sum == sum);
+} /* end of check_section_private*/
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_section_private()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_sections_nowait.c b/openmp/runtime/test/worksharing/sections/omp_sections_nowait.c
new file mode 100644
index 00000000000..b282988abac
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_sections_nowait.c
@@ -0,0 +1,69 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+#include "omp_my_sleep.h"
+
+int test_omp_sections_nowait()
+{
+ int result;
+ int count;
+ int j;
+
+ result = 0;
+ count = 0;
+
+ #pragma omp parallel
+ {
+ int rank;
+ rank = omp_get_thread_num ();
+ #pragma omp sections nowait
+ {
+ #pragma omp section
+ {
+ fprintf(stderr, "Thread nr %d enters first section"
+ " and gets sleeping.\n", rank);
+ my_sleep(SLEEPTIME);
+ count = 1;
+ fprintf(stderr, "Thread nr %d woke up an set"
+ " count to 1.\n", rank);
+ #pragma omp flush(count)
+ }
+ #pragma omp section
+ {
+ fprintf(stderr, "Thread nr %d executed work in the"
+ " first section.\n", rank);
+ }
+ }
+ /* Begin of second sections environment */
+ #pragma omp sections
+ {
+ #pragma omp section
+ {
+ fprintf(stderr, "Thread nr %d executed work in the"
+ " second section.\n", rank);
+ }
+ #pragma omp section
+ {
+ fprintf(stderr, "Thread nr %d executed work in the"
+ " second section and controls the value of count\n", rank);
+ if (count == 0)
+ result = 1;
+ fprintf(stderr, "count was %d\n", count);
+ }
+ }
+ }
+ return result;
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_sections_nowait()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/sections/omp_sections_reduction.c b/openmp/runtime/test/worksharing/sections/omp_sections_reduction.c
new file mode 100644
index 00000000000..99e92cf0da4
--- /dev/null
+++ b/openmp/runtime/test/worksharing/sections/omp_sections_reduction.c
@@ -0,0 +1,543 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include <math.h>
+#include "omp_testsuite.h"
+
+int test_omp_sections_reduction()
+{
+ int sum;
+ int known_sum;
+ double dpt,dsum;
+ double dknown_sum;
+ double dt=0.5; /* base of geometric row for + and - test*/
+ double rounding_error= 1.E-9;
+ int diff;
+ double ddiff;
+ int product;
+ int known_product;
+ int logic_and;
+ int bit_and;
+ int logic_or;
+ int bit_or;
+ int exclusiv_bit_or;
+ int logics[1000];
+ int i;
+ int result;
+ /* int my_islarger; */
+ /*int is_larger=1;*/
+ sum =7;
+ dpt =1;
+ dsum=0;
+ product =1;
+ logic_and=1;
+ bit_and=1;
+ logic_or=0;
+ bit_or=0;
+ exclusiv_bit_or=0;
+ result = 0;
+ dt = 1./3.;
+
+ known_sum = (999*1000)/2+7;
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(+:sum)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ sum=sum+i;
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ sum=sum+i;
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ sum=sum+i;
+ }
+ }
+ }
+ }
+ if(known_sum!=sum) {
+ ++result;
+ fprintf(stderr,"Error in sum with integers: Result was %d"
+ " instead of %d\n", sum,known_sum);
+ }
+
+ diff = (999*1000)/2;
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(-:diff)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ diff=diff-i;
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ diff=diff-i;
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ diff=diff-i;
+ }
+ }
+ }
+ }
+ if(diff != 0) {
+ result++;
+ fprintf(stderr,"Error in Difference with integers: Result was %d"
+ " instead of 0.\n",diff);
+ }
+
+ for (i=0;i<20;++i) {
+ dpt*=dt;
+ }
+ dknown_sum = (1-dpt)/(1-dt);
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(+:dsum)
+ {
+ #pragma omp section
+ {
+ for (i=0;i<6;++i) {
+ dsum += pow(dt,i);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=6;i<12;++i) {
+ dsum += pow(dt,i);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=12;i<20;++i) {
+ dsum += pow(dt,i);
+ }
+ }
+ }
+ }
+ if( fabs(dsum-dknown_sum) > rounding_error ) {
+ result++;
+ fprintf(stderr,"Error in sum with doubles: Result was %f"
+ " instead of %f (Difference: %E)\n",
+ dsum, dknown_sum, dsum-dknown_sum);
+ }
+
+ dpt=1;
+ for (i=0;i<20;++i) {
+ dpt*=dt;
+ }
+ fprintf(stderr,"\n");
+ ddiff = (1-dpt)/(1-dt);
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(-:ddiff)
+ {
+ #pragma omp section
+ {
+ for (i=0;i<6;++i) {
+ ddiff -= pow(dt,i);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=6;i<12;++i) {
+ ddiff -= pow(dt,i);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=12;i<20;++i) {
+ ddiff -= pow(dt,i);
+ }
+ }
+ }
+ }
+
+ if(fabs(ddiff) > rounding_error) {
+ result++;
+ fprintf(stderr,"Error in Difference with doubles: Result was %E"
+ " instead of 0.0\n",ddiff);
+ }
+
+ known_product = 3628800;
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(*:product)
+ {
+ #pragma omp section
+ {
+ for(i=1;i<3;i++) {
+ product *= i;
+ }
+ }
+ #pragma omp section
+ {
+ for(i=3;i<7;i++) {
+ product *= i;
+ }
+ }
+ #pragma omp section
+ {
+ for(i=7;i<11;i++) {
+ product *= i;
+ }
+ }
+ }
+ }
+ if(known_product != product) {
+ result++;
+ fprintf(stderr,"Error in Product with integers: Result was %d"
+ " instead of %d\n",product,known_product);
+ }
+
+ for(i=0;i<1000;i++) {
+ logics[i]=1;
+ }
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(&&:logic_and)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ }
+ }
+ if(!logic_and) {
+ result++;
+ fprintf(stderr,"Error in logic AND part 1\n");
+ }
+
+ logic_and = 1;
+ logics[501] = 0;
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(&&:logic_and)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ logic_and = (logic_and && logics[i]);
+ }
+ }
+ }
+ }
+ if(logic_and) {
+ result++;
+ fprintf(stderr,"Error in logic AND part 2\n");
+ }
+
+ for(i=0;i<1000;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(||:logic_or)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ }
+ }
+ if(logic_or) {
+ result++;
+ fprintf(stderr,"\nError in logic OR part 1\n");
+ }
+
+ logic_or = 0;
+ logics[501]=1;
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(||:logic_or)
+ {
+ #pragma omp section
+ {
+ for (i=1;i<300;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=300;i<700;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for (i=700;i<1000;i++) {
+ logic_or = (logic_or || logics[i]);
+ }
+ }
+ }
+ }
+ if(!logic_or) {
+ result++;
+ fprintf(stderr,"Error in logic OR part 2\n");
+ }
+
+ for(i=0;i<1000;++i) {
+ logics[i]=1;
+ }
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(&:bit_and)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ bit_and = (bit_and & logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ bit_and = (bit_and & logics[i]);
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ bit_and = (bit_and & logics[i]);
+ }
+ }
+ }
+ }
+ if(!bit_and) {
+ result++;
+ fprintf(stderr,"Error in BIT AND part 1\n");
+ }
+
+ bit_and = 1;
+ logics[501]=0;
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(&:bit_and)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ bit_and = bit_and & logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ bit_and = bit_and & logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ bit_and = bit_and & logics[i];
+ }
+ }
+ }
+ }
+ if(bit_and) {
+ result++;
+ fprintf(stderr,"Error in BIT AND part 2\n");
+ }
+
+ for(i=0;i<1000;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(|:bit_or)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ }
+ }
+ if(bit_or) {
+ result++;
+ fprintf(stderr,"Error in BIT OR part 1\n");
+ }
+ bit_or = 0;
+ logics[501]=1;
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(|:bit_or)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ bit_or = bit_or | logics[i];
+ }
+ }
+ }
+ }
+ if(!bit_or) {
+ result++;
+ fprintf(stderr,"Error in BIT OR part 2\n");
+ }
+
+ for(i=0;i<1000;i++) {
+ logics[i]=0;
+ }
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(^:exclusiv_bit_or)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ }
+ }
+ if(exclusiv_bit_or) {
+ result++;
+ fprintf(stderr,"Error in EXCLUSIV BIT OR part 1\n");
+ }
+
+ exclusiv_bit_or = 0;
+ logics[501]=1;
+
+ #pragma omp parallel
+ {
+ #pragma omp sections private(i) reduction(^:exclusiv_bit_or)
+ {
+ #pragma omp section
+ {
+ for(i=0;i<300;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=300;i<700;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ #pragma omp section
+ {
+ for(i=700;i<1000;++i) {
+ exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
+ }
+ }
+ }
+ }
+ if(!exclusiv_bit_or) {
+ result++;
+ fprintf(stderr,"Error in EXCLUSIV BIT OR part 2\n");
+ }
+
+ /*printf("\nResult:%d\n",result);*/
+ return (result==0);
+}
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_sections_reduction()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/single/omp_single.c b/openmp/runtime/test/worksharing/single/omp_single.c
new file mode 100644
index 00000000000..6a3c341467d
--- /dev/null
+++ b/openmp/runtime/test/worksharing/single/omp_single.c
@@ -0,0 +1,44 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int test_omp_single()
+{
+ int nr_threads_in_single;
+ int result;
+ int nr_iterations;
+ int i;
+
+ nr_threads_in_single = 0;
+ result = 0;
+ nr_iterations = 0;
+
+ #pragma omp parallel private(i)
+ {
+ for (i = 0; i < LOOPCOUNT; i++) {
+ #pragma omp single
+ {
+ #pragma omp flush
+ nr_threads_in_single++;
+ #pragma omp flush
+ nr_iterations++;
+ nr_threads_in_single--;
+ result = result + nr_threads_in_single;
+ }
+ }
+ }
+ return ((result == 0) && (nr_iterations == LOOPCOUNT));
+} /* end of check_single*/
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_single()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/single/omp_single_copyprivate.c b/openmp/runtime/test/worksharing/single/omp_single_copyprivate.c
new file mode 100644
index 00000000000..ef5cd955063
--- /dev/null
+++ b/openmp/runtime/test/worksharing/single/omp_single_copyprivate.c
@@ -0,0 +1,60 @@
+// RUN: %libomp-compile-and-run
+#include "omp_testsuite.h"
+
+#define DEBUG_TEST 0
+
+int j;
+#pragma omp threadprivate(j)
+
+int test_omp_single_copyprivate()
+{
+ int result;
+ int nr_iterations;
+
+ result = 0;
+ nr_iterations = 0;
+ #pragma omp parallel
+ {
+ int i;
+ for (i = 0; i < LOOPCOUNT; i++)
+ {
+#if DEBUG_TEST
+ int thread;
+ thread = omp_get_thread_num ();
+#endif
+ #pragma omp single copyprivate(j)
+ {
+ nr_iterations++;
+ j = i;
+#if DEBUG_TEST
+ printf ("thread %d assigns, j = %d, i = %d\n", thread, j, i);
+#endif
+ }
+#if DEBUG_TEST
+ #pragma omp barrier
+#endif
+ #pragma omp critical
+ {
+#if DEBUG_TEST
+ printf ("thread = %d, j = %d, i = %d\n", thread, j, i);
+#endif
+ result = result + j - i;
+ }
+ #pragma omp barrier
+ } /* end of for */
+ } /* end of parallel */
+ return ((result == 0) && (nr_iterations == LOOPCOUNT));
+}
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_single_copyprivate()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/single/omp_single_nowait.c b/openmp/runtime/test/worksharing/single/omp_single_nowait.c
new file mode 100644
index 00000000000..983748d59ed
--- /dev/null
+++ b/openmp/runtime/test/worksharing/single/omp_single_nowait.c
@@ -0,0 +1,57 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int my_iterations;
+#pragma omp threadprivate(my_iterations)
+
+int test_omp_single_nowait()
+{
+ int nr_iterations;
+ int total_iterations = 0;
+ int i;
+
+ nr_iterations = 0;
+ my_iterations = 0;
+
+ #pragma omp parallel private(i)
+ {
+ for (i = 0; i < LOOPCOUNT; i++) {
+ #pragma omp single nowait
+ {
+ #pragma omp atomic
+ nr_iterations++;
+ }
+ }
+ }
+
+ #pragma omp parallel private(i)
+ {
+ my_iterations = 0;
+ for (i = 0; i < LOOPCOUNT; i++) {
+ #pragma omp single nowait
+ {
+ my_iterations++;
+ }
+ }
+ #pragma omp critical
+ {
+ total_iterations += my_iterations;
+ }
+
+ }
+ return ((nr_iterations == LOOPCOUNT) && (total_iterations == LOOPCOUNT));
+} /* end of check_single_nowait*/
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_single_nowait()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
diff --git a/openmp/runtime/test/worksharing/single/omp_single_private.c b/openmp/runtime/test/worksharing/single/omp_single_private.c
new file mode 100644
index 00000000000..77556cfbc43
--- /dev/null
+++ b/openmp/runtime/test/worksharing/single/omp_single_private.c
@@ -0,0 +1,57 @@
+// RUN: %libomp-compile-and-run
+#include <stdio.h>
+#include "omp_testsuite.h"
+
+int myit = 0;
+#pragma omp threadprivate(myit)
+int myresult = 0;
+#pragma omp threadprivate(myresult)
+
+int test_omp_single_private()
+{
+ int nr_threads_in_single;
+ int result;
+ int nr_iterations;
+ int i;
+
+ myit = 0;
+ nr_threads_in_single = 0;
+ nr_iterations = 0;
+ result = 0;
+
+ #pragma omp parallel private(i)
+ {
+ myresult = 0;
+ myit = 0;
+ for (i = 0; i < LOOPCOUNT; i++) {
+ #pragma omp single private(nr_threads_in_single) nowait
+ {
+ nr_threads_in_single = 0;
+ #pragma omp flush
+ nr_threads_in_single++;
+ #pragma omp flush
+ myit++;
+ myresult = myresult + nr_threads_in_single;
+ }
+ }
+ #pragma omp critical
+ {
+ result += nr_threads_in_single;
+ nr_iterations += myit;
+ }
+ }
+ return ((result == 0) && (nr_iterations == LOOPCOUNT));
+} /* end of check_single private */
+
+int main()
+{
+ int i;
+ int num_failed=0;
+
+ for(i = 0; i < REPETITIONS; i++) {
+ if(!test_omp_single_private()) {
+ num_failed++;
+ }
+ }
+ return num_failed;
+}
OpenPOWER on IntegriCloud