Browse Source

FindOpenMP: Add tests

Christian Pfeiffer 8 years ago
parent
commit
99ac0940ad

+ 4 - 0
Tests/CMakeLists.txt

@@ -1407,6 +1407,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     add_subdirectory(FindOpenGL)
   endif()
 
+  if(CMake_TEST_FindOpenMP)
+    add_subdirectory(FindOpenMP)
+  endif()
+
   if(CMake_TEST_FindOpenSSL)
     add_subdirectory(FindOpenSSL)
   endif()

+ 21 - 0
Tests/FindOpenMP/CMakeLists.txt

@@ -0,0 +1,21 @@
+foreach(c C CXX Fortran)
+  if(CMake_TEST_FindOpenMP_${c})
+    set(CMake_TEST_FindOpenMP_FLAG_${c} 1)
+  else()
+    set(CMake_TEST_FindOpenMP_FLAG_${c} 0)
+  endif()
+endforeach()
+
+add_test(NAME FindOpenMP.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindOpenMP/Test"
+  "${CMake_BINARY_DIR}/Tests/FindOpenMP/Test"
+  ${build_generator_args}
+  --build-project TestFindOpenMP
+  --build-options ${build_options}
+  -DOpenMP_TEST_C=${CMake_TEST_FindOpenMP_FLAG_C}
+  -DOpenMP_TEST_CXX=${CMake_TEST_FindOpenMP_FLAG_CXX}
+  -DOpenMP_TEST_Fortran=${CMake_TEST_FindOpenMP_FLAG_Fortran}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )

+ 73 - 0
Tests/FindOpenMP/Test/CMakeLists.txt

@@ -0,0 +1,73 @@
+cmake_minimum_required(VERSION 3.8)
+project(TestFindOpenMP)
+include(CTest)
+
+macro(source_code_mapper_helper LANG_NAME SRC_FILE_NAME)
+  if("${LANG_NAME}" STREQUAL "C")
+    set(OpenMPTEST_SOURCE_FILE "${SRC_FILE_NAME}.c")
+  elseif("${LANG_NAME}" STREQUAL "CXX")
+    configure_file("${SRC_FILE_NAME}.c" "${SRC_FILE_NAME}.cxx" COPYONLY)
+    set(OpenMPTEST_SOURCE_FILE "${SRC_FILE_NAME}.cxx")
+  elseif("${LANG_NAME}" STREQUAL "Fortran")
+    set(OpenMPTEST_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SRC_FILE_NAME}.f90")
+    if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
+      set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n      implicit none")
+    else()
+      set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n      include 'omp_lib.h'")
+    endif()
+    configure_file("${SRC_FILE_NAME}.f90.in" "${OpenMPTEST_SOURCE_FILE}" @ONLY)
+  endif()
+endmacro()
+
+foreach(c C CXX Fortran)
+  if("${OpenMP_TEST_${c}}")
+    message("Testing ${c}")
+    enable_language(${c})
+  endif()
+endforeach()
+
+find_package(OpenMP REQUIRED)
+
+foreach(c C CXX Fortran)
+  if(NOT "${OpenMP_TEST_${c}}")
+    continue()
+  endif()
+  source_code_mapper_helper(${c} main)
+  add_executable(test_tgt_${c} ${OpenMPTEST_SOURCE_FILE})
+  target_link_libraries(test_tgt_${c} PRIVATE OpenMP::OpenMP_${c})
+  set_property(TARGET test_tgt_${c} PROPERTY LINKER_LANGUAGE ${c})
+  add_test(NAME test_tgt_${c} COMMAND test_tgt_${c})
+
+  add_executable(test_var_${c} ${OpenMPTEST_SOURCE_FILE})
+  if(CMAKE_HOST_WIN32)
+    separate_arguments(_OpenMP_${c}_OPTIONS WINDOWS_COMMAND "${OpenMP_${c}_FLAGS}")
+  else()
+    separate_arguments(_OpenMP_${c}_OPTIONS UNIX_COMMAND "${OpenMP_${c}_FLAGS}")
+  endif()
+  target_compile_options(test_var_${c} PRIVATE "${_OpenMP_${c}_OPTIONS}")
+  target_link_libraries(test_var_${c} PRIVATE "${OpenMP_${c}_FLAGS}")
+  set_property(TARGET test_var_${c} PROPERTY LINKER_LANGUAGE ${c})
+  add_test(NAME test_var_${c} COMMAND test_var_${c})
+
+  source_code_mapper_helper(${c} scalprod)
+  add_library(scalprod_${c} STATIC ${OpenMPTEST_SOURCE_FILE})
+  target_link_libraries(scalprod_${c} PRIVATE OpenMP::OpenMP_${c})
+  set_property(TARGET scalprod_${c} PROPERTY LINKER_LANGUAGE ${c})
+endforeach()
+
+foreach(c C CXX Fortran)
+  if(NOT "${OpenMP_TEST_${c}}")
+    continue()
+  endif()
+  foreach(d C CXX Fortran)
+    if(NOT "${OpenMP_TEST_${d}}")
+      continue()
+    endif()
+    source_code_mapper_helper(${c} scaltest)
+    add_executable(scaltest_${c}_${d} ${OpenMPTEST_SOURCE_FILE})
+    target_link_libraries(scaltest_${c}_${d} PRIVATE scalprod_${d})
+    set_property(TARGET scaltest_${c}_${d} PROPERTY LINKER_LANGUAGE ${c})
+    add_test(NAME test_omp_${c}_${d} COMMAND scaltest_${c}_${d})
+    set_property(TEST test_omp_${c}_${d} PROPERTY PASS_REGULAR_EXPRESSION "^[ \t]*70\\.?0*")
+  endforeach()
+endforeach()

