]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
A bunch of compiler feature tests
authormaier <maier@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 12 Sep 2012 15:41:17 +0000 (15:41 +0000)
committermaier <maier@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 12 Sep 2012 15:41:17 +0000 (15:41 +0000)
git-svn-id: https://svn.dealii.org/branches/branch_cmake@26315 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/contrib/cmake/check/check_for_compiler_features.cmake
deal.II/contrib/cmake/check/check_for_cxx_features.cmake
deal.II/include/deal.II/base/config.h.in
deal.II/include/deal.II/base/config.h.in.old
deal.II/threads.m4 [deleted file]

index 3030edc086d4bbb05209d28d024072eeec13d20d..f8e4127fa5fc88c8d2fa793b5d83b6f162109ede 100644 (file)
@@ -1,5 +1,5 @@
 INCLUDE(CheckCXXSourceCompiles)
-INCLUDE(CheckIncludeFiles)
+INCLUDE(CheckCXXSourceRuns)
 
 
 #
@@ -163,3 +163,216 @@ CHECK_CXX_SOURCE_COMPILES(
   }
   "
   HAVE_LIBSTDCXX_DEMANGLER)
+
+
+
+#
+# See if the compiler understands the attribute to mark functions
+# as deprecated.
+#
+
+#
+# First see if the following compiles without error (it should
+# produce a warning but we don't care about this)
+
+
+CHECK_CXX_SOURCE_COMPILES(
+  "
+  int old_fn () __attribute__((deprecated));
+  int old_fn () {};
+  int (*fn_ptr)() = old_fn;
+  int main() { return 0; }
+  "
+  DEAL_II_COMPILER_HAS_ATTRIBUTE_DEPRECATED)
+
+LIST(APPEND CMAKE_REQUIRED_FLAGS "-Werror")
+CHECK_CXX_SOURCE_COMPILES(
+  "
+  int old_fn () __attribute__((deprecated));
+  int old_fn () {};
+  int (*fn_ptr)() = old_fn;
+  int main() { return 0; }
+  "
+  DEAL_II_COMPILER_HAS_ATTRIBUTE_DEPRECATED_SHOULD_FAIL)
+LIST(REMOVE_ITEM CMAKE_REQUIRED_FLAGS "-Werror")
+
+IF(DEAL_II_COMPILER_HAS_ATTRIBUTE_DEPRECATED AND NOT
+    DEAL_II_COMPILER_HAS_ATTRIBUTE_DEPRECATED_SHOULD_FAIL)
+  SET(DEAL_II_DEPRECATED TRUE)
+ENDIF()
+
+
+
+#
+# Check whether the compiler allows for vectorization and that
+# vectorization actually works. For this test, we use compiler
+# intrinsics similar to what is used in the deal.II library and
+# check whether the arithmetic operations are correctly performed
+# on examples where all numbers are exactly represented as
+# floating point numbers.
+#
+CHECK_CXX_SOURCE_RUNS(
+  "
+  #include <emmintrin.h>
+  #include <mm_malloc.h>
+  int main()
+  {
+  __m128d a, b;
+  const unsigned int vector_bytes = sizeof(__m128d);
+  const int n_vectors = vector_bytes/sizeof(double);
+  __m128d * data =
+    reinterpret_cast<__m128d*>(_mm_malloc (2*vector_bytes, vector_bytes));
+  double * ptr = reinterpret_cast<double*>(&a);
+  ptr[0] = (volatile double)(1.0);
+  for (int i=1; i<n_vectors; ++i)
+    ptr[i] = 0.0;
+  b = _mm_set1_pd ((volatile double)(2.25));
+  data[0] = _mm_add_pd (a, b);
+  data[1] = _mm_mul_pd (b, data[0]);
+  ptr = reinterpret_cast<double*>(&data[1]);
+  unsigned int return_value = 0;
+  if (ptr[0] != 7.3125)
+    return_value = 1;
+  for (int i=1; i<n_vectors; ++i)
+    if (ptr[i] != 5.0625)
+      return_value = 1;
+  _mm_free (data);
+  return return_value;
+  }
+  "
+  DEAL_II_COMPILER_HAS_SSE2)
+
+CHECK_CXX_SOURCE_RUNS(
+  "
+  #include <immintrin.h>
+  #include <mm_malloc.h>
+  int main()
+  {
+    __m256d a, b;
+    const unsigned int vector_bytes = sizeof(__m256d);
+    const int n_vectors = vector_bytes/sizeof(double);
+    __m256d * data =
+      reinterpret_cast<__m256d*>(_mm_malloc (2*vector_bytes, vector_bytes));
+    double * ptr = reinterpret_cast<double*>(&a);
+    ptr[0] = (volatile double)(1.0);
+    for (int i=1; i<n_vectors; ++i)
+      ptr[i] = 0.0;
+    b = _mm256_set1_pd ((volatile double)(2.25));
+    data[0] = _mm256_add_pd (a, b);
+    data[1] = _mm256_mul_pd (b, data[0]);
+    ptr = reinterpret_cast<double*>(&data[1]);
+    unsigned int return_value = 0;
+    if (ptr[0] != 7.3125)
+      return_value = 1;
+    for (int i=1; i<n_vectors; ++i)
+      if (ptr[i] != 5.0625)
+        return_value = 1;
+    _mm_free (data);
+    return return_value;
+  }
+  "
+  DEAL_II_COMPILER_HAS_AVX)
+
+IF(DEAL_II_COMPILER_HAS_SSE2)
+  IF(DEAL_II_COMPILER_HAS_AVX)
+    SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 2)
+  ELSE()
+    SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 1)
+  ENDIF()
+ELSE()
+  SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 0)
+ENDIF()
+
+
+
+#
+# Check whether the compiler allows to use arithmetic operations
+# +-*/ on vectorized data types or whether we need to use
+# _mm_add_pd for addition and so on. +-*/ is preferred because
+# it allows the compiler to choose other optimizations like
+# fused multiply add, whereas _mm_add_pd explicitly enforces the
+# assembler command.
+#
+CHECK_CXX_SOURCE_COMPILES(
+  "
+  #include <emmintrin.h>
+  int main()
+  {
+    __m128d a, b;
+    a = _mm_set_sd (1.0);
+    b = _mm_set1_pd (2.1);
+    __m128d c = a + b;
+    __m128d d = b - c;
+    __m128d e = c * a + d;
+    __m128d f = e/a;
+    (void)f;
+  }
+  "
+  DEAL_II_COMPILER_USE_VECTOR_ARITHMETICS)
+
+
+
+#
+# Check if the declared prototype of abort() has a throw()
+# specification. We overload abort() in our testsuite, so have
+# to make sure that we match the exception specification
+# correctly.
+#
+#include <cstdlib>
+CHECK_CXX_SOURCE_COMPILES(
+  "
+  extern \\"C\\" void abort () { for(;;) ; }
+  int main(){ return 0; }
+  "
+  DEAL_II_ABORT_WITHOUT_NOTHROW_EXCEPTION)
+
+IF(DEAL_II_ABORT_WITHOUT_NOTHROW_EXCEPTION)
+  SET(DEAL_II_ABORT_NOTHROW_EXCEPTION TRUE)
+ENDIF()
+
+
+
+#
+# Gcc and some other compilers have __PRETTY_FUNCTION__, showing
+# an unmangled version of the function we are presently in,
+# while __FUNCTION__ (or __func__ in ISO C99) simply give the
+# function name which would not include the arguments of that
+# function, leading to problems in C++ with overloaded function
+# names.
+#
+# If __PRETTY_FUNCTION__ is not available, try to find out whether
+# __func__ is available and use the preprocessor to set the first
+# thing to the second. If this is also not the case, then set it
+# to something indicating non-availability.
+#
+
+CHECK_CXX_SOURCE_COMPILES(
+  "
+  #include <iostream>
+  int main()
+  {
+    std::cout << __PRETTY_FUNCTION__ << std::endl;
+    return 0;
+  }
+  "
+  DEAL_II_COMPILER_HAS_ATTRIBUTE_PRETTY_FUNCTION)
+
+IF(NOT DEAL_II_COMPILER_HAS_ATTRIBUTE_PRETTY_FUNCTION)
+  CHECK_CXX_SOURCE_COMPILES(
+    "
+    #include <iostream>
+    int main()
+    {
+      std::cout << __func__ << std::endl;
+      return 0;
+    }
+    "
+    DEAL_II_COMPILER_HAS_ATTRIBUTE_FUNC)
+
+  IF(DEAL_II_COMPILER_HAS_ATTRIBUTE_FUNC)
+    SET(__PRETTY_FUNCTION__ "__func")
+  ELSE()
+    SET(__PRETTY_FUNCTION__ "(not available)")
+  ENDIF()
+
+ENDIF()
index 86c15bfec1ef850211d16316a552fe76587198bd..b4fe1a6c1c3d0ccbbd1e08ff0dee58353ebcc06a 100644 (file)
@@ -208,3 +208,6 @@ CHECK_INCLUDE_FILES("sys/syscall.h" HAVE_SYS_SYSCALL_H)
 CHECK_INCLUDE_FILES("sys/times.h" HAVE_SYS_TIMES_H)
 CHECK_INCLUDE_FILES("sys/types.h" HAVE_SYS_TYPES_H)
 
