INCLUDE(CheckCXXSourceCompiles)
-INCLUDE(CheckIncludeFiles)
+INCLUDE(CheckCXXSourceRuns)
#
}
"
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()
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