Index: runtime/CMakeLists.txt =================================================================== --- runtime/CMakeLists.txt +++ runtime/CMakeLists.txt @@ -194,6 +194,7 @@ 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}) @@ -312,4 +313,5 @@ endif() add_subdirectory(src) +add_subdirectory(test) Index: runtime/src/CMakeLists.txt =================================================================== --- runtime/src/CMakeLists.txt +++ runtime/src/CMakeLists.txt @@ -165,6 +165,26 @@ 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}) Index: runtime/test/CMakeLists.txt =================================================================== --- /dev/null +++ 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_warning_say("Cannot find llvm-lit.") + libomp_warning_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 ${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) + Index: runtime/test/api/has_openmp.c =================================================================== --- /dev/null +++ runtime/test/api/has_openmp.c @@ -0,0 +1,23 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/api/omp_get_num_threads.c =================================================================== --- /dev/null +++ runtime/test/api/omp_get_num_threads.c @@ -0,0 +1,39 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/api/omp_get_wtick.c =================================================================== --- /dev/null +++ runtime/test/api/omp_get_wtick.c @@ -0,0 +1,24 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/api/omp_get_wtime.c =================================================================== --- /dev/null +++ runtime/test/api/omp_get_wtime.c @@ -0,0 +1,33 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/api/omp_in_parallel.c =================================================================== --- /dev/null +++ runtime/test/api/omp_in_parallel.c @@ -0,0 +1,39 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/atomic/omp_atomic.c =================================================================== --- /dev/null +++ runtime/test/atomic/omp_atomic.c @@ -0,0 +1,367 @@ +// RUN: %libomp-compile-and-run +#include +#include +#include "omp_testsuite.h" +#include "omp_my_sleep.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; +} Index: runtime/test/barrier/omp_barrier.c =================================================================== --- /dev/null +++ runtime/test/barrier/omp_barrier.c @@ -0,0 +1,40 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/critical/omp_critical.c =================================================================== --- /dev/null +++ runtime/test/critical/omp_critical.c @@ -0,0 +1,38 @@ +// RUN: %libomp-compile-and-run +#include +#include "omp_testsuite.h" +#include "omp_my_sleep.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; +} Index: runtime/test/flush/omp_flush.c =================================================================== --- /dev/null +++ runtime/test/flush/omp_flush.c @@ -0,0 +1,45 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/lit.cfg =================================================================== --- /dev/null +++ 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)) + Index: runtime/test/lit.site.cfg.in =================================================================== --- /dev/null +++ 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") + Index: runtime/test/lock/omp_lock.c =================================================================== --- /dev/null +++ runtime/test/lock/omp_lock.c @@ -0,0 +1,45 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/lock/omp_nest_lock.c =================================================================== --- /dev/null +++ runtime/test/lock/omp_nest_lock.c @@ -0,0 +1,45 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/lock/omp_test_lock.c =================================================================== --- /dev/null +++ runtime/test/lock/omp_test_lock.c @@ -0,0 +1,45 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/lock/omp_test_nest_lock.c =================================================================== --- /dev/null +++ runtime/test/lock/omp_test_nest_lock.c @@ -0,0 +1,47 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/master/omp_master.c =================================================================== --- /dev/null +++ runtime/test/master/omp_master.c @@ -0,0 +1,38 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/master/omp_master_3.c =================================================================== --- /dev/null +++ runtime/test/master/omp_master_3.c @@ -0,0 +1,44 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/omp_my_sleep.h =================================================================== --- /dev/null +++ runtime/test/omp_my_sleep.h @@ -0,0 +1,64 @@ +#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 +#include +#include +#include + +#if defined(_WIN32) +# include + +// Windows version of sleeping +// According to Windows documentation: clock() "Calculates the *wall-clock* +// time used by the calling process" +// So it can be used as a millisecond resolution timer. +static void my_sleep(double sleeptime) { + clock_t start; + clock_t real; + start = clock(); + if(start == -1) { + fprintf("error: my_sleep(): elapsed time is unavailable\r\n"); + exit(-1); + } + real = start; + while(((double)(real-start)/(double)CLOCKS_PER_SEC) < sleeptime) { + real = clock(); + if(real == -1) { + fprintf("error: my_sleep(): elapsed time is unavailable\r\n"); + exit(-1); + } + } +} + +#else // _WIN32 + +// Unices use this my_sleep() function +# include + +static void my_sleep(double sleeptime) { + struct timeval tv; + struct timezone tzp; + double start; + double real; + if(gettimeofday(&tv,&tzp)!=0) { + perror("get_time: "); + exit(-1); + } + start = (double)tv.tv_sec + ((double)tv.tv_usec/1000000.0); + real = start; + while((real-start) < sleeptime) { + if(gettimeofday(&tv,&tzp)!=0) { + perror("get_time: "); + exit(-1); + } + real = (double)tv.tv_sec + ((double)tv.tv_usec/1000000.0); + } +} + +#endif // _WIN32 + +#endif // MY_SLEEP_H Index: runtime/test/omp_testsuite.h =================================================================== --- /dev/null +++ runtime/test/omp_testsuite.h @@ -0,0 +1,22 @@ +/* Global headerfile of the OpenMP Testsuite */ + +#ifndef OMP_TESTSUITE_H +#define OMP_TESTSUITE_H + +#include +#include + +/* 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 Index: runtime/test/parallel/omp_nested.c =================================================================== --- /dev/null +++ runtime/test/parallel/omp_nested.c @@ -0,0 +1,41 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/parallel/omp_parallel_copyin.c =================================================================== --- /dev/null +++ runtime/test/parallel/omp_parallel_copyin.c @@ -0,0 +1,47 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/parallel/omp_parallel_default.c =================================================================== --- /dev/null +++ runtime/test/parallel/omp_parallel_default.c @@ -0,0 +1,43 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/parallel/omp_parallel_firstprivate.c =================================================================== --- /dev/null +++ runtime/test/parallel/omp_parallel_firstprivate.c @@ -0,0 +1,46 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/parallel/omp_parallel_if.c =================================================================== --- /dev/null +++ runtime/test/parallel/omp_parallel_if.c @@ -0,0 +1,40 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/parallel/omp_parallel_num_threads.c =================================================================== --- /dev/null +++ runtime/test/parallel/omp_parallel_num_threads.c @@ -0,0 +1,46 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/parallel/omp_parallel_private.c =================================================================== --- /dev/null +++ runtime/test/parallel/omp_parallel_private.c @@ -0,0 +1,46 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/parallel/omp_parallel_reduction.c =================================================================== --- /dev/null +++ runtime/test/parallel/omp_parallel_reduction.c @@ -0,0 +1,254 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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 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 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 +#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; +} Index: runtime/test/tasking/omp_task.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_task.c @@ -0,0 +1,52 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/tasking/omp_task_final.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_task_final.c @@ -0,0 +1,58 @@ +// RUN: %libomp-compile-and-run +#include +#include +#include "omp_testsuite.h" +#include "omp_my_sleep.h" + +int test_omp_task_final() +{ + int tids[NUM_TASKS]; + int in_final[NUM_TASKS]; + int error; + #pragma omp parallel + { + #pragma omp single + { + int i; + 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) firstprivate(myi) shared(tids) shared(in_final) + { + my_sleep (SLEEPTIME); + tids[myi] = omp_get_thread_num(); + in_final[myi] = omp_in_final(); + } + } + } + } + + /* Now we check if more than one thread executed the tasks. */ + int i; + for (i = 10; i < NUM_TASKS; i++) { + fprintf(stderr, "tids[10] = %d , tids[%d] = %d\n", tids[10], i, tids[i]); + fprintf(stderr, "in_final[%d] = %d\n", i, in_final[i]); + if (tids[10] != tids[i]) + error++; + } + fprintf(stderr, "\n"); + return (error==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_final()) { + num_failed++; + } + } + return num_failed; +} Index: runtime/test/tasking/omp_task_firstprivate.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_task_firstprivate.c @@ -0,0 +1,51 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/tasking/omp_task_if.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_task_if.c @@ -0,0 +1,43 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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 flush (count) + result = (0 == count); + } /* end of omp task */ + count = 1; + //#pragma omp flush (count) + } /* 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; +} Index: runtime/test/tasking/omp_task_imp_firstprivate.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_task_imp_firstprivate.c @@ -0,0 +1,47 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/tasking/omp_task_private.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_task_private.c @@ -0,0 +1,53 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/tasking/omp_task_shared.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_task_shared.c @@ -0,0 +1,41 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/tasking/omp_task_untied.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_task_untied.c @@ -0,0 +1,67 @@ +// RUN: %libomp-compile-and-run +#include +#include +#include "omp_testsuite.h" +#include "omp_my_sleep.h" + +int test_omp_task_untied() +{ + int i; + int count; + int start_tid[NUM_TASKS]; + int current_tid[NUM_TASKS]; + + count = 0; + + /*initialization*/ + for (i=0; i< NUM_TASKS; i++){ + start_tid[i]=0; + current_tid[i]=0; + } + + #pragma omp parallel firstprivate(i) + { + #pragma omp single + { + for (i = 0; i < NUM_TASKS; i++) { + int myi = i; + #pragma omp task untied + { + my_sleep(SLEEPTIME); + start_tid[myi] = omp_get_thread_num(); + current_tid[myi] = omp_get_thread_num(); + + #pragma omp taskwait + + if((start_tid[myi] % 2) != 0) { + my_sleep(SLEEPTIME); + current_tid[myi] = omp_get_thread_num(); + } else { + current_tid[myi] = omp_get_thread_num(); + } + } /*end of omp task */ + } /* end of for */ + } /* end of single */ + } /* end of parallel */ + + for (i=0;i +#include +#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; +} Index: runtime/test/tasking/omp_taskyield.c =================================================================== --- /dev/null +++ runtime/test/tasking/omp_taskyield.c @@ -0,0 +1,58 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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 +#include + +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; +} Index: runtime/test/threadprivate/omp_threadprivate_for.c =================================================================== --- /dev/null +++ runtime/test/threadprivate/omp_threadprivate_for.c @@ -0,0 +1,47 @@ +// RUN: %libomp-compile-and-run +#include "omp_testsuite.h" +#include +#include + +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; +} Index: runtime/test/worksharing/for/omp_for_collapse.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_collapse.c @@ -0,0 +1,51 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_firstprivate.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_firstprivate.c @@ -0,0 +1,55 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_lastprivate.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_lastprivate.c @@ -0,0 +1,52 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_nowait.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_nowait.c @@ -0,0 +1,53 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_ordered.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_ordered.c @@ -0,0 +1,60 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_private.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_private.c @@ -0,0 +1,63 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_reduction.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_reduction.c @@ -0,0 +1,339 @@ +// RUN: %libomp-compile-and-run +#include +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_schedule_auto.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_schedule_auto.c @@ -0,0 +1,56 @@ +// RUN: %libomp-compile-and-run +#include +#include +#include "omp_testsuite.h" + +int sum1; +#pragma omp threadprivate(sum1) + +int test_omp_for_auto() +{ + 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) schedule(auto) + for (i = 1; i <= LOOPCOUNT; i++) { + sum0 = sum0 + i; + sum1 = sum0; + } + + #pragma omp critical + { + sum = sum + sum1; + } + } + + 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; +} Index: runtime/test/worksharing/for/omp_for_schedule_dynamic.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_schedule_dynamic.c @@ -0,0 +1,91 @@ +// 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 +#include +#include +#include +#include "omp_testsuite.h" +#include "omp_my_sleep.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 +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_schedule_static.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_schedule_static.c @@ -0,0 +1,155 @@ +// RUN: %libomp-compile-and-run +#include +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_for_schedule_static_3.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_for_schedule_static_3.c @@ -0,0 +1,203 @@ +// RUN: %libomp-compile-and-run +#include +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_parallel_for_firstprivate.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_parallel_for_firstprivate.c @@ -0,0 +1,35 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/for/omp_parallel_for_if.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_parallel_for_if.c @@ -0,0 +1,42 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_parallel_for_lastprivate.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_parallel_for_lastprivate.c @@ -0,0 +1,37 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/for/omp_parallel_for_ordered.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_parallel_for_ordered.c @@ -0,0 +1,64 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/for/omp_parallel_for_private.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_parallel_for_private.c @@ -0,0 +1,50 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/for/omp_parallel_for_reduction.c =================================================================== --- /dev/null +++ runtime/test/worksharing/for/omp_parallel_for_reduction.c @@ -0,0 +1,266 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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 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 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 +#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; +} Index: runtime/test/worksharing/sections/omp_parallel_sections_lastprivate.c =================================================================== --- /dev/null +++ runtime/test/worksharing/sections/omp_parallel_sections_lastprivate.c @@ -0,0 +1,71 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/sections/omp_parallel_sections_private.c =================================================================== --- /dev/null +++ runtime/test/worksharing/sections/omp_parallel_sections_private.c @@ -0,0 +1,64 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/sections/omp_parallel_sections_reduction.c =================================================================== --- /dev/null +++ runtime/test/worksharing/sections/omp_parallel_sections_reduction.c @@ -0,0 +1,508 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/sections/omp_section_firstprivate.c =================================================================== --- /dev/null +++ runtime/test/worksharing/sections/omp_section_firstprivate.c @@ -0,0 +1,55 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/sections/omp_section_lastprivate.c =================================================================== --- /dev/null +++ runtime/test/worksharing/sections/omp_section_lastprivate.c @@ -0,0 +1,76 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/sections/omp_section_private.c =================================================================== --- /dev/null +++ runtime/test/worksharing/sections/omp_section_private.c @@ -0,0 +1,66 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/sections/omp_sections_nowait.c =================================================================== --- /dev/null +++ runtime/test/worksharing/sections/omp_sections_nowait.c @@ -0,0 +1,69 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/sections/omp_sections_reduction.c =================================================================== --- /dev/null +++ runtime/test/worksharing/sections/omp_sections_reduction.c @@ -0,0 +1,543 @@ +// RUN: %libomp-compile-and-run +#include +#include +#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; +} Index: runtime/test/worksharing/single/omp_single.c =================================================================== --- /dev/null +++ runtime/test/worksharing/single/omp_single.c @@ -0,0 +1,44 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/single/omp_single_copyprivate.c =================================================================== --- /dev/null +++ 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; +} Index: runtime/test/worksharing/single/omp_single_nowait.c =================================================================== --- /dev/null +++ runtime/test/worksharing/single/omp_single_nowait.c @@ -0,0 +1,57 @@ +// RUN: %libomp-compile-and-run +#include +#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; +} Index: runtime/test/worksharing/single/omp_single_private.c =================================================================== --- /dev/null +++ runtime/test/worksharing/single/omp_single_private.c @@ -0,0 +1,57 @@ +// RUN: %libomp-compile-and-run +#include +#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; +}