+
+
+
index 5428ceb97f898053117a6d22d82a2ff19ba32397..ad9782919f5e6f833682b3f33fe9908a01a4f8b3 100644 (file)
    libstdc++ interface. */
 #cmakedefine HAVE_LIBSTDCXX_DEMANGLER
 
+  SET(DEAL_II_DEPRECATED TRUE)
+
+/* Equal to 0 in the generic case, equal to 1 if CPU compiled for supports
+   SSE2, equal to 2 if CPU compiled for supports AVX */
+#define DEAL_II_COMPILER_VECTORIZATION_LEVEL @DEAL_II_COMPILER_VECTORIZATION_LEVEL@
+
+/* Defined if the compiler can use arithmetic operations on vectorized data
+   types */
+#cmakedefine DEAL_II_COMPILER_USE_VECTOR_ARITHMETICS
+
+/* If already available, do not define at all. Otherwise, define to __func__
+   if that is available. In all other cases, indicate that no information
+   about the present function is available for this compiler. */
+#cmakedefine __PRETTY_FUNCTION__ @__PRETTY_FUNCTION__@
+
 
 
 
index 4b563eb0e9ca2e8d3247db15543b15ad9260a063..9b8e2095ecec7c13118b7a8b01d685031c82bb62 100644 (file)
    floating point computations on cygwin systems. */
 #cmakedefine DEAL_II_BROKEN_SOCKETS
 