+ 7 - 0
Tests/FindOpenMP/Test/main.c

@@ -0,0 +1,7 @@
+#include <omp.h>
+int main()
+{
+#ifndef _OPENMP
+  breaks_on_purpose
+#endif
+}

+ 5 - 0
Tests/FindOpenMP/Test/main.f90.in

@@ -0,0 +1,5 @@
+      program test
+      @OpenMP_Fortran_INCLUDE_LINE@
+  !$  integer :: n
+      n = omp_get_num_threads()
+      end program test

+ 16 - 0
Tests/FindOpenMP/Test/scalprod.c

@@ -0,0 +1,16 @@
+#include <omp.h>
+
+#ifdef __cplusplus
+extern "C"
+#endif
+  void
+  scalprod(int n, double* x, double* y, double* res)
+{
+  int i;
+  double res_v = 0.;
+#pragma omp parallel for reduction(+ : res_v)
+  for (i = 0; i < n; ++i) {
+    res_v += x[i] * y[i];
+  }
+  *res = res_v;
+}

+ 19 - 0
Tests/FindOpenMP/Test/scalprod.f90.in

@@ -0,0 +1,19 @@
+subroutine scalprod(n, x_p, y_p, res) bind(c)
+    use iso_c_binding
+    implicit none
+    integer(c_int), intent(in), value :: n
+    type(c_ptr), intent(in), value :: x_p, y_p
+    real(c_double), pointer :: x(:), y(:)
+    integer :: i
+
+    real(c_double) :: res
+    real(c_double) :: scalpt = 0
+    call c_f_pointer(x_p, x, shape=[n])
+    call c_f_pointer(y_p, y, shape=[n])
+    res = 0
+!$omp parallel do private(scalpt), reduction(+:res)
+    do i=1,n
+        scalpt = y(i) * x(i)
+        res = res + scalpt
+    end do
+end subroutine scalprod

+ 20 - 0
Tests/FindOpenMP/Test/scaltest.c

@@ -0,0 +1,20 @@
+#ifdef __cplusplus
+#include <iostream>
+extern "C"
+#else
+#include <stdio.h>
+#endif
+int scalprod(int n, double* x, double* y, double* res);
+
+int main()
+{
+  double a[5] = { 1., 2., 3., 4., 5. };
+  double b[5] = { 2., 3., 4., 5., 6. };
+  double rk;
+  scalprod(5, a, b, &rk);
+#ifdef __cplusplus
+  std::cout << rk << std::endl;
+#else
+  printf("%f\n", rk);
+#endif
+}

+ 21 - 0
Tests/FindOpenMP/Test/scaltest.f90.in

@@ -0,0 +1,21 @@
+program scaltest
+    use iso_c_binding
+    implicit none
+    interface
+        subroutine scalprod(n, x_p, y_p, res) bind(c)
+            use iso_c_binding
+            integer(c_int), value :: n
+            type(c_ptr), value :: x_p, y_p
+            real(c_double) :: res
+        end subroutine scalprod
+    end interface
+    type(c_ptr) :: x_pt, y_pt
+    real(c_double), dimension(5), target :: a = (/ 1, 2, 3, 4, 5 /)
+    real(c_double), dimension(5), target :: b = (/ 2, 3, 4, 5, 6 /)
+    integer(c_int) :: n = size(a)
+    real(c_double) :: res
+    x_pt = c_loc(a)
+    y_pt = c_loc(b)
+    call scalprod(n, x_pt, y_pt, res)
+    print *, res
+end program scaltest