+/* Define if the compiler provides a <errno.g> header file which does not
+   define all error codes such as EINTR. In that case, use the system include
+   file at /usr/include instead. There is probably a better way to do this,
+   but it is not apparent by looking at the C/C++ compatibility header
+   provided by the compiler. */
+#cmakedefine DEAL_II_USE_DIRECT_ERRNO_H
+
 /* Backward compatibility support for functions and classes that do not take
    an explicit mapping variable, but rather use a default Q1 mapping instead
    */
 #cmakedefine DEAL_II_COMPAT_MAPPING
 
-/* Defined if the compiler can use arithmetic operations on vectorized data
-   types */
-#cmakedefine DEAL_II_COMPILER_USE_VECTOR_ARITHMETICS
-
-/* Equal to 0 in the generic case, equal to 1 if CPU compiled for supports
-   SSE2, equal to 2 if CPU compiled for supports AVX */
-#cmakedefine DEAL_II_COMPILER_VECTORIZATION_LEVEL
-
 /* Defined if the compiler has a bug in deducing the type of pointers to const
    member functions. */
 #cmakedefine DEAL_II_CONST_MEMBER_DEDUCTION_BUG
 /* Defined if an ARPACK installation was found and is going to be used */
 #cmakedefine DEAL_II_USE_ARPACK
 
-/* Define if the compiler provides a <errno.g> header file which does not
-   define all error codes such as EINTR. In that case, use the system include
-   file at /usr/include instead. There is probably a better way to do this,
-   but it is not apparent by looking at the C/C++ compatibility header
-   provided by the compiler. */
-#cmakedefine DEAL_II_USE_DIRECT_ERRNO_H
-
 /* Defined if a Metis installation was found and is going to be used */
 #cmakedefine DEAL_II_USE_METIS
 
 # endif
 #endif
 
-/* If already available, do not define at all. Otherwise, define to __func__
-   if that is available. In all other cases, indicate that no information
-   about the present function is available for this compiler. */
-#cmakedefine __PRETTY_FUNCTION__
-
-
 /**
  * A #define that indicates whether we are using the Microsoft
  * Windows Visual C/C++ compiler. We currently do not run ./configure
diff --git a/deal.II/threads.m4 b/deal.II/threads.m4
deleted file mode 100644 (file)
index b586c5d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-dnl -------------------------------------------------------------
-dnl In some cases, -threads (or whatever else command line option)
-dnl switches on some preprocessor flags. If this is not the case,
-dnl then define them explicitely.
-dnl
-dnl Usage: DEAL_II_THREAD_CPPFLAGS
-dnl
-dnl -------------------------------------------------------------
-AC_DEFUN(DEAL_II_THREAD_CPPFLAGS, dnl
-[
-  AC_MSG_CHECKING(for platform specific multi-threading defines)
-  AC_LANG(C++)
-  CXXFLAGS="$CXXFLAGSG"
-  AC_TRY_COMPILE(
-   [
-#       if !defined (_REENTRANT) && !defined (_THREAD_SAFE)
-#       error Neither _REENTRANT nor _THREAD_SAFE were defined.
-        nonsense
-#       endif
-   ],
-   [
-        ;
-   ],
-   [
-        AC_MSG_RESULT(not necessary)
-   ],
-   [
-        AC_MSG_RESULT(-D_REENTRANT -D_THREAD_SAFE)
-        CXXFLAGSG="$CXXFLAGSG -D_REENTRANT -D_THREAD_SAFE"
-        CXXFLAGSO="$CXXFLAGSO -D_REENTRANT -D_THREAD_SAFE"
-   ])
-])
-
-
-
-
-

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.