Update Eigen to: https://gitlab.com/libeigen/eigen/-/commit/f0f1d7938b7083800ff75fe88e15092f08a4e67e

PiperOrigin-RevId: 405697181
Change-Id: I86729a434c0b848875459b1b6c28273aac26bf59
diff --git a/Eigen/Core b/Eigen/Core
index 3c03519..2643981 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -8,8 +8,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_CORE_H
-#define EIGEN_CORE_H
+#ifndef EIGEN_CORE_MODULE_H
+#define EIGEN_CORE_MODULE_H
 
 // first thing Eigen does: stop the compiler from reporting useless warnings.
 #include "src/Core/util/DisableStupidWarnings.h"
@@ -166,6 +166,7 @@
 #include "src/Core/util/XprHelper.h"
 #include "src/Core/util/Memory.h"
 #include "src/Core/util/IntegralConstant.h"
+#include "src/Core/util/Serializer.h"
 #include "src/Core/util/SymbolicIndex.h"
 
 #include "src/Core/NumTraits.h"
@@ -382,4 +383,4 @@
 
 #include "src/Core/util/ReenableStupidWarnings.h"
 
-#endif // EIGEN_CORE_H
+#endif // EIGEN_CORE_MODULE_H
diff --git a/Eigen/src/Cholesky/InternalHeaderCheck.h b/Eigen/src/Cholesky/InternalHeaderCheck.h
new file mode 100644
index 0000000..5de2b21
--- /dev/null
+++ b/Eigen/src/Cholesky/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_CHOLESKY_MODULE_H
+#error "Please include Eigen/Cholesky instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h
index 1dffbb6..2674405 100644
--- a/Eigen/src/Cholesky/LDLT.h
+++ b/Eigen/src/Cholesky/LDLT.h
@@ -13,6 +13,8 @@
 #ifndef EIGEN_LDLT_H
 #define EIGEN_LDLT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -270,10 +272,7 @@
 
   protected:
 
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
     /** \internal
       * Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U.
@@ -498,8 +497,6 @@
 template<typename InputType>
 LDLT<MatrixType,UpLo_>& LDLT<MatrixType,UpLo_>::compute(const EigenBase<InputType>& a)
 {
-  check_template_parameters();
-
   eigen_assert(a.rows()==a.cols());
   const Index size = a.rows();
 
diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h
index 3b7aa4d..f22d2a7 100644
--- a/Eigen/src/Cholesky/LLT.h
+++ b/Eigen/src/Cholesky/LLT.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_LLT_H
 #define EIGEN_LLT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal{
@@ -217,10 +219,7 @@
 
   protected:
 
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
     /** \internal
       * Used to compute and store L
@@ -431,8 +430,6 @@
 template<typename InputType>
 LLT<MatrixType,UpLo_>& LLT<MatrixType,UpLo_>::compute(const EigenBase<InputType>& a)
 {
-  check_template_parameters();
-
   eigen_assert(a.rows()==a.cols());
   const Index size = a.rows();
   m_matrix.resize(size, size);
diff --git a/Eigen/src/Cholesky/LLT_LAPACKE.h b/Eigen/src/Cholesky/LLT_LAPACKE.h
index bc6489e..6b2bf28 100644
--- a/Eigen/src/Cholesky/LLT_LAPACKE.h
+++ b/Eigen/src/Cholesky/LLT_LAPACKE.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_LLT_LAPACKE_H
 #define EIGEN_LLT_LAPACKE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/CholmodSupport/CholmodSupport.h b/Eigen/src/CholmodSupport/CholmodSupport.h
index 817e769..a56ebfd 100644
--- a/Eigen/src/CholmodSupport/CholmodSupport.h
+++ b/Eigen/src/CholmodSupport/CholmodSupport.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CHOLMODSUPPORT_H
 #define EIGEN_CHOLMODSUPPORT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/CholmodSupport/InternalHeaderCheck.h b/Eigen/src/CholmodSupport/InternalHeaderCheck.h
new file mode 100644
index 0000000..0fb3abc
--- /dev/null
+++ b/Eigen/src/CholmodSupport/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_CHOLMODSUPPORT_MODULE_H
+#error "Please include Eigen/CholmodSupport instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/Core/ArithmeticSequence.h b/Eigen/src/Core/ArithmeticSequence.h
index b6200fa..331ff49 100644
--- a/Eigen/src/Core/ArithmeticSequence.h
+++ b/Eigen/src/Core/ArithmeticSequence.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ARITHMETIC_SEQUENCE_H
 #define EIGEN_ARITHMETIC_SEQUENCE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -72,7 +74,7 @@
   typedef typename cleanup_index_type<T,DynamicIndex>::type type;
 };
 
-}
+}  // namespace internal
 
 //--------------------------------------------------------------------------------
 // seq(first,last,incr) and seqN(first,size,incr)
@@ -319,6 +321,7 @@
 
 #endif // EIGEN_PARSED_BY_DOXYGEN
 
+namespace placeholders {
 
 #if EIGEN_HAS_CXX11 || defined(EIGEN_PARSED_BY_DOXYGEN)
 /** \cpp11
@@ -329,9 +332,9 @@
   * \sa lastN(SizeType), seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
 template<typename SizeType,typename IncrType>
 auto lastN(SizeType size, IncrType incr)
--> decltype(seqN(Eigen::last-(size-fix<1>())*incr, size, incr))
+-> decltype(seqN(Eigen::placeholders::last-(size-fix<1>())*incr, size, incr))
 {
-  return seqN(Eigen::last-(size-fix<1>())*incr, size, incr);
+  return seqN(Eigen::placeholders::last-(size-fix<1>())*incr, size, incr);
 }
 
 /** \cpp11
@@ -342,12 +345,14 @@
   * \sa lastN(SizeType,IncrType, seqN(FirstType,SizeType), seq(FirstType,LastType) */
 template<typename SizeType>
 auto lastN(SizeType size)
--> decltype(seqN(Eigen::last+fix<1>()-size, size))
+-> decltype(seqN(Eigen::placeholders::last+fix<1>()-size, size))
 {
-  return seqN(Eigen::last+fix<1>()-size, size);
+  return seqN(Eigen::placeholders::last+fix<1>()-size, size);
 }
 #endif
 
+}  // namespace placeholders
+
 namespace internal {
 
 // Convert a symbolic span into a usable one (i.e., remove last/end "keywords")
@@ -387,25 +392,25 @@
   * \code using namespace Eigen::indexing; \endcode
   * is equivalent to:
   * \code
-  using Eigen::all;
+  using Eigen::fix;
   using Eigen::seq;
   using Eigen::seqN;
-  using Eigen::lastN; // c++11 only
-  using Eigen::last;
-  using Eigen::lastp1;
-  using Eigen::fix;
+  using Eigen::placeholders::all;
+  using Eigen::placeholders::last;
+  using Eigen::placeholders::lastN;  // c++11 only
+  using Eigen::placeholders::lastp1;
   \endcode
   */
 namespace indexing {
-  using Eigen::all;
+  using Eigen::fix;
   using Eigen::seq;
   using Eigen::seqN;
+  using Eigen::placeholders::all;
+  using Eigen::placeholders::last;
   #if EIGEN_HAS_CXX11
-  using Eigen::lastN;
+  using Eigen::placeholders::lastN;
   #endif
-  using Eigen::last;
-  using Eigen::lastp1;
-  using Eigen::fix;
+  using Eigen::placeholders::lastp1;
 }
 
 } // end namespace Eigen
diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h
index 85676ae..c39aa15 100644
--- a/Eigen/src/Core/Array.h
+++ b/Eigen/src/Core/Array.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ARRAY_H
 #define EIGEN_ARRAY_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -131,7 +133,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE Array() : Base()
     {
-      Base::_check_template_params();
       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     }
 
@@ -142,7 +143,6 @@
     Array(internal::constructor_without_unaligned_array_assert)
       : Base(internal::constructor_without_unaligned_array_assert())
     {
-      Base::_check_template_params();
       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     }
 #endif
@@ -152,7 +152,6 @@
     Array(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
       : Base(std::move(other))
     {
-      Base::_check_template_params();
     }
     EIGEN_DEVICE_FUNC
     Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
@@ -206,7 +205,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE explicit Array(const T& x)
     {
-      Base::_check_template_params();
       Base::template _init1<T>(x);
     }
 
@@ -214,7 +212,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1)
     {
-      Base::_check_template_params();
       this->template _init2<T0,T1>(val0, val1);
     }
 
@@ -249,7 +246,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
     {
-      Base::_check_template_params();
       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3)
       m_storage.data()[0] = val0;
       m_storage.data()[1] = val1;
@@ -261,7 +257,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
     {
-      Base::_check_template_params();
       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4)
       m_storage.data()[0] = val0;
       m_storage.data()[1] = val1;
diff --git a/Eigen/src/Core/ArrayBase.h b/Eigen/src/Core/ArrayBase.h
index ea3dd1c..28397e5 100644
--- a/Eigen/src/Core/ArrayBase.h
+++ b/Eigen/src/Core/ArrayBase.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ARRAYBASE_H
 #define EIGEN_ARRAYBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename ExpressionType> class MatrixWrapper;
@@ -21,7 +23,7 @@
   *
   * An array is similar to a dense vector or matrix. While matrices are mathematical
   * objects with well defined linear algebra operators, an array is just a collection
-  * of scalar values arranged in a one or two dimensionnal fashion. As the main consequence,
+  * of scalar values arranged in a one or two dimensional fashion. As the main consequence,
   * all operations applied to an array are performed coefficient wise. Furthermore,
   * arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient
   * constructors allowing to easily write generic code working for both scalar values
diff --git a/Eigen/src/Core/ArrayWrapper.h b/Eigen/src/Core/ArrayWrapper.h
index 2e9555b..8a34ca5 100644
--- a/Eigen/src/Core/ArrayWrapper.h
+++ b/Eigen/src/Core/ArrayWrapper.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ARRAYWRAPPER_H
 #define EIGEN_ARRAYWRAPPER_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class ArrayWrapper
diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h
index 655412e..dc716d3 100644
--- a/Eigen/src/Core/Assign.h
+++ b/Eigen/src/Core/Assign.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_ASSIGN_H
 #define EIGEN_ASSIGN_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename Derived>
diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h
index 7d76f0c..5056328 100644
--- a/Eigen/src/Core/AssignEvaluator.h
+++ b/Eigen/src/Core/AssignEvaluator.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_ASSIGN_EVALUATOR_H
 #define EIGEN_ASSIGN_EVALUATOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // This implementation is based on Assign.h
@@ -327,8 +329,7 @@
 {
   EIGEN_DEVICE_FUNC static void EIGEN_STRONG_INLINE run(Kernel& /*kernel*/)
   {
-    typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
-    EIGEN_STATIC_ASSERT(int(DstXprType::SizeAtCompileTime) == 0,
+    EIGEN_STATIC_ASSERT(int(Kernel::DstEvaluatorType::XprType::SizeAtCompileTime) == 0,
       EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT)
   }
 };
diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h
index c6140d1..c2afebd 100755
--- a/Eigen/src/Core/Assign_MKL.h
+++ b/Eigen/src/Core/Assign_MKL.h
@@ -34,6 +34,8 @@
 #ifndef EIGEN_ASSIGN_VML_H
 #define EIGEN_ASSIGN_VML_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h
index 590573b..69b7681 100644
--- a/Eigen/src/Core/BandMatrix.h
+++ b/Eigen/src/Core/BandMatrix.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_BANDMATRIX_H
 #define EIGEN_BANDMATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h
index d0b95d5..585323c 100644
--- a/Eigen/src/Core/Block.h
+++ b/Eigen/src/Core/Block.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_BLOCK_H
 #define EIGEN_BLOCK_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/BooleanRedux.h b/Eigen/src/Core/BooleanRedux.h
index 852de8b..9689ca3 100644
--- a/Eigen/src/Core/BooleanRedux.h
+++ b/Eigen/src/Core/BooleanRedux.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ALLANDANY_H
 #define EIGEN_ALLANDANY_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/CommaInitializer.h b/Eigen/src/Core/CommaInitializer.h
index c0e29c7..5c89d14 100644
--- a/Eigen/src/Core/CommaInitializer.h
+++ b/Eigen/src/Core/CommaInitializer.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_COMMAINITIALIZER_H
 #define EIGEN_COMMAINITIALIZER_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \class CommaInitializer
diff --git a/Eigen/src/Core/ConditionEstimator.h b/Eigen/src/Core/ConditionEstimator.h
index 51a2e5f..bd4455f 100644
--- a/Eigen/src/Core/ConditionEstimator.h
+++ b/Eigen/src/Core/ConditionEstimator.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CONDITIONESTIMATOR_H
 #define EIGEN_CONDITIONESTIMATOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h
index 0ff8c8d..1dcd2f8 100644
--- a/Eigen/src/Core/CoreEvaluators.h
+++ b/Eigen/src/Core/CoreEvaluators.h
@@ -13,6 +13,8 @@
 #ifndef EIGEN_COREEVALUATORS_H
 #define EIGEN_COREEVALUATORS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/CoreIterators.h b/Eigen/src/Core/CoreIterators.h
index b967196..f74568a 100644
--- a/Eigen/src/Core/CoreIterators.h
+++ b/Eigen/src/Core/CoreIterators.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_COREITERATORS_H
 #define EIGEN_COREITERATORS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h
index 2202b1c..98fdabb 100644
--- a/Eigen/src/Core/CwiseBinaryOp.h
+++ b/Eigen/src/Core/CwiseBinaryOp.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_CWISE_BINARY_OP_H
 #define EIGEN_CWISE_BINARY_OP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -95,6 +97,9 @@
                                                       BinaryOp>::ret>::Base Base;
     EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
 
+    EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar)
+    EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
+
     typedef typename internal::ref_selector<LhsType>::type LhsNested;
     typedef typename internal::ref_selector<RhsType>::type RhsNested;
     typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
@@ -110,9 +115,6 @@
     CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
       : m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
     {
-      EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
-      // require the sizes to match
-      EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
       eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
     }
 
diff --git a/Eigen/src/Core/CwiseNullaryOp.h b/Eigen/src/Core/CwiseNullaryOp.h
index 289ec51..a62f54d 100644
--- a/Eigen/src/Core/CwiseNullaryOp.h
+++ b/Eigen/src/Core/CwiseNullaryOp.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CWISE_NULLARY_OP_H
 #define EIGEN_CWISE_NULLARY_OP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/CwiseTernaryOp.h b/Eigen/src/Core/CwiseTernaryOp.h
index 9f3576f..52a0ae7 100644
--- a/Eigen/src/Core/CwiseTernaryOp.h
+++ b/Eigen/src/Core/CwiseTernaryOp.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_CWISE_TERNARY_OP_H
 #define EIGEN_CWISE_TERNARY_OP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -91,6 +93,20 @@
   typedef typename internal::remove_all<Arg2Type>::type Arg2;
   typedef typename internal::remove_all<Arg3Type>::type Arg3;
 
+  // require the sizes to match
+  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
+  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
+
+  // The index types should match
+  EIGEN_STATIC_ASSERT((internal::is_same<
+                       typename internal::traits<Arg1Type>::StorageKind,
+                       typename internal::traits<Arg2Type>::StorageKind>::value),
+                      STORAGE_KIND_MUST_MATCH)
+  EIGEN_STATIC_ASSERT((internal::is_same<
+                       typename internal::traits<Arg1Type>::StorageKind,
+                       typename internal::traits<Arg3Type>::StorageKind>::value),
+                      STORAGE_KIND_MUST_MATCH)
+
   typedef typename CwiseTernaryOpImpl<
       TernaryOp, Arg1Type, Arg2Type, Arg3Type,
       typename internal::traits<Arg1Type>::StorageKind>::Base Base;
@@ -108,20 +124,6 @@
                                      const Arg3& a3,
                                      const TernaryOp& func = TernaryOp())
       : m_arg1(a1), m_arg2(a2), m_arg3(a3), m_functor(func) {
-    // require the sizes to match
-    EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
-    EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
-
-    // The index types should match
-    EIGEN_STATIC_ASSERT((internal::is_same<
-                         typename internal::traits<Arg1Type>::StorageKind,
-                         typename internal::traits<Arg2Type>::StorageKind>::value),
-                        STORAGE_KIND_MUST_MATCH)
-    EIGEN_STATIC_ASSERT((internal::is_same<
-                         typename internal::traits<Arg1Type>::StorageKind,
-                         typename internal::traits<Arg3Type>::StorageKind>::value),
-                        STORAGE_KIND_MUST_MATCH)
-
     eigen_assert(a1.rows() == a2.rows() && a1.cols() == a2.cols() &&
                  a1.rows() == a3.rows() && a1.cols() == a3.cols());
   }
diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h
index e68c4f7..f2c6518 100644
--- a/Eigen/src/Core/CwiseUnaryOp.h
+++ b/Eigen/src/Core/CwiseUnaryOp.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_CWISE_UNARY_OP_H
 #define EIGEN_CWISE_UNARY_OP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/CwiseUnaryView.h b/Eigen/src/Core/CwiseUnaryView.h
index a06d762..9fc1dcd 100644
--- a/Eigen/src/Core/CwiseUnaryView.h
+++ b/Eigen/src/Core/CwiseUnaryView.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CWISE_UNARY_VIEW_H
 #define EIGEN_CWISE_UNARY_VIEW_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index 9b16db6..940eabd 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -11,17 +11,12 @@
 #ifndef EIGEN_DENSEBASE_H
 #define EIGEN_DENSEBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
-namespace internal {
-
 // The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
-// This dummy function simply aims at checking that at compile time.
-static inline void check_DenseIndex_is_signed() {
-  EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
-}
-
-} // end namespace internal
+EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
 
 /** \class DenseBase
   * \ingroup Core_Module
diff --git a/Eigen/src/Core/DenseCoeffsBase.h b/Eigen/src/Core/DenseCoeffsBase.h
index 37fcdb5..46d8730 100644
--- a/Eigen/src/Core/DenseCoeffsBase.h
+++ b/Eigen/src/Core/DenseCoeffsBase.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_DENSECOEFFSBASE_H
 #define EIGEN_DENSECOEFFSBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -43,7 +45,7 @@
     // - This is the return type of the coeff() method.
     // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
     // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
-    // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems
+    // - The is_arithmetic check is required since "const int", "const double", etc. will cause warnings on some systems
     // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
     // not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
     typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
diff --git a/Eigen/src/Core/DenseStorage.h b/Eigen/src/Core/DenseStorage.h
index 3805084..19a6980 100644
--- a/Eigen/src/Core/DenseStorage.h
+++ b/Eigen/src/Core/DenseStorage.h
@@ -18,6 +18,8 @@
   #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X)
 #endif
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/Diagonal.h b/Eigen/src/Core/Diagonal.h
index d15f0af..7564c4c 100644
--- a/Eigen/src/Core/Diagonal.h
+++ b/Eigen/src/Core/Diagonal.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_DIAGONAL_H
 #define EIGEN_DIAGONAL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class Diagonal
diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h
index 474dcfa..cf5e906 100644
--- a/Eigen/src/Core/DiagonalMatrix.h
+++ b/Eigen/src/Core/DiagonalMatrix.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_DIAGONALMATRIX_H
 #define EIGEN_DIAGONALMATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 #ifndef EIGEN_PARSED_BY_DOXYGEN
diff --git a/Eigen/src/Core/DiagonalProduct.h b/Eigen/src/Core/DiagonalProduct.h
index 7911d1c..3cd34ba 100644
--- a/Eigen/src/Core/DiagonalProduct.h
+++ b/Eigen/src/Core/DiagonalProduct.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_DIAGONALPRODUCT_H
 #define EIGEN_DIAGONALPRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal.
diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h
index 5c3441b..387b6ce 100644
--- a/Eigen/src/Core/Dot.h
+++ b/Eigen/src/Core/Dot.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_DOT_H
 #define EIGEN_DOT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/EigenBase.h b/Eigen/src/Core/EigenBase.h
index 6b3c7d3..105488d 100644
--- a/Eigen/src/Core/EigenBase.h
+++ b/Eigen/src/Core/EigenBase.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_EIGENBASE_H
 #define EIGEN_EIGENBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class EigenBase
diff --git a/Eigen/src/Core/ForceAlignedAccess.h b/Eigen/src/Core/ForceAlignedAccess.h
index 817a43a..7c46573 100644
--- a/Eigen/src/Core/ForceAlignedAccess.h
+++ b/Eigen/src/Core/ForceAlignedAccess.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_FORCEALIGNEDACCESS_H
 #define EIGEN_FORCEALIGNEDACCESS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class ForceAlignedAccess
diff --git a/Eigen/src/Core/Fuzzy.h b/Eigen/src/Core/Fuzzy.h
index 43aa49b..b16b2da 100644
--- a/Eigen/src/Core/Fuzzy.h
+++ b/Eigen/src/Core/Fuzzy.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_FUZZY_H
 #define EIGEN_FUZZY_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal
diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h
index 6906aa7..251b5d4 100644
--- a/Eigen/src/Core/GeneralProduct.h
+++ b/Eigen/src/Core/GeneralProduct.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_GENERAL_PRODUCT_H
 #define EIGEN_GENERAL_PRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 enum {
diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h
index cf677a1..7223428 100644
--- a/Eigen/src/Core/GenericPacketMath.h
+++ b/Eigen/src/Core/GenericPacketMath.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_GENERIC_PACKET_MATH_H
 #define EIGEN_GENERIC_PACKET_MATH_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -160,7 +162,7 @@
 {
   EIGEN_ALWAYS_INLINE operator T&() { return m_val; }
   EIGEN_ALWAYS_INLINE operator const T&() const { return m_val; }
-  EIGEN_ALWAYS_INLINE eigen_packet_wrapper() {}
+  EIGEN_ALWAYS_INLINE eigen_packet_wrapper() = default;
   EIGEN_ALWAYS_INLINE eigen_packet_wrapper(const T &v) : m_val(v) {}
   EIGEN_ALWAYS_INLINE eigen_packet_wrapper& operator=(const T &v) {
     m_val = v;
diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h
index 629af94..c6d36ea 100644
--- a/Eigen/src/Core/GlobalFunctions.h
+++ b/Eigen/src/Core/GlobalFunctions.h
@@ -51,6 +51,8 @@
     } \
   };
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen
 {
   EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op,real part,\sa ArrayBase::real)
diff --git a/Eigen/src/Core/IO.h b/Eigen/src/Core/IO.h
index e81c315..efc2c43 100644
--- a/Eigen/src/Core/IO.h
+++ b/Eigen/src/Core/IO.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_IO_H
 #define EIGEN_IO_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 enum { DontAlignCols = 1 };
diff --git a/Eigen/src/Core/IndexedView.h b/Eigen/src/Core/IndexedView.h
index 0847625..51e28b9 100644
--- a/Eigen/src/Core/IndexedView.h
+++ b/Eigen/src/Core/IndexedView.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_INDEXED_VIEW_H
 #define EIGEN_INDEXED_VIEW_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -96,7 +98,7 @@
   *  - decltype(ArrayXi::LinSpaced(...))
   *  - Any view/expressions of the previous types
   *  - Eigen::ArithmeticSequence
-  *  - Eigen::internal::AllRange      (helper for Eigen::all)
+  *  - Eigen::internal::AllRange     (helper for Eigen::placeholders::all)
   *  - Eigen::internal::SingleRange  (helper for single index)
   *  - etc.
   *
diff --git a/Eigen/src/Core/InternalHeaderCheck.h b/Eigen/src/Core/InternalHeaderCheck.h
new file mode 100644
index 0000000..1cea572
--- /dev/null
+++ b/Eigen/src/Core/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_CORE_MODULE_H
+#error "Please include Eigen/Core instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/Core/Inverse.h b/Eigen/src/Core/Inverse.h
index c514438..268f8d4 100644
--- a/Eigen/src/Core/Inverse.h
+++ b/Eigen/src/Core/Inverse.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_INVERSE_H
 #define EIGEN_INVERSE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename XprType,typename StorageKind> class InverseImpl;
diff --git a/Eigen/src/Core/Map.h b/Eigen/src/Core/Map.h
index 218cc15..56d1ff8 100644
--- a/Eigen/src/Core/Map.h
+++ b/Eigen/src/Core/Map.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_MAP_H
 #define EIGEN_MAP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -129,7 +131,6 @@
     explicit inline Map(PointerArgType dataPtr, const StrideType& stride = StrideType())
       : Base(cast_to_pointer_type(dataPtr)), m_stride(stride)
     {
-      PlainObjectType::Base::_check_template_params();
     }
 
     /** Constructor in the dynamic-size vector case.
@@ -142,7 +143,6 @@
     inline Map(PointerArgType dataPtr, Index size, const StrideType& stride = StrideType())
       : Base(cast_to_pointer_type(dataPtr), size), m_stride(stride)
     {
-      PlainObjectType::Base::_check_template_params();
     }
 
     /** Constructor in the dynamic-size matrix case.
@@ -156,7 +156,6 @@
     inline Map(PointerArgType dataPtr, Index rows, Index cols, const StrideType& stride = StrideType())
       : Base(cast_to_pointer_type(dataPtr), rows, cols), m_stride(stride)
     {
-      PlainObjectType::Base::_check_template_params();
     }
 
     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
diff --git a/Eigen/src/Core/MapBase.h b/Eigen/src/Core/MapBase.h
index d856447..89192c3 100644
--- a/Eigen/src/Core/MapBase.h
+++ b/Eigen/src/Core/MapBase.h
@@ -15,6 +15,8 @@
       EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
                           YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \ingroup Core_Module
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index 61b78f4..957cca7 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -17,6 +17,8 @@
 #define EIGEN_LOG2E 1.442695040888963407359924681001892137426645954152985934135449406931109219L
 #define EIGEN_LN2   0.693147180559945309417232121458176568075500134360255254120680009493393621L
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // On WINCE, std::abs is defined for int only, so let's defined our own overloads:
@@ -469,10 +471,11 @@
 template<typename Scalar>
 struct round_impl
 {
+  EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
+
   EIGEN_DEVICE_FUNC
   static inline Scalar run(const Scalar& x)
   {
-    EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
 #if EIGEN_HAS_CXX11_MATH
     EIGEN_USING_STD(round);
 #endif
@@ -495,10 +498,11 @@
 template<typename Scalar>
 struct round_using_floor_ceil_impl
 {
+  EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
+
   EIGEN_DEVICE_FUNC
   static inline Scalar run(const Scalar& x)
   {
-    EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
     // Without C99 round/roundf, resort to floor/ceil.
     EIGEN_USING_STD(floor);
     EIGEN_USING_STD(ceil);
@@ -532,10 +536,11 @@
 
 template<typename Scalar>
 struct rint_impl {
+  EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
+
   EIGEN_DEVICE_FUNC
   static inline Scalar run(const Scalar& x)
   {
-    EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
 #if EIGEN_HAS_CXX11_MATH
       EIGEN_USING_STD(rint);
 #endif
@@ -736,9 +741,10 @@
 
 template<typename Scalar>
 struct log1p_impl {
+  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
+
   EIGEN_DEVICE_FUNC static inline Scalar run(const Scalar& x)
   {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
     #if EIGEN_HAS_CXX11_MATH
     using std::log1p;
     #else
@@ -751,9 +757,10 @@
 // Specialization for complex types that are not supported by std::log1p.
 template <typename RealScalar>
 struct log1p_impl<std::complex<RealScalar> > {
+  EIGEN_STATIC_ASSERT_NON_INTEGER(RealScalar)
+
   EIGEN_DEVICE_FUNC static inline std::complex<RealScalar> run(
       const std::complex<RealScalar>& x) {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(RealScalar)
     return std_fallback::log1p(x);
   }
 };
@@ -2006,9 +2013,10 @@
 // Specialization for complex types that are not supported by std::expm1.
 template <typename RealScalar>
 struct expm1_impl<std::complex<RealScalar> > {
+  EIGEN_STATIC_ASSERT_NON_INTEGER(RealScalar)
+
   EIGEN_DEVICE_FUNC static inline std::complex<RealScalar> run(
       const std::complex<RealScalar>& x) {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(RealScalar)
     RealScalar xr = x.real();
     RealScalar xi = x.imag();
     // expm1(z) = exp(z) - 1
diff --git a/Eigen/src/Core/MathFunctionsImpl.h b/Eigen/src/Core/MathFunctionsImpl.h
index 4eaaaa7..2c9bbb5 100644
--- a/Eigen/src/Core/MathFunctionsImpl.h
+++ b/Eigen/src/Core/MathFunctionsImpl.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_MATHFUNCTIONSIMPL_H
 #define EIGEN_MATHFUNCTIONSIMPL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -21,7 +23,7 @@
     outside of which tanh(x) = +/-1 in single precision. The input is clamped
     to the range [-c, c]. The value c is chosen as the smallest value where
     the approximation evaluates to exactly 1. In the reange [-0.0004, 0.0004]
-    the approxmation tanh(x) ~= x is used for better accuracy as x tends to zero.
+    the approximation tanh(x) ~= x is used for better accuracy as x tends to zero.
 
     This implementation works on both scalars and packets.
 */
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index de54824..bc75a28 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_MATRIX_H
 #define EIGEN_MATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -258,7 +260,6 @@
     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     Matrix() : Base()
     {
-      Base::_check_template_params();
       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     }
 
@@ -266,15 +267,12 @@
     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     explicit Matrix(internal::constructor_without_unaligned_array_assert)
       : Base(internal::constructor_without_unaligned_array_assert())
-    { Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
+    { EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
 
 #if EIGEN_HAS_RVALUE_REFERENCES
     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     Matrix(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
-      : Base(std::move(other))
-    {
-      Base::_check_template_params();
-    }
+      : Base(std::move(other)) {}
     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
     {
@@ -328,7 +326,6 @@
     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     explicit Matrix(const T& x)
     {
-      Base::_check_template_params();
       Base::template _init1<T>(x);
     }
 
@@ -336,7 +333,6 @@
     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     Matrix(const T0& x, const T1& y)
     {
-      Base::_check_template_params();
       Base::template _init2<T0,T1>(x, y);
     }
 
@@ -388,7 +384,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
     {
-      Base::_check_template_params();
       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3)
       m_storage.data()[0] = x;
       m_storage.data()[1] = y;
@@ -400,7 +395,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
     {
-      Base::_check_template_params();
       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4)
       m_storage.data()[0] = x;
       m_storage.data()[1] = y;
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 45c3a59..3552d5a 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_MATRIXBASE_H
 #define EIGEN_MATRIXBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class MatrixBase
diff --git a/Eigen/src/Core/NestByValue.h b/Eigen/src/Core/NestByValue.h
index b427576..5f1dc84 100644
--- a/Eigen/src/Core/NestByValue.h
+++ b/Eigen/src/Core/NestByValue.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_NESTBYVALUE_H
 #define EIGEN_NESTBYVALUE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h
index 570283d..09c0aac 100644
--- a/Eigen/src/Core/NoAlias.h
+++ b/Eigen/src/Core/NoAlias.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_NOALIAS_H
 #define EIGEN_NOALIAS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class NoAlias
diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h
index 608a4e7..dfe6fe3 100644
--- a/Eigen/src/Core/NumTraits.h
+++ b/Eigen/src/Core/NumTraits.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_NUMTRAITS_H
 #define EIGEN_NUMTRAITS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/PartialReduxEvaluator.h b/Eigen/src/Core/PartialReduxEvaluator.h
index 29abf35..4040ae7 100644
--- a/Eigen/src/Core/PartialReduxEvaluator.h
+++ b/Eigen/src/Core/PartialReduxEvaluator.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PARTIALREDUX_H
 #define EIGEN_PARTIALREDUX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
@@ -29,7 +31,7 @@
 *    some (optional) processing of the outcome, e.g., division by n for mean.
 *
 * For the vectorized path let's observe that the packet-size and outer-unrolling
-* are both decided by the assignement logic. So all we have to do is to decide
+* are both decided by the assignment logic. So all we have to do is to decide
 * on the inner unrolling.
 *
 * For the unrolling, we can reuse "internal::redux_vec_unroller" from Redux.h,
diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h
index 24fe660..a6910e2 100644
--- a/Eigen/src/Core/PermutationMatrix.h
+++ b/Eigen/src/Core/PermutationMatrix.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_PERMUTATIONMATRIX_H
 #define EIGEN_PERMUTATIONMATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h
index 00cdc55..607e1c8 100644
--- a/Eigen/src/Core/PlainObjectBase.h
+++ b/Eigen/src/Core/PlainObjectBase.h
@@ -22,6 +22,8 @@
 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
 #endif
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -134,6 +136,16 @@
     enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) };
     EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
 
+    EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (int(Options)&RowMajor)==RowMajor), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+    EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (int(Options)&RowMajor)==0), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+    EIGEN_STATIC_ASSERT((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+    EIGEN_STATIC_ASSERT((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+    EIGEN_STATIC_ASSERT((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+    EIGEN_STATIC_ASSERT((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+    EIGEN_STATIC_ASSERT((MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+    EIGEN_STATIC_ASSERT((MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+    EIGEN_STATIC_ASSERT(((Options & (DontAlign|RowMajor)) == Options), INVALID_MATRIX_TEMPLATE_PARAMETERS)
+
     EIGEN_DEVICE_FUNC
     Base& base() { return *static_cast<Base*>(this); }
     EIGEN_DEVICE_FUNC
@@ -270,7 +282,7 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
     {
-      eigen_assert(   EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
+      eigen_assert(EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
                    && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime)
                    && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime)
                    && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime)
@@ -475,7 +487,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
     {
-//       _check_template_params();
 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     }
 
@@ -486,7 +497,7 @@
     explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
       : m_storage(internal::constructor_without_unaligned_array_assert())
     {
-//       _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
+      // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     }
 #endif
 
@@ -500,7 +511,6 @@
     EIGEN_DEVICE_FUNC
     PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
     {
-      _check_template_params();
       m_storage = std::move(other.m_storage);
       return *this;
     }
@@ -514,7 +524,6 @@
     EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
       : m_storage(size, rows, cols)
     {
-//       _check_template_params();
 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     }
 
@@ -534,7 +543,6 @@
     PlainObjectBase(const Scalar& a0, const Scalar& a1, const Scalar& a2,  const Scalar& a3, const ArgTypes&... args)
       : m_storage()
     {
-      _check_template_params();
       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, sizeof...(args) + 4);
       m_storage.data()[0] = a0;
       m_storage.data()[1] = a1;
@@ -552,8 +560,6 @@
     explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<std::initializer_list<Scalar>>& list)
       : m_storage()
     {
-      _check_template_params();
-
       size_t list_size = 0;
       if (list.begin() != list.end()) {
         list_size = list.begin()->size();
@@ -589,7 +595,6 @@
     EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
       : m_storage()
     {
-      _check_template_params();
       resizeLike(other);
       _set_noalias(other);
     }
@@ -600,7 +605,6 @@
     EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
       : m_storage()
     {
-      _check_template_params();
       resizeLike(other);
       *this = other.derived();
     }
@@ -609,7 +613,6 @@
     EIGEN_DEVICE_FUNC
     EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
     {
-      _check_template_params();
       // FIXME this does not automatically transpose vectors if necessary
       resize(other.rows(), other.cols());
       other.evalTo(this->derived());
@@ -964,21 +967,6 @@
     void swap(DenseBase<OtherDerived> const & other)
     { Base::swap(other.derived()); }
 
-    EIGEN_DEVICE_FUNC
-    static EIGEN_STRONG_INLINE void _check_template_params()
-    {
-      EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (int(Options)&RowMajor)==RowMajor)
-                        && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (int(Options)&RowMajor)==0)
-                        && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
-                        && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
-                        && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
-                        && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
-                        && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
-                        && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
-                        && (Options & (DontAlign|RowMajor)) == Options),
-        INVALID_MATRIX_TEMPLATE_PARAMETERS)
-    }
-
     enum { IsPlainObjectBase = 1 };
 #endif
   public:
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index 1941749..545fdb9 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PRODUCT_H
 #define EIGEN_PRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename Lhs, typename Rhs, int Option, typename StorageKind> class ProductImpl;
diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h
index b9eab97..42e92c2 100644
--- a/Eigen/src/Core/ProductEvaluators.h
+++ b/Eigen/src/Core/ProductEvaluators.h
@@ -13,6 +13,8 @@
 #ifndef EIGEN_PRODUCTEVALUATORS_H
 #define EIGEN_PRODUCTEVALUATORS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -427,8 +429,8 @@
   //  3 - it makes this fallback consistent with the heavy GEMM routine.
   //  4 - it fully by-passes huge stack allocation attempts when multiplying huge fixed-size matrices.
   //      (see https://stackoverflow.com/questions/54738495)
-  // For small fixed sizes matrices, howver, the gains are less obvious, it is sometimes x2 faster, but sometimes x3 slower,
-  // and the behavior depends also a lot on the compiler... This is why this re-writting strategy is currently
+  // For small fixed sizes matrices, however, the gains are less obvious, it is sometimes x2 faster, but sometimes x3 slower,
+  // and the behavior depends also a lot on the compiler... This is why this re-writing strategy is currently
   // enabled only when falling back from the main GEMM.
   template<typename Dst, typename Func>
   static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
diff --git a/Eigen/src/Core/Random.h b/Eigen/src/Core/Random.h
index dab2ac8..0b304e7 100644
--- a/Eigen/src/Core/Random.h
+++ b/Eigen/src/Core/Random.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_RANDOM_H
 #define EIGEN_RANDOM_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h
index 5732ba8..e05a0cc 100644
--- a/Eigen/src/Core/Redux.h
+++ b/Eigen/src/Core/Redux.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_REDUX_H
 #define EIGEN_REDUX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/Ref.h b/Eigen/src/Core/Ref.h
index 716552a..3e1d99c 100644
--- a/Eigen/src/Core/Ref.h
+++ b/Eigen/src/Core/Ref.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_REF_H
 #define EIGEN_REF_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -298,7 +300,7 @@
                                  typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
     {
       EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
-      // Construction must pass since we will not create temprary storage in the non-const case.
+      // Construction must pass since we will not create temporary storage in the non-const case.
       const bool success = Base::construct(expr.derived());
       EIGEN_UNUSED_VARIABLE(success)
       eigen_assert(success);
diff --git a/Eigen/src/Core/Replicate.h b/Eigen/src/Core/Replicate.h
index ab5be7e..0ee9a10 100644
--- a/Eigen/src/Core/Replicate.h
+++ b/Eigen/src/Core/Replicate.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_REPLICATE_H
 #define EIGEN_REPLICATE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/Reshaped.h b/Eigen/src/Core/Reshaped.h
index 52de73b..8a9cedb 100644
--- a/Eigen/src/Core/Reshaped.h
+++ b/Eigen/src/Core/Reshaped.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_RESHAPED_H
 #define EIGEN_RESHAPED_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class Reshaped
diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h
index 4dad13e..d2dd349 100644
--- a/Eigen/src/Core/ReturnByValue.h
+++ b/Eigen/src/Core/ReturnByValue.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_RETURNBYVALUE_H
 #define EIGEN_RETURNBYVALUE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/Reverse.h b/Eigen/src/Core/Reverse.h
index 28cdd76..7ad5023 100644
--- a/Eigen/src/Core/Reverse.h
+++ b/Eigen/src/Core/Reverse.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_REVERSE_H
 #define EIGEN_REVERSE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/Select.h b/Eigen/src/Core/Select.h
index 7c86bf8..f2a2a03 100644
--- a/Eigen/src/Core/Select.h
+++ b/Eigen/src/Core/Select.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SELECT_H
 #define EIGEN_SELECT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class Select
diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h
index 28f3a70..97c2a19 100644
--- a/Eigen/src/Core/SelfAdjointView.h
+++ b/Eigen/src/Core/SelfAdjointView.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SELFADJOINTMATRIX_H
 #define EIGEN_SELFADJOINTMATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class SelfAdjointView
@@ -50,6 +52,7 @@
   : public TriangularBase<SelfAdjointView<MatrixType_, UpLo> >
 {
   public:
+    EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY)
 
     typedef MatrixType_ MatrixType;
     typedef TriangularBase<SelfAdjointView> Base;
@@ -71,10 +74,7 @@
     typedef typename MatrixType::PlainObject PlainObject;
 
     EIGEN_DEVICE_FUNC
-    explicit inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix)
-    {
-      EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY);
-    }
+    explicit inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix) { }
 
     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
     inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
diff --git a/Eigen/src/Core/SelfCwiseBinaryOp.h b/Eigen/src/Core/SelfCwiseBinaryOp.h
index 7c89c2e..14dbec0 100644
--- a/Eigen/src/Core/SelfCwiseBinaryOp.h
+++ b/Eigen/src/Core/SelfCwiseBinaryOp.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SELFCWISEBINARYOP_H
 #define EIGEN_SELFCWISEBINARYOP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 // TODO generalize the scalar type of 'other'
diff --git a/Eigen/src/Core/Solve.h b/Eigen/src/Core/Solve.h
index af30fce..3d3a3c9 100644
--- a/Eigen/src/Core/Solve.h
+++ b/Eigen/src/Core/Solve.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SOLVE_H
 #define EIGEN_SOLVE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename Decomposition, typename RhsType, typename StorageKind> class SolveImpl;
diff --git a/Eigen/src/Core/SolveTriangular.h b/Eigen/src/Core/SolveTriangular.h
index dfbf995..518a6c6 100644
--- a/Eigen/src/Core/SolveTriangular.h
+++ b/Eigen/src/Core/SolveTriangular.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SOLVETRIANGULAR_H
 #define EIGEN_SOLVETRIANGULAR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/SolverBase.h b/Eigen/src/Core/SolverBase.h
index 5014610..2f238ac 100644
--- a/Eigen/src/Core/SolverBase.h
+++ b/Eigen/src/Core/SolverBase.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SOLVERBASE_H
 #define EIGEN_SOLVERBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/StableNorm.h b/Eigen/src/Core/StableNorm.h
index 4a3f0cc..c006c25 100644
--- a/Eigen/src/Core/StableNorm.h
+++ b/Eigen/src/Core/StableNorm.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_STABLENORM_H
 #define EIGEN_STABLENORM_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/StlIterators.h b/Eigen/src/Core/StlIterators.h
index b412b39..d9529c0 100644
--- a/Eigen/src/Core/StlIterators.h
+++ b/Eigen/src/Core/StlIterators.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_STLITERATORS_H
 #define EIGEN_STLITERATORS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/Stride.h b/Eigen/src/Core/Stride.h
index 6ad48f8..8d7820d 100644
--- a/Eigen/src/Core/Stride.h
+++ b/Eigen/src/Core/Stride.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_STRIDE_H
 #define EIGEN_STRIDE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class Stride
diff --git a/Eigen/src/Core/Swap.h b/Eigen/src/Core/Swap.h
index 180a4e5..b2e7511 100644
--- a/Eigen/src/Core/Swap.h
+++ b/Eigen/src/Core/Swap.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SWAP_H
 #define EIGEN_SWAP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 2bc658f..d302766 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_TRANSPOSE_H
 #define EIGEN_TRANSPOSE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/Transpositions.h b/Eigen/src/Core/Transpositions.h
index 4119621..6996ca2 100644
--- a/Eigen/src/Core/Transpositions.h
+++ b/Eigen/src/Core/Transpositions.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TRANSPOSITIONS_H
 #define EIGEN_TRANSPOSITIONS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename Derived>
diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index de95ff1..e9a4cae 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_TRIANGULARMATRIX_H
 #define EIGEN_TRIANGULARMATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/VectorBlock.h b/Eigen/src/Core/VectorBlock.h
index 71c5b95..ee28da1 100644
--- a/Eigen/src/Core/VectorBlock.h
+++ b/Eigen/src/Core/VectorBlock.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_VECTORBLOCK_H
 #define EIGEN_VECTORBLOCK_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
@@ -66,6 +68,7 @@
     };
   public:
     EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock)
+    EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock)
 
     using Base::operator=;
 
@@ -76,18 +79,14 @@
       : Base(vector,
              IsColVector ? start : 0, IsColVector ? 0 : start,
              IsColVector ? size  : 1, IsColVector ? 1 : size)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
-    }
+    { }
 
     /** Fixed-size constructor
       */
     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     VectorBlock(VectorType& vector, Index start)
       : Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
-    }
+    { }
 };
 
 
diff --git a/Eigen/src/Core/VectorwiseOp.h b/Eigen/src/Core/VectorwiseOp.h
index 870f4f1..3c3cc45 100644
--- a/Eigen/src/Core/VectorwiseOp.h
+++ b/Eigen/src/Core/VectorwiseOp.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_PARTIAL_REDUX_H
 #define EIGEN_PARTIAL_REDUX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class PartialReduxExpr
@@ -594,7 +596,7 @@
       return m_matrix += extendedTo(other.derived());
     }
 
-    /** Substracts the vector \a other to each subvector of \c *this */
+    /** Subtracts the vector \a other to each subvector of \c *this */
     template<typename OtherDerived>
     EIGEN_DEVICE_FUNC
     ExpressionType& operator-=(const DenseBase<OtherDerived>& other)
@@ -604,7 +606,7 @@
       return m_matrix -= extendedTo(other.derived());
     }
 
-    /** Multiples each subvector of \c *this by the vector \a other */
+    /** Multiplies each subvector of \c *this by the vector \a other */
     template<typename OtherDerived>
     EIGEN_DEVICE_FUNC
     ExpressionType& operator*=(const DenseBase<OtherDerived>& other)
diff --git a/Eigen/src/Core/Visitor.h b/Eigen/src/Core/Visitor.h
index 00bcca8..cf4e06a 100644
--- a/Eigen/src/Core/Visitor.h
+++ b/Eigen/src/Core/Visitor.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_VISITOR_H
 #define EIGEN_VISITOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AVX/Complex.h b/Eigen/src/Core/arch/AVX/Complex.h
index 0491be9..3abb5bd 100644
--- a/Eigen/src/Core/arch/AVX/Complex.h
+++ b/Eigen/src/Core/arch/AVX/Complex.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_COMPLEX_AVX_H
 #define EIGEN_COMPLEX_AVX_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -99,7 +101,9 @@
 
 template<> EIGEN_STRONG_INLINE Packet4cf pset1<Packet4cf>(const std::complex<float>& from)
 {
-  return Packet4cf(_mm256_castpd_ps(_mm256_broadcast_sd((const double*)(const void*)&from)));
+  const float re = std::real(from);
+  const float im = std::imag(from);
+  return Packet4cf(_mm256_set_ps(im, re, im, re, im, re, im, re));
 }
 
 template<> EIGEN_STRONG_INLINE Packet4cf ploaddup<Packet4cf>(const std::complex<float>* from)
diff --git a/Eigen/src/Core/arch/AVX/MathFunctions.h b/Eigen/src/Core/arch/AVX/MathFunctions.h
index 67041c8..17b9d0b 100644
--- a/Eigen/src/Core/arch/AVX/MathFunctions.h
+++ b/Eigen/src/Core/arch/AVX/MathFunctions.h
@@ -14,6 +14,8 @@
  * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/
  */
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AVX/PacketMath.h b/Eigen/src/Core/arch/AVX/PacketMath.h
index 41cb7af..cdf0fdf 100644
--- a/Eigen/src/Core/arch/AVX/PacketMath.h
+++ b/Eigen/src/Core/arch/AVX/PacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PACKET_MATH_AVX_H
 #define EIGEN_PACKET_MATH_AVX_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -1439,7 +1441,6 @@
 
 // Convert float to bfloat16 according to round-to-nearest-even/denormals algorithm.
 EIGEN_STRONG_INLINE Packet8bf F32ToBf16(const Packet8f& a) {
-  Packet8bf r;
 
   __m256i input = _mm256_castps_si256(a);
 
diff --git a/Eigen/src/Core/arch/AVX/TypeCasting.h b/Eigen/src/Core/arch/AVX/TypeCasting.h
index d507fb6..320479b 100644
--- a/Eigen/src/Core/arch/AVX/TypeCasting.h
+++ b/Eigen/src/Core/arch/AVX/TypeCasting.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TYPE_CASTING_AVX_H
 #define EIGEN_TYPE_CASTING_AVX_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AVX512/Complex.h b/Eigen/src/Core/arch/AVX512/Complex.h
index c11b8d2..e1b6ff2 100644
--- a/Eigen/src/Core/arch/AVX512/Complex.h
+++ b/Eigen/src/Core/arch/AVX512/Complex.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_COMPLEX_AVX512_H
 #define EIGEN_COMPLEX_AVX512_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -97,7 +99,9 @@
 
 template<> EIGEN_STRONG_INLINE Packet8cf pset1<Packet8cf>(const std::complex<float>& from)
 {
-  return Packet8cf(_mm512_castpd_ps(pload1<Packet8d>((const double*)(const void*)&from)));
+  const float re = std::real(from);
+  const float im = std::imag(from);
+  return Packet8cf(_mm512_set_ps(im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re));
 }
 
 template<> EIGEN_STRONG_INLINE Packet8cf ploaddup<Packet8cf>(const std::complex<float>* from)
diff --git a/Eigen/src/Core/arch/AVX512/MathFunctions.h b/Eigen/src/Core/arch/AVX512/MathFunctions.h
index 6fd726d..26ab168 100644
--- a/Eigen/src/Core/arch/AVX512/MathFunctions.h
+++ b/Eigen/src/Core/arch/AVX512/MathFunctions.h
@@ -10,6 +10,8 @@
 #ifndef THIRD_PARTY_EIGEN3_EIGEN_SRC_CORE_ARCH_AVX512_MATHFUNCTIONS_H_
 #define THIRD_PARTY_EIGEN3_EIGEN_SRC_CORE_ARCH_AVX512_MATHFUNCTIONS_H_
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AVX512/PacketMath.h b/Eigen/src/Core/arch/AVX512/PacketMath.h
index 0810f66..4f85726 100644
--- a/Eigen/src/Core/arch/AVX512/PacketMath.h
+++ b/Eigen/src/Core/arch/AVX512/PacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PACKET_MATH_AVX512_H
 #define EIGEN_PACKET_MATH_AVX512_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -2202,7 +2204,6 @@
 
 template<> EIGEN_STRONG_INLINE Packet16bf
 ploaddup<Packet16bf>(const bfloat16* from) {
-  Packet16bf r;
   unsigned short a = from[0].value;
   unsigned short b = from[1].value;
   unsigned short c = from[2].value;
@@ -2216,7 +2217,6 @@
 
 template<> EIGEN_STRONG_INLINE Packet16bf
 ploadquad(const bfloat16* from) {
-  Packet16bf r;
   unsigned short a = from[0].value;
   unsigned short b = from[1].value;
   unsigned short c = from[2].value;
@@ -2234,7 +2234,7 @@
 
 #if defined(EIGEN_VECTORIZE_AVX512BF16) && EIGEN_GNUC_AT_LEAST(10, 1)
   // Since GCC 10.1 supports avx512bf16 and C style explicit cast
-  // (C++ static_cast is not supported yet), do converion via intrinsic
+  // (C++ static_cast is not supported yet), do conversion via intrinsic
   // and register path for performance.
   r = (__m256i)(_mm512_cvtneps_pbh(a));
 
diff --git a/Eigen/src/Core/arch/AVX512/TypeCasting.h b/Eigen/src/Core/arch/AVX512/TypeCasting.h
index 3304127..2f299e2 100644
--- a/Eigen/src/Core/arch/AVX512/TypeCasting.h
+++ b/Eigen/src/Core/arch/AVX512/TypeCasting.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TYPE_CASTING_AVX512_H
 #define EIGEN_TYPE_CASTING_AVX512_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AltiVec/Complex.h b/Eigen/src/Core/arch/AltiVec/Complex.h
index b603dff..f730ce8 100644
--- a/Eigen/src/Core/arch/AltiVec/Complex.h
+++ b/Eigen/src/Core/arch/AltiVec/Complex.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_COMPLEX32_ALTIVEC_H
 #define EIGEN_COMPLEX32_ALTIVEC_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AltiVec/MathFunctions.h b/Eigen/src/Core/arch/AltiVec/MathFunctions.h
index 3a7a329..d6e3a00 100644
--- a/Eigen/src/Core/arch/AltiVec/MathFunctions.h
+++ b/Eigen/src/Core/arch/AltiVec/MathFunctions.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_MATH_FUNCTIONS_ALTIVEC_H
 #define EIGEN_MATH_FUNCTIONS_ALTIVEC_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AltiVec/MatrixProduct.h b/Eigen/src/Core/arch/AltiVec/MatrixProduct.h
index 3f79b97..1d67d60 100644
--- a/Eigen/src/Core/arch/AltiVec/MatrixProduct.h
+++ b/Eigen/src/Core/arch/AltiVec/MatrixProduct.h
@@ -43,6 +43,8 @@
  * - Check StorageOrder on dhs_pack (the innermost second loop seems unvectorized when it could). *
  * - Check the possibility of transposing as GETREAL and GETIMAG when needed.                     *
  **************************************************************************************************/
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h b/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h
index 33d5434..d4287cc 100644
--- a/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h
+++ b/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h
@@ -5,6 +5,8 @@
 #define EIGEN_POWER_PREFETCH(p)
 #endif
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h b/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h
index 6540c6f..f1f8352 100644
--- a/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h
+++ b/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h
@@ -19,6 +19,8 @@
 #endif
 #endif
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/AltiVec/PacketMath.h b/Eigen/src/Core/arch/AltiVec/PacketMath.h
index 2a44054..c6b632f 100755
--- a/Eigen/src/Core/arch/AltiVec/PacketMath.h
+++ b/Eigen/src/Core/arch/AltiVec/PacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PACKET_MATH_ALTIVEC_H
 #define EIGEN_PACKET_MATH_ALTIVEC_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/CUDA/Complex.h b/Eigen/src/Core/arch/CUDA/Complex.h
index deb4c86..425e6c2 100644
--- a/Eigen/src/Core/arch/CUDA/Complex.h
+++ b/Eigen/src/Core/arch/CUDA/Complex.h
@@ -11,13 +11,24 @@
 #ifndef EIGEN_COMPLEX_CUDA_H
 #define EIGEN_COMPLEX_CUDA_H
 
-// clang-format off
 // Many std::complex methods such as operator+, operator-, operator* and
 // operator/ are not constexpr. Due to this, GCC and older versions of clang do
 // not treat them as device functions and thus Eigen functors making use of
 // these operators fail to compile. Here, we manually specialize these
 // operators and functors for complex types when building for CUDA to enable
 // their use on-device.
+//
+// NOTES:
+//  - Compound assignment operators +=,-=,*=,/=(Scalar) will not work on device,
+//    since they are already specialized in the standard. Using them will result
+//    in silent kernel failures.
+//  - Compiling with MSVC and using +=,-=,*=,/=(std::complex<Scalar>) will lead
+//    to duplicate definition errors, since these are already specialized in
+//    Visual Studio's <complex> header (contrary to the standard).  This is
+//    preferable to removing such definitions, which will lead to silent kernel
+//    failures.
+//  - Compiling with ICC requires defining _USE_COMPLEX_SPECIALIZATION_ prior
+//    to the first inclusion of <complex>.
 
 #if defined(EIGEN_CUDACC) && defined(EIGEN_GPU_COMPILE_PHASE)
     
@@ -43,6 +54,8 @@
   using Eigen::complex_operator_detail::operator==; \
   using Eigen::complex_operator_detail::operator!=;
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // Specialized std::complex overloads.
diff --git a/Eigen/src/Core/arch/Default/BFloat16.h b/Eigen/src/Core/arch/Default/BFloat16.h
index 1c28f4f..88f5c9b 100644
--- a/Eigen/src/Core/arch/Default/BFloat16.h
+++ b/Eigen/src/Core/arch/Default/BFloat16.h
@@ -16,6 +16,8 @@
 #ifndef EIGEN_BFLOAT16_H
 #define EIGEN_BFLOAT16_H
 
+#include "../../InternalHeaderCheck.h"
+
 #define BF16_PACKET_FUNCTION(PACKET_F, PACKET_BF16, METHOD)         \
   template <>                                                       \
   EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED  \
@@ -251,12 +253,7 @@
     output.value = std::signbit(v) ? 0xFFC0: 0x7FC0;
     return output;
   }
-  const uint16_t* p = reinterpret_cast<const uint16_t*>(&v);
-#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-  output.value = p[0];
-#else
-  output.value = p[1];
-#endif
+  output.value = static_cast<numext::uint16_t>(numext::bit_cast<numext::uint32_t>(v) >> 16);
   return output;
 }
 
@@ -462,14 +459,7 @@
 }
 
 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float bfloat16_to_float(__bfloat16_raw h) {
-    float result = 0;
-    unsigned short* q = reinterpret_cast<unsigned short*>(&result);
-#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-    q[0] = h.value;
-#else
-    q[1] = h.value;
-#endif
-    return result;
+    return numext::bit_cast<float>(static_cast<numext::uint32_t>(h.value) << 16);
 }
 // --- standard functions ---
 
diff --git a/Eigen/src/Core/arch/Default/ConjHelper.h b/Eigen/src/Core/arch/Default/ConjHelper.h
index 53830b5..6b5afe3 100644
--- a/Eigen/src/Core/arch/Default/ConjHelper.h
+++ b/Eigen/src/Core/arch/Default/ConjHelper.h
@@ -38,6 +38,8 @@
     }                                                                   \
   };
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h b/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
index 596d8a5..071acf0 100644
--- a/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
+++ b/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
@@ -16,6 +16,8 @@
 #ifndef EIGEN_ARCH_GENERIC_PACKET_MATH_FUNCTIONS_H
 #define EIGEN_ARCH_GENERIC_PACKET_MATH_FUNCTIONS_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
@@ -570,7 +572,7 @@
   using Eigen::numext::uint64_t;
 
   const double pio2_62 = 3.4061215800865545e-19;    // pi/2 * 2^-62
-  const uint64_t zero_dot_five = uint64_t(1) << 61; // 0.5 in 2.62-bit fixed-point foramt
+  const uint64_t zero_dot_five = uint64_t(1) << 61; // 0.5 in 2.62-bit fixed-point format
 
   // 192 bits of 2/pi for Payne-Hanek reduction
   // Bits are introduced by packet of 8 to enable aligned reads.
diff --git a/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h b/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
index 730cc73..03e3820 100644
--- a/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
+++ b/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ARCH_GENERIC_PACKET_MATH_FUNCTIONS_FWD_H
 #define EIGEN_ARCH_GENERIC_PACKET_MATH_FUNCTIONS_FWD_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/Core/arch/Default/Half.h b/Eigen/src/Core/arch/Default/Half.h
index 9f8e8cc..df82612 100644
--- a/Eigen/src/Core/arch/Default/Half.h
+++ b/Eigen/src/Core/arch/Default/Half.h
@@ -36,6 +36,7 @@
 #ifndef EIGEN_HALF_H
 #define EIGEN_HALF_H
 
+#include "../../InternalHeaderCheck.h"
 #include <sstream>
 
 #if defined(EIGEN_HAS_GPU_FP16) || defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
@@ -261,7 +262,7 @@
 #if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && \
      EIGEN_CUDA_ARCH >= 530) ||                                  \
     (defined(EIGEN_HAS_HIP_FP16) && defined(HIP_DEVICE_COMPILE))
-// Note: We deliberatly do *not* define this to 1 even if we have Arm's native
+// Note: We deliberately do *not* define this to 1 even if we have Arm's native
 // fp16 type since GPU halfs are rather different from native CPU halfs.
 // TODO: Rename to something like EIGEN_HAS_NATIVE_GPU_FP16
 #define EIGEN_HAS_NATIVE_FP16
diff --git a/Eigen/src/Core/arch/Default/TypeCasting.h b/Eigen/src/Core/arch/Default/TypeCasting.h
index fb8183b7..b71cbdf 100644
--- a/Eigen/src/Core/arch/Default/TypeCasting.h
+++ b/Eigen/src/Core/arch/Default/TypeCasting.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_GENERIC_TYPE_CASTING_H
 #define EIGEN_GENERIC_TYPE_CASTING_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/GPU/MathFunctions.h b/Eigen/src/Core/arch/GPU/MathFunctions.h
index d2b3a25..ad61e95 100644
--- a/Eigen/src/Core/arch/GPU/MathFunctions.h
+++ b/Eigen/src/Core/arch/GPU/MathFunctions.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_MATH_FUNCTIONS_GPU_H
 #define EIGEN_MATH_FUNCTIONS_GPU_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/GPU/PacketMath.h b/Eigen/src/Core/arch/GPU/PacketMath.h
index 25c45fd..4c68536 100644
--- a/Eigen/src/Core/arch/GPU/PacketMath.h
+++ b/Eigen/src/Core/arch/GPU/PacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PACKET_MATH_GPU_H
 #define EIGEN_PACKET_MATH_GPU_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/GPU/Tuple.h b/Eigen/src/Core/arch/GPU/Tuple.h
new file mode 100644
index 0000000..d381cd8
--- /dev/null
+++ b/Eigen/src/Core/arch/GPU/Tuple.h
@@ -0,0 +1,302 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2021 The Eigen Team
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_TUPLE_GPU
+#define EIGEN_TUPLE_GPU
+
+#include <type_traits>
+#include <utility>
+
+// This is a replacement of std::tuple that can be used in device code.
+
+namespace Eigen {
+namespace internal {
+namespace tuple_impl {
+
+// Internal tuple implementation.
+template<size_t N, typename... Types>
+class TupleImpl;
+
+// Generic recursive tuple.
+template<size_t N, typename T1, typename... Ts>
+class TupleImpl<N, T1, Ts...> {
+ public:
+  // Tuple may contain Eigen types.
+  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+  
+  // Default constructor, enable if all types are default-constructible.
+  template<typename U1 = T1, typename EnableIf = typename std::enable_if<
+      std::is_default_constructible<U1>::value
+      && reduce_all<std::is_default_constructible<Ts>::value...>::value
+    >::type>
+  EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC
+  TupleImpl() : head_{}, tail_{} {}
+ 
+  // Element constructor.
+  template<typename U1, typename... Us, 
+           // Only enable if...
+           typename EnableIf = typename std::enable_if<
+              // the number of input arguments match, and ...
+              sizeof...(Us) == sizeof...(Ts) && (
+                // this does not look like a copy/move constructor.
+                N > 1 || std::is_convertible<U1, T1>::value)
+           >::type>
+  EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC
+  TupleImpl(U1&& arg1, Us&&... args) 
+    : head_(std::forward<U1>(arg1)), tail_(std::forward<Us>(args)...) {}
+ 
+  // The first stored value. 
+  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+  T1& head() {
+    return head_;
+  }
+  
+  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+  const T1& head() const {
+    return head_;
+  }
+  
+  // The tail values.
+  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+  TupleImpl<N-1, Ts...>& tail() {
+    return tail_;
+  }
+  
+  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+  const TupleImpl<N-1, Ts...>& tail() const {
+    return tail_;
+  }
+  
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  void swap(TupleImpl& other) {
+    using numext::swap;
+    swap(head_, other.head_);
+    swap(tail_, other.tail_);
+  }
+  
+  template<typename... UTypes>
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  TupleImpl& operator=(const TupleImpl<N, UTypes...>& other) {
+    head_ = other.head_;
+    tail_ = other.tail_;
+    return *this;
+  }
+  
+  template<typename... UTypes>
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  TupleImpl& operator=(TupleImpl<N, UTypes...>&& other) {
+    head_ = std::move(other.head_);
+    tail_ = std::move(other.tail_);
+    return *this;
+  }
+  
+ private:
+  // Allow related tuples to reference head_/tail_.
+  template<size_t M, typename... UTypes>
+  friend class TupleImpl;
+ 
+  T1 head_;
+  TupleImpl<N-1, Ts...> tail_;
+};
+
+// Empty tuple specialization.
+template<>
+class TupleImpl<size_t(0)> {};
+
+template<typename TupleType>
+struct is_tuple : std::false_type {};
+
+template<typename... Types>
+struct is_tuple< TupleImpl<sizeof...(Types), Types...> > : std::true_type {};
+
+// Gets an element from a tuple.
+template<size_t Idx, typename T1, typename... Ts>
+struct tuple_get_impl {
+  using TupleType = TupleImpl<sizeof...(Ts) + 1, T1, Ts...>;
+  using ReturnType = typename tuple_get_impl<Idx - 1, Ts...>::ReturnType;
+  
+  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+  ReturnType& run(TupleType& tuple) {
+    return tuple_get_impl<Idx-1, Ts...>::run(tuple.tail());
+  }
+
+  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+  const ReturnType& run(const TupleType& tuple) {
+    return tuple_get_impl<Idx-1, Ts...>::run(tuple.tail());
+  }
+};
+
+// Base case, getting the head element.
+template<typename T1, typename... Ts>
+struct tuple_get_impl<0, T1, Ts...> {
+  using TupleType = TupleImpl<sizeof...(Ts) + 1, T1, Ts...>;
+  using ReturnType = T1;
+
+  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+  T1& run(TupleType& tuple) {
+    return tuple.head();
+  }
+
+  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+  const T1& run(const TupleType& tuple) {
+    return tuple.head();
+  }
+};
+
+// Concatenates N Tuples.
+template<size_t NTuples, typename... Tuples>
+struct tuple_cat_impl;
+
+template<size_t NTuples, size_t N1, typename... Args1, size_t N2, typename... Args2, typename... Tuples>
+struct tuple_cat_impl<NTuples, TupleImpl<N1, Args1...>, TupleImpl<N2, Args2...>, Tuples...> {
+  using TupleType1 = TupleImpl<N1, Args1...>;
+  using TupleType2 = TupleImpl<N2, Args2...>;
+  using MergedTupleType = TupleImpl<N1 + N2, Args1..., Args2...>;
+  
+  using ReturnType = typename tuple_cat_impl<NTuples-1, MergedTupleType, Tuples...>::ReturnType;
+  
+  // Uses the index sequences to extract and merge elements from tuple1 and tuple2,
+  // then recursively calls again.
+  template<typename Tuple1, size_t... I1s, typename Tuple2, size_t... I2s, typename... MoreTuples>
+  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  ReturnType run(Tuple1&& tuple1, index_sequence<I1s...>,
+                 Tuple2&& tuple2, index_sequence<I2s...>,
+                 MoreTuples&&... tuples) {
+    return tuple_cat_impl<NTuples-1, MergedTupleType, Tuples...>::run(
+        MergedTupleType(tuple_get_impl<I1s, Args1...>::run(std::forward<Tuple1>(tuple1))...,
+                        tuple_get_impl<I2s, Args2...>::run(std::forward<Tuple2>(tuple2))...),
+        std::forward<MoreTuples>(tuples)...);
+  }
+  
+  // Concatenates the first two tuples.
+  template<typename Tuple1, typename Tuple2, typename... MoreTuples>
+  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  ReturnType run(Tuple1&& tuple1, Tuple2&& tuple2, MoreTuples&&... tuples) {
+    return run(std::forward<Tuple1>(tuple1), make_index_sequence<N1>{},
+               std::forward<Tuple2>(tuple2), make_index_sequence<N2>{},
+               std::forward<MoreTuples>(tuples)...);
+  }
+};
+
+// Base case with a single tuple.
+template<size_t N, typename... Args>
+struct tuple_cat_impl<1, TupleImpl<N, Args...> > { 
+  using ReturnType = TupleImpl<N, Args...>;
+  
+  template<typename Tuple1>
+  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  ReturnType run(Tuple1&& tuple1) {
+    return tuple1;
+  }
+};
+
+// Special case of no tuples.
+template<>
+struct tuple_cat_impl<0> { 
+  using ReturnType = TupleImpl<0>;
+  static EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  ReturnType run() {return ReturnType{}; }
+};
+
+// For use in make_tuple, unwraps a reference_wrapper.
+template <typename T>
+struct unwrap_reference_wrapper { using type = T; };
+ 
+template <typename T>
+struct unwrap_reference_wrapper<std::reference_wrapper<T> > { using type = T&; };
+
+// For use in make_tuple, decays a type and unwraps a reference_wrapper.
+template <typename T>
+struct unwrap_decay {
+  using type = typename unwrap_reference_wrapper<typename std::decay<T>::type>::type;
+};
+
+/**
+ * Alternative to std::tuple that can be used on device.
+ */
+template<typename... Types>
+using tuple = TupleImpl<sizeof...(Types), Types...>;
+
+/**
+ * Utility for determining a tuple's size.
+ */
+template<typename Tuple>
+struct tuple_size;
+
+template<typename... Types >
+struct tuple_size< tuple<Types...> > : std::integral_constant<size_t, sizeof...(Types)> {};
+
+/**
+ * Gets an element of a tuple.
+ * \tparam Idx index of the element.
+ * \tparam Types ... tuple element types.
+ * \param tuple the tuple.
+ * \return a reference to the desired element.
+ */
+template<size_t Idx, typename... Types>
+EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+const typename tuple_get_impl<Idx, Types...>::ReturnType&
+get(const tuple<Types...>& tuple) {
+  return tuple_get_impl<Idx, Types...>::run(tuple);
+}
+
+template<size_t Idx, typename... Types>
+EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+typename tuple_get_impl<Idx, Types...>::ReturnType&
+get(tuple<Types...>& tuple) {
+  return tuple_get_impl<Idx, Types...>::run(tuple);
+}
+
+/**
+ * Concatenate multiple tuples.
+ * \param tuples ... list of tuples.
+ * \return concatenated tuple.
+ */
+template<typename... Tuples,
+          typename EnableIf = typename std::enable_if<
+            internal::reduce_all<
+              is_tuple<typename std::decay<Tuples>::type>::value...>::value>::type>
+EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+typename tuple_cat_impl<sizeof...(Tuples), typename std::decay<Tuples>::type...>::ReturnType
+tuple_cat(Tuples&&... tuples) {
+  return tuple_cat_impl<sizeof...(Tuples), typename std::decay<Tuples>::type...>::run(std::forward<Tuples>(tuples)...);
+}
+
+/**
+ * Tie arguments together into a tuple.
+ */
+template <typename... Args, typename ReturnType = tuple<Args&...> >
+EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ReturnType tie(Args&... args) EIGEN_NOEXCEPT {
+    return ReturnType{args...};
+}
+
+/**
+ * Create a tuple of l-values with the supplied arguments.
+ */
+template <typename... Args, typename ReturnType = tuple<typename unwrap_decay<Args>::type...> >
+EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ReturnType make_tuple(Args&&... args) {
+  return ReturnType{std::forward<Args>(args)...};
+}
+
+/**
+ * Forward a set of arguments as a tuple.
+ */
+template <typename... Args>
+EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+tuple<Args...> forward_as_tuple(Args&&... args) {
+  return tuple<Args...>(std::forward<Args>(args)...);
+}
+
+}  // namespace tuple_impl
+}  // namespace internal
+}  // namespace Eigen
+
+#endif  // EIGEN_TUPLE_GPU
diff --git a/Eigen/src/Core/arch/GPU/TypeCasting.h b/Eigen/src/Core/arch/GPU/TypeCasting.h
index c8195bb..6e8ba27 100644
--- a/Eigen/src/Core/arch/GPU/TypeCasting.h
+++ b/Eigen/src/Core/arch/GPU/TypeCasting.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TYPE_CASTING_GPU_H
 #define EIGEN_TYPE_CASTING_GPU_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/MSA/Complex.h b/Eigen/src/Core/arch/MSA/Complex.h
index 76e9f7c..b11a9b4 100644
--- a/Eigen/src/Core/arch/MSA/Complex.h
+++ b/Eigen/src/Core/arch/MSA/Complex.h
@@ -15,6 +15,8 @@
 
 #include <iostream>
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/MSA/MathFunctions.h b/Eigen/src/Core/arch/MSA/MathFunctions.h
index f5181b9..bbebde5 100644
--- a/Eigen/src/Core/arch/MSA/MathFunctions.h
+++ b/Eigen/src/Core/arch/MSA/MathFunctions.h
@@ -26,6 +26,8 @@
 #ifndef EIGEN_MATH_FUNCTIONS_MSA_H
 #define EIGEN_MATH_FUNCTIONS_MSA_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/MSA/PacketMath.h b/Eigen/src/Core/arch/MSA/PacketMath.h
index afe8f33..3dc95a1 100644
--- a/Eigen/src/Core/arch/MSA/PacketMath.h
+++ b/Eigen/src/Core/arch/MSA/PacketMath.h
@@ -16,6 +16,8 @@
 #include <iostream>
 #include <string>
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/NEON/Complex.h b/Eigen/src/Core/arch/NEON/Complex.h
index 0f74fe8..fd6b14b 100644
--- a/Eigen/src/Core/arch/NEON/Complex.h
+++ b/Eigen/src/Core/arch/NEON/Complex.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_COMPLEX_NEON_H
 #define EIGEN_COMPLEX_NEON_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h b/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h
index 3481f33..6cd6edd 100644
--- a/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h
+++ b/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h
@@ -1,3 +1,5 @@
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
   
diff --git a/Eigen/src/Core/arch/NEON/MathFunctions.h b/Eigen/src/Core/arch/NEON/MathFunctions.h
index fa6615a..d34882a 100644
--- a/Eigen/src/Core/arch/NEON/MathFunctions.h
+++ b/Eigen/src/Core/arch/NEON/MathFunctions.h
@@ -8,6 +8,8 @@
 #ifndef EIGEN_MATH_FUNCTIONS_NEON_H
 #define EIGEN_MATH_FUNCTIONS_NEON_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/NEON/PacketMath.h b/Eigen/src/Core/arch/NEON/PacketMath.h
index f5fa3fa..382a2c8 100644
--- a/Eigen/src/Core/arch/NEON/PacketMath.h
+++ b/Eigen/src/Core/arch/NEON/PacketMath.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_PACKET_MATH_NEON_H
 #define EIGEN_PACKET_MATH_NEON_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -3459,7 +3461,7 @@
 
 EIGEN_STRONG_INLINE Packet4bf F32ToBf16(const Packet4f& p)
 {
-  // See the scalar implemention in BFloat16.h for a comprehensible explanation
+  // See the scalar implementation in BFloat16.h for a comprehensible explanation
   // of this fast rounding algorithm
   Packet4ui input = reinterpret_cast<Packet4ui>(p);
 
diff --git a/Eigen/src/Core/arch/NEON/TypeCasting.h b/Eigen/src/Core/arch/NEON/TypeCasting.h
index 54f9733..e5ddab6 100644
--- a/Eigen/src/Core/arch/NEON/TypeCasting.h
+++ b/Eigen/src/Core/arch/NEON/TypeCasting.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_TYPE_CASTING_NEON_H
 #define EIGEN_TYPE_CASTING_NEON_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/SSE/Complex.h b/Eigen/src/Core/arch/SSE/Complex.h
index 08abd84..ccee04b 100644
--- a/Eigen/src/Core/arch/SSE/Complex.h
+++ b/Eigen/src/Core/arch/SSE/Complex.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_COMPLEX_SSE_H
 #define EIGEN_COMPLEX_SSE_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -106,14 +108,9 @@
 
 template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>&  from)
 {
-  Packet2cf res;
-#ifdef EIGEN_VECTORIZE_SSE3
-  res.v = _mm_castpd_ps(_mm_loaddup_pd(reinterpret_cast<double const*>(&from)));
-#else
-  res.v = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<double const*>(&from)));
-  res.v = _mm_movelh_ps(res.v, res.v);
-#endif
-  return res;
+  const float re = std::real(from);
+  const float im = std::imag(from);
+  return Packet2cf(_mm_set_ps(im, re, im, re));
 }
 
 template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) { return pset1<Packet2cf>(*from); }
diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h
index 8736d0d..4bdb9af 100644
--- a/Eigen/src/Core/arch/SSE/MathFunctions.h
+++ b/Eigen/src/Core/arch/SSE/MathFunctions.h
@@ -15,6 +15,8 @@
 #ifndef EIGEN_MATH_FUNCTIONS_SSE_H
 #define EIGEN_MATH_FUNCTIONS_SSE_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h
index d658f65..3d91502 100755
--- a/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PACKET_MATH_SSE_H
 #define EIGEN_PACKET_MATH_SSE_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -620,7 +622,7 @@
 #ifdef EIGEN_VECTORIZE_SSE4_1
 template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(const Packet4f& a)
 {
-  // Unfortunatly _mm_round_ps doesn't have a rounding mode to implement numext::round.
+  // Unfortunately _mm_round_ps doesn't have a rounding mode to implement numext::round.
   const Packet4f mask = pset1frombits<Packet4f>(0x80000000u);
   const Packet4f prev0dot5 = pset1frombits<Packet4f>(0x3EFFFFFFu);
   return _mm_round_ps(padd(por(pand(a, mask), prev0dot5), a), _MM_FROUND_TO_ZERO);
diff --git a/Eigen/src/Core/arch/SSE/TypeCasting.h b/Eigen/src/Core/arch/SSE/TypeCasting.h
index d2a0037..c21d1ac 100644
--- a/Eigen/src/Core/arch/SSE/TypeCasting.h
+++ b/Eigen/src/Core/arch/SSE/TypeCasting.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TYPE_CASTING_SSE_H
 #define EIGEN_TYPE_CASTING_SSE_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/SVE/MathFunctions.h b/Eigen/src/Core/arch/SVE/MathFunctions.h
index b139ea2..50b06bc 100644
--- a/Eigen/src/Core/arch/SVE/MathFunctions.h
+++ b/Eigen/src/Core/arch/SVE/MathFunctions.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_MATH_FUNCTIONS_SVE_H
 #define EIGEN_MATH_FUNCTIONS_SVE_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/Core/arch/SVE/PacketMath.h b/Eigen/src/Core/arch/SVE/PacketMath.h
index 9060b37..98c0b77 100644
--- a/Eigen/src/Core/arch/SVE/PacketMath.h
+++ b/Eigen/src/Core/arch/SVE/PacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PACKET_MATH_SVE_H
 #define EIGEN_PACKET_MATH_SVE_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen
 {
 namespace internal
diff --git a/Eigen/src/Core/arch/SVE/TypeCasting.h b/Eigen/src/Core/arch/SVE/TypeCasting.h
index 7ba5d9c..1067a41 100644
--- a/Eigen/src/Core/arch/SVE/TypeCasting.h
+++ b/Eigen/src/Core/arch/SVE/TypeCasting.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TYPE_CASTING_SVE_H
 #define EIGEN_TYPE_CASTING_SVE_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/Core/arch/SYCL/InteropHeaders.h b/Eigen/src/Core/arch/SYCL/InteropHeaders.h
index 10856ff..57bfb69 100644
--- a/Eigen/src/Core/arch/SYCL/InteropHeaders.h
+++ b/Eigen/src/Core/arch/SYCL/InteropHeaders.h
@@ -21,6 +21,8 @@
 #ifndef EIGEN_INTEROP_HEADERS_SYCL_H
 #define EIGEN_INTEROP_HEADERS_SYCL_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 #if !defined(EIGEN_DONT_VECTORIZE_SYCL)
diff --git a/Eigen/src/Core/arch/SYCL/MathFunctions.h b/Eigen/src/Core/arch/SYCL/MathFunctions.h
index 2ab0f2a..9eb46bb 100644
--- a/Eigen/src/Core/arch/SYCL/MathFunctions.h
+++ b/Eigen/src/Core/arch/SYCL/MathFunctions.h
@@ -20,6 +20,8 @@
 
 #ifndef EIGEN_MATH_FUNCTIONS_SYCL_H
 #define EIGEN_MATH_FUNCTIONS_SYCL_H
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/SYCL/PacketMath.h b/Eigen/src/Core/arch/SYCL/PacketMath.h
index 87badc0..92accc8 100644
--- a/Eigen/src/Core/arch/SYCL/PacketMath.h
+++ b/Eigen/src/Core/arch/SYCL/PacketMath.h
@@ -21,6 +21,8 @@
 #ifndef EIGEN_PACKET_MATH_SYCL_H
 #define EIGEN_PACKET_MATH_SYCL_H
 #include <type_traits>
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h b/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h
index f81e59d..2b96587 100644
--- a/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h
+++ b/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h
@@ -33,6 +33,8 @@
 #include <set>
 #include <unordered_map>
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace TensorSycl {
 namespace internal {
@@ -166,7 +168,7 @@
   /**
    * Obtain the insertion point in the pointer map for
    * a pointer of the given size.
-   * \param requiredSize Size attemted to reclaim
+   * \param requiredSize Size attempted to reclaim
    */
   typename pointerMap_t::iterator get_insertion_point(size_t requiredSize) {
     typename pointerMap_t::iterator retVal;
diff --git a/Eigen/src/Core/arch/SYCL/TypeCasting.h b/Eigen/src/Core/arch/SYCL/TypeCasting.h
index 9208ab2..613e823 100644
--- a/Eigen/src/Core/arch/SYCL/TypeCasting.h
+++ b/Eigen/src/Core/arch/SYCL/TypeCasting.h
@@ -21,6 +21,8 @@
 #ifndef EIGEN_TYPE_CASTING_SYCL_H
 #define EIGEN_TYPE_CASTING_SYCL_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/ZVector/Complex.h b/Eigen/src/Core/arch/ZVector/Complex.h
index a81ec24..264c266 100644
--- a/Eigen/src/Core/arch/ZVector/Complex.h
+++ b/Eigen/src/Core/arch/ZVector/Complex.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_COMPLEX32_ALTIVEC_H
 #define EIGEN_COMPLEX32_ALTIVEC_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/ZVector/MathFunctions.h b/Eigen/src/Core/arch/ZVector/MathFunctions.h
index 1635e12..c86e185 100644
--- a/Eigen/src/Core/arch/ZVector/MathFunctions.h
+++ b/Eigen/src/Core/arch/ZVector/MathFunctions.h
@@ -16,6 +16,8 @@
 #ifndef EIGEN_MATH_FUNCTIONS_ALTIVEC_H
 #define EIGEN_MATH_FUNCTIONS_ALTIVEC_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/arch/ZVector/PacketMath.h b/Eigen/src/Core/arch/ZVector/PacketMath.h
index 1f55a90..890578f 100755
--- a/Eigen/src/Core/arch/ZVector/PacketMath.h
+++ b/Eigen/src/Core/arch/ZVector/PacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PACKET_MATH_ZVECTOR_H
 #define EIGEN_PACKET_MATH_ZVECTOR_H
 
+#include "../../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/functors/AssignmentFunctors.h b/Eigen/src/Core/functors/AssignmentFunctors.h
index bf64ef4..6bf755f 100644
--- a/Eigen/src/Core/functors/AssignmentFunctors.h
+++ b/Eigen/src/Core/functors/AssignmentFunctors.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ASSIGNMENT_FUNCTORS_H
 #define EIGEN_ASSIGNMENT_FUNCTORS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/functors/BinaryFunctors.h b/Eigen/src/Core/functors/BinaryFunctors.h
index fc87815..88e2e8a 100644
--- a/Eigen/src/Core/functors/BinaryFunctors.h
+++ b/Eigen/src/Core/functors/BinaryFunctors.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_BINARY_FUNCTORS_H
 #define EIGEN_BINARY_FUNCTORS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -356,7 +358,7 @@
     PacketAccess = (!NumTraits<Scalar>::IsComplex && !NumTraits<Scalar>::IsInteger &&
                     packet_traits<Scalar>::HasExp && packet_traits<Scalar>::HasLog &&
                     packet_traits<Scalar>::HasRound && packet_traits<Scalar>::HasCmp &&
-                    // Temporarly disable packet access for half/bfloat16 until
+                    // Temporarily disable packet access for half/bfloat16 until
                     // accuracy is improved.
                     !is_same<Scalar, half>::value && !is_same<Scalar, bfloat16>::value
                     )
diff --git a/Eigen/src/Core/functors/NullaryFunctors.h b/Eigen/src/Core/functors/NullaryFunctors.h
index 192f225..8e43266 100644
--- a/Eigen/src/Core/functors/NullaryFunctors.h
+++ b/Eigen/src/Core/functors/NullaryFunctors.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_NULLARY_FUNCTORS_H
 #define EIGEN_NULLARY_FUNCTORS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/functors/StlFunctors.h b/Eigen/src/Core/functors/StlFunctors.h
index 4570c9b..dbb3854 100644
--- a/Eigen/src/Core/functors/StlFunctors.h
+++ b/Eigen/src/Core/functors/StlFunctors.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_STL_FUNCTORS_H
 #define EIGEN_STL_FUNCTORS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // Portable replacements for certain functors.
diff --git a/Eigen/src/Core/functors/TernaryFunctors.h b/Eigen/src/Core/functors/TernaryFunctors.h
index b254e96..41c0d5f 100644
--- a/Eigen/src/Core/functors/TernaryFunctors.h
+++ b/Eigen/src/Core/functors/TernaryFunctors.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TERNARY_FUNCTORS_H
 #define EIGEN_TERNARY_FUNCTORS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h
index 16136d1..044f7dd 100644
--- a/Eigen/src/Core/functors/UnaryFunctors.h
+++ b/Eigen/src/Core/functors/UnaryFunctors.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_UNARY_FUNCTORS_H
 #define EIGEN_UNARY_FUNCTORS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -1035,7 +1037,7 @@
   *  Uses just a 9/10-degree rational interpolant which
   *  interpolates 1/(1+exp(-x)) - 0.5 up to a couple of ulps in the range
   *  [-9, 18]. Below -9 we use the more accurate approximation
-  *  1/(1+exp(-x)) ~= exp(x), and above 18 the logistic function is 1 withing
+  *  1/(1+exp(-x)) ~= exp(x), and above 18 the logistic function is 1 within
   *  one ulp. The shifted logistic is interpolated because it was easier to
   *  make the fit converge.
   *
diff --git a/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/Eigen/src/Core/products/GeneralBlockPanelKernel.h
index ed26b9a..89e999b 100644
--- a/Eigen/src/Core/products/GeneralBlockPanelKernel.h
+++ b/Eigen/src/Core/products/GeneralBlockPanelKernel.h
@@ -11,6 +11,8 @@
 #define EIGEN_GENERAL_BLOCK_PANEL_H
 
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -795,7 +797,7 @@
   typedef typename conditional<Vectorizable,ScalarPacket,Scalar>::type ResPacket;
   typedef typename conditional<Vectorizable,DoublePacketType,Scalar>::type AccPacket;
 
-  // this actualy holds 8 packets!
+  // this actually holds 8 packets!
   typedef QuadPacket<RhsPacket> RhsPacketx4;
   
   EIGEN_STRONG_INLINE void initAcc(Scalar& p) { p = Scalar(0); }
diff --git a/Eigen/src/Core/products/GeneralMatrixMatrix.h b/Eigen/src/Core/products/GeneralMatrixMatrix.h
index 62a6aaa..72e094e 100644
--- a/Eigen/src/Core/products/GeneralMatrixMatrix.h
+++ b/Eigen/src/Core/products/GeneralMatrixMatrix.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_GENERAL_MATRIX_MATRIX_H
 #define EIGEN_GENERAL_MATRIX_MATRIX_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
index 6ba0d9b..fc6f838 100644
--- a/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+++ b/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H
 #define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjLhs, bool ConjRhs>
diff --git a/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h b/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
index 9a650ec..45ad5da 100644
--- a/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
+++ b/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_BLAS_H
 #define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_BLAS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h b/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h
index 71abf40..490fe67 100644
--- a/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h
+++ b/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_GENERAL_MATRIX_MATRIX_BLAS_H
 #define EIGEN_GENERAL_MATRIX_MATRIX_BLAS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/GeneralMatrixVector.h b/Eigen/src/Core/products/GeneralMatrixVector.h
index 0fa5736..b775dbe 100644
--- a/Eigen/src/Core/products/GeneralMatrixVector.h
+++ b/Eigen/src/Core/products/GeneralMatrixVector.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_GENERAL_MATRIX_VECTOR_H
 #define EIGEN_GENERAL_MATRIX_VECTOR_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -64,7 +66,7 @@
 
 /* Optimized col-major matrix * vector product:
  * This algorithm processes the matrix per vertical panels,
- * which are then processed horizontaly per chunck of 8*PacketSize x 1 vertical segments.
+ * which are then processed horizontally per chunck of 8*PacketSize x 1 vertical segments.
  *
  * Mixing type logic: C += alpha * A * B
  *  |  A  |  B  |alpha| comments
diff --git a/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h b/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h
index 6e36c2b..f77e2e4 100644
--- a/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h
+++ b/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_GENERAL_MATRIX_VECTOR_BLAS_H
 #define EIGEN_GENERAL_MATRIX_VECTOR_BLAS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/Parallelizer.h b/Eigen/src/Core/products/Parallelizer.h
index 8f91879..c046ba3 100644
--- a/Eigen/src/Core/products/Parallelizer.h
+++ b/Eigen/src/Core/products/Parallelizer.h
@@ -14,6 +14,8 @@
 #include <atomic>
 #endif
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
index 33ecf10..504fa0c 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_H
 #define EIGEN_SELFADJOINT_MATRIX_MATRIX_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h b/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h
index 61396db..0e371da 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_BLAS_H
 #define EIGEN_SELFADJOINT_MATRIX_MATRIX_BLAS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/SelfadjointMatrixVector.h b/Eigen/src/Core/products/SelfadjointMatrixVector.h
index d38fd72..3176398 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixVector.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixVector.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_H
 #define EIGEN_SELFADJOINT_MATRIX_VECTOR_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h b/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h
index 1238345..99a8ccd 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_BLAS_H
 #define EIGEN_SELFADJOINT_MATRIX_VECTOR_BLAS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/SelfadjointProduct.h b/Eigen/src/Core/products/SelfadjointProduct.h
index a21be80..629ce1d 100644
--- a/Eigen/src/Core/products/SelfadjointProduct.h
+++ b/Eigen/src/Core/products/SelfadjointProduct.h
@@ -16,6 +16,8 @@
 * It corresponds to the level 3 SYRK and level 2 SYR Blas routines.
 **********************************************************************/
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 
diff --git a/Eigen/src/Core/products/SelfadjointRank2Update.h b/Eigen/src/Core/products/SelfadjointRank2Update.h
index f752a0b..3153009 100644
--- a/Eigen/src/Core/products/SelfadjointRank2Update.h
+++ b/Eigen/src/Core/products/SelfadjointRank2Update.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SELFADJOINTRANK2UPTADE_H
 #define EIGEN_SELFADJOINTRANK2UPTADE_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/TriangularMatrixMatrix.h b/Eigen/src/Core/products/TriangularMatrixMatrix.h
index f0c6050..60d4b05 100644
--- a/Eigen/src/Core/products/TriangularMatrixMatrix.h
+++ b/Eigen/src/Core/products/TriangularMatrixMatrix.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_H
 #define EIGEN_TRIANGULAR_MATRIX_MATRIX_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h b/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h
index a98d12e..1eb57d3 100644
--- a/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h
+++ b/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_BLAS_H
 #define EIGEN_TRIANGULAR_MATRIX_MATRIX_BLAS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/TriangularMatrixVector.h b/Eigen/src/Core/products/TriangularMatrixVector.h
index 76bfa15..754345f 100644
--- a/Eigen/src/Core/products/TriangularMatrixVector.h
+++ b/Eigen/src/Core/products/TriangularMatrixVector.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TRIANGULARMATRIXVECTOR_H
 #define EIGEN_TRIANGULARMATRIXVECTOR_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h b/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h
index 3d47a2b..7a4d59e 100644
--- a/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h
+++ b/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_TRIANGULAR_MATRIX_VECTOR_BLAS_H
 #define EIGEN_TRIANGULAR_MATRIX_VECTOR_BLAS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/TriangularSolverMatrix.h b/Eigen/src/Core/products/TriangularSolverMatrix.h
index 6d879ba..0abc468 100644
--- a/Eigen/src/Core/products/TriangularSolverMatrix.h
+++ b/Eigen/src/Core/products/TriangularSolverMatrix.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_H
 #define EIGEN_TRIANGULAR_SOLVER_MATRIX_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h b/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h
index 621194c..2b63388 100644
--- a/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h
+++ b/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_BLAS_H
 #define EIGEN_TRIANGULAR_SOLVER_MATRIX_BLAS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/products/TriangularSolverVector.h b/Eigen/src/Core/products/TriangularSolverVector.h
index 6473170..c1c9e4c 100644
--- a/Eigen/src/Core/products/TriangularSolverVector.h
+++ b/Eigen/src/Core/products/TriangularSolverVector.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TRIANGULAR_SOLVER_VECTOR_H
 #define EIGEN_TRIANGULAR_SOLVER_VECTOR_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h
index 5bb86e5..2268593 100755
--- a/Eigen/src/Core/util/BlasUtil.h
+++ b/Eigen/src/Core/util/BlasUtil.h
@@ -13,6 +13,8 @@
 // This file contains many lightweight helper classes used to
 // implement and control fast level 2 and level 3 BLAS-like routines.
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/util/ConfigureVectorization.h b/Eigen/src/Core/util/ConfigureVectorization.h
index af4e696..3745e47 100644
--- a/Eigen/src/Core/util/ConfigureVectorization.h
+++ b/Eigen/src/Core/util/ConfigureVectorization.h
@@ -472,6 +472,8 @@
 
 
 /** \brief Namespace containing all symbols from the %Eigen library. */
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 inline static const char *SimdInstructionSetsInUse(void) {
diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h
index b93f689..72fe330 100644
--- a/Eigen/src/Core/util/Constants.h
+++ b/Eigen/src/Core/util/Constants.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_CONSTANTS_H
 #define EIGEN_CONSTANTS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is
diff --git a/Eigen/src/Core/util/DisableStupidWarnings.h b/Eigen/src/Core/util/DisableStupidWarnings.h
index fa33689..848aa68 100755
--- a/Eigen/src/Core/util/DisableStupidWarnings.h
+++ b/Eigen/src/Core/util/DisableStupidWarnings.h
@@ -94,6 +94,19 @@
   #pragma diag_suppress 2735
   #pragma diag_suppress 2737
   #pragma diag_suppress 2739
+  #pragma diag_suppress 2885
+  #pragma diag_suppress 2888
+  #pragma diag_suppress 2976
+  #pragma diag_suppress 2979
+  #pragma diag_suppress 20011
+  #pragma diag_suppress 20014
+  // Disable the "// __device__ annotation is ignored on a function(...) that is
+  //              explicitly defaulted on its first declaration" message.
+  // The __device__ annotation seems to actually be needed in some cases,
+  // otherwise resulting in kernel runtime errors.
+  #pragma diag_suppress 2886
+  #pragma diag_suppress 2977
+  #pragma diag_suppress 20012
 #endif
 
 #else
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index 90db26c..6b0ac50 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_FORWARDDECLARATIONS_H
 #define EIGEN_FORWARDDECLARATIONS_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/Core/util/IndexedViewHelper.h b/Eigen/src/Core/util/IndexedViewHelper.h
index f85de30..3e5fc09 100644
--- a/Eigen/src/Core/util/IndexedViewHelper.h
+++ b/Eigen/src/Core/util/IndexedViewHelper.h
@@ -11,11 +11,17 @@
 #ifndef EIGEN_INDEXED_VIEW_HELPER_H
 #define EIGEN_INDEXED_VIEW_HELPER_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
 struct symbolic_last_tag {};
-}
+}  // namespace internal
+
+namespace placeholders {
+
+typedef symbolic::SymbolExpr<internal::symbolic_last_tag> last_t;
 
 /** \var last
   * \ingroup Core_Module
@@ -28,38 +34,20 @@
   * A typical usage example would be:
   * \code
   * using namespace Eigen;
-  * using Eigen::last;
+  * using Eigen::placeholders::last;
   * VectorXd v(n);
   * v(seq(2,last-2)).setOnes();
   * \endcode
   *
   * \sa end
   */
-static const symbolic::SymbolExpr<internal::symbolic_last_tag> last; // PLEASE use Eigen::last   instead of Eigen::placeholders::last
+static const last_t last;
 
-/** \var lastp1
-  * \ingroup Core_Module
-  *
-  * Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically
-  * reference the last+1 element/row/columns of the underlying vector or matrix once
-  * passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
-  *
-  * This symbolic placeholder supports standard arithmetic operations.
-  * It is essentially an alias to last+fix<1>.
-  *
-  * \sa last
-  */
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-static const auto lastp1 = last+fix<1>;
-#else
-// Using a FixedExpr<1> expression is important here to make sure the compiler
-// can fully optimize the computation starting indices with zero overhead.
-static const symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > lastp1(last+fix<1>());
-#endif
+}  // namespace placeholders
 
 namespace internal {
 
- // Replace symbolic last/end "keywords" by their true runtime value
+// Replace symbolic last/end "keywords" by their true runtime value
 inline Index eval_expr_given_size(Index x, Index /* size */)   { return x; }
 
 template<int N>
@@ -68,7 +56,7 @@
 template<typename Derived>
 Index eval_expr_given_size(const symbolic::BaseExpr<Derived> &x, Index size)
 {
-  return x.derived().eval(last=size-1);
+  return x.derived().eval(Eigen::placeholders::last=size-1);
 }
 
 // Extract increment/step at compile time
@@ -163,23 +151,44 @@
 
 } // end namespace internal
 
+namespace placeholders {
+
+typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > lastp1_t;
+typedef Eigen::internal::all_t all_t;
+
+/** \var lastp1
+  * \ingroup Core_Module
+  *
+  * Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically
+  * reference the last+1 element/row/columns of the underlying vector or matrix once
+  * passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
+  *
+  * This symbolic placeholder supports standard arithmetic operations.
+  * It is essentially an alias to last+fix<1>.
+  *
+  * \sa last
+  */
+#ifdef EIGEN_PARSED_BY_DOXYGEN
+static const auto lastp1 = last+fix<1>;
+#else
+// Using a FixedExpr<1> expression is important here to make sure the compiler
+// can fully optimize the computation starting indices with zero overhead.
+static const lastp1_t lastp1(last+fix<1>());
+#endif
+
+/** \var end
+  * \ingroup Core_Module
+  * \sa lastp1
+  */
+static const lastp1_t end = lastp1;
 
 /** \var all
   * \ingroup Core_Module
   * Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or columns
   */
-static const Eigen::internal::all_t all; // PLEASE use Eigen::all instead of Eigen::placeholders::all
+static const Eigen::internal::all_t all;
 
-
-namespace placeholders {
-  typedef symbolic::SymbolExpr<internal::symbolic_last_tag> last_t;
-  typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > end_t;
-  typedef Eigen::internal::all_t all_t;
-
-  EIGEN_DEPRECATED static const all_t  all  = Eigen::all;    // PLEASE use Eigen::all    instead of Eigen::placeholders::all
-  EIGEN_DEPRECATED static const last_t last = Eigen::last;   // PLEASE use Eigen::last   instead of Eigen::placeholders::last
-  EIGEN_DEPRECATED static const end_t  end  = Eigen::lastp1; // PLEASE use Eigen::lastp1 instead of Eigen::placeholders::end
-}
+} // namespace placeholders
 
 } // end namespace Eigen
 
diff --git a/Eigen/src/Core/util/IntegralConstant.h b/Eigen/src/Core/util/IntegralConstant.h
index e0092f6..ddcd370 100644
--- a/Eigen/src/Core/util/IntegralConstant.h
+++ b/Eigen/src/Core/util/IntegralConstant.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_INTEGRAL_CONSTANT_H
 #define EIGEN_INTEGRAL_CONSTANT_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/util/MKL_support.h b/Eigen/src/Core/util/MKL_support.h
index 17963fa..9cf5f6f 100755
--- a/Eigen/src/Core/util/MKL_support.h
+++ b/Eigen/src/Core/util/MKL_support.h
@@ -120,6 +120,8 @@
 #include "../../misc/blas.h"
 #endif
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 typedef std::complex<double> dcomplex;
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index ff3ed17..439c8be 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_MACROS_H
 #define EIGEN_MACROS_H
 
+#include "../InternalHeaderCheck.h"
+
 //------------------------------------------------------------------------------------------
 // Eigen version and basic defaults
 //------------------------------------------------------------------------------------------
@@ -626,7 +628,7 @@
 #define EIGEN_CPLUSPLUS 0
 #endif
 
-// The macro EIGEN_COMP_CXXVER defines the c++ verson expected by the compiler.
+// The macro EIGEN_COMP_CXXVER defines the c++ version expected by the compiler.
 // For instance, if compiling with gcc and -std=c++17, then EIGEN_COMP_CXXVER
 // is defined to 17.
 #if EIGEN_CPLUSPLUS > 201703L
@@ -651,7 +653,7 @@
 
 
 // The macros EIGEN_HAS_CXX?? defines a rough estimate of available c++ features
-// but in practice we should not rely on them but rather on the availabilty of
+// but in practice we should not rely on them but rather on the availability of
 // individual features as defined later.
 // This is why there is no EIGEN_HAS_CXX17.
 // FIXME: get rid of EIGEN_HAS_CXX14 and maybe even EIGEN_HAS_CXX11.
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 875318c..4ed98d5 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -59,6 +59,8 @@
 
 #endif
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h
index 81ae2a3..26a6ea4 100755
--- a/Eigen/src/Core/util/Meta.h
+++ b/Eigen/src/Core/util/Meta.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_META_H
 #define EIGEN_META_H
 
+#include "../InternalHeaderCheck.h"
+
 #if defined(EIGEN_GPU_COMPILE_PHASE)
 
  #include <cfloat>
@@ -31,6 +33,7 @@
 // Define portable (u)int{32,64} types
 #if EIGEN_HAS_CXX11 || EIGEN_ICC_NEEDS_CSTDINT
 #include <cstdint>
+
 namespace Eigen {
 namespace numext {
 typedef std::uint8_t  uint8_t;
@@ -47,6 +50,7 @@
 // Without c++11, all compilers able to compile Eigen also
 // provide the C99 stdint.h header file.
 #include <stdint.h>
+
 namespace Eigen {
 namespace numext {
 typedef ::uint8_t  uint8_t;
@@ -648,6 +652,60 @@
 };
 #endif
 
+// C++14 integer/index_sequence.
+#if defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304L && EIGEN_MAX_CPP_VER >= 14
+
+using std::integer_sequence;
+using std::make_integer_sequence;
+
+using std::index_sequence;
+using std::make_index_sequence;
+
+#else 
+
+template <typename T, T... Ints>
+struct integer_sequence {
+  static EIGEN_CONSTEXPR size_t size() EIGEN_NOEXCEPT { return sizeof...(Ints); }
+};
+
+template <typename T, typename Sequence, T N>
+struct append_integer;
+
+template<typename T, T... Ints, T N>
+struct append_integer<T, integer_sequence<T, Ints...>, N> {
+  using type = integer_sequence<T, Ints..., N>;
+};
+
+template<typename T, size_t N>
+struct generate_integer_sequence {
+  using type = typename append_integer<T, typename generate_integer_sequence<T, N-1>::type, N-1>::type;
+};
+
+template<typename T>
+struct generate_integer_sequence<T, 0> {
+  using type = integer_sequence<T>;
+};
+
+template <typename T, size_t N>
+using make_integer_sequence = typename generate_integer_sequence<T, N>::type;
+
+template<size_t... Ints>
+using index_sequence = integer_sequence<size_t, Ints...>;
+
+template<size_t N>
+using make_index_sequence = make_integer_sequence<size_t, N>;
+
+#endif
+
+// Reduces a sequence of bools to true if all are true, false otherwise.
+template<bool... values>
+using reduce_all = std::is_same<integer_sequence<bool, values..., true>, integer_sequence<bool, true, values...> >;
+
+// Reduces a sequence of bools to true if any are true, false if all false.
+template<bool... values>
+using reduce_any = std::integral_constant<bool,
+    !std::is_same<integer_sequence<bool, values..., false>, integer_sequence<bool, false, values...> >::value>;
+
 struct meta_yes { char a[1]; };
 struct meta_no  { char a[2]; };
 
diff --git a/Eigen/src/Core/util/ReenableStupidWarnings.h b/Eigen/src/Core/util/ReenableStupidWarnings.h
index 1ce6fd1..9dad396 100644
--- a/Eigen/src/Core/util/ReenableStupidWarnings.h
+++ b/Eigen/src/Core/util/ReenableStupidWarnings.h
@@ -1,5 +1,5 @@
 #ifdef EIGEN_WARNINGS_DISABLED_2
-// "DisableStupidWarnings.h" was included twice recursively: Do not reenable warnings yet!
+// "DisableStupidWarnings.h" was included twice recursively: Do not re-enable warnings yet!
 #  undef EIGEN_WARNINGS_DISABLED_2
 
 #elif defined(EIGEN_WARNINGS_DISABLED)
@@ -17,7 +17,7 @@
   #endif
 
   #if defined __NVCC__
-//    Don't reenable the diagnostic messages, as it turns out these messages need
+//    Don't re-enable the diagnostic messages, as it turns out these messages need
 //    to be disabled at the point of the template instantiation (i.e the user code)
 //    otherwise they'll be triggered by nvcc.
 //    #pragma diag_default code_is_unreachable
diff --git a/Eigen/src/Core/util/ReshapedHelper.h b/Eigen/src/Core/util/ReshapedHelper.h
index 4124321..6d949eb 100644
--- a/Eigen/src/Core/util/ReshapedHelper.h
+++ b/Eigen/src/Core/util/ReshapedHelper.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_RESHAPED_HELPER_H
 #define EIGEN_RESHAPED_HELPER_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 enum AutoSize_t   { AutoSize };
diff --git a/Eigen/src/Core/util/Serializer.h b/Eigen/src/Core/util/Serializer.h
new file mode 100644
index 0000000..7ec5eed
--- /dev/null
+++ b/Eigen/src/Core/util/Serializer.h
@@ -0,0 +1,207 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2021 The Eigen Team
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SERIALIZER_H
+#define EIGEN_SERIALIZER_H
+
+#include <type_traits>
+
+// The Serializer class encodes data into a memory buffer so it can be later
+// reconstructed. This is mainly used to send objects back-and-forth between
+// the CPU and GPU.
+
+namespace Eigen {
+
+/**
+ * Serializes an object to a memory buffer.
+ * 
+ * Useful for transferring data (e.g. back-and-forth to a device).
+ */
+template<typename T, typename EnableIf = void>
+class Serializer;
+
+// Specialization for POD types.
+template<typename T>
+class Serializer<T, typename std::enable_if<
+                      std::is_trivial<T>::value 
+                      && std::is_standard_layout<T>::value>::type > {
+ public:
+ 
+  /**
+   * Determines the required size of the serialization buffer for a value.
+   * 
+   * \param value the value to serialize.
+   * \return the required size.
+   */
+  EIGEN_DEVICE_FUNC size_t size(const T& value) const {
+    return sizeof(value);
+  }
+  
+  /**
+   * Serializes a value to a byte buffer.
+   * \param dest the destination buffer.
+   * \param T the value to serialize.
+   * \return the next memory address past the end of the serialized data.
+   */
+  EIGEN_DEVICE_FUNC uint8_t* serialize(uint8_t* dest, const T& value) {
+    EIGEN_USING_STD(memcpy)
+    memcpy(dest, &value, sizeof(value));
+    return dest + sizeof(value);
+  }
+  
+  /**
+   * Deserializes a value from a byte buffer.
+   * \param src the source buffer.
+   * \param value the value to populate.
+   * \return the next unprocessed memory address.
+   */
+  EIGEN_DEVICE_FUNC uint8_t* deserialize(uint8_t* src, T& value) const {
+    EIGEN_USING_STD(memcpy)
+    memcpy(&value, src, sizeof(value));
+    return src + sizeof(value);
+  }
+};
+
+// Specialization for DenseBase.
+// Serializes [rows, cols, data...].
+template<typename Derived>
+class Serializer<DenseBase<Derived>, void> {
+ public:
+  typedef typename Derived::Scalar Scalar;
+  
+  struct Header {
+    typename Derived::Index rows;
+    typename Derived::Index cols;
+  };
+  
+  EIGEN_DEVICE_FUNC size_t size(const Derived& value) const {
+    return sizeof(Header) + sizeof(Scalar) * value.size();
+  }
+  
+  EIGEN_DEVICE_FUNC uint8_t* serialize(uint8_t* dest, const Derived& value) {
+    const size_t header_bytes = sizeof(Header);
+    const size_t data_bytes = sizeof(Scalar) * value.size();
+    Header header = {value.rows(), value.cols()};
+    EIGEN_USING_STD(memcpy)
+    memcpy(dest, &header, header_bytes);
+    dest += header_bytes;
+    memcpy(dest, value.data(), data_bytes);
+    return dest + data_bytes;
+  }
+  
+  EIGEN_DEVICE_FUNC uint8_t* deserialize(uint8_t* src, Derived& value) const {
+    const size_t header_bytes = sizeof(Header);
+    Header header;
+    EIGEN_USING_STD(memcpy)
+    memcpy(&header, src, header_bytes);
+    src += header_bytes;
+    value.resize(header.rows, header.cols);
+    const size_t data_bytes = sizeof(Scalar) * header.rows * header.cols;
+    memcpy(value.data(), src, data_bytes);
+    return src + data_bytes;
+  }
+};
+
+template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
+class Serializer<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > : public
+  Serializer<DenseBase<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > > {};
+  
+template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
+class Serializer<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > : public
+  Serializer<DenseBase<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > > {};
+  
+namespace internal {
+ 
+// Recursive serialization implementation helper.
+template<size_t N, typename... Types>
+struct serialize_impl;
+
+template<size_t N, typename T1, typename... Ts>
+struct serialize_impl<N, T1, Ts...> {
+  using Serializer = Eigen::Serializer<typename std::decay<T1>::type>;
+  
+  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  size_t serialize_size(const T1& value, const Ts&... args) {
+    Serializer serializer;
+    size_t size = serializer.size(value);
+    return size + serialize_impl<N-1, Ts...>::serialize_size(args...);
+  }
+  
+  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  uint8_t* serialize(uint8_t* dest, const T1& value, const Ts&... args) {
+    Serializer serializer;
+    dest = serializer.serialize(dest, value);
+    return serialize_impl<N-1, Ts...>::serialize(dest, args...);
+  }
+  
+  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  uint8_t* deserialize(uint8_t* src, T1& value, Ts&... args) {
+    Serializer serializer;
+    src = serializer.deserialize(src, value);
+    return serialize_impl<N-1, Ts...>::deserialize(src, args...);
+  }
+};
+
+// Base case.
+template<>
+struct serialize_impl<0> {
+  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  size_t serialize_size() { return 0; }
+  
+  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  uint8_t* serialize(uint8_t* dest) { return dest; }
+  
+  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+  uint8_t* deserialize(uint8_t* src) { return src; }
+};
+
+}  // namespace internal
+
+
+/**
+ * Determine the buffer size required to serialize a set of values.
+ * 
+ * \param args ... arguments to serialize in sequence.
+ * \return the total size of the required buffer.
+ */
+template<typename... Args>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+size_t serialize_size(const Args&... args) {
+  return internal::serialize_impl<sizeof...(args), Args...>::serialize_size(args...);
+}
+
+/**
+ * Serialize a set of values to the byte buffer.
+ * 
+ * \param dest output byte buffer.
+ * \param args ... arguments to serialize in sequence.
+ * \return the next address after all serialized values.
+ */
+template<typename... Args>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+uint8_t* serialize(uint8_t* dest, const Args&... args) {
+  return internal::serialize_impl<sizeof...(args), Args...>::serialize(dest, args...);
+}
+
+/**
+ * Deserialize a set of values from the byte buffer.
+ * 
+ * \param src input byte buffer.
+ * \param args ... arguments to deserialize in sequence.
+ * \return the next address after all parsed values.
+ */
+template<typename... Args>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+uint8_t* deserialize(uint8_t* src, Args&... args) {
+  return internal::serialize_impl<sizeof...(args), Args...>::deserialize(src, args...);
+}
+
+}  // namespace Eigen
+
+#endif // EIGEN_SERIALIZER_H
diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h
index c45de59..c938eb8 100644
--- a/Eigen/src/Core/util/StaticAssert.h
+++ b/Eigen/src/Core/util/StaticAssert.h
@@ -16,10 +16,6 @@
  *  - in EIGEN_STATIC_ASSERT(CONDITION,MSG) the parameter CONDITION must be a compile time boolean
  *    expression, and MSG an enum listed in struct internal::static_assertion<true>
  *
- *  - define EIGEN_NO_STATIC_ASSERT to disable them (and save compilation time)
- *    in that case, the static assertion is converted to the following runtime assert:
- *      eigen_assert(CONDITION && "MSG")
- *
  *  - currently EIGEN_STATIC_ASSERT can only be used in function scope
  *
  */
@@ -27,113 +23,11 @@
 #ifndef EIGEN_STATIC_ASSERT
 #ifndef EIGEN_NO_STATIC_ASSERT
 
-  #if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (EIGEN_COMP_CXXVER >= 11) || (EIGEN_COMP_MSVC >= 1600))
-
-    // if native static_assert is enabled, let's use it
-    #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
-
-  #else // not CXX0X
-
-    namespace Eigen {
-
-    namespace internal {
-
-    template<bool condition>
-    struct static_assertion {};
-
-    template<>
-    struct static_assertion<true>
-    {
-      enum {
-        YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX=1,
-        YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES=1,
-        YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES=1,
-        THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE=1,
-        THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE=1,
-        THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE=1,
-        OUT_OF_RANGE_ACCESS=1,
-        YOU_MADE_A_PROGRAMMING_MISTAKE=1,
-        EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT=1,
-        EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE=1,
-        YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR=1,
-        YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR=1,
-        UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC=1,
-        THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES=1,
-        FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED=1,
-        NUMERIC_TYPE_MUST_BE_REAL=1,
-        COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED=1,
-        WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED=1,
-        THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE=1,
-        INVALID_MATRIX_PRODUCT=1,
-        INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS=1,
-        INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION=1,
-        YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY=1,
-        THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES=1,
-        THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES=1,
-        INVALID_MATRIX_TEMPLATE_PARAMETERS=1,
-        INVALID_MATRIXBASE_TEMPLATE_PARAMETERS=1,
-        BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER=1,
-        THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX=1,
-        THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE=1,
-        THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES=1,
-        YOU_ALREADY_SPECIFIED_THIS_STRIDE=1,
-        INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION=1,
-        THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD=1,
-        PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1=1,
-        THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS=1,
-        YOU_CANNOT_MIX_ARRAYS_AND_MATRICES=1,
-        YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION=1,
-        THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY=1,
-        YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT=1,
-        THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS=1,
-        THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS=1,
-        THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL=1,
-        THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES=1,
-        YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED=1,
-        YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED=1,
-        THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE=1,
-        THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH=1,
-        OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG=1,
-        IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY=1,
-        STORAGE_LAYOUT_DOES_NOT_MATCH=1,
-        EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE=1,
-        THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS=1,
-        MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY=1,
-        THIS_TYPE_IS_NOT_SUPPORTED=1,
-        STORAGE_KIND_MUST_MATCH=1,
-        STORAGE_INDEX_MUST_MATCH=1,
-        CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY=1,
-        SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY=1,
-        INVALID_TEMPLATE_PARAMETER=1,
-        GPU_TENSOR_CONTRACTION_DOES_NOT_SUPPORT_OUTPUT_KERNELS=1,
-        THE_ARRAY_SIZE_SHOULD_EQUAL_WITH_PACKET_SIZE=1
-      };
-    };
-
-    } // end namespace internal
-
-    } // end namespace Eigen
-
-    // Specialized implementation for MSVC to avoid "conditional
-    // expression is constant" warnings.  This implementation doesn't
-    // appear to work under GCC, hence the multiple implementations.
-    #if EIGEN_COMP_MSVC
-
-      #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
-        {Eigen::internal::static_assertion<bool(CONDITION)>::MSG;}
-
-    #else
-      // In some cases clang interprets bool(CONDITION) as function declaration
-      #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
-        if (Eigen::internal::static_assertion<static_cast<bool>(CONDITION)>::MSG) {}
-
-    #endif
-
-  #endif // not CXX0X
+#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
 
 #else // EIGEN_NO_STATIC_ASSERT
 
-  #define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);
+#define EIGEN_STATIC_ASSERT(CONDITION,MSG)
 
 #endif // EIGEN_NO_STATIC_ASSERT
 #endif // EIGEN_STATIC_ASSERT
diff --git a/Eigen/src/Core/util/SymbolicIndex.h b/Eigen/src/Core/util/SymbolicIndex.h
index 354dd9a..9135a4a 100644
--- a/Eigen/src/Core/util/SymbolicIndex.h
+++ b/Eigen/src/Core/util/SymbolicIndex.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SYMBOLIC_INDEX_H
 #define EIGEN_SYMBOLIC_INDEX_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \namespace Eigen::symbolic
@@ -35,7 +37,9 @@
   * std::cout << expr98.eval(x=6) << "\n";
   * \endcode
   *
-  * It is currently only used internally to define and manipulate the Eigen::last and Eigen::lastp1 symbols in Eigen::seq and Eigen::seqN.
+  * It is currently only used internally to define and manipulate the
+  * Eigen::placeholders::last and Eigen::placeholders::lastp1 symbols in
+  * Eigen::seq and Eigen::seqN.
   *
   */
 namespace symbolic {
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index 63885bc..918d488 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -22,6 +22,8 @@
   #define EIGEN_EMPTY_STRUCT_CTOR(X)
 #endif
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/Eigen/src/Eigenvalues/ComplexEigenSolver.h
index f658e4e..1cfc0ca 100644
--- a/Eigen/src/Eigenvalues/ComplexEigenSolver.h
+++ b/Eigen/src/Eigenvalues/ComplexEigenSolver.h
@@ -14,6 +14,8 @@
 
 #include "./ComplexSchur.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \eigenvalues_module \ingroup Eigenvalues_Module
@@ -236,12 +238,9 @@
     }
 
   protected:
-    
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-    
+
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
+
     EigenvectorType m_eivec;
     EigenvalueType m_eivalues;
     ComplexSchur<MatrixType> m_schur;
@@ -260,8 +259,6 @@
 ComplexEigenSolver<MatrixType>& 
 ComplexEigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeEigenvectors)
 {
-  check_template_parameters();
-  
   // this code is inspired from Jampack
   eigen_assert(matrix.cols() == matrix.rows());
 
diff --git a/Eigen/src/Eigenvalues/ComplexSchur.h b/Eigen/src/Eigenvalues/ComplexSchur.h
index 5beaa36..b4f8249 100644
--- a/Eigen/src/Eigenvalues/ComplexSchur.h
+++ b/Eigen/src/Eigenvalues/ComplexSchur.h
@@ -14,6 +14,8 @@
 
 #include "./HessenbergDecomposition.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
@@ -259,7 +261,7 @@
     friend struct internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>;
 };
 
-/** If m_matT(i+1,i) is neglegible in floating point arithmetic
+/** If m_matT(i+1,i) is negligible in floating point arithmetic
   * compared to m_matT(i,i) and m_matT(j,j), then set it to zero and
   * return true, else return false. */
 template<typename MatrixType>
diff --git a/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h b/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h
index 4980a3e..144eb2a 100644
--- a/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h
+++ b/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_COMPLEX_SCHUR_LAPACKE_H
 #define EIGEN_COMPLEX_SCHUR_LAPACKE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \internal Specialization for the data types supported by LAPACKe */
diff --git a/Eigen/src/Eigenvalues/EigenSolver.h b/Eigen/src/Eigenvalues/EigenSolver.h
index d412601..f6ff140 100644
--- a/Eigen/src/Eigenvalues/EigenSolver.h
+++ b/Eigen/src/Eigenvalues/EigenSolver.h
@@ -13,6 +13,8 @@
 
 #include "./RealSchur.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \eigenvalues_module \ingroup Eigenvalues_Module
diff --git a/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
index fbc7679..3df3092 100644
--- a/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
+++ b/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
@@ -14,6 +14,8 @@
 
 #include "./RealQZ.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \eigenvalues_module \ingroup Eigenvalues_Module
@@ -267,13 +269,10 @@
     }
 
   protected:
-    
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-      EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);
-    }
-    
+
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
+    EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL)
+
     EigenvectorsType m_eivec;
     ComplexVectorType m_alphas;
     VectorType m_betas;
@@ -286,8 +285,6 @@
 GeneralizedEigenSolver<MatrixType>&
 GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors)
 {
-  check_template_parameters();
-  
   using std::sqrt;
   using std::abs;
   eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
diff --git a/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h b/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
index fd1105b..dab66ca 100644
--- a/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
+++ b/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
@@ -13,6 +13,8 @@
 
 #include "./Tridiagonalization.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \eigenvalues_module \ingroup Eigenvalues_Module
diff --git a/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/Eigen/src/Eigenvalues/HessenbergDecomposition.h
index ae855b9..387c13a 100644
--- a/Eigen/src/Eigenvalues/HessenbergDecomposition.h
+++ b/Eigen/src/Eigenvalues/HessenbergDecomposition.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_HESSENBERGDECOMPOSITION_H
 #define EIGEN_HESSENBERGDECOMPOSITION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Eigenvalues/InternalHeaderCheck.h b/Eigen/src/Eigenvalues/InternalHeaderCheck.h
new file mode 100644
index 0000000..374cbd4
--- /dev/null
+++ b/Eigen/src/Eigenvalues/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_EIGENVALUES_MODULE_H
+#error "Please include Eigen/Eigenvalues instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
index 66e5a3d..c8df260 100644
--- a/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
+++ b/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_MATRIXBASEEIGENVALUES_H
 #define EIGEN_MATRIXBASEEIGENVALUES_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Eigenvalues/RealQZ.h b/Eigen/src/Eigenvalues/RealQZ.h
index 0fe8543..5564f7f 100644
--- a/Eigen/src/Eigenvalues/RealQZ.h
+++ b/Eigen/src/Eigenvalues/RealQZ.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_REAL_QZ_H
 #define EIGEN_REAL_QZ_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
   /** \eigenvalues_module \ingroup Eigenvalues_Module
diff --git a/Eigen/src/Eigenvalues/RealSchur.h b/Eigen/src/Eigenvalues/RealSchur.h
index 5b7d38c..96372dc 100644
--- a/Eigen/src/Eigenvalues/RealSchur.h
+++ b/Eigen/src/Eigenvalues/RealSchur.h
@@ -13,6 +13,8 @@
 
 #include "./HessenbergDecomposition.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \eigenvalues_module \ingroup Eigenvalues_Module
diff --git a/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h b/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h
index 2c22517..0a6ed21 100644
--- a/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h
+++ b/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_REAL_SCHUR_LAPACKE_H
 #define EIGEN_REAL_SCHUR_LAPACKE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \internal Specialization for the data types supported by LAPACKe */
diff --git a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
index e6073cd..70d370c 100644
--- a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+++ b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
@@ -13,6 +13,8 @@
 
 #include "./Tridiagonalization.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename MatrixType_>
@@ -372,12 +374,8 @@
     static const int m_maxIterations = 30;
 
   protected:
-    static EIGEN_DEVICE_FUNC
-    void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-    
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
+
     EigenvectorsType m_eivec;
     RealVectorType m_eivalues;
     typename TridiagonalizationType::SubDiagonalType m_subdiag;
@@ -419,10 +417,8 @@
 SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
 ::compute(const EigenBase<InputType>& a_matrix, int options)
 {
-  check_template_parameters();
-  
   const InputType &matrix(a_matrix.derived());
-  
+
   EIGEN_USING_STD(abs);
   eigen_assert(matrix.cols() == matrix.rows());
   eigen_assert((options&~(EigVecMask|GenEigMask))==0
diff --git a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h
index b0c947d..b24de67 100644
--- a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h
+++ b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_SAEIGENSOLVER_LAPACKE_H
 #define EIGEN_SAEIGENSOLVER_LAPACKE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \internal Specialization for the data types supported by LAPACKe */
diff --git a/Eigen/src/Eigenvalues/Tridiagonalization.h b/Eigen/src/Eigenvalues/Tridiagonalization.h
index e82cbe3..be95093 100644
--- a/Eigen/src/Eigenvalues/Tridiagonalization.h
+++ b/Eigen/src/Eigenvalues/Tridiagonalization.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_TRIDIAGONALIZATION_H
 #define EIGEN_TRIDIAGONALIZATION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Geometry/AlignedBox.h b/Eigen/src/Geometry/AlignedBox.h
index 7481ea3..d9f6306 100644
--- a/Eigen/src/Geometry/AlignedBox.h
+++ b/Eigen/src/Geometry/AlignedBox.h
@@ -46,6 +46,8 @@
 #ifndef EIGEN_ALIGNEDBOX_H
 #define EIGEN_ALIGNEDBOX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/AngleAxis.h b/Eigen/src/Geometry/AngleAxis.h
index d23fd59..c23a908 100644
--- a/Eigen/src/Geometry/AngleAxis.h
+++ b/Eigen/src/Geometry/AngleAxis.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ANGLEAXIS_H
 #define EIGEN_ANGLEAXIS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/EulerAngles.h b/Eigen/src/Geometry/EulerAngles.h
index 19b734c..2b99960 100644
--- a/Eigen/src/Geometry/EulerAngles.h
+++ b/Eigen/src/Geometry/EulerAngles.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_EULERANGLES_H
 #define EIGEN_EULERANGLES_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h
index e909984..e1ddb3e 100644
--- a/Eigen/src/Geometry/Homogeneous.h
+++ b/Eigen/src/Geometry/Homogeneous.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_HOMOGENEOUS_H
 #define EIGEN_HOMOGENEOUS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/Hyperplane.h b/Eigen/src/Geometry/Hyperplane.h
index 268c9dd..db0a485 100644
--- a/Eigen/src/Geometry/Hyperplane.h
+++ b/Eigen/src/Geometry/Hyperplane.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_HYPERPLANE_H
 #define EIGEN_HYPERPLANE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/InternalHeaderCheck.h b/Eigen/src/Geometry/InternalHeaderCheck.h
new file mode 100644
index 0000000..a1159a3
--- /dev/null
+++ b/Eigen/src/Geometry/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_GEOMETRY_MODULE_H
+#error "Please include Eigen/Geometry instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h
index 524aebe..1b657b5 100644
--- a/Eigen/src/Geometry/OrthoMethods.h
+++ b/Eigen/src/Geometry/OrthoMethods.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_ORTHOMETHODS_H
 #define EIGEN_ORTHOMETHODS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/ParametrizedLine.h b/Eigen/src/Geometry/ParametrizedLine.h
index 9ade8dc..fa90a9e 100644
--- a/Eigen/src/Geometry/ParametrizedLine.h
+++ b/Eigen/src/Geometry/ParametrizedLine.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_PARAMETRIZEDLINE_H
 #define EIGEN_PARAMETRIZEDLINE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h
index 4c929c5..3a27505 100644
--- a/Eigen/src/Geometry/Quaternion.h
+++ b/Eigen/src/Geometry/Quaternion.h
@@ -10,6 +10,8 @@
 
 #ifndef EIGEN_QUATERNION_H
 #define EIGEN_QUATERNION_H
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 
@@ -341,20 +343,17 @@
   EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs;}
 
   EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(NeedsAlignment))
-  
+
 #ifdef EIGEN_QUATERNION_PLUGIN
 # include EIGEN_QUATERNION_PLUGIN
 #endif
 
 protected:
   Coefficients m_coeffs;
-  
+
 #ifndef EIGEN_PARSED_BY_DOXYGEN
-    static EIGEN_STRONG_INLINE void _check_template_params()
-    {
-      EIGEN_STATIC_ASSERT( (Options_ & DontAlign) == Options_,
-        INVALID_MATRIX_TEMPLATE_PARAMETERS)
-    }
+  EIGEN_STATIC_ASSERT( (Options_ & DontAlign) == Options_,
+                       INVALID_MATRIX_TEMPLATE_PARAMETERS)
 #endif
 };
 
diff --git a/Eigen/src/Geometry/Rotation2D.h b/Eigen/src/Geometry/Rotation2D.h
index 74d9f87..aa7f863 100644
--- a/Eigen/src/Geometry/Rotation2D.h
+++ b/Eigen/src/Geometry/Rotation2D.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ROTATION2D_H
 #define EIGEN_ROTATION2D_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/RotationBase.h b/Eigen/src/Geometry/RotationBase.h
index bdbec1e..b05e24b 100644
--- a/Eigen/src/Geometry/RotationBase.h
+++ b/Eigen/src/Geometry/RotationBase.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ROTATIONBASE_H
 #define EIGEN_ROTATIONBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 // forward declaration
diff --git a/Eigen/src/Geometry/Scaling.h b/Eigen/src/Geometry/Scaling.h
index 4e75753..48a192e 100644
--- a/Eigen/src/Geometry/Scaling.h
+++ b/Eigen/src/Geometry/Scaling.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SCALING_H
 #define EIGEN_SCALING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h
index 56b10e6..81c8efa 100644
--- a/Eigen/src/Geometry/Transform.h
+++ b/Eigen/src/Geometry/Transform.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_TRANSFORM_H
 #define EIGEN_TRANSFORM_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h
index cad623b..7ad5afa 100644
--- a/Eigen/src/Geometry/Translation.h
+++ b/Eigen/src/Geometry/Translation.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_TRANSLATION_H
 #define EIGEN_TRANSLATION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \geometry_module \ingroup Geometry_Module
diff --git a/Eigen/src/Geometry/Umeyama.h b/Eigen/src/Geometry/Umeyama.h
index c5e1edd..b402dfa 100644
--- a/Eigen/src/Geometry/Umeyama.h
+++ b/Eigen/src/Geometry/Umeyama.h
@@ -16,6 +16,8 @@
 // * Eigen/SVD
 // * Eigen/Array
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 #ifndef EIGEN_PARSED_BY_DOXYGEN
diff --git a/Eigen/src/Geometry/arch/Geometry_SIMD.h b/Eigen/src/Geometry/arch/Geometry_SIMD.h
index 9af6a9a..bd91949 100644
--- a/Eigen/src/Geometry/arch/Geometry_SIMD.h
+++ b/Eigen/src/Geometry/arch/Geometry_SIMD.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_GEOMETRY_SIMD_H
 #define EIGEN_GEOMETRY_SIMD_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Householder/BlockHouseholder.h b/Eigen/src/Householder/BlockHouseholder.h
index 39ce1c2..9dec1aa 100644
--- a/Eigen/src/Householder/BlockHouseholder.h
+++ b/Eigen/src/Householder/BlockHouseholder.h
@@ -13,6 +13,8 @@
 
 // This file contains some helper function to deal with block householder reflectors
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Householder/Householder.h b/Eigen/src/Householder/Householder.h
index 5bc037f..dc6bf3e 100644
--- a/Eigen/src/Householder/Householder.h
+++ b/Eigen/src/Householder/Householder.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_HOUSEHOLDER_H
 #define EIGEN_HOUSEHOLDER_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h
index 984b236..d35d319 100644
--- a/Eigen/src/Householder/HouseholderSequence.h
+++ b/Eigen/src/Householder/HouseholderSequence.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H
 #define EIGEN_HOUSEHOLDER_SEQUENCE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \ingroup Householder_Module
diff --git a/Eigen/src/Householder/InternalHeaderCheck.h b/Eigen/src/Householder/InternalHeaderCheck.h
new file mode 100644
index 0000000..70de89b
--- /dev/null
+++ b/Eigen/src/Householder/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_HOUSEHOLDER_MODULE_H
+#error "Please include Eigen/Householder instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
index 3adfe4f..d2d55b7 100644
--- a/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
+++ b/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_BASIC_PRECONDITIONERS_H
 #define EIGEN_BASIC_PRECONDITIONERS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \ingroup IterativeLinearSolvers_Module
diff --git a/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
index 22ad539..079b22d 100644
--- a/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
+++ b/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_BICGSTAB_H
 #define EIGEN_BICGSTAB_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
index 6cc6532..a1408a6 100644
--- a/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
+++ b/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CONJUGATE_GRADIENT_H
 #define EIGEN_CONJUGATE_GRADIENT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h b/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h
index d4f7155..f57fc33 100644
--- a/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h
+++ b/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h
@@ -14,6 +14,8 @@
 #include <vector>
 #include <list>
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 /**
   * \brief Modified Incomplete Cholesky with dual threshold
diff --git a/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
index 6637a8e..44f25fc 100644
--- a/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
+++ b/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
@@ -12,6 +12,8 @@
 #define EIGEN_INCOMPLETE_LUT_H
 
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/IterativeLinearSolvers/InternalHeaderCheck.h b/Eigen/src/IterativeLinearSolvers/InternalHeaderCheck.h
new file mode 100644
index 0000000..b657e84
--- /dev/null
+++ b/Eigen/src/IterativeLinearSolvers/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_ITERATIVELINEARSOLVERS_MODULE_H
+#error "Please include Eigen/IterativeLinearSolvers instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
index 28a0c51..39a7afc 100644
--- a/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
+++ b/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ITERATIVE_SOLVER_BASE_H
 #define EIGEN_ITERATIVE_SOLVER_BASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h b/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h
index be816e4..f59fa05 100644
--- a/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h
+++ b/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_LEAST_SQUARE_CONJUGATE_GRADIENT_H
 #define EIGEN_LEAST_SQUARE_CONJUGATE_GRADIENT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h b/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h
index 7b89657..121363b 100644
--- a/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h
+++ b/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SOLVEWITHGUESS_H
 #define EIGEN_SOLVEWITHGUESS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename Decomposition, typename RhsType, typename GuessType> class SolveWithGuess;
diff --git a/Eigen/src/Jacobi/InternalHeaderCheck.h b/Eigen/src/Jacobi/InternalHeaderCheck.h
new file mode 100644
index 0000000..b17b1f2
--- /dev/null
+++ b/Eigen/src/Jacobi/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_JACOBI_MODULE_H
+#error "Please include Eigen/Jacobi instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/Jacobi/Jacobi.h b/Eigen/src/Jacobi/Jacobi.h
index 76668a5..55a94c2 100644
--- a/Eigen/src/Jacobi/Jacobi.h
+++ b/Eigen/src/Jacobi/Jacobi.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_JACOBI_H
 #define EIGEN_JACOBI_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \ingroup Jacobi_Module
diff --git a/Eigen/src/KLUSupport/InternalHeaderCheck.h b/Eigen/src/KLUSupport/InternalHeaderCheck.h
new file mode 100644
index 0000000..eb1d671
--- /dev/null
+++ b/Eigen/src/KLUSupport/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_KLUSUPPORT_MODULE_H
+#error "Please include Eigen/KLUSupport instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/KLUSupport/KLUSupport.h b/Eigen/src/KLUSupport/KLUSupport.h
index c13a332..769c45d 100644
--- a/Eigen/src/KLUSupport/KLUSupport.h
+++ b/Eigen/src/KLUSupport/KLUSupport.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_KLUSUPPORT_H
 #define EIGEN_KLUSUPPORT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /* TODO extract L, extract U, compute det, etc... */
diff --git a/Eigen/src/LU/Determinant.h b/Eigen/src/LU/Determinant.h
index 3a41e6f..c94c394 100644
--- a/Eigen/src/LU/Determinant.h
+++ b/Eigen/src/LU/Determinant.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_DETERMINANT_H
 #define EIGEN_DETERMINANT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h
index c45b258..1dd0a4e 100644
--- a/Eigen/src/LU/FullPivLU.h
+++ b/Eigen/src/LU/FullPivLU.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_LU_H
 #define EIGEN_LU_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -419,10 +421,7 @@
 
   protected:
 
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
     void computeInPlace();
 
@@ -487,8 +486,6 @@
 template<typename MatrixType>
 void FullPivLU<MatrixType>::computeInPlace()
 {
-  check_template_parameters();
-
   // the permutations are stored as int indices, so just to be sure:
   eigen_assert(m_lu.rows()<=NumTraits<int>::highest() && m_lu.cols()<=NumTraits<int>::highest());
 
diff --git a/Eigen/src/LU/InternalHeaderCheck.h b/Eigen/src/LU/InternalHeaderCheck.h
new file mode 100644
index 0000000..f346b17
--- /dev/null
+++ b/Eigen/src/LU/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_LU_MODULE_H
+#error "Please include Eigen/LU instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/LU/InverseImpl.h b/Eigen/src/LU/InverseImpl.h
index a40cefa..9c1a605 100644
--- a/Eigen/src/LU/InverseImpl.h
+++ b/Eigen/src/LU/InverseImpl.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_INVERSE_IMPL_H
 #define EIGEN_INVERSE_IMPL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h
index 52e4bcc..4034745 100644
--- a/Eigen/src/LU/PartialPivLU.h
+++ b/Eigen/src/LU/PartialPivLU.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_PARTIALLU_H
 #define EIGEN_PARTIALLU_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -265,10 +267,7 @@
 
   protected:
 
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
     void compute();
 
@@ -524,8 +523,6 @@
 template<typename MatrixType>
 void PartialPivLU<MatrixType>::compute()
 {
-  check_template_parameters();
-
   // the row permutation is stored as int indices, so just to be sure:
   eigen_assert(m_lu.rows()<NumTraits<int>::highest());
 
diff --git a/Eigen/src/LU/PartialPivLU_LAPACKE.h b/Eigen/src/LU/PartialPivLU_LAPACKE.h
index 755168a..2f244f6 100644
--- a/Eigen/src/LU/PartialPivLU_LAPACKE.h
+++ b/Eigen/src/LU/PartialPivLU_LAPACKE.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_PARTIALLU_LAPACK_H
 #define EIGEN_PARTIALLU_LAPACK_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/LU/arch/InverseSize4.h b/Eigen/src/LU/arch/InverseSize4.h
index a232ffc..ecb3a6b 100644
--- a/Eigen/src/LU/arch/InverseSize4.h
+++ b/Eigen/src/LU/arch/InverseSize4.h
@@ -35,6 +35,8 @@
 #ifndef EIGEN_INVERSE_SIZE_4_H
 #define EIGEN_INVERSE_SIZE_4_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen
 {
 namespace internal
diff --git a/Eigen/src/MetisSupport/InternalHeaderCheck.h b/Eigen/src/MetisSupport/InternalHeaderCheck.h
new file mode 100644
index 0000000..9d34825
--- /dev/null
+++ b/Eigen/src/MetisSupport/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_METISSUPPORT_MODULE_H
+#error "Please include Eigen/MetisSupport instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/MetisSupport/MetisSupport.h b/Eigen/src/MetisSupport/MetisSupport.h
index 4c15304..c5e143b 100644
--- a/Eigen/src/MetisSupport/MetisSupport.h
+++ b/Eigen/src/MetisSupport/MetisSupport.h
@@ -9,6 +9,8 @@
 #ifndef METIS_SUPPORT_H
 #define METIS_SUPPORT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 /**
  * Get the fill-reducing ordering from the METIS package
diff --git a/Eigen/src/OrderingMethods/Amd.h b/Eigen/src/OrderingMethods/Amd.h
index 7ca3f33..5bd531c 100644
--- a/Eigen/src/OrderingMethods/Amd.h
+++ b/Eigen/src/OrderingMethods/Amd.h
@@ -21,6 +21,8 @@
 #ifndef EIGEN_SPARSE_AMD_H
 #define EIGEN_SPARSE_AMD_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/OrderingMethods/InternalHeaderCheck.h b/Eigen/src/OrderingMethods/InternalHeaderCheck.h
new file mode 100644
index 0000000..713c447
--- /dev/null
+++ b/Eigen/src/OrderingMethods/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_ORDERINGMETHODS_MODULE_H
+#error "Please include Eigen/OrderingMethods instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/OrderingMethods/Ordering.h b/Eigen/src/OrderingMethods/Ordering.h
index c578970..5cc4a85 100644
--- a/Eigen/src/OrderingMethods/Ordering.h
+++ b/Eigen/src/OrderingMethods/Ordering.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_ORDERING_H
 #define EIGEN_ORDERING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
   
 #include "Eigen_Colamd.h"
diff --git a/Eigen/src/PaStiXSupport/InternalHeaderCheck.h b/Eigen/src/PaStiXSupport/InternalHeaderCheck.h
new file mode 100644
index 0000000..f588e50
--- /dev/null
+++ b/Eigen/src/PaStiXSupport/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_PASTIXSUPPORT_MODULE_H
+#error "Please include Eigen/PaStiXSupport instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/PaStiXSupport/PaStiXSupport.h b/Eigen/src/PaStiXSupport/PaStiXSupport.h
index cb133c5..d3126b1 100644
--- a/Eigen/src/PaStiXSupport/PaStiXSupport.h
+++ b/Eigen/src/PaStiXSupport/PaStiXSupport.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_PASTIXSUPPORT_H
 #define EIGEN_PASTIXSUPPORT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 #if defined(DCOMPLEX)
diff --git a/Eigen/src/PardisoSupport/InternalHeaderCheck.h b/Eigen/src/PardisoSupport/InternalHeaderCheck.h
new file mode 100644
index 0000000..8ef33f0
--- /dev/null
+++ b/Eigen/src/PardisoSupport/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_PARDISOSUPPORT_MODULE_H
+#error "Please include Eigen/PardisoSupport instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/PardisoSupport/PardisoSupport.h b/Eigen/src/PardisoSupport/PardisoSupport.h
index f09856a..e9815e6 100644
--- a/Eigen/src/PardisoSupport/PardisoSupport.h
+++ b/Eigen/src/PardisoSupport/PardisoSupport.h
@@ -32,6 +32,8 @@
 #ifndef EIGEN_PARDISOSUPPORT_H
 #define EIGEN_PARDISOSUPPORT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename MatrixType_> class PardisoLU;
diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h
index 3c884e7..b9500c8 100644
--- a/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/Eigen/src/QR/ColPivHouseholderQR.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
 #define EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -426,10 +428,7 @@
 
     friend class CompleteOrthogonalDecomposition<MatrixType>;
 
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
     void computeInPlace();
 
@@ -481,8 +480,6 @@
 template<typename MatrixType>
 void ColPivHouseholderQR<MatrixType>::computeInPlace()
 {
-  check_template_parameters();
-
   // the column permutation is stored as int indices, so just to be sure:
   eigen_assert(m_qr.cols()<=NumTraits<int>::highest());
 
diff --git a/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h b/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h
index 4e9651f..7652d31 100644
--- a/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h
+++ b/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h
@@ -34,6 +34,8 @@
 #ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_LAPACKE_H
 #define EIGEN_COLPIVOTINGHOUSEHOLDERQR_LAPACKE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \internal Specialization for the data types supported by LAPACKe */
diff --git a/Eigen/src/QR/CompleteOrthogonalDecomposition.h b/Eigen/src/QR/CompleteOrthogonalDecomposition.h
index 0445edb..111d583 100644
--- a/Eigen/src/QR/CompleteOrthogonalDecomposition.h
+++ b/Eigen/src/QR/CompleteOrthogonalDecomposition.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
 #define EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -377,9 +379,7 @@
 #endif
 
  protected:
-  static void check_template_parameters() {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-  }
+  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
   template<bool Transpose_, typename Rhs>
   void _check_solve_assertion(const Rhs& b) const {
@@ -429,8 +429,6 @@
 template <typename MatrixType>
 void CompleteOrthogonalDecomposition<MatrixType>::computeInPlace()
 {
-  check_template_parameters();
-
   // the column permutation is stored as int indices, so just to be sure:
   eigen_assert(m_cpqr.cols() <= NumTraits<int>::highest());
 
diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h
index 68585df..0a61f22 100644
--- a/Eigen/src/QR/FullPivHouseholderQR.h
+++ b/Eigen/src/QR/FullPivHouseholderQR.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H
 #define EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
@@ -403,10 +405,7 @@
 
   protected:
 
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
     void computeInPlace();
 
@@ -458,8 +457,6 @@
 template<typename MatrixType>
 void FullPivHouseholderQR<MatrixType>::computeInPlace()
 {
-  check_template_parameters();
-
   using std::abs;
   Index rows = m_qr.rows();
   Index cols = m_qr.cols();
diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h
index d2216c5..c55cac3 100644
--- a/Eigen/src/QR/HouseholderQR.h
+++ b/Eigen/src/QR/HouseholderQR.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_QR_H
 #define EIGEN_QR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
@@ -230,10 +232,7 @@
 
   protected:
 
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
+    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
     void computeInPlace();
 
@@ -403,8 +402,6 @@
 template<typename MatrixType>
 void HouseholderQR<MatrixType>::computeInPlace()
 {
-  check_template_parameters();
-  
   Index rows = m_qr.rows();
   Index cols = m_qr.cols();
   Index size = (std::min)(rows,cols);
diff --git a/Eigen/src/QR/HouseholderQR_LAPACKE.h b/Eigen/src/QR/HouseholderQR_LAPACKE.h
index 1dc7d53..ef67760 100644
--- a/Eigen/src/QR/HouseholderQR_LAPACKE.h
+++ b/Eigen/src/QR/HouseholderQR_LAPACKE.h
@@ -34,6 +34,8 @@
 #ifndef EIGEN_QR_LAPACKE_H
 #define EIGEN_QR_LAPACKE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/QR/InternalHeaderCheck.h b/Eigen/src/QR/InternalHeaderCheck.h
new file mode 100644
index 0000000..bf8df01
--- /dev/null
+++ b/Eigen/src/QR/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_QR_MODULE_H
+#error "Please include Eigen/QR instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/SPQRSupport/InternalHeaderCheck.h b/Eigen/src/SPQRSupport/InternalHeaderCheck.h
new file mode 100644
index 0000000..8d94ba4
--- /dev/null
+++ b/Eigen/src/SPQRSupport/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SPQRSUPPORT_MODULE_H
+#error "Please include Eigen/SPQRSupport instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h b/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
index 0826c4d..f1c29dd 100644
--- a/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
+++ b/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SUITESPARSEQRSUPPORT_H
 #define EIGEN_SUITESPARSEQRSUPPORT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
   
   template<typename MatrixType> class SPQR; 
diff --git a/Eigen/src/SVD/BDCSVD.h b/Eigen/src/SVD/BDCSVD.h
index 31a766d..86f270d 100644
--- a/Eigen/src/SVD/BDCSVD.h
+++ b/Eigen/src/SVD/BDCSVD.h
@@ -27,6 +27,8 @@
 #define eigen_internal_assert(X) assert(X);
 #endif
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
diff --git a/Eigen/src/SVD/InternalHeaderCheck.h b/Eigen/src/SVD/InternalHeaderCheck.h
new file mode 100644
index 0000000..fa67b96
--- /dev/null
+++ b/Eigen/src/SVD/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SVD_MODULE_H
+#error "Please include Eigen/SVD instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h
index b135fb0..91c95ec 100644
--- a/Eigen/src/SVD/JacobiSVD.h
+++ b/Eigen/src/SVD/JacobiSVD.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_JACOBISVD_H
 #define EIGEN_JACOBISVD_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SVD/JacobiSVD_LAPACKE.h b/Eigen/src/SVD/JacobiSVD_LAPACKE.h
index ff0516f..611ae8c 100644
--- a/Eigen/src/SVD/JacobiSVD_LAPACKE.h
+++ b/Eigen/src/SVD/JacobiSVD_LAPACKE.h
@@ -33,6 +33,8 @@
 #ifndef EIGEN_JACOBISVD_LAPACKE_H
 #define EIGEN_JACOBISVD_LAPACKE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \internal Specialization for the data types supported by LAPACKe */
diff --git a/Eigen/src/SVD/SVDBase.h b/Eigen/src/SVD/SVDBase.h
index bc7ab88..7ecaf21 100644
--- a/Eigen/src/SVD/SVDBase.h
+++ b/Eigen/src/SVD/SVDBase.h
@@ -16,6 +16,8 @@
 #ifndef EIGEN_SVDBASE_H
 #define EIGEN_SVDBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -52,7 +54,7 @@
  * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix,
  * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving.
  * 
- * The status of the computation can be retrived using the \a info() method. Unless \a info() returns \a Success, the results should be not
+ * The status of the computation can be retrieved using the \a info() method. Unless \a info() returns \a Success, the results should be not
  * considered well defined.
  *  
  * If the input matrix has inf or nan coefficients, the result of the computation is undefined, and \a info() will return \a InvalidInput, but the computation is guaranteed to
@@ -249,10 +251,7 @@
 
 protected:
 
-  static void check_template_parameters()
-  {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-  }
+  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
 
   void _check_compute_assertions() const {
     eigen_assert(m_isInitialized && "SVD is not initialized.");
@@ -295,9 +294,7 @@
       m_computeThinV(false),
       m_computationOptions(0),
       m_rows(-1), m_cols(-1), m_diagSize(0)
-  {
-    check_template_parameters();
-  }
+  { }
 
 
 };
diff --git a/Eigen/src/SVD/UpperBidiagonalization.h b/Eigen/src/SVD/UpperBidiagonalization.h
index 48d6385..d4e72e5 100644
--- a/Eigen/src/SVD/UpperBidiagonalization.h
+++ b/Eigen/src/SVD/UpperBidiagonalization.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_BIDIAGONALIZATION_H
 #define EIGEN_BIDIAGONALIZATION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCholesky/InternalHeaderCheck.h b/Eigen/src/SparseCholesky/InternalHeaderCheck.h
new file mode 100644
index 0000000..f8d8762
--- /dev/null
+++ b/Eigen/src/SparseCholesky/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SPARSECHOLESKY_MODULE_H
+#error "Please include Eigen/SparseCholesky instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/SparseCholesky/SimplicialCholesky.h b/Eigen/src/SparseCholesky/SimplicialCholesky.h
index cbd3089..d90ca13 100644
--- a/Eigen/src/SparseCholesky/SimplicialCholesky.h
+++ b/Eigen/src/SparseCholesky/SimplicialCholesky.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SIMPLICIAL_CHOLESKY_H
 #define EIGEN_SIMPLICIAL_CHOLESKY_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 enum SimplicialCholeskyMode {
diff --git a/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h b/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
index 72e1740..3106c9b 100644
--- a/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
+++ b/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
@@ -20,6 +20,8 @@
 #ifndef EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H
 #define EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename Derived>
diff --git a/Eigen/src/SparseCore/AmbiVector.h b/Eigen/src/SparseCore/AmbiVector.h
index 212389b..594e91d 100644
--- a/Eigen/src/SparseCore/AmbiVector.h
+++ b/Eigen/src/SparseCore/AmbiVector.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_AMBIVECTOR_H
 #define EIGEN_AMBIVECTOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/CompressedStorage.h b/Eigen/src/SparseCore/CompressedStorage.h
index a5202c1..696f29d 100644
--- a/Eigen/src/SparseCore/CompressedStorage.h
+++ b/Eigen/src/SparseCore/CompressedStorage.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_COMPRESSED_STORAGE_H
 #define EIGEN_COMPRESSED_STORAGE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h b/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
index 9486502..d4aa473 100644
--- a/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
+++ b/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H
 #define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/InternalHeaderCheck.h b/Eigen/src/SparseCore/InternalHeaderCheck.h
new file mode 100644
index 0000000..9de5936
--- /dev/null
+++ b/Eigen/src/SparseCore/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SPARSECORE_MODULE_H
+#error "Please include Eigen/SparseCore instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/SparseCore/MappedSparseMatrix.h b/Eigen/src/SparseCore/MappedSparseMatrix.h
index e980277..efb7b49 100644
--- a/Eigen/src/SparseCore/MappedSparseMatrix.h
+++ b/Eigen/src/SparseCore/MappedSparseMatrix.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_MAPPED_SPARSEMATRIX_H
 #define EIGEN_MAPPED_SPARSEMATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \deprecated Use Map<SparseMatrix<> >
diff --git a/Eigen/src/SparseCore/SparseAssign.h b/Eigen/src/SparseCore/SparseAssign.h
index 905485c..bcd783c 100644
--- a/Eigen/src/SparseCore/SparseAssign.h
+++ b/Eigen/src/SparseCore/SparseAssign.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSEASSIGN_H
 #define EIGEN_SPARSEASSIGN_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename Derived>    
diff --git a/Eigen/src/SparseCore/SparseBlock.h b/Eigen/src/SparseCore/SparseBlock.h
index c7bbb9e..521331c 100644
--- a/Eigen/src/SparseCore/SparseBlock.h
+++ b/Eigen/src/SparseCore/SparseBlock.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_BLOCK_H
 #define EIGEN_SPARSE_BLOCK_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // Subset of columns or rows
@@ -467,7 +469,7 @@
 class unary_evaluator<Block<ArgType,BlockRows,BlockCols,InnerPanel>, IteratorBased>::InnerVectorInnerIterator
  : public EvalIterator
 {
-  // NOTE MSVC fails to compile if we don't explicitely "import" IsRowMajor from unary_evaluator
+  // NOTE MSVC fails to compile if we don't explicitly "import" IsRowMajor from unary_evaluator
   //      because the base class EvalIterator has a private IsRowMajor enum too. (bug #1786)
   // NOTE We cannot call it IsRowMajor because it would shadow unary_evaluator::IsRowMajor
   enum { XprIsRowMajor = unary_evaluator::IsRowMajor };
diff --git a/Eigen/src/SparseCore/SparseColEtree.h b/Eigen/src/SparseCore/SparseColEtree.h
index ebe02d1..ff32458 100644
--- a/Eigen/src/SparseCore/SparseColEtree.h
+++ b/Eigen/src/SparseCore/SparseColEtree.h
@@ -31,6 +31,8 @@
 #ifndef SPARSE_COLETREE_H
 #define SPARSE_COLETREE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseCompressedBase.h b/Eigen/src/SparseCore/SparseCompressedBase.h
index 6a2c7a8c..b3c716d 100644
--- a/Eigen/src/SparseCore/SparseCompressedBase.h
+++ b/Eigen/src/SparseCore/SparseCompressedBase.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_COMPRESSED_BASE_H
 #define EIGEN_SPARSE_COMPRESSED_BASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename Derived> class SparseCompressedBase;
diff --git a/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
index 9b0d3f9..17cdb8e 100644
--- a/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
+++ b/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
 #define EIGEN_SPARSE_CWISE_BINARY_OP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 // Here we have to handle 3 cases:
@@ -40,14 +42,11 @@
     typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
     typedef SparseMatrixBase<Derived> Base;
     EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
-    CwiseBinaryOpImpl()
-    {
-      EIGEN_STATIC_ASSERT((
-                (!internal::is_same<typename internal::traits<Lhs>::StorageKind,
-                                    typename internal::traits<Rhs>::StorageKind>::value)
-            ||  ((internal::evaluator<Lhs>::Flags&RowMajorBit) == (internal::evaluator<Rhs>::Flags&RowMajorBit))),
-            THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
-    }
+    EIGEN_STATIC_ASSERT((
+              (!internal::is_same<typename internal::traits<Lhs>::StorageKind,
+                                  typename internal::traits<Rhs>::StorageKind>::value)
+          ||  ((internal::evaluator<Lhs>::Flags&RowMajorBit) == (internal::evaluator<Rhs>::Flags&RowMajorBit))),
+          THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH)
 };
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/Eigen/src/SparseCore/SparseCwiseUnaryOp.h
index 32dac0f..6f48fa7 100644
--- a/Eigen/src/SparseCore/SparseCwiseUnaryOp.h
+++ b/Eigen/src/SparseCore/SparseCwiseUnaryOp.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H
 #define EIGEN_SPARSE_CWISE_UNARY_OP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseDenseProduct.h b/Eigen/src/SparseCore/SparseDenseProduct.h
index 722e928..878a759 100644
--- a/Eigen/src/SparseCore/SparseDenseProduct.h
+++ b/Eigen/src/SparseCore/SparseDenseProduct.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSEDENSEPRODUCT_H
 #define EIGEN_SPARSEDENSEPRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseDiagonalProduct.h b/Eigen/src/SparseCore/SparseDiagonalProduct.h
index 941c03b..4dc9502 100644
--- a/Eigen/src/SparseCore/SparseDiagonalProduct.h
+++ b/Eigen/src/SparseCore/SparseDiagonalProduct.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_DIAGONAL_PRODUCT_H
 #define EIGEN_SPARSE_DIAGONAL_PRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 // The product of a diagonal matrix with a sparse matrix can be easily
diff --git a/Eigen/src/SparseCore/SparseDot.h b/Eigen/src/SparseCore/SparseDot.h
index 38bc4aa..a45ecfa 100644
--- a/Eigen/src/SparseCore/SparseDot.h
+++ b/Eigen/src/SparseCore/SparseDot.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_DOT_H
 #define EIGEN_SPARSE_DOT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename Derived>
diff --git a/Eigen/src/SparseCore/SparseFuzzy.h b/Eigen/src/SparseCore/SparseFuzzy.h
index 7d47eb9..4b3911b 100644
--- a/Eigen/src/SparseCore/SparseFuzzy.h
+++ b/Eigen/src/SparseCore/SparseFuzzy.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_FUZZY_H
 #define EIGEN_SPARSE_FUZZY_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
   
 template<typename Derived>
diff --git a/Eigen/src/SparseCore/SparseMap.h b/Eigen/src/SparseCore/SparseMap.h
index f99be33..a73bd8d 100644
--- a/Eigen/src/SparseCore/SparseMap.h
+++ b/Eigen/src/SparseCore/SparseMap.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_MAP_H
 #define EIGEN_SPARSE_MAP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h
index 75589e2..4bf47bb 100644
--- a/Eigen/src/SparseCore/SparseMatrix.h
+++ b/Eigen/src/SparseCore/SparseMatrix.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSEMATRIX_H
 #define EIGEN_SPARSEMATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \ingroup SparseCore_Module
@@ -665,7 +667,6 @@
     inline SparseMatrix()
       : m_outerSize(-1), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
     {
-      check_template_parameters();
       resize(0, 0);
     }
 
@@ -673,7 +674,6 @@
     inline SparseMatrix(Index rows, Index cols)
       : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
     {
-      check_template_parameters();
       resize(rows, cols);
     }
 
@@ -684,7 +684,6 @@
     {
       EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
         YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
-      check_template_parameters();
       const bool needToTranspose = (Flags & RowMajorBit) != (internal::evaluator<OtherDerived>::Flags & RowMajorBit);
       if (needToTranspose)
         *this = other.derived();
@@ -696,13 +695,12 @@
         internal::call_assignment_no_alias(*this, other.derived());
       }
     }
-    
+
     /** Constructs a sparse matrix from the sparse selfadjoint view \a other */
     template<typename OtherDerived, unsigned int UpLo>
     inline SparseMatrix(const SparseSelfAdjointView<OtherDerived, UpLo>& other)
       : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
     {
-      check_template_parameters();
       Base::operator=(other);
     }
 
@@ -710,7 +708,6 @@
     inline SparseMatrix(const SparseMatrix& other)
       : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
     {
-      check_template_parameters();
       *this = other.derived();
     }
 
@@ -719,17 +716,15 @@
     SparseMatrix(const ReturnByValue<OtherDerived>& other)
       : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
     {
-      check_template_parameters();
       initAssignment(other);
       other.evalTo(*this);
     }
-    
+
     /** \brief Copy constructor with in-place evaluation */
     template<typename OtherDerived>
     explicit SparseMatrix(const DiagonalBase<OtherDerived>& other)
       : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
     {
-      check_template_parameters();
       *this = other.derived();
     }
 
@@ -1013,11 +1008,8 @@
     }
 
 private:
-  static void check_template_parameters()
-  {
-    EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
-    EIGEN_STATIC_ASSERT((Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
-  }
+  EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
+  EIGEN_STATIC_ASSERT((Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS)
 
   struct default_prunning_func {
     default_prunning_func(const Scalar& ref, const RealScalar& eps) : reference(ref), epsilon(eps) {}
diff --git a/Eigen/src/SparseCore/SparseMatrixBase.h b/Eigen/src/SparseCore/SparseMatrixBase.h
index 229449f..ee5eafc 100644
--- a/Eigen/src/SparseCore/SparseMatrixBase.h
+++ b/Eigen/src/SparseCore/SparseMatrixBase.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSEMATRIXBASE_H
 #define EIGEN_SPARSEMATRIXBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \ingroup SparseCore_Module
diff --git a/Eigen/src/SparseCore/SparsePermutation.h b/Eigen/src/SparseCore/SparsePermutation.h
index ef38357..7549434 100644
--- a/Eigen/src/SparseCore/SparsePermutation.h
+++ b/Eigen/src/SparseCore/SparsePermutation.h
@@ -12,6 +12,8 @@
 
 // This file implements sparse * permutation products
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseProduct.h b/Eigen/src/SparseCore/SparseProduct.h
index 78654d1..de11529 100644
--- a/Eigen/src/SparseCore/SparseProduct.h
+++ b/Eigen/src/SparseCore/SparseProduct.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSEPRODUCT_H
 #define EIGEN_SPARSEPRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \returns an expression of the product of two sparse matrices.
diff --git a/Eigen/src/SparseCore/SparseRedux.h b/Eigen/src/SparseCore/SparseRedux.h
index 0748d3b..6b14c58 100644
--- a/Eigen/src/SparseCore/SparseRedux.h
+++ b/Eigen/src/SparseCore/SparseRedux.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSEREDUX_H
 #define EIGEN_SPARSEREDUX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename Derived>
diff --git a/Eigen/src/SparseCore/SparseRef.h b/Eigen/src/SparseCore/SparseRef.h
index f6e18aa..166b17e 100644
--- a/Eigen/src/SparseCore/SparseRef.h
+++ b/Eigen/src/SparseCore/SparseRef.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_REF_H
 #define EIGEN_SPARSE_REF_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 enum {
diff --git a/Eigen/src/SparseCore/SparseSelfAdjointView.h b/Eigen/src/SparseCore/SparseSelfAdjointView.h
index efad570..0302ef3 100644
--- a/Eigen/src/SparseCore/SparseSelfAdjointView.h
+++ b/Eigen/src/SparseCore/SparseSelfAdjointView.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSE_SELFADJOINTVIEW_H
 #define EIGEN_SPARSE_SELFADJOINTVIEW_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
   
 /** \ingroup SparseCore_Module
diff --git a/Eigen/src/SparseCore/SparseSolverBase.h b/Eigen/src/SparseCore/SparseSolverBase.h
index b4c9a42..ea98373 100644
--- a/Eigen/src/SparseCore/SparseSolverBase.h
+++ b/Eigen/src/SparseCore/SparseSolverBase.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSESOLVERBASE_H
 #define EIGEN_SPARSESOLVERBASE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
index 88820a4..efa0a9c 100644
--- a/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
+++ b/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H
 #define EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseTranspose.h b/Eigen/src/SparseCore/SparseTranspose.h
index 3757d4c..cce5903 100644
--- a/Eigen/src/SparseCore/SparseTranspose.h
+++ b/Eigen/src/SparseCore/SparseTranspose.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSETRANSPOSE_H
 #define EIGEN_SPARSETRANSPOSE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/SparseTriangularView.h b/Eigen/src/SparseCore/SparseTriangularView.h
index 9ac1202..76ff97a 100644
--- a/Eigen/src/SparseCore/SparseTriangularView.h
+++ b/Eigen/src/SparseCore/SparseTriangularView.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SPARSE_TRIANGULARVIEW_H
 #define EIGEN_SPARSE_TRIANGULARVIEW_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \ingroup SparseCore_Module
diff --git a/Eigen/src/SparseCore/SparseUtil.h b/Eigen/src/SparseCore/SparseUtil.h
index 9ead5ae..3127c7e 100644
--- a/Eigen/src/SparseCore/SparseUtil.h
+++ b/Eigen/src/SparseCore/SparseUtil.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSEUTIL_H
 #define EIGEN_SPARSEUTIL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 #ifdef NDEBUG
diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h
index c9d0127..5706948 100644
--- a/Eigen/src/SparseCore/SparseVector.h
+++ b/Eigen/src/SparseCore/SparseVector.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSEVECTOR_H
 #define EIGEN_SPARSEVECTOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \ingroup SparseCore_Module
@@ -256,11 +258,11 @@
 
     void resizeNonZeros(Index size) { m_data.resize(size); }
 
-    inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); }
+    inline SparseVector() : m_size(0) { resize(0); }
 
-    explicit inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); }
+    explicit inline SparseVector(Index size) : m_size(0) { resize(size); }
 
-    inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); }
+    inline SparseVector(Index rows, Index cols) : m_size(0) { resize(rows,cols); }
 
     template<typename OtherDerived>
     inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
@@ -269,14 +271,12 @@
       #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
         EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
       #endif
-      check_template_parameters();
       *this = other.derived();
     }
 
     inline SparseVector(const SparseVector& other)
       : Base(other), m_size(0)
     {
-      check_template_parameters();
       *this = other.derived();
     }
 
@@ -393,13 +393,9 @@
 #   endif
 
 protected:
-  
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
-      EIGEN_STATIC_ASSERT((Options_&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
-    }
-    
+    EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
+    EIGEN_STATIC_ASSERT((Options_&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS)
+
     Storage m_data;
     Index m_size;
 };
diff --git a/Eigen/src/SparseCore/SparseView.h b/Eigen/src/SparseCore/SparseView.h
index 92b3d1f..0b9d70a 100644
--- a/Eigen/src/SparseCore/SparseView.h
+++ b/Eigen/src/SparseCore/SparseView.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SPARSEVIEW_H
 #define EIGEN_SPARSEVIEW_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseCore/TriangularSolver.h b/Eigen/src/SparseCore/TriangularSolver.h
index f9c56ba..76c32f2 100644
--- a/Eigen/src/SparseCore/TriangularSolver.h
+++ b/Eigen/src/SparseCore/TriangularSolver.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSETRIANGULARSOLVER_H
 #define EIGEN_SPARSETRIANGULARSOLVER_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/SparseLU/InternalHeaderCheck.h b/Eigen/src/SparseLU/InternalHeaderCheck.h
new file mode 100644
index 0000000..78ebfcc
--- /dev/null
+++ b/Eigen/src/SparseLU/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SPARSELU_MODULE_H
+#error "Please include Eigen/SparseLU instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/SparseLU/SparseLU.h b/Eigen/src/SparseLU/SparseLU.h
index 9814565..cdc2b73 100644
--- a/Eigen/src/SparseLU/SparseLU.h
+++ b/Eigen/src/SparseLU/SparseLU.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_SPARSE_LU_H
 #define EIGEN_SPARSE_LU_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template <typename MatrixType_, typename OrderingType_ = COLAMDOrdering<typename MatrixType_::StorageIndex> > class SparseLU;
diff --git a/Eigen/src/SparseLU/SparseLUImpl.h b/Eigen/src/SparseLU/SparseLUImpl.h
index fc0cfc4..daec837 100644
--- a/Eigen/src/SparseLU/SparseLUImpl.h
+++ b/Eigen/src/SparseLU/SparseLUImpl.h
@@ -9,6 +9,8 @@
 #ifndef SPARSELU_IMPL_H
 #define SPARSELU_IMPL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
   
diff --git a/Eigen/src/SparseLU/SparseLU_Memory.h b/Eigen/src/SparseLU/SparseLU_Memory.h
index 349bfd5..798745f 100644
--- a/Eigen/src/SparseLU/SparseLU_Memory.h
+++ b/Eigen/src/SparseLU/SparseLU_Memory.h
@@ -31,6 +31,8 @@
 #ifndef EIGEN_SPARSELU_MEMORY
 #define EIGEN_SPARSELU_MEMORY
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
   
diff --git a/Eigen/src/SparseLU/SparseLU_Structs.h b/Eigen/src/SparseLU/SparseLU_Structs.h
index cf5ec44..74c6561 100644
--- a/Eigen/src/SparseLU/SparseLU_Structs.h
+++ b/Eigen/src/SparseLU/SparseLU_Structs.h
@@ -68,6 +68,8 @@
 
 #ifndef EIGEN_LU_STRUCTS
 #define EIGEN_LU_STRUCTS
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
   
diff --git a/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h b/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
index 7eda565..0d59a38 100644
--- a/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
+++ b/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SPARSELU_SUPERNODAL_MATRIX_H
 #define EIGEN_SPARSELU_SUPERNODAL_MATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/SparseLU/SparseLU_Utils.h b/Eigen/src/SparseLU/SparseLU_Utils.h
index 9e3dab4..e399fed 100644
--- a/Eigen/src/SparseLU/SparseLU_Utils.h
+++ b/Eigen/src/SparseLU/SparseLU_Utils.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SPARSELU_UTILS_H
 #define EIGEN_SPARSELU_UTILS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/SparseLU/SparseLU_column_bmod.h b/Eigen/src/SparseLU/SparseLU_column_bmod.h
index b57f068..d5c29b3 100644
--- a/Eigen/src/SparseLU/SparseLU_column_bmod.h
+++ b/Eigen/src/SparseLU/SparseLU_column_bmod.h
@@ -31,6 +31,8 @@
 #ifndef SPARSELU_COLUMN_BMOD_H
 #define SPARSELU_COLUMN_BMOD_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/SparseLU/SparseLU_column_dfs.h b/Eigen/src/SparseLU/SparseLU_column_dfs.h
index 5a2c941..be4cfd1 100644
--- a/Eigen/src/SparseLU/SparseLU_column_dfs.h
+++ b/Eigen/src/SparseLU/SparseLU_column_dfs.h
@@ -31,6 +31,8 @@
 #define SPARSELU_COLUMN_DFS_H
 
 template <typename Scalar, typename StorageIndex> class SparseLUImpl;
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h b/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
index c32d8d8..e06b2a0 100644
--- a/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
+++ b/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h
@@ -29,6 +29,8 @@
 #ifndef SPARSELU_COPY_TO_UCOL_H
 #define SPARSELU_COPY_TO_UCOL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/SparseLU/SparseLU_gemm_kernel.h b/Eigen/src/SparseLU/SparseLU_gemm_kernel.h
index e37c2fe..034d379 100644
--- a/Eigen/src/SparseLU/SparseLU_gemm_kernel.h
+++ b/Eigen/src/SparseLU/SparseLU_gemm_kernel.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPARSELU_GEMM_KERNEL_H
 #define EIGEN_SPARSELU_GEMM_KERNEL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h b/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h
index 6f75d50..7bed85d 100644
--- a/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h
+++ b/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h
@@ -28,6 +28,8 @@
 #ifndef SPARSELU_HEAP_RELAX_SNODE_H
 #define SPARSELU_HEAP_RELAX_SNODE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/SparseLU/SparseLU_kernel_bmod.h b/Eigen/src/SparseLU/SparseLU_kernel_bmod.h
index 8c1b3e8..424f93c 100644
--- a/Eigen/src/SparseLU/SparseLU_kernel_bmod.h
+++ b/Eigen/src/SparseLU/SparseLU_kernel_bmod.h
@@ -11,6 +11,8 @@
 #ifndef SPARSELU_KERNEL_BMOD_H
 #define SPARSELU_KERNEL_BMOD_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
   
diff --git a/Eigen/src/SparseLU/SparseLU_panel_bmod.h b/Eigen/src/SparseLU/SparseLU_panel_bmod.h
index f052001..8cd331a 100644
--- a/Eigen/src/SparseLU/SparseLU_panel_bmod.h
+++ b/Eigen/src/SparseLU/SparseLU_panel_bmod.h
@@ -31,6 +31,8 @@
 #ifndef SPARSELU_PANEL_BMOD_H
 #define SPARSELU_PANEL_BMOD_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/SparseLU/SparseLU_panel_dfs.h b/Eigen/src/SparseLU/SparseLU_panel_dfs.h
index 155df73..c3ff013 100644
--- a/Eigen/src/SparseLU/SparseLU_panel_dfs.h
+++ b/Eigen/src/SparseLU/SparseLU_panel_dfs.h
@@ -30,6 +30,8 @@
 #ifndef SPARSELU_PANEL_DFS_H
 #define SPARSELU_PANEL_DFS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/SparseLU/SparseLU_pivotL.h b/Eigen/src/SparseLU/SparseLU_pivotL.h
index a86dac9..6daed91 100644
--- a/Eigen/src/SparseLU/SparseLU_pivotL.h
+++ b/Eigen/src/SparseLU/SparseLU_pivotL.h
@@ -30,6 +30,8 @@
 #ifndef SPARSELU_PIVOTL_H
 #define SPARSELU_PIVOTL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
   
diff --git a/Eigen/src/SparseLU/SparseLU_pruneL.h b/Eigen/src/SparseLU/SparseLU_pruneL.h
index ad32fed..e5da73b 100644
--- a/Eigen/src/SparseLU/SparseLU_pruneL.h
+++ b/Eigen/src/SparseLU/SparseLU_pruneL.h
@@ -30,6 +30,8 @@
 #ifndef SPARSELU_PRUNEL_H
 #define SPARSELU_PRUNEL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/Eigen/src/SparseLU/SparseLU_relax_snode.h b/Eigen/src/SparseLU/SparseLU_relax_snode.h
index c408d01..ed79532 100644
--- a/Eigen/src/SparseLU/SparseLU_relax_snode.h
+++ b/Eigen/src/SparseLU/SparseLU_relax_snode.h
@@ -28,6 +28,8 @@
 #ifndef SPARSELU_RELAX_SNODE_H
 #define SPARSELU_RELAX_SNODE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/SparseQR/InternalHeaderCheck.h b/Eigen/src/SparseQR/InternalHeaderCheck.h
new file mode 100644
index 0000000..0564e93
--- /dev/null
+++ b/Eigen/src/SparseQR/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SPARSEQR_MODULE_H
+#error "Please include Eigen/SparseQR instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/SparseQR/SparseQR.h b/Eigen/src/SparseQR/SparseQR.h
index a19eacc..d3a904d 100644
--- a/Eigen/src/SparseQR/SparseQR.h
+++ b/Eigen/src/SparseQR/SparseQR.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SPARSE_QR_H
 #define EIGEN_SPARSE_QR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename MatrixType, typename OrderingType> class SparseQR;
diff --git a/Eigen/src/StlSupport/StdDeque.h b/Eigen/src/StlSupport/StdDeque.h
index 6d47e75..cd79a15 100644
--- a/Eigen/src/StlSupport/StdDeque.h
+++ b/Eigen/src/StlSupport/StdDeque.h
@@ -11,6 +11,10 @@
 #ifndef EIGEN_STDDEQUE_H
 #define EIGEN_STDDEQUE_H
 
+#ifndef EIGEN_STDDEQUE_MODULE_H
+#error "Please include Eigen/StdDeque instead of including this file directly."
+#endif
+
 #include "details.h"
 
 /**
diff --git a/Eigen/src/StlSupport/StdList.h b/Eigen/src/StlSupport/StdList.h
index 8ba3fad..6070e95 100644
--- a/Eigen/src/StlSupport/StdList.h
+++ b/Eigen/src/StlSupport/StdList.h
@@ -10,6 +10,10 @@
 #ifndef EIGEN_STDLIST_H
 #define EIGEN_STDLIST_H
 
+#ifndef EIGEN_STDLIST_MODULE_H
+#error "Please include Eigen/StdList instead of including this file directly."
+#endif
+
 #include "details.h"
 
 /**
diff --git a/Eigen/src/StlSupport/StdVector.h b/Eigen/src/StlSupport/StdVector.h
index 9fcf19b..93cc4a0 100644
--- a/Eigen/src/StlSupport/StdVector.h
+++ b/Eigen/src/StlSupport/StdVector.h
@@ -11,6 +11,10 @@
 #ifndef EIGEN_STDVECTOR_H
 #define EIGEN_STDVECTOR_H
 
+#ifndef EIGEN_STDVECTOR_MODULE_H
+#error "Please include Eigen/StdVector instead of including this file directly."
+#endif
+
 #include "details.h"
 
 /**
diff --git a/Eigen/src/SuperLUSupport/InternalHeaderCheck.h b/Eigen/src/SuperLUSupport/InternalHeaderCheck.h
new file mode 100644
index 0000000..94a62b5
--- /dev/null
+++ b/Eigen/src/SuperLUSupport/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SUPERLUSUPPORT_MODULE_H
+#error "Please include Eigen/SuperLUSupport instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/SuperLUSupport/SuperLUSupport.h b/Eigen/src/SuperLUSupport/SuperLUSupport.h
index 825988d..f9a9a43 100644
--- a/Eigen/src/SuperLUSupport/SuperLUSupport.h
+++ b/Eigen/src/SuperLUSupport/SuperLUSupport.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SUPERLUSUPPORT_H
 #define EIGEN_SUPERLUSUPPORT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 #if defined(SUPERLU_MAJOR_VERSION) && (SUPERLU_MAJOR_VERSION >= 5)
diff --git a/Eigen/src/UmfPackSupport/InternalHeaderCheck.h b/Eigen/src/UmfPackSupport/InternalHeaderCheck.h
new file mode 100644
index 0000000..64112f1
--- /dev/null
+++ b/Eigen/src/UmfPackSupport/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_UMFPACKSUPPORT_MODULE_H
+#error "Please include Eigen/UmfPackSupport instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/UmfPackSupport/UmfPackSupport.h b/Eigen/src/UmfPackSupport/UmfPackSupport.h
index 07d1f8b..10a8ae2 100644
--- a/Eigen/src/UmfPackSupport/UmfPackSupport.h
+++ b/Eigen/src/UmfPackSupport/UmfPackSupport.h
@@ -20,6 +20,8 @@
 #endif
 #endif
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /* TODO extract L, extract U, compute det, etc... */
diff --git a/Eigen/src/misc/Image.h b/Eigen/src/misc/Image.h
index e99f2d5..b500036 100644
--- a/Eigen/src/misc/Image.h
+++ b/Eigen/src/misc/Image.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_MISC_IMAGE_H
 #define EIGEN_MISC_IMAGE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/misc/InternalHeaderCheck.h b/Eigen/src/misc/InternalHeaderCheck.h
new file mode 100644
index 0000000..1cea572
--- /dev/null
+++ b/Eigen/src/misc/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_CORE_MODULE_H
+#error "Please include Eigen/Core instead of including headers inside the src directory directly."
+#endif
diff --git a/Eigen/src/misc/Kernel.h b/Eigen/src/misc/Kernel.h
index 377a8ce..7abfbb7 100644
--- a/Eigen/src/misc/Kernel.h
+++ b/Eigen/src/misc/Kernel.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_MISC_KERNEL_H
 #define EIGEN_MISC_KERNEL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/Eigen/src/misc/RealSvd2x2.h b/Eigen/src/misc/RealSvd2x2.h
index abb4d3c..5dd75f3 100644
--- a/Eigen/src/misc/RealSvd2x2.h
+++ b/Eigen/src/misc/RealSvd2x2.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_REALSVD2X2_H
 #define EIGEN_REALSVD2X2_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/Eigen/src/plugins/CommonCwiseBinaryOps.h b/Eigen/src/plugins/CommonCwiseBinaryOps.h
index 8b6730e..2f50329 100644
--- a/Eigen/src/plugins/CommonCwiseBinaryOps.h
+++ b/Eigen/src/plugins/CommonCwiseBinaryOps.h
@@ -12,7 +12,7 @@
 
 /** \returns an expression of the difference of \c *this and \a other
   *
-  * \note If you want to substract a given scalar from all coefficients, see Cwise::operator-().
+  * \note If you want to subtract a given scalar from all coefficients, see Cwise::operator-().
   *
   * \sa class CwiseBinaryOp, operator-=()
   */
diff --git a/Eigen/src/plugins/IndexedViewMethods.h b/Eigen/src/plugins/IndexedViewMethods.h
index 5bfb19a..463602a 100644
--- a/Eigen/src/plugins/IndexedViewMethods.h
+++ b/Eigen/src/plugins/IndexedViewMethods.h
@@ -218,7 +218,7 @@
   *
   * Each parameter must either be:
   *  - An integer indexing a single row or column
-  *  - Eigen::all indexing the full set of respective rows or columns in increasing order
+  *  - Eigen::placeholders::all indexing the full set of respective rows or columns in increasing order
   *  - An ArithmeticSequence as returned by the Eigen::seq and Eigen::seqN functions
   *  - Any %Eigen's vector/array of integers or expressions
   *  - Plain C arrays: \c int[N]
@@ -235,7 +235,7 @@
   * method will returns a Block object after extraction of the relevant information from the passed arguments. This is the case
   * when all arguments are either:
   *  - An integer
-  *  - Eigen::all
+  *  - Eigen::placeholders::all
   *  - An ArithmeticSequence with compile-time increment strictly equal to 1, as returned by Eigen::seq(a,b), and Eigen::seqN(a,N).
   *
   * Otherwise a more general IndexedView<Derived,RowIndices',ColIndices'> object will be returned, after conversion of the inputs
diff --git a/Eigen/src/plugins/InternalHeaderCheck.h b/Eigen/src/plugins/InternalHeaderCheck.h
new file mode 100644
index 0000000..ac6821d
--- /dev/null
+++ b/Eigen/src/plugins/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_CORE_MODULE_H
+#error "Please include Eigen/plugins instead of including headers inside the src directory directly."
+#endif
diff --git a/cmake/EigenConfigureTesting.cmake b/cmake/EigenConfigureTesting.cmake
index 9cb3bb2..2a1e7ab 100644
--- a/cmake/EigenConfigureTesting.cmake
+++ b/cmake/EigenConfigureTesting.cmake
@@ -8,9 +8,18 @@
 ei_set_build_string()
 
 add_custom_target(buildtests)
-add_custom_target(check COMMAND "ctest")
+add_custom_target(check COMMAND "ctest" ${EIGEN_CTEST_ARGS})
 add_dependencies(check buildtests)
 
+# Convenience target for only building GPU tests.
+add_custom_target(buildtests_gpu)
+add_custom_target(check_gpu COMMAND "ctest" "--output-on-failure" 
+                                            "--no-compress-output"
+                                            "--build-no-clean"
+                                            "-T" "test"
+                                            "-L" "gpu")
+add_dependencies(check_gpu buildtests_gpu)
+
 # check whether /bin/bash exists (disabled as not used anymore)
 # find_file(EIGEN_BIN_BASH_EXISTS "/bin/bash" PATHS "/" NO_DEFAULT_PATH)
 
diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake
index eb8457d..5711901 100644
--- a/cmake/EigenTesting.cmake
+++ b/cmake/EigenTesting.cmake
@@ -23,7 +23,9 @@
   set(EIGEN_SUBTESTS_LIST "${EIGEN_SUBTESTS_LIST}${targetname}\n")
   set_property(GLOBAL PROPERTY EIGEN_SUBTESTS_LIST "${EIGEN_SUBTESTS_LIST}")
 
+  set(is_gpu_test OFF)
   if(EIGEN_ADD_TEST_FILENAME_EXTENSION STREQUAL cu)
+    set(is_gpu_test ON)
     if(EIGEN_TEST_HIP)
       hip_reset_flags()
       hip_add_executable(${targetname} ${filename} HIPCC_OPTIONS "-DEIGEN_USE_HIP ${ARGV2}")
@@ -57,10 +59,10 @@
     add_executable(${targetname} ${filename})
   endif()
 
-  if (targetname MATCHES "^eigen2_")
-    add_dependencies(eigen2_buildtests ${targetname})
-  else()
-    add_dependencies(buildtests ${targetname})
+  add_dependencies(buildtests ${targetname})
+  
+  if (is_gpu_test)
+    add_dependencies(buildtests_gpu ${targetname})
   endif()
 
   if(EIGEN_NO_ASSERTION_CHECKING)
@@ -118,6 +120,11 @@
     add_dependencies("Build${current_subproject}" ${targetname})
     set_property(TEST ${testname_with_suffix} PROPERTY LABELS "${current_subproject}")
   endif()
+  if (is_gpu_test)
+    # Add gpu tag for testing only GPU tests.
+    set_property(TEST ${testname_with_suffix} APPEND PROPERTY LABELS "gpu")
+  endif()
+  
   if(EIGEN_SYCL)
     # Force include of the SYCL file at the end to avoid errors.
     set_property(TARGET ${targetname} PROPERTY COMPUTECPP_INCLUDE_AFTER 1)
@@ -671,8 +678,8 @@
 # Split all tests listed in EIGEN_TESTS_LIST into num_splits many targets
 # named buildtestspartN with N = { 0, ..., num_splits-1}.
 #
-# The intention behind the existance of this macro is the size of Eigen's
-# testsuite. Together with the relativly big compile-times building all tests
+# The intention behind the existence of this macro is the size of Eigen's
+# testsuite. Together with the relatively big compile-times building all tests
 # can take a substantial amount of time depending on the available hardware.
 # 
 # The last buildtestspartN target will build possible remaining tests.
@@ -775,8 +782,7 @@
     if ("${test}" IN_LIST EIGEN_SUBTESTS_LIST)
       add_dependencies("${buildtarget}" "${test}")
       # Add label smoketest to be able to run smoketests using ctest
-      get_property(test_labels TEST ${test} PROPERTY LABELS)
-      set_property(TEST ${test} PROPERTY LABELS "${test_labels};smoketest")
+      set_property(TEST ${test} APPEND PROPERTY LABELS "smoketest")
     endif()
   endforeach()
 endmacro(ei_add_smoke_tests)
diff --git a/cmake/FindComputeCpp.cmake b/cmake/FindComputeCpp.cmake
index 1c271f0..e200522 100644
--- a/cmake/FindComputeCpp.cmake
+++ b/cmake/FindComputeCpp.cmake
@@ -382,7 +382,7 @@
 #######################
 #
 #  Adds a SYCL compilation custom command associated with an existing
-#  target and sets a dependancy on that new command.
+#  target and sets a dependency on that new command.
 #
 #  TARGET : Name of the target to add SYCL to.
 #  SOURCES : Source files to be compiled for SYCL.
diff --git a/debug/lldb/eigenlldb.py b/debug/lldb/eigenlldb.py
new file mode 100644
index 0000000..d9b5d06
--- /dev/null
+++ b/debug/lldb/eigenlldb.py
@@ -0,0 +1,234 @@
+# -*- coding: utf-8 -*-
+# This file is part of Eigen, a lightweight C++ template library
+# for linear algebra.
+#
+# Copyright (C) 2021 Huang, Zhaoquan <zhaoquan2008@hotmail.com>
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Pretty printers for Eigen::Matrix to use with LLDB debugger
+#
+# Usage:
+# 1. Add the following line (change it according to the path to this file)
+#    to the file ~/.lldbinit (create one if it doesn't exist):
+#        `command script import /path/to/eigenlldb.py`
+# 2. Inspect the variables in LLDB command line
+#        `frame variable`
+
+import lldb
+from typing import List
+import bisect
+
+
+def __lldb_init_module(debugger, internal_dict):
+    debugger.HandleCommand("type synthetic add -x Eigen::Matrix<.*> --python-class eigenlldb.EigenMatrixChildProvider")
+    debugger.HandleCommand(
+        "type synthetic add -x Eigen::SparseMatrix<.*> --python-class eigenlldb.EigenSparseMatrixChildProvider")
+
+
+class EigenMatrixChildProvider:
+    _valobj: lldb.SBValue
+    _scalar_type: lldb.SBType
+    _scalar_size: int
+    _rows_compile_time: int
+    _cols_compile_time: int
+    _row_major: bool
+    _fixed_storage: bool
+
+    def __init__(self, valobj, internal_dict):
+        self._valobj = valobj
+        valtype = valobj.GetType().GetCanonicalType()
+
+        scalar_type = valtype.GetTemplateArgumentType(0)
+        if not scalar_type.IsValid():
+            # In the case that scalar_type is invalid on LLDB 9.0 on Windows with CLion
+            storage = valobj.GetChildMemberWithName("m_storage")
+            data = storage.GetChildMemberWithName("m_data")
+            data_type = data.GetType()
+            if data_type.IsPointerType():
+                scalar_type = data.GetType().GetPointeeType()
+            else:
+                scalar_type = data.GetChildMemberWithName("array").GetType().GetArrayElementType()
+        self._scalar_type = scalar_type
+        self._scalar_size = self._scalar_type.GetByteSize()
+
+        name = valtype.GetName()
+        template_begin = name.find("<")
+        template_end = name.find(">")
+        template_args = name[(template_begin + 1):template_end].split(",")
+        self._rows_compile_time = int(template_args[1])
+        self._cols_compile_time = int(template_args[2])
+        self._row_major = (int(template_args[3]) & 1) != 0
+
+        max_rows = int(template_args[4])
+        max_cols = int(template_args[5])
+        self._fixed_storage = (max_rows != -1 and max_cols != -1)
+
+    def num_children(self):
+        return self._cols() * self._rows()
+
+    def get_child_index(self, name):
+        pass
+
+    def get_child_at_index(self, index):
+        storage = self._valobj.GetChildMemberWithName("m_storage")
+        data = storage.GetChildMemberWithName("m_data")
+        offset = self._scalar_size * index
+
+        if self._row_major:
+            row = index // self._cols()
+            col = index % self._cols()
+        else:
+            row = index % self._rows()
+            col = index // self._rows()
+        if self._fixed_storage:
+            data = data.GetChildMemberWithName("array")
+        if self._cols() == 1:
+            name = '[{}]'.format(row)
+        elif self._rows() == 1:
+            name = '[{}]'.format(col)
+        else:
+            name = '[{},{}]'.format(row, col)
+        return data.CreateChildAtOffset(
+            name, offset, self._scalar_type
+        )
+
+    def _cols(self):
+        if self._cols_compile_time == -1:
+            storage = self._valobj.GetChildMemberWithName("m_storage")
+            cols = storage.GetChildMemberWithName("m_cols")
+            return cols.GetValueAsUnsigned()
+        else:
+            return self._cols_compile_time
+
+    def _rows(self):
+        if self._rows_compile_time == -1:
+            storage = self._valobj.GetChildMemberWithName("m_storage")
+            rows = storage.GetChildMemberWithName("m_rows")
+            return rows.GetValueAsUnsigned()
+        else:
+            return self._rows_compile_time
+
+
+class EigenSparseMatrixChildProvider:
+    _valobj: lldb.SBValue
+    _scalar_type: lldb.SBType
+    _scalar_size: int
+    _index_type: lldb.SBType
+    _index_size: int
+    _row_major: bool
+
+    _outer_size: int
+    _nnz: int
+    _values: lldb.SBValue
+    _inner_indices: lldb.SBValue
+    _outer_starts: lldb.SBValue
+    _inner_nnzs: lldb.SBValue
+    _compressed: bool
+
+    # Index of the first synthetic child under each outer index
+    _child_indices: List[int]
+
+    def __init__(self, valobj, internal_dict):
+        self._valobj = valobj
+        valtype = valobj.GetType().GetCanonicalType()
+        scalar_type = valtype.GetTemplateArgumentType(0)
+        if not scalar_type.IsValid():
+            # In the case that scalar_type is invalid on LLDB 9.0 on Windows with CLion
+            data = valobj.GetChildMemberWithName("m_data")
+            values = data.GetChildMemberWithName("m_values")
+            scalar_type = values.GetType().GetPointeeType()
+        self._scalar_type = scalar_type
+        self._scalar_size = scalar_type.GetByteSize()
+
+        index_type = valtype.GetTemplateArgumentType(2)
+        if not index_type.IsValid():
+            # In the case that scalar_type is invalid on LLDB 9.0 on Windows with CLion
+            outer_starts = valobj.GetChildMemberWithName("m_outerIndex")
+            index_type = outer_starts.GetType().GetPointeeType()
+        self._index_type = index_type
+        self._index_size = index_type.GetByteSize()
+
+        name = valtype.GetName()
+        template_begin = name.find("<")
+        template_end = name.find(">")
+        template_args = name[(template_begin + 1):template_end].split(",")
+        self._row_major = (int(template_args[1]) & 1) != 0
+
+    def num_children(self):
+        return self._nnz + 2
+
+    def get_child_index(self, name):
+        pass
+
+    def get_child_at_index(self, index):
+        if index == 0:
+            name = "rows" if self._row_major else "cols"
+            return self._valobj.GetChildMemberWithName("m_outerSize") \
+                .CreateChildAtOffset(name, 0, self._index_type)
+        elif index == 1:
+            name = "cols" if self._row_major else "rows"
+            return self._valobj.GetChildMemberWithName("m_innerSize") \
+                .CreateChildAtOffset(name, 0, self._index_type)
+        else:
+            index = index - 2
+        outer_index = bisect.bisect_right(self._child_indices, index) - 1
+        total_nnzs = self._child_indices[outer_index]
+        if self._compressed:
+            item_index = index
+            inner_index = self._inner_indices \
+                .CreateChildAtOffset("", item_index * self._index_size, self._index_type) \
+                .GetValueAsUnsigned()
+            return self._values \
+                .CreateChildAtOffset(self._child_name(outer_index, inner_index),
+                                     item_index * self._scalar_size,
+                                     self._scalar_type)
+        else:
+            index_begin = self._outer_starts \
+                .CreateChildAtOffset("", outer_index * self._index_size, self._index_type) \
+                .GetValueAsUnsigned()
+            item_index = index - total_nnzs + index_begin
+            inner_index = self._inner_indices \
+                .CreateChildAtOffset("", item_index * self._index_size, self._index_type) \
+                .GetValueAsUnsigned()
+            return self._values \
+                .CreateChildAtOffset(self._child_name(outer_index, inner_index),
+                                     item_index * self._scalar_size,
+                                     self._scalar_type)
+
+    def update(self):
+        valobj = self._valobj
+        self._outer_size = valobj.GetChildMemberWithName("m_outerSize").GetValueAsUnsigned()
+        data = valobj.GetChildMemberWithName("m_data")
+        self._values = data.GetChildMemberWithName("m_values")
+        self._inner_indices = data.GetChildMemberWithName("m_indices")
+        self._outer_starts = valobj.GetChildMemberWithName("m_outerIndex")
+        self._inner_nnzs = valobj.GetChildMemberWithName("m_innerNonZeros")
+
+        self._compressed = self._inner_nnzs.GetValueAsUnsigned() == 0
+
+        total_nnzs = 0
+        child_indices = [0]
+        for outer_index in range(self._outer_size):
+            if self._compressed:
+                index_end = self._outer_starts \
+                    .CreateChildAtOffset("", (outer_index + 1) * self._index_size, self._index_type) \
+                    .GetValueAsUnsigned()
+                total_nnzs = index_end
+                child_indices.append(total_nnzs)
+            else:
+                nnzs = self._inner_nnzs \
+                    .CreateChildAtOffset("", outer_index * self._index_size, self._index_type) \
+                    .GetValueAsUnsigned()
+                total_nnzs = total_nnzs + nnzs
+                child_indices.append(total_nnzs)
+        self._child_indices = child_indices
+        self._nnz = total_nnzs
+
+    def _child_name(self, outer_index, inner_index):
+        if self._row_major:
+            return "[{0},{1}]".format(outer_index, inner_index)
+        else:
+            return "[{1},{0}]".format(outer_index, inner_index)
diff --git a/doc/PreprocessorDirectives.dox b/doc/PreprocessorDirectives.dox
index 0f545b0..9d46388 100644
--- a/doc/PreprocessorDirectives.dox
+++ b/doc/PreprocessorDirectives.dox
@@ -104,7 +104,7 @@
  - \b \c EIGEN_MAX_ALIGN_BYTES - Must be a power of two, or 0. Defines an upper bound on the memory boundary in bytes on which dynamically and statically allocated data may be aligned by %Eigen. If not defined, a default value is automatically computed based on architecture, compiler, and OS.
  This option is typically used to enforce binary compatibility between code/libraries compiled with different SIMD options. For instance, one may compile AVX code and enforce ABI compatibility with existing SSE code by defining \c EIGEN_MAX_ALIGN_BYTES=16. In the other way round, since by default AVX implies 32 bytes alignment for best performance, one can compile SSE code to be ABI compatible with AVX code by defining \c EIGEN_MAX_ALIGN_BYTES=32.
  - \b \c EIGEN_MAX_STATIC_ALIGN_BYTES - Same as \c EIGEN_MAX_ALIGN_BYTES but for statically allocated data only. By default, if only  \c EIGEN_MAX_ALIGN_BYTES is defined, then \c EIGEN_MAX_STATIC_ALIGN_BYTES == \c EIGEN_MAX_ALIGN_BYTES, otherwise a default value is automatically computed based on architecture, compiler, and OS (can be smaller than the default value of EIGEN_MAX_ALIGN_BYTES on architectures that do not support stack alignment).
- Let us emphasize that \c EIGEN_MAX_*_ALIGN_BYTES define only a diserable upper bound. In practice data is aligned to largest power-of-two common divisor of \c EIGEN_MAX_STATIC_ALIGN_BYTES and the size of the data, such that memory is not wasted.
+ Let us emphasize that \c EIGEN_MAX_*_ALIGN_BYTES define only a desirable upper bound. In practice data is aligned to largest power-of-two common divisor of \c EIGEN_MAX_STATIC_ALIGN_BYTES and the size of the data, such that memory is not wasted.
  - \b \c EIGEN_DONT_PARALLELIZE - if defined, this disables multi-threading. This is only relevant if you enabled OpenMP.
    See \ref TopicMultiThreading for details.
  - \b \c EIGEN_DONT_VECTORIZE - disables explicit vectorization when defined. Not defined by default, unless 
diff --git a/doc/TopicLinearAlgebraDecompositions.dox b/doc/TopicLinearAlgebraDecompositions.dox
index 402b376..8598ce6 100644
--- a/doc/TopicLinearAlgebraDecompositions.dox
+++ b/doc/TopicLinearAlgebraDecompositions.dox
@@ -272,7 +272,7 @@
   <dt><b>Blocking</b></dt>
     <dd>Means the algorithm can work per block, whence guaranteeing a good scaling of the performance for large matrices.</dd>
   <dt><b>Implicit Multi Threading (MT)</b></dt>
-    <dd>Means the algorithm can take advantage of multicore processors via OpenMP. "Implicit" means the algortihm itself is not parallelized, but that it relies on parallelized matrix-matrix product routines.</dd>
+    <dd>Means the algorithm can take advantage of multicore processors via OpenMP. "Implicit" means the algorithm itself is not parallelized, but that it relies on parallelized matrix-matrix product routines.</dd>
   <dt><b>Explicit Multi Threading (MT)</b></dt>
     <dd>Means the algorithm is explicitly parallelized to take advantage of multicore processors via OpenMP.</dd>
   <dt><b>Meta-unroller</b></dt>
diff --git a/doc/TutorialSlicingIndexing.dox b/doc/TutorialSlicingIndexing.dox
index 98ace43..57cc401 100644
--- a/doc/TutorialSlicingIndexing.dox
+++ b/doc/TutorialSlicingIndexing.dox
@@ -15,7 +15,7 @@
 Each argument can be:
   - An integer indexing a single row or column, including symbolic indices.
   - The symbol Eigen::all representing the whole set of respective rows or columns in increasing order.
-  - An ArithmeticSequence as constructed by the Eigen::seq, Eigen::seqN, or Eigen::lastN functions.
+  - An ArithmeticSequence as constructed by the Eigen::seq, Eigen::seqN, or Eigen::placeholders::lastN functions.
   - Any 1D vector/array of integers including %Eigen's vector/array, expressions, std::vector, std::array, as well as plain C arrays: `int[N]`.
 
 More generally, it can accepts any object exposing the following two member functions:
@@ -112,9 +112,10 @@
 </tr>
 </table>
 
-As seen in the last exemple, referencing the <i> last n </i> elements (or rows/columns) is a bit cumbersome to write.
+As seen in the last example, referencing the <i> last n </i> elements (or rows/columns) is a bit cumbersome to write.
 This becomes even more tricky and error prone with a non-default increment.
-Here comes \link Eigen::lastN(SizeType) Eigen::lastN(size) \endlink, and \link Eigen::lastN(SizeType,IncrType) Eigen::lastN(size,incr) \endlink:
+Here comes \link Eigen::placeholders::lastN(SizeType) Eigen::placeholders::lastN(size) \endlink, and
+\link Eigen::placeholders::lastN(SizeType,IncrType) Eigen::placeholders::lastN(size,incr) \endlink:
 
 <table class="manual">
 <tr>
@@ -221,7 +222,7 @@
 \endcode
 
 This means you can easily build your own fancy sequence generator and pass it to `operator()`.
-Here is an exemple enlarging a given matrix while padding the additional first rows and columns through repetition:
+Here is an example enlarging a given matrix while padding the additional first rows and columns through repetition:
 
 <table class="example">
 <tr><th>Example:</th><th>Output:</th></tr>
diff --git a/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp b/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp
index bbb821e..cc0c50e 100644
--- a/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp
+++ b/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp
@@ -3,7 +3,7 @@
 cout << "Here is a random symmetric matrix, A:" << endl << A << endl;
 X = MatrixXd::Random(5,5);
 MatrixXd B = X * X.transpose();
-cout << "and a random postive-definite matrix, B:" << endl << B << endl << endl;
+cout << "and a random positive-definite matrix, B:" << endl << B << endl << endl;
 
 GeneralizedSelfAdjointEigenSolver<MatrixXd> es(A,B);
 cout << "The eigenvalues of the pencil (A,B) are:" << endl << es.eigenvalues() << endl;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f0136db..ad09599 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -288,6 +288,8 @@
 ei_add_test(random_matrix)
 ei_add_test(initializer_list_construction)
 ei_add_test(diagonal_matrix_variadic_ctor)
+ei_add_test(serializer)
+ei_add_test(tuple_test)
 
 add_executable(bug1213 bug1213.cpp bug1213_main.cpp)
 
@@ -382,42 +384,51 @@
   message(WARNING "EIGEN_TEST_CUDA_CLANG is set, but CMAKE_CXX_COMPILER does not appear to be clang.")
 endif()
 
-if(EIGEN_TEST_CUDA)
+find_package(CUDA 9.0)
+if(CUDA_FOUND AND EIGEN_TEST_CUDA)
+  # Make sure to compile without the -pedantic, -Wundef, -Wnon-virtual-dtor
+  # and -fno-check-new flags since they trigger thousands of compilation warnings
+  # in the CUDA runtime
+  string(REPLACE "-pedantic" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  string(REPLACE "-Wundef" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  string(REPLACE "-Wnon-virtual-dtor" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  string(REPLACE "-fno-check-new" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")  
 
-find_package(CUDA 5.0)
-if(CUDA_FOUND)
-  
-  set(CUDA_PROPAGATE_HOST_FLAGS OFF)
-  
-  set(EIGEN_CUDA_RELAXED_CONSTEXPR "--expt-relaxed-constexpr")
-  if (${CUDA_VERSION} STREQUAL "7.0")
-    set(EIGEN_CUDA_RELAXED_CONSTEXPR "--relaxed-constexpr")
-  endif()
-  
-  if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 
-    set(CUDA_NVCC_FLAGS "-ccbin ${CMAKE_C_COMPILER}" CACHE STRING "nvcc flags" FORCE)
-  endif()
   if(EIGEN_TEST_CUDA_CLANG)
     string(APPEND CMAKE_CXX_FLAGS " --cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
     foreach(GPU IN LISTS EIGEN_CUDA_COMPUTE_ARCH)
       string(APPEND CMAKE_CXX_FLAGS " --cuda-gpu-arch=sm_${GPU}")
     endforeach()
+    string(APPEND CMAKE_CXX_FLAGS " ${EIGEN_CUDA_CXX_FLAGS}")
   else()
-    foreach(GPU IN LISTS EIGEN_CUDA_COMPUTE_ARCH)
-      string(APPEND CUDA_NVCC_FLAGS " -gencode arch=compute_${GPU},code=sm_${GPU}")
+    set(CUDA_PROPAGATE_HOST_FLAGS OFF)
+    set(NVCC_ARCH_FLAGS)
+    # Define an -arch=sm_<arch>, otherwise if GPU does not exactly match one of
+    # those in the arch list for -gencode, the kernels will fail to run with
+    #    cudaErrorNoKernelImageForDevice
+    # This can happen with newer cards (e.g. sm_75) and compiling with older
+    # versions of nvcc (e.g. 9.2) that do not support their specific arch.
+    list(LENGTH EIGEN_CUDA_COMPUTE_ARCH EIGEN_CUDA_COMPUTE_ARCH_SIZE)
+    if(EIGEN_CUDA_COMPUTE_ARCH_SIZE)
+      list(GET EIGEN_CUDA_COMPUTE_ARCH 0 EIGEN_CUDA_COMPUTE_DEFAULT)
+      set(NVCC_ARCH_FLAGS " -arch=sm_${EIGEN_CUDA_COMPUTE_DEFAULT}")
+    endif()
+    foreach(ARCH IN LISTS EIGEN_CUDA_COMPUTE_ARCH)
+      string(APPEND NVCC_ARCH_FLAGS " -gencode arch=compute_${ARCH},code=sm_${ARCH}")
     endforeach()
+    set(CUDA_NVCC_FLAGS  "--expt-relaxed-constexpr -Xcudafe \"--display_error_number\" ${NVCC_ARCH_FLAGS} ${CUDA_NVCC_FLAGS} ${EIGEN_CUDA_CXX_FLAGS}")
+    cuda_include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}/include")
   endif()
-  string(APPEND CUDA_NVCC_FLAGS " ${EIGEN_CUDA_RELAXED_CONSTEXPR}")
+  
   set(EIGEN_ADD_TEST_FILENAME_EXTENSION  "cu")
   
+  ei_add_test(gpu_example)
   ei_add_test(gpu_basic)
   
   unset(EIGEN_ADD_TEST_FILENAME_EXTENSION)
 
 endif()
 
-endif()
-
 
 # HIP unit tests
 option(EIGEN_TEST_HIP "Add HIP support." OFF)
@@ -440,6 +451,7 @@
 
 	set(EIGEN_ADD_TEST_FILENAME_EXTENSION  "cu")
 	ei_add_test(gpu_basic)
+  ei_add_test(gpu_example)
 	unset(EIGEN_ADD_TEST_FILENAME_EXTENSION)
 	
       elseif ((${HIP_PLATFORM} STREQUAL "nvcc") OR (${HIP_PLATFORM} STREQUAL "nvidia"))
diff --git a/test/adjoint.cpp b/test/adjoint.cpp
index 4c4f98b..84f430c 100644
--- a/test/adjoint.cpp
+++ b/test/adjoint.cpp
@@ -7,8 +7,6 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT
-
 #include "main.h"
 
 template<bool IsInteger> struct adjoint_specific;
diff --git a/test/basicstuff.cpp b/test/basicstuff.cpp
index 4ca607c..00ef96a 100644
--- a/test/basicstuff.cpp
+++ b/test/basicstuff.cpp
@@ -7,11 +7,20 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT
-
 #include "main.h"
 #include "random_without_cast_overflow.h"
 
+template <typename MatrixType>
+typename internal::enable_if<(MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1),void>::type
+check_index(const MatrixType& m) {
+  VERIFY_RAISES_ASSERT(m[0]);
+  VERIFY_RAISES_ASSERT((m+m)[0]);
+}
+
+template <typename MatrixType>
+typename internal::enable_if<!(MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1),void>::type
+check_index(const MatrixType& /*unused*/) {}
+
 template<typename MatrixType> void basicStuff(const MatrixType& m)
 {
   typedef typename MatrixType::Scalar Scalar;
@@ -101,8 +110,7 @@
 
   if(cols!=1 && rows!=1)
   {
-    VERIFY_RAISES_ASSERT(m1[0]);
-    VERIFY_RAISES_ASSERT((m1+m1)[0]);
+    check_index(m1);
   }
 
   VERIFY_IS_APPROX(m3 = m1,m1);
diff --git a/test/block.cpp b/test/block.cpp
index 84124ab..43849ad 100644
--- a/test/block.cpp
+++ b/test/block.cpp
@@ -7,7 +7,6 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT // otherwise we fail at compile time on unused paths
 #include "main.h"
 
 template<typename MatrixType, typename Index, typename Scalar>
@@ -37,6 +36,20 @@
   return a.isApprox(b);
 }
 
+template <typename MatrixType>
+typename internal::enable_if<((MatrixType::Flags&RowMajorBit)==0),void>::type
+check_left_top(const MatrixType& m, Index r, Index c,
+               Index rows, Index /*unused*/) {
+  VERIFY_IS_EQUAL(m.leftCols(c).coeff(r+c*rows), m(r,c));
+}
+
+template <typename MatrixType>
+typename internal::enable_if<((MatrixType::Flags&RowMajorBit)!=0),void>::type
+check_left_top(const MatrixType& m,  Index r, Index c,
+               Index /*unused*/, Index cols) {
+  VERIFY_IS_EQUAL(m.topRows(r).coeff(c+r*cols), m(r,c));
+}
+
 template<typename MatrixType> void block(const MatrixType& m)
 {
   typedef typename MatrixType::Scalar Scalar;
@@ -79,7 +92,8 @@
   VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + s1 * m1_copy.col(c2));
   m1.col(c1).col(0) += s1 * m1_copy.col(c2);
   VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + Scalar(2) * s1 * m1_copy.col(c2));
-  
+
+  check_left_top(m1,r1,c1,rows,cols);
   
   //check block()
   Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);
@@ -143,11 +157,6 @@
   
   // check that linear acccessors works on blocks
   m1 = m1_copy;
-  if((MatrixType::Flags&RowMajorBit)==0)
-    VERIFY_IS_EQUAL(m1.leftCols(c1).coeff(r1+c1*rows), m1(r1,c1));
-  else
-    VERIFY_IS_EQUAL(m1.topRows(r1).coeff(c1+r1*cols), m1(r1,c1));
-  
 
   // now test some block-inside-of-block.
   
@@ -213,14 +222,6 @@
   VERIFY_IS_EQUAL( ((m1*1).template block<Dynamic,1>(1,0,0,1)), m1.block(1,0,0,1));
   VERIFY_IS_EQUAL( ((m1*1).template block<1,Dynamic>(0,1,1,0)), m1.block(0,1,1,0));
 
-  if (rows>=2 && cols>=2)
-  {
-    VERIFY_RAISES_ASSERT( m1 += m1.col(0) );
-    VERIFY_RAISES_ASSERT( m1 -= m1.col(0) );
-    VERIFY_RAISES_ASSERT( m1.array() *= m1.col(0).array() );
-    VERIFY_RAISES_ASSERT( m1.array() /= m1.col(0).array() );
-  }
-
   VERIFY_IS_EQUAL( m1.template subVector<Horizontal>(r1), m1.row(r1) );
   VERIFY_IS_APPROX( (m1+m1).template subVector<Horizontal>(r1), (m1+m1).row(r1) );
   VERIFY_IS_EQUAL( m1.template subVector<Vertical>(c1), m1.col(c1) );
@@ -240,13 +241,35 @@
 }
 
 
+
 template<typename MatrixType>
-void compare_using_data_and_stride(const MatrixType& m)
+typename internal::enable_if<MatrixType::IsVectorAtCompileTime,void>::type
+compare_using_data_and_stride(const MatrixType& m)
 {
   Index rows = m.rows();
   Index cols = m.cols();
   Index size = m.size();
   Index innerStride = m.innerStride();
+  Index rowStride = m.rowStride();
+  Index colStride = m.colStride();
+  const typename MatrixType::Scalar* data = m.data();
+
+  for(int j=0;j<cols;++j)
+    for(int i=0;i<rows;++i)
+      VERIFY(m.coeff(i,j) == data[i*rowStride + j*colStride]);
+
+  VERIFY(innerStride == int((&m.coeff(1))-(&m.coeff(0))));
+  for (int i=0;i<size;++i)
+    VERIFY(m.coeff(i) == data[i*innerStride]);
+}
+
+template<typename MatrixType>
+typename internal::enable_if<!MatrixType::IsVectorAtCompileTime,void>::type
+compare_using_data_and_stride(const MatrixType& m)
+{
+  Index rows = m.rows();
+  Index cols = m.cols();
+  Index innerStride = m.innerStride();
   Index outerStride = m.outerStride();
   Index rowStride = m.rowStride();
   Index colStride = m.colStride();
@@ -256,21 +279,11 @@
     for(int i=0;i<rows;++i)
       VERIFY(m.coeff(i,j) == data[i*rowStride + j*colStride]);
 
-  if(!MatrixType::IsVectorAtCompileTime)
-  {
-    for(int j=0;j<cols;++j)
-      for(int i=0;i<rows;++i)
-        VERIFY(m.coeff(i,j) == data[(MatrixType::Flags&RowMajorBit)
-                                     ? i*outerStride + j*innerStride
-                                     : j*outerStride + i*innerStride]);
-  }
-
-  if(MatrixType::IsVectorAtCompileTime)
-  {
-    VERIFY(innerStride == int((&m.coeff(1))-(&m.coeff(0))));
-    for (int i=0;i<size;++i)
-      VERIFY(m.coeff(i) == data[i*innerStride]);
-  }
+  for(int j=0;j<cols;++j)
+    for(int i=0;i<rows;++i)
+      VERIFY(m.coeff(i,j) == data[(MatrixType::Flags&RowMajorBit)
+                                  ? i*outerStride + j*innerStride
+                                  : j*outerStride + i*innerStride]);
 }
 
 template<typename MatrixType>
diff --git a/test/diagonal_matrix_variadic_ctor.cpp b/test/diagonal_matrix_variadic_ctor.cpp
index fbc8f84..db56539 100644
--- a/test/diagonal_matrix_variadic_ctor.cpp
+++ b/test/diagonal_matrix_variadic_ctor.cpp
@@ -7,32 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT
-
 #include "main.h"
 
-template <typename Scalar>
-void assertionTest()
-{
-  typedef DiagonalMatrix<Scalar, 5> DiagMatrix5;
-  typedef DiagonalMatrix<Scalar, 7> DiagMatrix7;
-  typedef DiagonalMatrix<Scalar, Dynamic> DiagMatrixX;
-
-  Scalar raw[6];
-  for (int i = 0; i < 6; ++i) {
-    raw[i] = internal::random<Scalar>();
-  }
-
-  VERIFY_RAISES_ASSERT((DiagMatrix5{raw[0], raw[1], raw[2], raw[3]}));
-  VERIFY_RAISES_ASSERT((DiagMatrix5{raw[0], raw[1], raw[3]}));
-  VERIFY_RAISES_ASSERT((DiagMatrix7{raw[0], raw[1], raw[2], raw[3]}));
-
-  VERIFY_RAISES_ASSERT((DiagMatrixX {
-    {raw[0], raw[1], raw[2]},
-    {raw[3], raw[4], raw[5]}
-  }));
-}
-
 #define VERIFY_IMPLICIT_CONVERSION_3(DIAGTYPE, V0, V1, V2) \
   DIAGTYPE d(V0, V1, V2);                                  \
   DIAGTYPE::DenseMatrixType Dense = d.toDenseMatrix();     \
@@ -167,14 +143,6 @@
 
 EIGEN_DECLARE_TEST(diagonal_matrix_variadic_ctor)
 {
-  CALL_SUBTEST_1(assertionTest<unsigned char>());
-  CALL_SUBTEST_1(assertionTest<float>());
-  CALL_SUBTEST_1(assertionTest<Index>());
-  CALL_SUBTEST_1(assertionTest<int>());
-  CALL_SUBTEST_1(assertionTest<long int>());
-  CALL_SUBTEST_1(assertionTest<std::ptrdiff_t>());
-  CALL_SUBTEST_1(assertionTest<std::complex<double>>());
-
   CALL_SUBTEST_2(constructorTest<unsigned char>());
   CALL_SUBTEST_2(constructorTest<float>());
   CALL_SUBTEST_2(constructorTest<Index>());
diff --git a/test/gpu_basic.cu b/test/gpu_basic.cu
index 4298da3..e424a93 100644
--- a/test/gpu_basic.cu
+++ b/test/gpu_basic.cu
@@ -138,10 +138,12 @@
     out[out_idx++] = a / numext::real(b);
     out[out_idx++] = numext::real(a) / b;
     
+#if !defined(EIGEN_COMP_MSVC)
     out[out_idx] = a; out[out_idx++] += b;
     out[out_idx] = a; out[out_idx++] -= b;
     out[out_idx] = a; out[out_idx++] *= b;
     out[out_idx] = a; out[out_idx++] /= b;
+#endif
     
     const ComplexType true_value = ComplexType(ValueType(1), ValueType(0));
     const ComplexType false_value = ComplexType(ValueType(0), ValueType(0));
@@ -188,6 +190,7 @@
     res.segment(block_idx, size) = x1.real().array() / x2.array();
     block_idx += size;
     
+#if !defined(EIGEN_COMP_MSVC)
     res.segment(block_idx, size) = x1; res.segment(block_idx, size) += x2;
     block_idx += size;
     res.segment(block_idx, size) = x1; res.segment(block_idx, size) -= x2;
@@ -196,6 +199,7 @@
     block_idx += size;
     res.segment(block_idx, size) = x1; res.segment(block_idx, size).array() /= x2.array();
     block_idx += size;
+#endif
 
     const T true_vector = T::Constant(true_value);
     const T false_vector = T::Constant(false_value);
diff --git a/test/gpu_example.cu b/test/gpu_example.cu
new file mode 100644
index 0000000..9bc34e5
--- /dev/null
+++ b/test/gpu_example.cu
@@ -0,0 +1,136 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2021 The Eigen Team.
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// The following is an example GPU test.
+
+#include "main.h"  // Include the main test utilities.
+
+// Define a kernel functor.
+//
+// The kernel must be a POD type and implement operator().
+struct AddKernel {
+  // Parameters must be POD or serializable Eigen types (e.g. Matrix,
+  // Array). The return value must be a POD or serializable value type.
+  template<typename Type1, typename Type2, typename Type3>
+  EIGEN_DEVICE_FUNC
+  Type3 operator()(const Type1& A, const Type2& B, Type3& C) const {
+    C = A + B;       // Populate output parameter.
+    Type3 D = A + B; // Populate return value.    
+    return D;
+  }
+};
+
+// Define a sub-test that uses the kernel.
+template <typename T>
+void test_add(const T& type) {
+  const Index rows = type.rows();
+  const Index cols = type.cols();
+  
+  // Create random inputs.
+  const T A = T::Random(rows, cols);
+  const T B = T::Random(rows, cols);
+  T C; // Output parameter.
+
+  // Create kernel.
+  AddKernel add_kernel;
+  
+  // Run add_kernel(A, B, C) via run(...).
+  // This will run on the GPU if using a GPU compiler, or CPU otherwise,
+  // facilitating generic tests that can run on either.
+  T D = run(add_kernel, A, B, C);
+  
+  // Check that both output parameter and return value are correctly populated.
+  const T expected = A + B;
+  VERIFY_IS_CWISE_EQUAL(C, expected);
+  VERIFY_IS_CWISE_EQUAL(D, expected);
+  
+  // In a GPU-only test, we can verify that the CPU and GPU produce the
+  // same results.
+  T C_cpu, C_gpu;
+  T D_cpu = run_on_cpu(add_kernel, A, B, C_cpu); // Runs on CPU.
+  T D_gpu = run_on_gpu(add_kernel, A, B, C_gpu); // Runs on GPU.
+  VERIFY_IS_CWISE_EQUAL(C_cpu, C_gpu);
+  VERIFY_IS_CWISE_EQUAL(D_cpu, D_gpu);
+};
+
+struct MultiplyKernel {
+  template<typename Type1, typename Type2, typename Type3>
+  EIGEN_DEVICE_FUNC
+  Type3 operator()(const Type1& A, const Type2& B, Type3& C) const {
+    C = A * B;
+    return A * B;
+  }
+};
+
+template <typename T1, typename T2, typename T3>
+void test_multiply(const T1& type1, const T2& type2, const T3& type3) {
+  
+  const T1 A = T1::Random(type1.rows(), type1.cols());
+  const T2 B = T2::Random(type2.rows(), type2.cols());
+  T3 C;
+
+  MultiplyKernel multiply_kernel;
+  
+  // The run(...) family of functions uses a memory buffer to transfer data back
+  // and forth to and from the device.  The size of this buffer is estimated
+  // from the size of all input parameters.  If the estimated buffer size is
+  // not sufficient for transferring outputs from device-to-host, then an
+  // explicit buffer size needs to be specified.
+  
+  // 2 outputs of size (A * B). For each matrix output, the buffer will store
+  // the number of rows, columns, and the data.
+  size_t buffer_capacity_hint = 2 * (                     // 2 output parameters
+    2 * sizeof(typename T3::Index)                        // # Rows, # Cols
+    + A.rows() * B.cols() * sizeof(typename T3::Scalar)); // Output data
+  
+  T3 D = run_with_hint(buffer_capacity_hint, multiply_kernel, A, B, C);
+  
+  const T3 expected = A * B;
+  VERIFY_IS_CWISE_APPROX(C, expected);
+  VERIFY_IS_CWISE_APPROX(D, expected);
+  
+  T3 C_cpu, C_gpu;
+  T3 D_cpu = run_on_cpu(multiply_kernel, A, B, C_cpu);
+  T3 D_gpu = run_on_gpu_with_hint(buffer_capacity_hint,
+                                  multiply_kernel, A, B, C_gpu);
+  VERIFY_IS_CWISE_APPROX(C_cpu, C_gpu);
+  VERIFY_IS_CWISE_APPROX(D_cpu, D_gpu);
+}
+
+// Declare the test fixture.
+EIGEN_DECLARE_TEST(gpu_example)
+{
+  // For the number of repeats, call the desired subtests.
+  for(int i = 0; i < g_repeat; i++) {    
+    // Call subtests with different sized/typed inputs.
+    CALL_SUBTEST( test_add(Eigen::Vector3f()) );
+    CALL_SUBTEST( test_add(Eigen::Matrix3d()) );
+#if !defined(EIGEN_USE_HIP) // FIXME
+    CALL_SUBTEST( test_add(Eigen::MatrixX<int>(10, 10)) );
+#endif
+
+    CALL_SUBTEST( test_add(Eigen::Array44f()) );
+#if !defined(EIGEN_USE_HIP)
+    CALL_SUBTEST( test_add(Eigen::ArrayXd(20)) );
+    CALL_SUBTEST( test_add(Eigen::ArrayXXi(13, 17)) );
+#endif
+
+    CALL_SUBTEST( test_multiply(Eigen::Matrix3d(),
+                                Eigen::Matrix3d(),
+                                Eigen::Matrix3d()) );
+#if !defined(EIGEN_USE_HIP)
+    CALL_SUBTEST( test_multiply(Eigen::MatrixX<int>(10, 10),
+                                Eigen::MatrixX<int>(10, 10),
+                                Eigen::MatrixX<int>()) );
+    CALL_SUBTEST( test_multiply(Eigen::MatrixXf(12, 1),
+                                Eigen::MatrixXf(1, 32),
+                                Eigen::MatrixXf()) );
+#endif
+  }
+}
diff --git a/test/gpu_test_helper.h b/test/gpu_test_helper.h
new file mode 100644
index 0000000..f796eeb
--- /dev/null
+++ b/test/gpu_test_helper.h
@@ -0,0 +1,469 @@
+#ifndef GPU_TEST_HELPER_H
+#define GPU_TEST_HELPER_H
+
+#include <Eigen/Core>
+
+#ifdef EIGEN_GPUCC
+#define EIGEN_USE_GPU
+#include "../unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaDefines.h"
+#endif // EIGEN_GPUCC
+
+// std::tuple cannot be used on device, and there is a bug in cuda < 9.2 that
+// doesn't allow std::tuple to compile for host code either. In these cases,
+// use our custom implementation.
+#if defined(EIGEN_GPU_COMPILE_PHASE) || (defined(EIGEN_CUDACC) && EIGEN_CUDA_SDK_VER < 92000)
+#define EIGEN_USE_CUSTOM_TUPLE 1
+#else
+#define EIGEN_USE_CUSTOM_TUPLE 0
+#endif
+
+#if EIGEN_USE_CUSTOM_TUPLE
+#include "../Eigen/src/Core/arch/GPU/Tuple.h"
+#else
+#include <tuple>
+#endif
+namespace Eigen {
+
+namespace internal {
+
+// Note: cannot re-use tuple_impl, since that will cause havoc for
+// tuple_test.
+namespace test_detail {
+// Use std::tuple on CPU, otherwise use the GPU-specific versions.
+#if !EIGEN_USE_CUSTOM_TUPLE
+using std::tuple;
+using std::get;
+using std::make_tuple;
+using std::tie;
+#else
+using tuple_impl::tuple;
+using tuple_impl::get;
+using tuple_impl::make_tuple;
+using tuple_impl::tie;
+#endif
+#undef EIGEN_USE_CUSTOM_TUPLE
+}  // namespace test_detail
+
+template<size_t N, size_t Idx, typename OutputIndexSequence, typename... Ts>
+struct extract_output_indices_helper;
+
+/**
+ * Extracts a set of indices corresponding to non-const l-value reference
+ * output types.
+ *
+ * \internal
+ * \tparam N the number of types {T1, Ts...}.
+ * \tparam Idx the "index" to append if T1 is an output type.
+ * \tparam OutputIndices the current set of output indices.
+ * \tparam T1 the next type to consider, with index Idx.
+ * \tparam Ts the remaining types.
+ */
+template<size_t N, size_t Idx, size_t... OutputIndices, typename T1, typename... Ts>
+struct extract_output_indices_helper<N, Idx, index_sequence<OutputIndices...>, T1, Ts...> {
+  using type = typename
+    extract_output_indices_helper<
+      N - 1, Idx + 1,
+      typename std::conditional<
+        // If is a non-const l-value reference, append index.
+        std::is_lvalue_reference<T1>::value 
+          && !std::is_const<typename std::remove_reference<T1>::type>::value,
+        index_sequence<OutputIndices..., Idx>,
+        index_sequence<OutputIndices...> >::type,
+      Ts...>::type;
+};
+
+// Base case.
+template<size_t Idx, size_t... OutputIndices>
+struct extract_output_indices_helper<0, Idx, index_sequence<OutputIndices...> > {
+  using type = index_sequence<OutputIndices...>;
+};
+
+// Extracts a set of indices into Types... that correspond to non-const
+// l-value references.
+template<typename... Types>
+using extract_output_indices = typename extract_output_indices_helper<sizeof...(Types), 0, index_sequence<>, Types...>::type;
+
+// Helper struct for dealing with Generic functors that may return void.
+struct void_helper {
+  struct Void {};
+  
+  // Converts void -> Void, T otherwise.
+  template<typename T>
+  using ReturnType = typename std::conditional<std::is_same<T, void>::value, Void, T>::type;
+  
+  // Non-void return value.
+  template<typename Func, typename... Args>
+  static EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC
+  auto call(Func&& func, Args&&... args) -> 
+      typename std::enable_if<!std::is_same<decltype(func(args...)), void>::value, 
+                              decltype(func(args...))>::type {
+    return func(std::forward<Args>(args)...);
+  }
+  
+  // Void return value.
+  template<typename Func, typename... Args>
+  static EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC
+  auto call(Func&& func, Args&&... args) -> 
+      typename std::enable_if<std::is_same<decltype(func(args...)), void>::value,
+                              Void>::type {
+    func(std::forward<Args>(args)...);
+    return Void{};
+  }
+  
+  // Restores the original return type, Void -> void, T otherwise.
+  template<typename T>
+  static EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC
+  typename std::enable_if<!std::is_same<typename std::decay<T>::type, Void>::value, T>::type
+  restore(T&& val) {
+    return val;
+  }
+  
+  // Void case.
+  template<typename T = void>
+  static EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC
+  void restore(const Void&) {}
+};
+
+// Runs a kernel via serialized buffer.  Does this by deserializing the buffer
+// to construct the arguments, calling the kernel, then re-serialing the outputs.
+// The buffer contains
+//     [ input_buffer_size, args ]
+// After the kernel call, it is then populated with
+//     [ output_buffer_size, output_parameters, return_value ]
+// If the output_buffer_size exceeds the buffer's capacity, then only the
+// output_buffer_size is populated.
+template<typename Kernel, typename... Args, size_t... Indices, size_t... OutputIndices>
+EIGEN_DEVICE_FUNC
+void run_serialized(index_sequence<Indices...>, index_sequence<OutputIndices...>,
+                    Kernel kernel, uint8_t* buffer, size_t capacity) {
+  using test_detail::get;
+  using test_detail::make_tuple;
+  using test_detail::tuple;
+  // Deserialize input size and inputs.
+  size_t input_size;
+  uint8_t* buff_ptr = Eigen::deserialize(buffer, input_size);
+  // Create value-type instances to populate.
+  auto args = make_tuple(typename std::decay<Args>::type{}...);
+  EIGEN_UNUSED_VARIABLE(args) // Avoid NVCC compile warning.
+  // NVCC 9.1 requires us to spell out the template parameters explicitly.
+  buff_ptr = Eigen::deserialize(buff_ptr, get<Indices, typename std::decay<Args>::type...>(args)...);
+  
+  // Call function, with void->Void conversion so we are guaranteed a complete
+  // output type.
+  auto result = void_helper::call(kernel, get<Indices, typename std::decay<Args>::type...>(args)...);
+  
+  // Determine required output size.
+  size_t output_size = Eigen::serialize_size(capacity);
+  output_size += Eigen::serialize_size(get<OutputIndices, typename std::decay<Args>::type...>(args)...);
+  output_size += Eigen::serialize_size(result);
+  
+  // Always serialize required buffer size.
+  buff_ptr = Eigen::serialize(buffer, output_size);
+  // Serialize outputs if they fit in the buffer.
+  if (output_size <= capacity) {
+    // Collect outputs and result.
+    buff_ptr = Eigen::serialize(buff_ptr, get<OutputIndices, typename std::decay<Args>::type...>(args)...);
+    buff_ptr = Eigen::serialize(buff_ptr, result);
+  }
+}
+
+template<typename Kernel, typename... Args>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+void run_serialized(Kernel kernel, uint8_t* buffer, size_t capacity) {
+  run_serialized<Kernel, Args...> (make_index_sequence<sizeof...(Args)>{},
+                                   extract_output_indices<Args...>{},
+                                   kernel, buffer, capacity);
+}
+
+#ifdef EIGEN_GPUCC
+
+// Checks for GPU errors and asserts / prints the error message.
+#define GPU_CHECK(expr)                                                \
+do {                                                                   \
+  gpuError_t err = expr;                                               \
+  if (err != gpuSuccess) {                                             \
+    printf("%s: %s\n", gpuGetErrorName(err), gpuGetErrorString(err));  \
+    gpu_assert(false);                                                 \
+  }                                                                    \
+} while(0)
+
+// Calls run_serialized on the GPU.
+template<typename Kernel, typename... Args>
+__global__
+EIGEN_HIP_LAUNCH_BOUNDS_1024
+void run_serialized_on_gpu_meta_kernel(const Kernel kernel, uint8_t* buffer, size_t capacity) {
+  run_serialized<Kernel, Args...>(kernel, buffer, capacity);
+}
+
+// Runs kernel(args...) on the GPU via the serialization mechanism. 
+//
+// Note: this may end up calling the kernel multiple times if the initial output
+// buffer is not large enough to hold the outputs.
+template<typename Kernel, typename... Args, size_t... Indices, size_t... OutputIndices>
+auto run_serialized_on_gpu(size_t buffer_capacity_hint,
+                           index_sequence<Indices...>, 
+                           index_sequence<OutputIndices...>,
+                           Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {  
+  // Compute the required serialization buffer capacity.
+  // Round up input size to next power of two to give a little extra room
+  // for outputs.
+  size_t input_data_size = sizeof(size_t) + Eigen::serialize_size(args...);
+  
+  size_t capacity;
+  if (buffer_capacity_hint == 0) {
+    // Estimate as the power of two larger than the total input size.
+    capacity = sizeof(size_t);
+    while (capacity <= input_data_size) {
+      capacity *= 2;
+    }
+  } else {
+    // Use the larger of the hint and the total input size.
+    // Add sizeof(size_t) to the hint to account for storing the buffer capacity
+    // itself so the user doesn't need to think about this.
+    capacity = std::max<size_t>(buffer_capacity_hint + sizeof(size_t),
+                                input_data_size);
+  }
+  std::vector<uint8_t> buffer(capacity);
+  
+  uint8_t* host_data = nullptr;
+  uint8_t* host_ptr = nullptr;
+  uint8_t* device_data = nullptr;
+  size_t output_data_size = 0;
+  
+  // Allocate buffers and copy input data.
+  capacity = std::max<size_t>(capacity, output_data_size);
+  buffer.resize(capacity);
+  host_data = buffer.data();
+  host_ptr = Eigen::serialize(host_data, input_data_size);
+  host_ptr = Eigen::serialize(host_ptr, args...);
+  
+  // Copy inputs to host.
+  gpuMalloc((void**)(&device_data), capacity);
+  gpuMemcpy(device_data, buffer.data(), input_data_size, gpuMemcpyHostToDevice);
+  GPU_CHECK(gpuDeviceSynchronize());
+      
+  // Run kernel.
+  #ifdef EIGEN_USE_HIP
+    hipLaunchKernelGGL(
+        HIP_KERNEL_NAME(run_serialized_on_gpu_meta_kernel<Kernel, Args...>), 
+        1, 1, 0, 0, kernel, device_data, capacity);
+  #else
+    run_serialized_on_gpu_meta_kernel<Kernel, Args...><<<1,1>>>(
+        kernel, device_data, capacity);
+  #endif
+  // Check pre-launch and kernel execution errors.
+  GPU_CHECK(gpuGetLastError());
+  GPU_CHECK(gpuDeviceSynchronize());
+  // Copy back new output to host.
+  gpuMemcpy(host_data, device_data, capacity, gpuMemcpyDeviceToHost);
+  gpuFree(device_data);
+  GPU_CHECK(gpuDeviceSynchronize());
+  
+  // Determine output buffer size.
+  host_ptr = Eigen::deserialize(host_data, output_data_size);
+  // If the output doesn't fit in the buffer, spit out warning and fail.
+  if (output_data_size > capacity) {
+    std::cerr << "The serialized output does not fit in the output buffer, "
+              << output_data_size << " vs capacity " << capacity << "."
+              << std::endl
+              << "Try specifying a minimum buffer capacity: " << std::endl
+              << "  run_with_hint(" << output_data_size << ", ...)"
+              << std::endl;
+    VERIFY(false);
+  }
+  
+  // Deserialize outputs.
+  auto args_tuple = test_detail::tie(args...);
+  EIGEN_UNUSED_VARIABLE(args_tuple)  // Avoid NVCC compile warning.
+  host_ptr = Eigen::deserialize(host_ptr, test_detail::get<OutputIndices, Args&...>(args_tuple)...);
+  
+  // Maybe deserialize return value, properly handling void.
+  typename void_helper::ReturnType<decltype(kernel(args...))> result;
+  host_ptr = Eigen::deserialize(host_ptr, result);
+  return void_helper::restore(result);
+}
+
+#endif // EIGEN_GPUCC
+
+} // namespace internal
+
+/**
+ * Runs a kernel on the CPU, returning the results.
+ * \param kernel kernel to run.
+ * \param args ... input arguments.
+ * \return kernel(args...).
+ */
+template<typename Kernel, typename... Args>
+auto run_on_cpu(Kernel kernel, Args&&... args) -> decltype(kernel(args...)){  
+  return kernel(std::forward<Args>(args)...);
+}
+
+#ifdef EIGEN_GPUCC
+
+/**
+ * Runs a kernel on the GPU, returning the results.
+ * 
+ * The kernel must be able to be passed directly as an input to a global
+ * function (i.e. empty or POD).  Its inputs must be "Serializable" so we
+ * can transfer them to the device, and the output must be a Serializable value
+ * type so it can be transferred back from the device.
+ * 
+ * \param kernel kernel to run.
+ * \param args ... input arguments, must be "Serializable".
+ * \return kernel(args...).
+ */
+template<typename Kernel, typename... Args>
+auto run_on_gpu(Kernel kernel, Args&&... args) -> decltype(kernel(args...)){  
+  return internal::run_serialized_on_gpu<Kernel, Args...>(
+      /*buffer_capacity_hint=*/ 0,
+      internal::make_index_sequence<sizeof...(Args)>{},
+      internal::extract_output_indices<Args...>{},
+      kernel, std::forward<Args>(args)...);
+}
+
+/**
+ * Runs a kernel on the GPU, returning the results.
+ *
+ * This version allows specifying a minimum buffer capacity size required for
+ * serializing the puts to transfer results from device to host.  Use this when
+ * `run_on_gpu(...)` fails to determine an appropriate capacity by default.
+ *
+ * \param buffer_capacity_hint minimum required buffer size for serializing
+ *        outputs.
+ * \param kernel kernel to run.
+ * \param args ... input arguments, must be "Serializable".
+ * \return kernel(args...).
+ * \sa run_on_gpu
+ */
+template<typename Kernel, typename... Args>
+auto run_on_gpu_with_hint(size_t buffer_capacity_hint, 
+    Kernel kernel, Args&&... args) -> decltype(kernel(args...)){  
+  return internal::run_serialized_on_gpu<Kernel, Args...>(
+      buffer_capacity_hint,
+      internal::make_index_sequence<sizeof...(Args)>{},
+      internal::extract_output_indices<Args...>{},
+      kernel, std::forward<Args>(args)...);
+}
+
+/**
+ * Kernel for determining basic Eigen compile-time information
+ * (i.e. the cuda/hip arch)
+ */
+struct CompileTimeDeviceInfoKernel {
+  struct Info {
+    int cuda;
+    int hip;
+  };
+  
+  EIGEN_DEVICE_FUNC
+  Info operator()() const
+  {
+    Info info = {-1, -1};
+    #if defined(__CUDA_ARCH__)
+    info.cuda = static_cast<int>(__CUDA_ARCH__ +0);
+    #endif
+    #if defined(EIGEN_HIP_DEVICE_COMPILE)
+    info.hip = static_cast<int>(EIGEN_HIP_DEVICE_COMPILE +0);
+    #endif
+    return info;
+  }
+};
+
+/**
+ * Queries and prints the compile-time and runtime GPU info.
+ */
+void print_gpu_device_info()
+{
+  int device = 0;
+  gpuDeviceProp_t deviceProp;
+  gpuGetDeviceProperties(&deviceProp, device);
+
+  auto info = run_on_gpu(CompileTimeDeviceInfoKernel());
+
+  std::cout << "GPU compile-time info:\n";
+  
+  #ifdef EIGEN_CUDACC
+  std::cout << "  EIGEN_CUDACC:                " << int(EIGEN_CUDACC) << std::endl;
+  #endif
+  
+  #ifdef EIGEN_CUDA_SDK_VER
+  std::cout << "  EIGEN_CUDA_SDK_VER:          " << int(EIGEN_CUDA_SDK_VER) << std::endl;
+  #endif
+
+  #ifdef EIGEN_COMP_NVCC
+  std::cout << "  EIGEN_COMP_NVCC:             " << int(EIGEN_COMP_NVCC) << std::endl;
+  #endif
+  
+  #ifdef EIGEN_HIPCC
+  std::cout << "  EIGEN_HIPCC:                 " << int(EIGEN_HIPCC) << std::endl;
+  #endif
+
+  std::cout << "  EIGEN_CUDA_ARCH:             " << info.cuda << std::endl;  
+  std::cout << "  EIGEN_HIP_DEVICE_COMPILE:    " << info.hip << std::endl;
+
+  std::cout << "GPU device info:\n";
+  std::cout << "  name:                        " << deviceProp.name << std::endl;
+  std::cout << "  capability:                  " << deviceProp.major << "." << deviceProp.minor << std::endl;
+  std::cout << "  multiProcessorCount:         " << deviceProp.multiProcessorCount << std::endl;
+  std::cout << "  maxThreadsPerMultiProcessor: " << deviceProp.maxThreadsPerMultiProcessor << std::endl;
+  std::cout << "  warpSize:                    " << deviceProp.warpSize << std::endl;
+  std::cout << "  regsPerBlock:                " << deviceProp.regsPerBlock << std::endl;
+  std::cout << "  concurrentKernels:           " << deviceProp.concurrentKernels << std::endl;
+  std::cout << "  clockRate:                   " << deviceProp.clockRate << std::endl;
+  std::cout << "  canMapHostMemory:            " << deviceProp.canMapHostMemory << std::endl;
+  std::cout << "  computeMode:                 " << deviceProp.computeMode << std::endl;
+}
+
+#endif // EIGEN_GPUCC
+
+/**
+ * Runs a kernel on the GPU (if EIGEN_GPUCC), or CPU otherwise.
+ * 
+ * This is to better support creating generic tests.
+ * 
+ * The kernel must be able to be passed directly as an input to a global
+ * function (i.e. empty or POD).  Its inputs must be "Serializable" so we
+ * can transfer them to the device, and the output must be a Serializable value
+ * type so it can be transferred back from the device.
+ * 
+ * \param kernel kernel to run.
+ * \param args ... input arguments, must be "Serializable".
+ * \return kernel(args...).
+ */
+template<typename Kernel, typename... Args>
+auto run(Kernel kernel, Args&&... args) -> decltype(kernel(args...)){
+#ifdef EIGEN_GPUCC
+  return run_on_gpu(kernel, std::forward<Args>(args)...);
+#else
+  return run_on_cpu(kernel, std::forward<Args>(args)...);
+#endif
+}
+
+/**
+ * Runs a kernel on the GPU (if EIGEN_GPUCC), or CPU otherwise.
+ * 
+ * This version allows specifying a minimum buffer capacity size required for
+ * serializing the puts to transfer results from device to host.  Use this when
+ * `run(...)` fails to determine an appropriate capacity by default.
+ *
+ * \param buffer_capacity_hint minimum required buffer size for serializing
+ *        outputs.
+ * \param kernel kernel to run.
+ * \param args ... input arguments, must be "Serializable".
+ * \return kernel(args...).
+ * \sa run
+ */
+template<typename Kernel, typename... Args>
+auto run_with_hint(size_t buffer_capacity_hint,
+    Kernel kernel, Args&&... args) -> decltype(kernel(args...)){
+#ifdef EIGEN_GPUCC
+  return run_on_gpu_with_hint(buffer_capacity_hint, kernel, std::forward<Args>(args)...);
+#else
+  EIGEN_UNUSED_VARIABLE(buffer_capacity_hint)
+  return run_on_cpu(kernel, std::forward<Args>(args)...);
+#endif
+}
+
+} // namespace Eigen
+
+#endif // GPU_TEST_HELPER_H
diff --git a/test/indexed_view.cpp b/test/indexed_view.cpp
index 72c54af..04ba91a 100644
--- a/test/indexed_view.cpp
+++ b/test/indexed_view.cpp
@@ -36,7 +36,12 @@
 #include <vector>
 #include "main.h"
 
+using Eigen::placeholders::all;
+using Eigen::placeholders::last;
+using Eigen::placeholders::lastp1;
+
 #if EIGEN_HAS_CXX11
+using Eigen::placeholders::lastN;
 #include <array>
 #endif
 
@@ -220,7 +225,7 @@
   VERIFY( is_same_seq_type( seqN(2,fix<5>(5),fix<-2>), seqN(2,fix<5>,fix<-2>()) ) );
 
   VERIFY( is_same_seq_type( seq(2,fix<5>), seqN(2,4) ) );
-#if EIGEN_HAS_CXX11
+  #if EIGEN_HAS_CXX11
   VERIFY( is_same_seq_type( seq(fix<2>,fix<5>), seqN(fix<2>,fix<4>) ) );
   VERIFY( is_same_seq( seqN(2,std::integral_constant<int,5>(),std::integral_constant<int,-2>()), seqN(2,fix<5>,fix<-2>()) ) );
   VERIFY( is_same_seq( seq(std::integral_constant<int,1>(),std::integral_constant<int,5>(),std::integral_constant<int,2>()),
diff --git a/test/initializer_list_construction.cpp b/test/initializer_list_construction.cpp
index 7a9c49e..b576ec2 100644
--- a/test/initializer_list_construction.cpp
+++ b/test/initializer_list_construction.cpp
@@ -7,7 +7,12 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT
+#if defined(__GNUC__) && __GNUC__ >= 10
+// GCC 10+ has a bug for unsigned char that thinks we're writing past the
+// end of an array when compiled with -O3.  This warning is not triggered for
+// any other types, nor for other compilers, nor for other optimization levels.
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+#endif
 
 #include "main.h"
 
@@ -320,16 +325,6 @@
     VERIFY(v.cols() == 1);
     VERIFY_IS_EQUAL(v, (VectorX {{raw[0], raw[1], raw[2], raw[3]}}));
   }
-
-  {
-    VERIFY_RAISES_ASSERT((VectorX {raw[0], raw[1], raw[2], raw[3]}));
-  }
-  {
-    VERIFY_RAISES_ASSERT((VectorX  {
-      {raw[0], raw[1], raw[2], raw[3]},
-      {raw[0], raw[1], raw[2], raw[3]},
-    }));
-  }
 }
 
 EIGEN_DECLARE_TEST(initializer_list_construction)
diff --git a/test/integer_types.cpp b/test/integer_types.cpp
index 31f4100..ce64e18 100644
--- a/test/integer_types.cpp
+++ b/test/integer_types.cpp
@@ -7,8 +7,6 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT
-
 #include "main.h"
 
 #undef VERIFY_IS_APPROX
diff --git a/test/main.h b/test/main.h
index 0166738..894d79b 100644
--- a/test/main.h
+++ b/test/main.h
@@ -1,4 +1,3 @@
-
 // This file is part of Eigen, a lightweight C++ template library
 // for linear algebra.
 //
@@ -55,19 +54,26 @@
 #endif
 #endif
 
-// Same for cuda_fp16.h
-#if defined(__CUDACC__) && !defined(EIGEN_NO_CUDA)
-  // Means the compiler is either nvcc or clang with CUDA enabled
+// Configure GPU.
+#if defined(EIGEN_USE_HIP)
+  #if defined(__HIPCC__) && !defined(EIGEN_NO_HIP)
+    #define EIGEN_HIPCC __HIPCC__
+    #include <hip/hip_runtime.h>
+    #include <hip/hip_runtime_api.h>
+  #endif
+#elif defined(__CUDACC__) && !defined(EIGEN_NO_CUDA)
   #define EIGEN_CUDACC __CUDACC__
+  #include <cuda.h>
+  #include <cuda_runtime.h>
+  #include <cuda_runtime_api.h>
+  #if CUDA_VERSION >= 7050
+    #include <cuda_fp16.h>
+  #endif
 #endif
-#if defined(EIGEN_CUDACC)
-#include <cuda.h>
-  #define EIGEN_CUDA_SDK_VER (CUDA_VERSION * 10)
-#else
-  #define EIGEN_CUDA_SDK_VER 0
-#endif
-#if EIGEN_CUDA_SDK_VER >= 70500
-#include <cuda_fp16.h>
+
+#if defined(EIGEN_CUDACC) || defined(EIGEN_HIPCC)
+  #define EIGEN_TEST_NO_LONGDOUBLE
+  #define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
 #endif
 
 // To test that all calls from Eigen code to std::min() and std::max() are
@@ -314,36 +320,10 @@
     #endif // EIGEN_EXCEPTIONS
   #endif // EIGEN_DEBUG_ASSERTS
 
-  #if defined(TEST_CHECK_STATIC_ASSERTIONS) && defined(EIGEN_EXCEPTIONS)
-    #define EIGEN_STATIC_ASSERT(a,MSG) \
-      if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\
-      {                                       \
-        Eigen::no_more_assert = true;         \
-        if(report_on_cerr_on_assert_failure)  \
-          eigen_plain_assert((a) && #MSG);      \
-        else                                  \
-          EIGEN_THROW_X(Eigen::eigen_static_assert_exception()); \
-      }
-    #define VERIFY_RAISES_STATIC_ASSERT(a) {                    \
-      Eigen::no_more_assert = false;                            \
-      Eigen::report_on_cerr_on_assert_failure = false;          \
-      try {                                                     \
-        a;                                                      \
-        VERIFY(Eigen::should_raise_an_assert && # a);           \
-      }                                                         \
-      catch (Eigen::eigen_static_assert_exception&) { VERIFY(true); }  \
-      Eigen::report_on_cerr_on_assert_failure = true;           \
-    }
-  #endif // TEST_CHECK_STATIC_ASSERTIONS
-
 #ifndef VERIFY_RAISES_ASSERT
   #define VERIFY_RAISES_ASSERT(a) \
     std::cout << "Can't VERIFY_RAISES_ASSERT( " #a " ) with exceptions disabled\n";
 #endif
-#ifndef VERIFY_RAISES_STATIC_ASSERT
-  #define VERIFY_RAISES_STATIC_ASSERT(a) \
-    std::cout << "Can't VERIFY_RAISES_STATIC_ASSERT( " #a " ) with exceptions disabled\n";
-#endif
 
   #if !defined(__CUDACC__) && !defined(__HIPCC__) && !defined(SYCL_DEVICE_ONLY)
   #define EIGEN_USE_CUSTOM_ASSERT
@@ -352,7 +332,6 @@
 #else // EIGEN_NO_ASSERTION_CHECKING
 
   #define VERIFY_RAISES_ASSERT(a) {}
-  #define VERIFY_RAISES_STATIC_ASSERT(a) {}
 
 #endif // EIGEN_NO_ASSERTION_CHECKING
 
@@ -391,6 +370,8 @@
 #define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_isMuchSmallerThan(a, b))
 #define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_isApproxOrLessThan(a, b))
 #define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_isApproxOrLessThan(a, b))
+#define VERIFY_IS_CWISE_EQUAL(a, b) VERIFY(test_isCwiseApprox(a, b, true))
+#define VERIFY_IS_CWISE_APPROX(a, b) VERIFY(test_isCwiseApprox(a, b, false))
 
 #define VERIFY_IS_UNITARY(a) VERIFY(test_isUnitary(a))
 
@@ -403,34 +384,19 @@
   } while (0)
 
 
-  namespace Eigen {
-
 // Forward declarations to avoid ICC warnings
+#if EIGEN_COMP_ICC
+
+template<typename T> std::string type_name();
+
+namespace Eigen {
+
 template<typename T, typename U>
 bool test_is_equal(const T& actual, const U& expected, bool expect_equal=true);
 
-template<typename MatrixType>
-void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m);
-
-template<typename PermutationVectorType>
-void randomPermutationVector(PermutationVectorType& v, Index size);
-
-template<typename MatrixType>
-MatrixType generateRandomUnitaryMatrix(const Index dim);
-
-template<typename MatrixType, typename RealScalarVectorType>
-void generateRandomMatrixSvs(const RealScalarVectorType &svs, const Index rows, const Index cols, MatrixType& M);
-
-template<typename VectorType, typename RealScalar>
-VectorType setupRandomSvs(const Index dim, const RealScalar max);
-
-template<typename VectorType, typename RealScalar>
-VectorType setupRangeSvs(const Index dim, const RealScalar min, const RealScalar max);
-
 } // end namespace Eigen
 
-// Forward declaration to avoid ICC warnings
-template<typename T> std::string type_name();
+#endif  // EIGEN_COMP_ICC
 
 
 namespace Eigen {
@@ -655,6 +621,29 @@
   return m.isUnitary(test_precision<typename internal::traits<Derived>::Scalar>());
 }
 
+// Checks component-wise, works with infs and nans.
+template<typename Derived1, typename Derived2>
+bool test_isCwiseApprox(const DenseBase<Derived1>& m1,
+                        const DenseBase<Derived2>& m2,
+                        bool exact) {
+  if (m1.rows() != m2.rows()) {
+    return false;
+  }
+  if (m1.cols() != m2.cols()) {
+    return false;
+  }
+  for (Index r = 0; r < m1.rows(); ++r) {
+    for (Index c = 0; c < m1.cols(); ++c) {
+      if (m1(r, c) != m2(r, c)
+          && !((numext::isnan)(m1(r, c)) && (numext::isnan)(m2(r, c))) 
+          && (exact || !test_isApprox(m1(r, c), m2(r, c)))) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
 template<typename T, typename U>
 bool test_is_equal(const T& actual, const U& expected, bool expect_equal)
 {
@@ -667,215 +656,7 @@
     return false;
 }
 
-// Forward declaration to avoid ICC warning
-template<typename MatrixType>
-void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m);
-/**
- * Creates a random partial isometry matrix of given rank.
- *
- * A partial isometry is a matrix all of whose singular values are either 0 or 1.
- * This is very useful to test rank-revealing algorithms.
- *
- * @tparam MatrixType type of random partial isometry matrix
- * @param desired_rank rank requested for the random partial isometry matrix
- * @param rows row dimension of requested random partial isometry matrix
- * @param cols column dimension of requested random partial isometry matrix
- * @param m random partial isometry matrix
- */
-template<typename MatrixType>
-void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m)
-{
-  typedef typename internal::traits<MatrixType>::Scalar Scalar;
-  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
 
-  typedef Matrix<Scalar, Dynamic, 1> VectorType;
-  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
-  typedef Matrix<Scalar, Cols, Cols> MatrixBType;
-
-  if(desired_rank == 0)
-  {
-    m.setZero(rows,cols);
-    return;
-  }
-
-  if(desired_rank == 1)
-  {
-    // here we normalize the vectors to get a partial isometry
-    m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
-    return;
-  }
-
-  MatrixAType a = MatrixAType::Random(rows,rows);
-  MatrixType d = MatrixType::Identity(rows,cols);
-  MatrixBType  b = MatrixBType::Random(cols,cols);
-
-  // set the diagonal such that only desired_rank non-zero entries remain
-  const Index diag_size = (std::min)(d.rows(),d.cols());
-  if(diag_size != desired_rank)
-    d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
-
-  HouseholderQR<MatrixAType> qra(a);
-  HouseholderQR<MatrixBType> qrb(b);
-  m = qra.householderQ() * d * qrb.householderQ();
-}
-
-// Forward declaration to avoid ICC warning
-template<typename PermutationVectorType>
-void randomPermutationVector(PermutationVectorType& v, Index size);
-/**
- * Generate random permutation vector.
- *
- * @tparam PermutationVectorType type of vector used to store permutation
- * @param v permutation vector
- * @param size length of permutation vector
- */
-template<typename PermutationVectorType>
-void randomPermutationVector(PermutationVectorType& v, Index size)
-{
-  typedef typename PermutationVectorType::Scalar Scalar;
-  v.resize(size);
-  for(Index i = 0; i < size; ++i) v(i) = Scalar(i);
-  if(size == 1) return;
-  for(Index n = 0; n < 3 * size; ++n)
-  {
-    Index i = internal::random<Index>(0, size-1);
-    Index j;
-    do j = internal::random<Index>(0, size-1); while(j==i);
-    std::swap(v(i), v(j));
-  }
-}
-
-/**
- * Generate a random unitary matrix of prescribed dimension.
- *
- * The algorithm is using a random Householder sequence to produce
- * a random unitary matrix.
- *
- * @tparam MatrixType type of matrix to generate
- * @param dim row and column dimension of the requested square matrix
- * @return random unitary matrix
- */
-template<typename MatrixType>
-MatrixType generateRandomUnitaryMatrix(const Index dim)
-{
-  typedef typename internal::traits<MatrixType>::Scalar Scalar;
-  typedef Matrix<Scalar, Dynamic, 1> VectorType;
-
-  MatrixType v = MatrixType::Identity(dim, dim);
-  VectorType h = VectorType::Zero(dim);
-  for (Index i = 0; i < dim; ++i)
-  {
-    v.col(i).tail(dim - i - 1) = VectorType::Random(dim - i - 1);
-    h(i) = 2 / v.col(i).tail(dim - i).squaredNorm();
-  }
-
-  const Eigen::HouseholderSequence<MatrixType, VectorType> HSeq(v, h);
-  return MatrixType(HSeq);
-}
-
-/**
- * Generation of random matrix with prescribed singular values.
- *
- * We generate random matrices with given singular values by setting up
- * a singular value decomposition. By choosing the number of zeros as
- * singular values we can specify the rank of the matrix.
- * Moreover, we also control its spectral norm, which is the largest
- * singular value, as well as its condition number with respect to the
- * l2-norm, which is the quotient of the largest and smallest singular
- * value.
- *
- * Reference: For details on the method see e.g. Section 8.1 (pp. 62 f) in
- *
- *   C. C. Paige, M. A. Saunders,
- *   LSQR: An algorithm for sparse linear equations and sparse least squares.
- *   ACM Transactions on Mathematical Software 8(1), pp. 43-71, 1982.
- *   https://web.stanford.edu/group/SOL/software/lsqr/lsqr-toms82a.pdf
- *
- * and also the LSQR webpage https://web.stanford.edu/group/SOL/software/lsqr/.
- *
- * @tparam MatrixType matrix type to generate
- * @tparam RealScalarVectorType vector type with real entries used for singular values
- * @param svs vector of desired singular values
- * @param rows row dimension of requested random matrix
- * @param cols column dimension of requested random matrix
- * @param M generated matrix with prescribed singular values
- */
-template<typename MatrixType, typename RealScalarVectorType>
-void generateRandomMatrixSvs(const RealScalarVectorType &svs, const Index rows, const Index cols, MatrixType& M)
-{
-  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
-  typedef typename internal::traits<MatrixType>::Scalar Scalar;
-  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
-  typedef Matrix<Scalar, Cols, Cols> MatrixBType;
-
-  const Index min_dim = (std::min)(rows, cols);
-
-  const MatrixAType U = generateRandomUnitaryMatrix<MatrixAType>(rows);
-  const MatrixBType V = generateRandomUnitaryMatrix<MatrixBType>(cols);
-
-  M = U.block(0, 0, rows, min_dim) * svs.asDiagonal() * V.block(0, 0, cols, min_dim).transpose();
-}
-
-/**
- * Setup a vector of random singular values with prescribed upper limit.
- * For use with generateRandomMatrixSvs().
- *
- * Singular values are non-negative real values. By convention (to be consistent with
- * singular value decomposition) we sort them in decreasing order.
- *
- * This strategy produces random singular values in the range [0, max], in particular
- * the singular values can be zero or arbitrarily close to zero.
- *
- * @tparam VectorType vector type with real entries used for singular values
- * @tparam RealScalar data type used for real entry
- * @param dim number of singular values to generate
- * @param max upper bound for singular values
- * @return vector of singular values
- */
-template<typename VectorType, typename RealScalar>
-VectorType setupRandomSvs(const Index dim, const RealScalar max)
-{
-  VectorType svs = max / RealScalar(2) * (VectorType::Random(dim) + VectorType::Ones(dim));
-  std::sort(svs.begin(), svs.end(), std::greater<RealScalar>());
-  return svs;
-}
-
-/**
- * Setup a vector of random singular values with prescribed range.
- * For use with generateRandomMatrixSvs().
- *
- * Singular values are non-negative real values. By convention (to be consistent with
- * singular value decomposition) we sort them in decreasing order.
- *
- * For dim > 1 this strategy generates a vector with largest entry max, smallest entry
- * min, and remaining entries in the range [min, max]. For dim == 1 the only entry is
- * min.
- *
- * @tparam VectorType vector type with real entries used for singular values
- * @tparam RealScalar data type used for real entry
- * @param dim number of singular values to generate
- * @param min smallest singular value to use
- * @param max largest singular value to use
- * @return vector of singular values
- */
-template<typename VectorType, typename RealScalar>
-VectorType setupRangeSvs(const Index dim, const RealScalar min, const RealScalar max)
-{
-  VectorType svs = VectorType::Random(dim);
-  if(dim == 0)
-    return svs;
-  if(dim == 1)
-  {
-    svs(0) = min;
-    return svs;
-  }
-  std::sort(svs.begin(), svs.end(), std::greater<RealScalar>());
-
-  // scale to range [min, max]
-  const RealScalar c_min = svs(dim - 1), c_max = svs(0);
-  svs = (svs - VectorType::Constant(dim, c_min)) / (c_max - c_min);
-  return min * (VectorType::Ones(dim) - svs) + max * svs;
-}
 
 /**
  * Check if number is "not a number" (NaN).
@@ -915,6 +696,10 @@
 
 } // end namespace Eigen
 
+
+#include "random_matrix_helper.h"
+
+
 template<typename T> struct GetDifferentType;
 
 template<> struct GetDifferentType<float> { typedef double type; };
@@ -1056,3 +841,5 @@
   // 4503 - decorated name length exceeded, name was truncated
   #pragma warning( disable : 4503)
 #endif
+
+#include "gpu_test_helper.h"
diff --git a/test/mapped_matrix.cpp b/test/mapped_matrix.cpp
index 0ea136a..1b576b0 100644
--- a/test/mapped_matrix.cpp
+++ b/test/mapped_matrix.cpp
@@ -7,10 +7,6 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_NO_STATIC_ASSERT
-#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them
-#endif
-
 #include "main.h"
 
 #define EIGEN_TESTMAP_MAX_SIZE 256
diff --git a/test/mixingtypes.cpp b/test/mixingtypes.cpp
index d450dbf..f836722 100644
--- a/test/mixingtypes.cpp
+++ b/test/mixingtypes.cpp
@@ -10,10 +10,6 @@
 
 #if defined(EIGEN_TEST_PART_7)
 
-#ifndef EIGEN_NO_STATIC_ASSERT
-#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them
-#endif
-
 // ignore double-promotion diagnostic for clang and gcc, if we check for static assertion anyway:
 // TODO do the same for MSVC?
 #if defined(__clang__)
@@ -49,28 +45,6 @@
   VERIFY_IS_APPROX(XPR,REF); \
   VERIFY( g_called && #XPR" not properly optimized");
 
-template<int SizeAtCompileType>
-void raise_assertion(Index size = SizeAtCompileType)
-{
-  // VERIFY_RAISES_ASSERT(mf+md); // does not even compile
-  Matrix<float, SizeAtCompileType, 1> vf; vf.setRandom(size);
-  Matrix<double, SizeAtCompileType, 1> vd; vd.setRandom(size);
-  VERIFY_RAISES_ASSERT(vf=vd);
-  VERIFY_RAISES_ASSERT(vf+=vd);
-  VERIFY_RAISES_ASSERT(vf-=vd);
-  VERIFY_RAISES_ASSERT(vd=vf);
-  VERIFY_RAISES_ASSERT(vd+=vf);
-  VERIFY_RAISES_ASSERT(vd-=vf);
-
-  //   vd.asDiagonal() * mf;    // does not even compile
-  //   vcd.asDiagonal() * mf;   // does not even compile
-
-#if 0 // we get other compilation errors here than just static asserts
-  VERIFY_RAISES_ASSERT(vd.dot(vf));
-#endif
-}
-
-
 template<int SizeAtCompileType> void mixingtypes(int size = SizeAtCompileType)
 {
   typedef std::complex<float>   CF;
@@ -320,10 +294,5 @@
     CALL_SUBTEST_4(mixingtypes<3>());
     CALL_SUBTEST_5(mixingtypes<4>());
     CALL_SUBTEST_6(mixingtypes<Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)));
-    CALL_SUBTEST_7(raise_assertion<Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)));
   }
-  CALL_SUBTEST_7(raise_assertion<0>());
-  CALL_SUBTEST_7(raise_assertion<3>());
-  CALL_SUBTEST_7(raise_assertion<4>());
-  CALL_SUBTEST_7(raise_assertion<Dynamic>(0));
 }
diff --git a/test/packetmath.cpp b/test/packetmath.cpp
index 121ec72..6150481 100644
--- a/test/packetmath.cpp
+++ b/test/packetmath.cpp
@@ -889,7 +889,7 @@
         data1[0] = std::numeric_limits<Scalar>::denorm_min();
         data1[1] = -std::numeric_limits<Scalar>::denorm_min();
         h.store(data2, internal::plog(h.load(data1)));
-        // TODO(rmlarsen): Reenable.
+        // TODO(rmlarsen): Re-enable.
         //        VERIFY_IS_EQUAL(std::log(std::numeric_limits<Scalar>::denorm_min()), data2[0]);
         VERIFY((numext::isnan)(data2[1]));
       }
diff --git a/test/product.h b/test/product.h
index c6c78fb..0477d77 100644
--- a/test/product.h
+++ b/test/product.h
@@ -17,6 +17,17 @@
                           * (std::max)(m1.cwiseAbs2().maxCoeff(), m2.cwiseAbs2().maxCoeff()));
 }
 
+template <typename LhsType, typename RhsType>
+typename internal::enable_if<RhsType::SizeAtCompileTime==Dynamic,void>::type
+check_mismatched_product(LhsType& lhs, const RhsType& rhs) {
+  VERIFY_RAISES_ASSERT(lhs = rhs*rhs);
+}
+
+template <typename LhsType, typename RhsType>
+typename internal::enable_if<RhsType::SizeAtCompileTime!=Dynamic,void>::type
+check_mismatched_product(LhsType& /*unused*/, const RhsType& /*unused*/) {
+}
+
 template<typename MatrixType> void product(const MatrixType& m)
 {
   /* this test covers the following files:
@@ -77,8 +88,9 @@
   // again, test operator() to check const-qualification
   VERIFY_IS_APPROX(MatrixType::Identity(rows, cols)(r,c), static_cast<Scalar>(r==c));
 
-  if (rows!=cols)
-     VERIFY_RAISES_ASSERT(m3 = m1*m1);
+  if (rows!=cols) {
+    check_mismatched_product(m3, m1);
+  }
 
   // test the previous tests were not screwed up because operator* returns 0
   // (we use the more accurate default epsilon)
diff --git a/test/product_small.cpp b/test/product_small.cpp
index 1d6df6e..8c56ea5 100644
--- a/test/product_small.cpp
+++ b/test/product_small.cpp
@@ -7,7 +7,6 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT
 #include "product.h"
 #include <Eigen/LU>
 
diff --git a/test/random_matrix_helper.h b/test/random_matrix_helper.h
new file mode 100644
index 0000000..733dec5
--- /dev/null
+++ b/test/random_matrix_helper.h
@@ -0,0 +1,256 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2021 Kolja Brix <kolja.brix@rwth-aachen.de>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_RANDOM_MATRIX_HELPER
+#define EIGEN_RANDOM_MATRIX_HELPER
+
+#include <typeinfo>
+#include <Eigen/QR> // required for createRandomPIMatrixOfRank and generateRandomMatrixSvs
+
+
+// Forward declarations to avoid ICC warnings
+#if EIGEN_COMP_ICC
+
+namespace Eigen {
+
+template<typename MatrixType>
+void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m);
+
+template<typename PermutationVectorType>
+void randomPermutationVector(PermutationVectorType& v, Index size);
+
+template<typename MatrixType>
+MatrixType generateRandomUnitaryMatrix(const Index dim);
+
+template<typename MatrixType, typename RealScalarVectorType>
+void generateRandomMatrixSvs(const RealScalarVectorType &svs, const Index rows, const Index cols, MatrixType& M);
+
+template<typename VectorType, typename RealScalar>
+VectorType setupRandomSvs(const Index dim, const RealScalar max);
+
+template<typename VectorType, typename RealScalar>
+VectorType setupRangeSvs(const Index dim, const RealScalar min, const RealScalar max);
+
+} // end namespace Eigen
+
+#endif  // EIGEN_COMP_ICC
+
+
+
+namespace Eigen {
+
+/**
+ * Creates a random partial isometry matrix of given rank.
+ *
+ * A partial isometry is a matrix all of whose singular values are either 0 or 1.
+ * This is very useful to test rank-revealing algorithms.
+ *
+ * @tparam MatrixType type of random partial isometry matrix
+ * @param desired_rank rank requested for the random partial isometry matrix
+ * @param rows row dimension of requested random partial isometry matrix
+ * @param cols column dimension of requested random partial isometry matrix
+ * @param m random partial isometry matrix
+ */
+template<typename MatrixType>
+void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m)
+{
+  typedef typename internal::traits<MatrixType>::Scalar Scalar;
+  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
+
+  typedef Matrix<Scalar, Dynamic, 1> VectorType;
+  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
+  typedef Matrix<Scalar, Cols, Cols> MatrixBType;
+
+  if(desired_rank == 0)
+  {
+    m.setZero(rows,cols);
+    return;
+  }
+
+  if(desired_rank == 1)
+  {
+    // here we normalize the vectors to get a partial isometry
+    m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
+    return;
+  }
+
+  MatrixAType a = MatrixAType::Random(rows,rows);
+  MatrixType d = MatrixType::Identity(rows,cols);
+  MatrixBType  b = MatrixBType::Random(cols,cols);
+
+  // set the diagonal such that only desired_rank non-zero entries remain
+  const Index diag_size = (std::min)(d.rows(),d.cols());
+  if(diag_size != desired_rank)
+    d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
+
+  HouseholderQR<MatrixAType> qra(a);
+  HouseholderQR<MatrixBType> qrb(b);
+  m = qra.householderQ() * d * qrb.householderQ();
+}
+
+/**
+ * Generate random permutation vector.
+ *
+ * @tparam PermutationVectorType type of vector used to store permutation
+ * @param v permutation vector
+ * @param size length of permutation vector
+ */
+template<typename PermutationVectorType>
+void randomPermutationVector(PermutationVectorType& v, Index size)
+{
+  typedef typename PermutationVectorType::Scalar Scalar;
+  v.resize(size);
+  for(Index i = 0; i < size; ++i) v(i) = Scalar(i);
+  if(size == 1) return;
+  for(Index n = 0; n < 3 * size; ++n)
+  {
+    Index i = internal::random<Index>(0, size-1);
+    Index j;
+    do j = internal::random<Index>(0, size-1); while(j==i);
+    std::swap(v(i), v(j));
+  }
+}
+
+/**
+ * Generate a random unitary matrix of prescribed dimension.
+ *
+ * The algorithm is using a random Householder sequence to produce
+ * a random unitary matrix.
+ *
+ * @tparam MatrixType type of matrix to generate
+ * @param dim row and column dimension of the requested square matrix
+ * @return random unitary matrix
+ */
+template<typename MatrixType>
+MatrixType generateRandomUnitaryMatrix(const Index dim)
+{
+  typedef typename internal::traits<MatrixType>::Scalar Scalar;
+  typedef Matrix<Scalar, Dynamic, 1> VectorType;
+
+  MatrixType v = MatrixType::Identity(dim, dim);
+  VectorType h = VectorType::Zero(dim);
+  for (Index i = 0; i < dim; ++i)
+  {
+    v.col(i).tail(dim - i - 1) = VectorType::Random(dim - i - 1);
+    h(i) = 2 / v.col(i).tail(dim - i).squaredNorm();
+  }
+
+  const Eigen::HouseholderSequence<MatrixType, VectorType> HSeq(v, h);
+  return MatrixType(HSeq);
+}
+
+/**
+ * Generation of random matrix with prescribed singular values.
+ *
+ * We generate random matrices with given singular values by setting up
+ * a singular value decomposition. By choosing the number of zeros as
+ * singular values we can specify the rank of the matrix.
+ * Moreover, we also control its spectral norm, which is the largest
+ * singular value, as well as its condition number with respect to the
+ * l2-norm, which is the quotient of the largest and smallest singular
+ * value.
+ *
+ * Reference: For details on the method see e.g. Section 8.1 (pp. 62 f) in
+ *
+ *   C. C. Paige, M. A. Saunders,
+ *   LSQR: An algorithm for sparse linear equations and sparse least squares.
+ *   ACM Transactions on Mathematical Software 8(1), pp. 43-71, 1982.
+ *   https://web.stanford.edu/group/SOL/software/lsqr/lsqr-toms82a.pdf
+ *
+ * and also the LSQR webpage https://web.stanford.edu/group/SOL/software/lsqr/.
+ *
+ * @tparam MatrixType matrix type to generate
+ * @tparam RealScalarVectorType vector type with real entries used for singular values
+ * @param svs vector of desired singular values
+ * @param rows row dimension of requested random matrix
+ * @param cols column dimension of requested random matrix
+ * @param M generated matrix with prescribed singular values
+ */
+template<typename MatrixType, typename RealScalarVectorType>
+void generateRandomMatrixSvs(const RealScalarVectorType &svs, const Index rows, const Index cols, MatrixType& M)
+{
+  enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
+  typedef typename internal::traits<MatrixType>::Scalar Scalar;
+  typedef Matrix<Scalar, Rows, Rows> MatrixAType;
+  typedef Matrix<Scalar, Cols, Cols> MatrixBType;
+
+  const Index min_dim = (std::min)(rows, cols);
+
+  const MatrixAType U = generateRandomUnitaryMatrix<MatrixAType>(rows);
+  const MatrixBType V = generateRandomUnitaryMatrix<MatrixBType>(cols);
+
+  M = U.block(0, 0, rows, min_dim) * svs.asDiagonal() * V.block(0, 0, cols, min_dim).transpose();
+}
+
+/**
+ * Setup a vector of random singular values with prescribed upper limit.
+ * For use with generateRandomMatrixSvs().
+ *
+ * Singular values are non-negative real values. By convention (to be consistent with
+ * singular value decomposition) we sort them in decreasing order.
+ *
+ * This strategy produces random singular values in the range [0, max], in particular
+ * the singular values can be zero or arbitrarily close to zero.
+ *
+ * @tparam VectorType vector type with real entries used for singular values
+ * @tparam RealScalar data type used for real entry
+ * @param dim number of singular values to generate
+ * @param max upper bound for singular values
+ * @return vector of singular values
+ */
+template<typename VectorType, typename RealScalar>
+VectorType setupRandomSvs(const Index dim, const RealScalar max)
+{
+  VectorType svs = max / RealScalar(2) * (VectorType::Random(dim) + VectorType::Ones(dim));
+  std::sort(svs.begin(), svs.end(), std::greater<RealScalar>());
+  return svs;
+}
+
+/**
+ * Setup a vector of random singular values with prescribed range.
+ * For use with generateRandomMatrixSvs().
+ *
+ * Singular values are non-negative real values. By convention (to be consistent with
+ * singular value decomposition) we sort them in decreasing order.
+ *
+ * For dim > 1 this strategy generates a vector with largest entry max, smallest entry
+ * min, and remaining entries in the range [min, max]. For dim == 1 the only entry is
+ * min.
+ *
+ * @tparam VectorType vector type with real entries used for singular values
+ * @tparam RealScalar data type used for real entry
+ * @param dim number of singular values to generate
+ * @param min smallest singular value to use
+ * @param max largest singular value to use
+ * @return vector of singular values
+ */
+template<typename VectorType, typename RealScalar>
+VectorType setupRangeSvs(const Index dim, const RealScalar min, const RealScalar max)
+{
+  VectorType svs = VectorType::Random(dim);
+  if(dim == 0)
+    return svs;
+  if(dim == 1)
+  {
+    svs(0) = min;
+    return svs;
+  }
+  std::sort(svs.begin(), svs.end(), std::greater<RealScalar>());
+
+  // scale to range [min, max]
+  const RealScalar c_min = svs(dim - 1), c_max = svs(0);
+  svs = (svs - VectorType::Constant(dim, c_min)) / (c_max - c_min);
+  return min * (VectorType::Ones(dim) - svs) + max * svs;
+}
+
+} // end namespace Eigen
+
+#endif // EIGEN_RANDOM_MATRIX_HELPER
diff --git a/test/ref.cpp b/test/ref.cpp
index ebfc70d..5e7a3b3 100644
--- a/test/ref.cpp
+++ b/test/ref.cpp
@@ -1,7 +1,7 @@
 // This file is part of Eigen, a lightweight C++ template library
 // for linear algebra.
 //
-// Copyright (C) 20013 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2013 Gael Guennebaud <gael.guennebaud@inria.fr>
 //
 // This Source Code Form is subject to the terms of the Mozilla
 // Public License v. 2.0. If a copy of the MPL was not distributed
@@ -106,9 +106,6 @@
   { RefMat    rm0 = v1.block(0,0,size,1); VERIFY_IS_EQUAL(rm0, v1); }
   { RefDynMat rv1 = v1;                   VERIFY_IS_EQUAL(rv1, v1); }
   { RefDynMat rv1 = v1.block(0,0,size,1); VERIFY_IS_EQUAL(rv1, v1); }
-  { VERIFY_RAISES_ASSERT( RefMat    rm0 = v1.block(0, 0, size, 0); EIGEN_UNUSED_VARIABLE(rm0); ); }
-  if(VectorType::SizeAtCompileTime!=1)
-  { VERIFY_RAISES_ASSERT( RefDynMat rv1 = v1.block(0, 0, size, 0); EIGEN_UNUSED_VARIABLE(rv1); ); }
 
   RefDynMat rv2 = v1.segment(i,bsize);
   VERIFY_IS_EQUAL(rv2, v1.segment(i,bsize));
@@ -320,17 +317,6 @@
   test_ref_ambiguous(A, B);
 }
 
-void test_ref_fixed_size_assert()
-{
-  Vector4f v4 = Vector4f::Random();
-  VectorXf vx = VectorXf::Random(10);
-  VERIFY_RAISES_STATIC_ASSERT( Ref<Vector3f> y = v4; (void)y; );
-  VERIFY_RAISES_STATIC_ASSERT( Ref<Vector3f> y = vx.head<4>(); (void)y; );
-  VERIFY_RAISES_STATIC_ASSERT( Ref<const Vector3f> y = v4; (void)y; );
-  VERIFY_RAISES_STATIC_ASSERT( Ref<const Vector3f> y = vx.head<4>(); (void)y; );
-  VERIFY_RAISES_STATIC_ASSERT( Ref<const Vector3f> y = 2*v4; (void)y; );
-}
-
 EIGEN_DECLARE_TEST(ref)
 {
   for(int i = 0; i < g_repeat; i++) {
@@ -356,5 +342,4 @@
   }
   
   CALL_SUBTEST_7( test_ref_overloads() );
-  CALL_SUBTEST_7( test_ref_fixed_size_assert() );
 }
diff --git a/test/reshape.cpp b/test/reshape.cpp
index 7b16742..23cb215 100644
--- a/test/reshape.cpp
+++ b/test/reshape.cpp
@@ -10,6 +10,9 @@
 
 #include "main.h"
 
+using Eigen::placeholders::last;
+using Eigen::placeholders::all;
+
 template<typename T1,typename T2>
 typename internal::enable_if<internal::is_same<T1,T2>::value,bool>::type
 is_same_eq(const T1& a, const T2& b)
diff --git a/test/selfadjoint.cpp b/test/selfadjoint.cpp
index 9ca9cef..74495fb 100644
--- a/test/selfadjoint.cpp
+++ b/test/selfadjoint.cpp
@@ -45,9 +45,6 @@
   m4 = m2;
   m4 -= m1.template selfadjointView<Lower>();
   VERIFY_IS_APPROX(m4, m2-m3);
-
-  VERIFY_RAISES_STATIC_ASSERT(m2.template selfadjointView<StrictlyUpper>());
-  VERIFY_RAISES_STATIC_ASSERT(m2.template selfadjointView<UnitLower>());
 }
 
 void bug_159()
diff --git a/test/serializer.cpp b/test/serializer.cpp
new file mode 100644
index 0000000..f5c0d67
--- /dev/null
+++ b/test/serializer.cpp
@@ -0,0 +1,108 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2021 The Eigen Team
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "main.h"
+
+#include <vector>
+#include <Eigen/Core>
+
+struct MyPodType {
+  double x;
+  int y;
+  float z;
+};
+
+// Plain-old-data serialization.
+void test_pod_type() {
+  MyPodType initial = {1.3, 17, 1.9f};
+  MyPodType clone = {-1, -1, -1};
+  
+  Eigen::Serializer<MyPodType> serializer;
+  
+  // Determine required size.
+  size_t buffer_size = serializer.size(initial);
+  VERIFY_IS_EQUAL(buffer_size, sizeof(MyPodType));
+  
+  // Serialize.
+  std::vector<uint8_t> buffer(buffer_size);
+  uint8_t* dest = serializer.serialize(buffer.data(), initial);
+  VERIFY_IS_EQUAL(dest - buffer.data(), buffer_size);
+  
+  // Deserialize.
+  uint8_t* src = serializer.deserialize(buffer.data(), clone);
+  VERIFY_IS_EQUAL(src - buffer.data(), buffer_size);
+  VERIFY_IS_EQUAL(clone.x, initial.x);
+  VERIFY_IS_EQUAL(clone.y, initial.y);
+  VERIFY_IS_EQUAL(clone.z, initial.z);
+}
+
+// Matrix, Vector, Array
+template<typename T>
+void test_eigen_type(const T& type) {
+  const Index rows = type.rows();
+  const Index cols = type.cols();
+  
+  const T initial = T::Random(rows, cols);
+  
+  // Serialize.
+  Eigen::Serializer<T> serializer;
+  size_t buffer_size = serializer.size(initial);
+  std::vector<uint8_t> buffer(buffer_size);
+  uint8_t* dest = serializer.serialize(buffer.data(), initial);
+  VERIFY_IS_EQUAL(dest - buffer.data(), buffer_size);
+  
+  // Deserialize.
+  T clone;
+  uint8_t* src = serializer.deserialize(buffer.data(), clone);
+  VERIFY_IS_EQUAL(src - buffer.data(), buffer_size);
+  VERIFY_IS_CWISE_EQUAL(clone, initial);
+}
+
+// Test a collection of dense types.
+template<typename T1, typename T2, typename T3>
+void test_dense_types(const T1& type1, const T2& type2, const T3& type3) {
+  
+  // Make random inputs.
+  const T1 x1 = T1::Random(type1.rows(), type1.cols());
+  const T2 x2 = T2::Random(type2.rows(), type2.cols());
+  const T3 x3 = T3::Random(type3.rows(), type3.cols());
+  
+  // Allocate buffer and serialize.
+  size_t buffer_size = Eigen::serialize_size(x1, x2, x3);
+  std::vector<uint8_t> buffer(buffer_size);
+  Eigen::serialize(buffer.data(), x1, x2, x3);
+  
+  // Clone everything.
+  T1 y1;
+  T2 y2;
+  T3 y3;
+  Eigen::deserialize(buffer.data(), y1, y2, y3);
+  
+  // Verify they equal.
+  VERIFY_IS_CWISE_EQUAL(y1, x1);
+  VERIFY_IS_CWISE_EQUAL(y2, x2);
+  VERIFY_IS_CWISE_EQUAL(y3, x3);
+}
+
+EIGEN_DECLARE_TEST(serializer)
+{
+  CALL_SUBTEST( test_pod_type() );
+
+  for(int i = 0; i < g_repeat; i++) {
+    CALL_SUBTEST( test_eigen_type(Eigen::Array33f()) );
+    CALL_SUBTEST( test_eigen_type(Eigen::ArrayXd(10)) );
+    CALL_SUBTEST( test_eigen_type(Eigen::Vector3f()) );
+    CALL_SUBTEST( test_eigen_type(Eigen::Matrix4d()) );
+    CALL_SUBTEST( test_eigen_type(Eigen::MatrixXd(15, 17)) );
+    
+    CALL_SUBTEST( test_dense_types( Eigen::Array33f(),
+                                    Eigen::ArrayXd(10),
+                                    Eigen::MatrixXd(15, 17)) );
+  }
+}
diff --git a/test/smallvectors.cpp b/test/smallvectors.cpp
index f9803ac..d58038f 100644
--- a/test/smallvectors.cpp
+++ b/test/smallvectors.cpp
@@ -7,7 +7,6 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT
 #include "main.h"
 
 template<typename Scalar> void smallVectors()
@@ -33,28 +32,11 @@
   VERIFY_IS_APPROX(x3, v4.z());
   VERIFY_IS_APPROX(x4, v4.w());
 
-  if (!NumTraits<Scalar>::IsInteger)
-  {
-    VERIFY_RAISES_ASSERT(V3(2, 1))
-    VERIFY_RAISES_ASSERT(V3(3, 2))
-    VERIFY_RAISES_ASSERT(V3(Scalar(3), 1))
-    VERIFY_RAISES_ASSERT(V3(3, Scalar(1)))
-    VERIFY_RAISES_ASSERT(V3(Scalar(3), Scalar(1)))
-    VERIFY_RAISES_ASSERT(V3(Scalar(123), Scalar(123)))
-
-    VERIFY_RAISES_ASSERT(V4(1, 3))
-    VERIFY_RAISES_ASSERT(V4(2, 4))
-    VERIFY_RAISES_ASSERT(V4(1, Scalar(4)))
-    VERIFY_RAISES_ASSERT(V4(Scalar(1), 4))
-    VERIFY_RAISES_ASSERT(V4(Scalar(1), Scalar(4)))
-    VERIFY_RAISES_ASSERT(V4(Scalar(123), Scalar(123)))
-
-    VERIFY_RAISES_ASSERT(VX(3, 2))
-    VERIFY_RAISES_ASSERT(VX(Scalar(3), 1))
-    VERIFY_RAISES_ASSERT(VX(3, Scalar(1)))
-    VERIFY_RAISES_ASSERT(VX(Scalar(3), Scalar(1)))
-    VERIFY_RAISES_ASSERT(VX(Scalar(123), Scalar(123)))
-  }
+  VERIFY_RAISES_ASSERT(V3(2, 1))
+  VERIFY_RAISES_ASSERT(V3(3, 2))
+  VERIFY_RAISES_ASSERT(V4(1, 3))
+  VERIFY_RAISES_ASSERT(V4(2, 4))
+  VERIFY_RAISES_ASSERT(VX(3, 2))
 }
 
 EIGEN_DECLARE_TEST(smallvectors)
diff --git a/test/sparse_ref.cpp b/test/sparse_ref.cpp
index 12b6f8a..8f33af8 100644
--- a/test/sparse_ref.cpp
+++ b/test/sparse_ref.cpp
@@ -1,7 +1,7 @@
 // This file is part of Eigen, a lightweight C++ template library
 // for linear algebra.
 //
-// Copyright (C) 20015 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
 //
 // This Source Code Form is subject to the terms of the Mozilla
 // Public License v. 2.0. If a copy of the MPL was not distributed
diff --git a/test/stl_iterators.cpp b/test/stl_iterators.cpp
index 72bbf82..f868d68 100644
--- a/test/stl_iterators.cpp
+++ b/test/stl_iterators.cpp
@@ -133,6 +133,7 @@
   ColMatrixType A = ColMatrixType::Random(rows,cols);
   const ColMatrixType& cA(A);
   RowMatrixType B = RowMatrixType::Random(rows,cols);
+  using Eigen::placeholders::last;
   
   Index i, j;
 
diff --git a/test/swap.cpp b/test/swap.cpp
index 813c613..6189f13 100644
--- a/test/swap.cpp
+++ b/test/swap.cpp
@@ -7,7 +7,6 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#define EIGEN_NO_STATIC_ASSERT
 #include "main.h"
 
 template<typename T>
@@ -22,6 +21,20 @@
   typedef Matrix<Scalar_, Rows_, Cols_, Options_^RowMajor, MaxRows_, MaxCols_> type;
 };
 
+template <typename MatrixType>
+typename internal::enable_if<(MatrixType::RowsAtCompileTime==1 || MatrixType::RowsAtCompileTime==Dynamic), void>::type
+check_row_swap(MatrixType& m1) {
+  // test assertion on mismatching size -- matrix case
+  VERIFY_RAISES_ASSERT(m1.swap(m1.row(0)));
+  // test assertion on mismatching size -- xpr case
+  VERIFY_RAISES_ASSERT(m1.row(0).swap(m1));
+}
+
+template <typename MatrixType>
+typename internal::enable_if<!(MatrixType::RowsAtCompileTime==1 || MatrixType::RowsAtCompileTime==Dynamic), void>::type
+check_row_swap(MatrixType& /* unused */) {
+}
+
 template<typename MatrixType> void swap(const MatrixType& m)
 {
   typedef typename other_matrix_type<MatrixType>::type OtherMatrixType;
@@ -73,14 +86,8 @@
   VERIFY_IS_APPROX(m3,m1_copy);
   m1 = m1_copy;
   m3 = m3_copy;
-  
-  if(m1.rows()>1)
-  {
-    // test assertion on mismatching size -- matrix case
-    VERIFY_RAISES_ASSERT(m1.swap(m1.row(0)));
-    // test assertion on mismatching size -- xpr case
-    VERIFY_RAISES_ASSERT(m1.row(0).swap(m1));
-  }
+
+  check_row_swap(m1);
 }
 
 EIGEN_DECLARE_TEST(swap)
diff --git a/test/symbolic_index.cpp b/test/symbolic_index.cpp
index a75ca11..e40cb18 100644
--- a/test/symbolic_index.cpp
+++ b/test/symbolic_index.cpp
@@ -19,6 +19,10 @@
 
 #include "main.h"
 
+using Eigen::placeholders::last;
+using Eigen::placeholders::lastp1;
+using Eigen::placeholders::all;
+
 template<typename T1,typename T2>
 bool is_same_symb(const T1& a, const T2& b, Index size)
 {
diff --git a/test/triangular.cpp b/test/triangular.cpp
index 981a0d0..eae0ea0 100644
--- a/test/triangular.cpp
+++ b/test/triangular.cpp
@@ -139,7 +139,6 @@
   m3.setZero();
   m3.template triangularView<Upper>().setOnes();
   VERIFY_IS_APPROX(m2,m3);
-  VERIFY_RAISES_STATIC_ASSERT(m1.template triangularView<Eigen::Lower>().swap(m2.template triangularView<Eigen::Upper>()));
 
   m1.setRandom();
   m3 = m1.template triangularView<Upper>();
diff --git a/test/tuple_test.cpp b/test/tuple_test.cpp
new file mode 100644
index 0000000..8d8a5aa
--- /dev/null
+++ b/test/tuple_test.cpp
@@ -0,0 +1,123 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2021 The Eigen Team
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "main.h"
+
+#include <Eigen/Core>
+#include <Eigen/src/Core/arch/GPU/Tuple.h>
+
+using namespace Eigen::internal;
+using Eigen::internal::tuple_impl::tuple;
+  
+void basic_tuple_test() {  
+  // Construction.
+  tuple<> tuple0 {};
+  tuple<int> tuple1 {1};
+  tuple<int, float> tuple2 {3, 5.0f};
+  tuple<int, float, double> tuple3 {7, 11.0f, 13.0};
+  // Default construction.
+  tuple<> tuple0default;
+  EIGEN_UNUSED_VARIABLE(tuple0default)
+  tuple<int> tuple1default;
+  EIGEN_UNUSED_VARIABLE(tuple1default)
+  tuple<int, float> tuple2default;
+  EIGEN_UNUSED_VARIABLE(tuple2default)
+  tuple<int, float, double> tuple3default;
+  EIGEN_UNUSED_VARIABLE(tuple3default)
+  
+  // Assignment.
+  tuple<> tuple0b = tuple0;
+  EIGEN_UNUSED_VARIABLE(tuple0b)
+  decltype(tuple1) tuple1b = tuple1;
+  EIGEN_UNUSED_VARIABLE(tuple1b)
+  decltype(tuple2) tuple2b = tuple2;
+  EIGEN_UNUSED_VARIABLE(tuple2b)
+  decltype(tuple3) tuple3b = tuple3;
+  EIGEN_UNUSED_VARIABLE(tuple3b)
+  
+  // get.
+  VERIFY_IS_EQUAL(tuple_impl::get<0>(tuple3), 7);
+  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple3), 11.0f);
+  VERIFY_IS_EQUAL(tuple_impl::get<2>(tuple3), 13.0);
+  
+  // tuple_impl::tuple_size.
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple0)>::value, size_t(0));
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple1)>::value, size_t(1));
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple2)>::value, size_t(2));
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple3)>::value, size_t(3));
+  
+  // tuple_impl::tuple_cat.
+  auto tuple2cat3 = tuple_impl::tuple_cat(tuple2, tuple3);
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple2cat3)>::value, size_t(5));
+  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple2cat3), 5.0f);
+  VERIFY_IS_EQUAL(tuple_impl::get<3>(tuple2cat3), 11.0f);
+  auto tuple3cat0 = tuple_impl::tuple_cat(tuple3, tuple0);
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple3cat0)>::value, size_t(3));
+  auto singlecat = tuple_impl::tuple_cat(tuple3);
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(singlecat)>::value, size_t(3));
+  auto emptycat = tuple_impl::tuple_cat();
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(emptycat)>::value, size_t(0));
+  auto tuple0cat1cat2cat3 = tuple_impl::tuple_cat(tuple0, tuple1, tuple2, tuple3);
+  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple0cat1cat2cat3)>::value, size_t(6));
+  
+  // make_tuple.
+  // The tuple types should uses values for the second and fourth parameters.
+  double tmp = 20;
+  auto tuple_make = tuple_impl::make_tuple(int(10), tmp, float(20.0f), tuple0);
+  VERIFY( (std::is_same<decltype(tuple_make), tuple<int, double, float, tuple<> > >::value) );
+  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple_make), tmp);
+  
+  // forward_as_tuple.
+  // The tuple types should uses references for the second and fourth parameters.
+  auto tuple_forward = tuple_impl::forward_as_tuple(int(10), tmp, float(20.0f), tuple0);
+  VERIFY( (std::is_same<decltype(tuple_forward), tuple<int, double&, float, tuple<>& > >::value) );
+  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple_forward), tmp);
+  
+  // tie.
+  auto tuple_tie = tuple_impl::tie(tuple0, tuple1, tuple2, tuple3);
+  VERIFY( (std::is_same<decltype(tuple_tie), 
+                        tuple<decltype(tuple0)&,
+                              decltype(tuple1)&,
+                              decltype(tuple2)&,
+                              decltype(tuple3)&> >::value) );
+  VERIFY_IS_EQUAL( (tuple_impl::get<1>(tuple_impl::get<2>(tuple_tie))), 5.0f );
+  // Modify value and ensure tuple2 is updated.
+  tuple_impl::get<1>(tuple_impl::get<2>(tuple_tie)) = 10.0f;
+  VERIFY_IS_EQUAL( (tuple_impl::get<1>(tuple2)), 10.0f );
+  
+  // Assignment.
+  int x = -1;
+  float y = -1;
+  double z = -1;
+  tuple_impl::tie(x, y, z) = tuple3;
+  VERIFY_IS_EQUAL(x, tuple_impl::get<0>(tuple3));
+  VERIFY_IS_EQUAL(y, tuple_impl::get<1>(tuple3));
+  VERIFY_IS_EQUAL(z, tuple_impl::get<2>(tuple3));
+  tuple<int, float, double> tuple3c(-2, -2, -2);
+  tuple3c = std::move(tuple3b);
+  VERIFY_IS_EQUAL(tuple_impl::get<0>(tuple3c), tuple_impl::get<0>(tuple3));
+  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple3c), tuple_impl::get<1>(tuple3));
+  VERIFY_IS_EQUAL(tuple_impl::get<2>(tuple3c), tuple_impl::get<2>(tuple3));
+}
+
+void eigen_tuple_test() {
+  tuple<Eigen::Matrix3d, Eigen::MatrixXd> tuple;
+  tuple_impl::get<0>(tuple).setRandom();
+  tuple_impl::get<1>(tuple).setRandom(10, 10);
+  
+  auto tuple_tie = tuple_impl::tie(tuple_impl::get<0>(tuple), tuple_impl::get<1>(tuple));
+  tuple_impl::get<1>(tuple_tie).setIdentity();
+  VERIFY(tuple_impl::get<1>(tuple).isIdentity());
+}
+
+EIGEN_DECLARE_TEST(tuple)
+{
+  CALL_SUBTEST(basic_tuple_test());
+  CALL_SUBTEST(eigen_tuple_test());
+}
diff --git a/test/vectorwiseop.cpp b/test/vectorwiseop.cpp
index 8ee5884..4369789 100644
--- a/test/vectorwiseop.cpp
+++ b/test/vectorwiseop.cpp
@@ -9,7 +9,6 @@
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #define TEST_ENABLE_TEMPORARY_TRACKING
-#define EIGEN_NO_STATIC_ASSERT
 
 #include "main.h"
 
@@ -32,77 +31,49 @@
   RowVectorType rowvec = RowVectorType::Random(cols);
 
   // test addition
-
   m2 = m1;
   m2.colwise() += colvec;
   VERIFY_IS_APPROX(m2, m1.colwise() + colvec);
   VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec);
 
-  VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose());
-  VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose());
-
   m2 = m1;
   m2.rowwise() += rowvec;
   VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec);
   VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec);
 
-  VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose());
-  VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose());
-
-  // test substraction
-
+  // test subtraction
   m2 = m1;
   m2.colwise() -= colvec;
   VERIFY_IS_APPROX(m2, m1.colwise() - colvec);
   VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec);
 
-  VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose());
-  VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose());
-
   m2 = m1;
   m2.rowwise() -= rowvec;
   VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec);
   VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec);
 
-  VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose());
-  VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose());
-
   // test multiplication
-
   m2 = m1;
   m2.colwise() *= colvec;
   VERIFY_IS_APPROX(m2, m1.colwise() * colvec);
   VERIFY_IS_APPROX(m2.col(c), m1.col(c) * colvec);
 
-  VERIFY_RAISES_ASSERT(m2.colwise() *= colvec.transpose());
-  VERIFY_RAISES_ASSERT(m1.colwise() * colvec.transpose());
-
   m2 = m1;
   m2.rowwise() *= rowvec;
   VERIFY_IS_APPROX(m2, m1.rowwise() * rowvec);
   VERIFY_IS_APPROX(m2.row(r), m1.row(r) * rowvec);
 
-  VERIFY_RAISES_ASSERT(m2.rowwise() *= rowvec.transpose());
-  VERIFY_RAISES_ASSERT(m1.rowwise() * rowvec.transpose());
-
   // test quotient
-
   m2 = m1;
   m2.colwise() /= colvec;
   VERIFY_IS_APPROX(m2, m1.colwise() / colvec);
   VERIFY_IS_APPROX(m2.col(c), m1.col(c) / colvec);
 
-  VERIFY_RAISES_ASSERT(m2.colwise() /= colvec.transpose());
-  VERIFY_RAISES_ASSERT(m1.colwise() / colvec.transpose());
-
   m2 = m1;
   m2.rowwise() /= rowvec;
   VERIFY_IS_APPROX(m2, m1.rowwise() / rowvec);
   VERIFY_IS_APPROX(m2.row(r), m1.row(r) / rowvec);
 
-  VERIFY_RAISES_ASSERT(m2.rowwise() /= rowvec.transpose());
-  VERIFY_RAISES_ASSERT(m1.rowwise() / rowvec.transpose());
-
   m2 = m1;
   // yes, there might be an aliasing issue there but ".rowwise() /="
   // is supposed to evaluate " m2.colwise().sum()" into a temporary to avoid
@@ -158,58 +129,30 @@
   m2.rowwise() = rowvec;
   for(Index i=0; i<rows; ++i)
     VERIFY_IS_APPROX(m2.row(i), rowvec);
-  if(rows>1)
-    VERIFY_RAISES_ASSERT(m2.colwise() = colvec.transpose());
-  if(cols>1)
-    VERIFY_RAISES_ASSERT(m2.rowwise() = rowvec.transpose());
 
   // test addition
-
   m2 = m1;
   m2.colwise() += colvec;
   VERIFY_IS_APPROX(m2, m1.colwise() + colvec);
   VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec);
 
-  if(rows>1)
-  {
-    VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose());
-    VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose());
-  }
-
   m2 = m1;
   m2.rowwise() += rowvec;
   VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec);
   VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec);
 
-  if(cols>1)
-  {
-    VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose());
-    VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose());
-  }
 
-  // test substraction
-
+  // test subtraction
   m2 = m1;
   m2.colwise() -= colvec;
   VERIFY_IS_APPROX(m2, m1.colwise() - colvec);
   VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec);
 
-  if(rows>1)
-  {
-    VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose());
-    VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose());
-  }
-
   m2 = m1;
   m2.rowwise() -= rowvec;
   VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec);
   VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec);
 
-  if(cols>1)
-  {
-    VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose());
-    VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose());
-  }
 
   // ------ partial reductions ------
 
@@ -272,11 +215,8 @@
   VERIFY_IS_APPROX(m1.matrix().middleRows(0,0).colwise().prod().eval(), MatrixX::Ones(1,cols));
   VERIFY_IS_APPROX(m1.matrix().middleCols(0,fix<0>).rowwise().prod().eval(), MatrixX::Ones(rows,1));
   VERIFY_IS_APPROX(m1.matrix().middleRows(0,fix<0>).colwise().prod().eval(), MatrixX::Ones(1,cols));
-  
   VERIFY_IS_APPROX(m1.matrix().middleCols(0,0).rowwise().squaredNorm().eval(), MatrixX::Zero(rows,1));
 
-  VERIFY_RAISES_ASSERT(m1.real().middleCols(0,0).rowwise().minCoeff().eval());
-  VERIFY_RAISES_ASSERT(m1.real().middleRows(0,0).colwise().maxCoeff().eval());
   VERIFY_IS_EQUAL(m1.real().middleRows(0,0).rowwise().maxCoeff().eval().rows(),0);
   VERIFY_IS_EQUAL(m1.real().middleCols(0,0).colwise().maxCoeff().eval().cols(),0);
   VERIFY_IS_EQUAL(m1.real().middleRows(0,fix<0>).rowwise().maxCoeff().eval().rows(),0);
diff --git a/unsupported/Eigen/AdolcForward b/unsupported/Eigen/AdolcForward
index 56caeae..ad05504 100644
--- a/unsupported/Eigen/AdolcForward
+++ b/unsupported/Eigen/AdolcForward
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_ADLOC_FORWARD
-#define EIGEN_ADLOC_FORWARD
+#ifndef EIGEN_ADLOC_FORWARD_MODULE_H
+#define EIGEN_ADLOC_FORWARD_MODULE_H
 
 //--------------------------------------------------------------------------------
 //
@@ -156,4 +156,4 @@
 
 }
 
-#endif // EIGEN_ADLOC_FORWARD
+#endif // EIGEN_ADLOC_FORWARD_MODULE_H
diff --git a/unsupported/Eigen/AlignedVector3 b/unsupported/Eigen/AlignedVector3
index fb36608..cf2b9f6 100644
--- a/unsupported/Eigen/AlignedVector3
+++ b/unsupported/Eigen/AlignedVector3
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_ALIGNED_VECTOR3
-#define EIGEN_ALIGNED_VECTOR3
+#ifndef EIGEN_ALIGNED_VECTOR3_MODULE_H
+#define EIGEN_ALIGNED_VECTOR3_MODULE_H
 
 #include "../../Eigen/Geometry"
 
@@ -231,4 +231,4 @@
 
 #include "../../Eigen/src/Core/util/ReenableStupidWarnings.h"
 
-#endif // EIGEN_ALIGNED_VECTOR3
+#endif // EIGEN_ALIGNED_VECTOR3_MODULE_H
diff --git a/unsupported/Eigen/AutoDiff b/unsupported/Eigen/AutoDiff
index 7a4ff46..1d1be3b 100644
--- a/unsupported/Eigen/AutoDiff
+++ b/unsupported/Eigen/AutoDiff
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_AUTODIFF_MODULE
-#define EIGEN_AUTODIFF_MODULE
+#ifndef EIGEN_AUTODIFF_MODULE_H
+#define EIGEN_AUTODIFF_MODULE_H
 
 namespace Eigen {
 
@@ -43,4 +43,4 @@
 //@}
 }
 
-#endif // EIGEN_AUTODIFF_MODULE
+#endif // EIGEN_AUTODIFF_MODULE_H
diff --git a/unsupported/Eigen/CXX11/Tensor b/unsupported/Eigen/CXX11/Tensor
index 0938bb5..1b8b33f 100644
--- a/unsupported/Eigen/CXX11/Tensor
+++ b/unsupported/Eigen/CXX11/Tensor
@@ -8,8 +8,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-//#ifndef EIGEN_CXX11_TENSOR_MODULE
-//#define EIGEN_CXX11_TENSOR_MODULE
+//#ifndef EIGEN_CXX11_TENSOR_MODULE_H
+#define EIGEN_CXX11_TENSOR_MODULE_H
 
 #include "../../../Eigen/Core"
 
@@ -134,4 +134,4 @@
 #include "../../../Eigen/src/Core/util/ReenableStupidWarnings.h"
 
 #endif  // EIGEN_HAS_CXX11
-//#endif // EIGEN_CXX11_TENSOR_MODULE
+//#endif // EIGEN_CXX11_TENSOR_MODULE_H
diff --git a/unsupported/Eigen/CXX11/TensorSymmetry b/unsupported/Eigen/CXX11/TensorSymmetry
index b09c5e4..a5c9609 100644
--- a/unsupported/Eigen/CXX11/TensorSymmetry
+++ b/unsupported/Eigen/CXX11/TensorSymmetry
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_CXX11_TENSORSYMMETRY_MODULE
-#define EIGEN_CXX11_TENSORSYMMETRY_MODULE
+#ifndef EIGEN_CXX11_TENSORSYMMETRY_MODULE_H
+#define EIGEN_CXX11_TENSORSYMMETRY_MODULE_H
 
 #include "Tensor"
 
@@ -35,8 +35,4 @@
 
 #include "../../../Eigen/src/Core/util/ReenableStupidWarnings.h"
 
-#endif // EIGEN_CXX11_TENSORSYMMETRY_MODULE
-
-/*
- * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
- */
+#endif // EIGEN_CXX11_TENSORSYMMETRY_MODULE_H
diff --git a/unsupported/Eigen/CXX11/ThreadPool b/unsupported/Eigen/CXX11/ThreadPool
index 1af1a07..5fb9fa7 100644
--- a/unsupported/Eigen/CXX11/ThreadPool
+++ b/unsupported/Eigen/CXX11/ThreadPool
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_CXX11_THREADPOOL_MODULE
-#define EIGEN_CXX11_THREADPOOL_MODULE
+#ifndef EIGEN_CXX11_THREADPOOL_MODULE_H
+#define EIGEN_CXX11_THREADPOOL_MODULE_H
 
 #include "../../../Eigen/Core"
 
@@ -95,4 +95,4 @@
 
 #include "../../../Eigen/src/Core/util/ReenableStupidWarnings.h"
 
-#endif // EIGEN_CXX11_THREADPOOL_MODULE
+#endif // EIGEN_CXX11_THREADPOOL_MODULE_H
diff --git a/unsupported/Eigen/CXX11/src/Tensor/InternalHeaderCheck.h b/unsupported/Eigen/CXX11/src/Tensor/InternalHeaderCheck.h
new file mode 100644
index 0000000..9e4c1ed
--- /dev/null
+++ b/unsupported/Eigen/CXX11/src/Tensor/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_CXX11_TENSOR_MODULE_H
+#error "Please include unsupported/Eigen/CXX11/Tensor instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h
index 03361e6..76e97cd 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_H
 #define EIGEN_CXX11_TENSOR_TENSOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class Tensor
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorArgMax.h b/unsupported/Eigen/CXX11/src/Tensor/TensorArgMax.h
index 1d7e9f1..9bf5373 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorArgMax.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorArgMax.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_ARG_MAX_H
 #define EIGEN_CXX11_TENSOR_TENSOR_ARG_MAX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorAssign.h b/unsupported/Eigen/CXX11/src/Tensor/TensorAssign.h
index e5811d6..c896eae 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorAssign.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorAssign.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_ASSIGN_H
 #define EIGEN_CXX11_TENSOR_TENSOR_ASSIGN_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorAssign
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
index 580b937..68aced5 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
@@ -12,6 +12,8 @@
 
 // clang-format off
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorBase
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorBlock.h b/unsupported/Eigen/CXX11/src/Tensor/TensorBlock.h
index 1e55d12..5f7d6d0 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorBlock.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorBlock.h
@@ -8,6 +8,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_BLOCK_H
 #define EIGEN_CXX11_TENSOR_TENSOR_BLOCK_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h b/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h
index a354132..8a7f5eb 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_BROADCASTING_H
 #define EIGEN_CXX11_TENSOR_TENSOR_BROADCASTING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorBroadcasting
@@ -105,7 +107,7 @@
   typedef typename XprType::CoeffReturnType CoeffReturnType;
   typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
   static const int PacketSize = PacketType<CoeffReturnType, Device>::size;
-  protected: //  all the non-static fields must have the same access control, otherwise the TensorEvaluator wont be standard layout;
+  protected: //  all the non-static fields must have the same access control, otherwise the TensorEvaluator won't be standard layout;
   bool isCopy, nByOne, oneByN;
   public:
   typedef StorageMemory<CoeffReturnType, Device> Storage;
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h b/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h
index 3764573..1fff5b7 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CHIPPING_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CHIPPING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorKChippingReshaping
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h b/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h
index 5235a8e..368ad78 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CONCATENATION_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CONCATENATION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorConcatenationOp
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h b/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h
index cdd8840..3477595 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorContraction
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h
index 4b69e2b..60748cc 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h
@@ -14,6 +14,8 @@
 #include "third_party/libxsmm/include/libxsmm.h"
 #endif
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionGpu.h b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionGpu.h
index 1e17e8b..65d9a34 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionGpu.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionGpu.h
@@ -14,6 +14,8 @@
 
 #if defined(EIGEN_USE_GPU) && defined(EIGEN_GPUCC)
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename Scalar, typename Index, typename LhsMapper,
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h
index 9ab900b..5378184 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_MAPPER_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_MAPPER_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h
index 473c228..dd11674 100755
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h
@@ -19,6 +19,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_SYCL_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CONTRACTION_SYCL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace TensorSycl {
@@ -110,7 +112,7 @@
   // BC : determines if supporting bank conflict is required
   static EIGEN_CONSTEXPR bool BC = true;
   // DoubleBuffer: determines if double buffering technique should be used (This can be disabled by
-  // EIGEN_SYCL_DISABLE_DOUBLE_BUFFER macro when the device doesnot have sufficient  local memory)
+  // EIGEN_SYCL_DISABLE_DOUBLE_BUFFER macro when the device does not have sufficient local memory)
   static EIGEN_CONSTEXPR bool DoubleBuffer =
 #ifdef EIGEN_SYCL_DISABLE_DOUBLE_BUFFER
       false;
@@ -428,7 +430,7 @@
  Otherwise, the result of contraction will be written iin a temporary buffer. This is the case when Tall/Skinny
  contraction is used. So in this case, a final reduction step is required to compute final output.
 
- * \tparam contraction_tp: it is an enum value representing whether the local memroy/no local memory implementation of
+ * \tparam contraction_tp: it is an enum value representing whether the local memory/no local memory implementation of
  the algorithm to be used
  *
  * \param scratch: local memory containing tiles of LHS and RHS tensors for each work-group
@@ -493,7 +495,7 @@
    * the TiledMemory for both local and private memory, the MemHolder structs is used as a helper to abstract out
    * different type of memory needed when local/no_local memory computation is called.
    *
-   * \tparam contraction_type: it is an enum value representing whether the local memroy/no local memory implementation
+   * \tparam contraction_type: it is an enum value representing whether the local memory/no local memory implementation
    of the algorithm to be used
    * \tparam the private memory size
    * \param ptr the tile memory pointer type
@@ -520,10 +522,10 @@
    * \param rhs_scratch_extract : determines the RHS tile memory. It is either private or local memory based on the
    * selected contraction_type.
    *
-   * \param lhs_extract_index: determins the position of each thread on a local memory for lhs input. When private
+   * \param lhs_extract_index: determines the position of each thread on a local memory for lhs input. When private
    * memory is used this is set to zero as this is not applicable in case of private memory.
    *
-   * \param rhs_extract_index: determins the position of each thread on a local memory for rhs input. When private
+   * \param rhs_extract_index: determines the position of each thread on a local memory for rhs input. When private
    * memory is used this is set to zero as this is not applicable in case of private memory.
    *
    * \param lhs_scratch_compute : determines the  location to load for computation for lhs_local memory. This is the
@@ -1234,7 +1236,7 @@
  *
  * \param out_res: determines the output tensor containing the contraction result
  *
- * \param rng: determins the total input data size
+ * \param rng: determines the total input data size
  */
 template <typename OutScalar, typename LhsScalar, typename RhsScalar, typename OutAccessor, typename LhsMapper,
           typename RhsMapper, typename StorageIndex, bool Vectorizable>
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h
index 84fac2a..0bbc1e8 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h
@@ -13,6 +13,8 @@
 // evaluator for thread pool device
 #ifdef EIGEN_USE_THREADS
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename Indices, typename LeftArgType, typename RightArgType, typename OutputKernelType>
@@ -96,7 +98,7 @@
     //     context from the heap.
     //
     // (*) EvalParallelContext & EvalShardedByInnerDimContext owns all the state
-    // and temporary buffers, requried for executing the tensor contraction.
+    // and temporary buffers, required for executing the tensor contraction.
     // They are responsible for cleaning it up after contraction is done.
     static const bool IsEvalInSyncMode =
         std::is_same<DoneCallback, NoCallback>::value;
@@ -698,7 +700,7 @@
           !is_rhs && std::is_same<BlockType, LhsBlock>::value;
       static const bool kIsRhs =
           is_rhs && std::is_same<BlockType, RhsBlock>::value;
-      static_assert(kIsLhs || kIsRhs, "Unkown block type");
+      static_assert(kIsLhs || kIsRhs, "Unknown block type");
 
       using Blocks = ThreadLocalBlocks<BlockType>;
 
@@ -895,7 +897,7 @@
         } else {
           // If we can't guarantee that all kernels in `k` slice will be
           // executed sequentially in current thread, it's no longer safe to use
-          // thread local memory in followig slices along the k dimensions.
+          // thread local memory in following slices along the k dimensions.
           eigen_assert(k > 0);
           can_use_thread_local_packed_[n].store(false,
                                                 std::memory_order_relaxed);
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h b/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h
index 09d2da9..a2f9e57 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CONVERSION_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CONVERSION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorConversionOp
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h b/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h
index b20f80b..98b4de3 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CONVOLUTION_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CONVOLUTION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorConvolution
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h b/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h
index 033318f..a9d3d68 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h
@@ -15,6 +15,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CONVOLUTION_SYCL_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CONVOLUTION_SYCL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorConvolution
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorCostModel.h b/unsupported/Eigen/CXX11/src/Tensor/TensorCostModel.h
index 195267c..c3f4bdd 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorCostModel.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorCostModel.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_COST_MODEL_H
 #define EIGEN_CXX11_TENSOR_TENSOR_COST_MODEL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorEvaluator
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorCustomOp.h b/unsupported/Eigen/CXX11/src/Tensor/TensorCustomOp.h
index 95a8a84..dd71415 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorCustomOp.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorCustomOp.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_CUSTOM_OP_H
 #define EIGEN_CXX11_TENSOR_TENSOR_CUSTOM_OP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorCustomUnaryOp
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDevice.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDevice.h
index 96fa46c..8148441 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorDevice.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDevice.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_DEVICE_H
 #define EIGEN_CXX11_TENSOR_TENSOR_DEVICE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorDevice
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h
index 5bde4d6..d9a3d32 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h
@@ -11,6 +11,8 @@
 #define EIGEN_CXX11_TENSOR_TENSOR_DEVICE_DEFAULT_H
 
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // Default device for the machine (typically a single cpu core)
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h
index 8ee4478..3b09a0f 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h
@@ -15,6 +15,8 @@
 // A separate header (included at the end of this file) will undefine all 
 #include "TensorGpuHipCudaDefines.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 static const int kGpuScratchSize = 1024;
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h
index 844c093..454944e 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h
@@ -16,6 +16,8 @@
 #define EIGEN_CXX11_TENSOR_TENSOR_DEVICE_SYCL_H
 #include <unordered_set>
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace TensorSycl {
@@ -244,7 +246,7 @@
   }
 
   /// The memcpyHostToDevice is used to copy the data from host to device
-  /// The destination pointer could be deleted before the copy happend which is
+  /// The destination pointer could be deleted before the copy happened which is
   /// why a callback function is needed. By default if none is provided, the
   /// function is blocking.
   EIGEN_STRONG_INLINE void memcpyHostToDevice(
@@ -272,7 +274,7 @@
   }
 
   /// The memcpyDeviceToHost is used to copy the data from device to host.
-  /// The source pointer could be deleted before the copy happend which is
+  /// The source pointer could be deleted before the copy happened which is
   /// why a callback function is needed. By default if none is provided, the
   /// function is blocking.
   EIGEN_STRONG_INLINE void memcpyDeviceToHost(
@@ -713,7 +715,7 @@
   EIGEN_STRONG_INLINE int majorDeviceVersion() const { return 1; }
 
   EIGEN_STRONG_INLINE unsigned long maxSyclThreadsPerMultiProcessor() const {
-    // OpenCL doesnot have such concept
+    // OpenCL does not have such a concept
     return 2;
   }
 
@@ -1033,7 +1035,7 @@
     return queue_stream()->maxWorkItemSizes();
   }
   EIGEN_STRONG_INLINE unsigned long maxSyclThreadsPerMultiProcessor() const {
-    // OpenCL doesnot have such concept
+    // OpenCL does not have such a concept
     return queue_stream()->maxSyclThreadsPerMultiProcessor();
   }
   EIGEN_STRONG_INLINE size_t sharedMemPerBlock() const {
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h
index 18cc79a..a3adf61 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h
@@ -10,6 +10,8 @@
 #if defined(EIGEN_USE_THREADS) && !defined(EIGEN_CXX11_TENSOR_TENSOR_DEVICE_THREAD_POOL_H)
 #define EIGEN_CXX11_TENSOR_TENSOR_DEVICE_THREAD_POOL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // Runs an arbitrary function and then calls Notify() on the passed in
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDimensionList.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDimensionList.h
index 1a30e45..ed827c1 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorDimensionList.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDimensionList.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_DIMENSION_LIST_H
 #define EIGEN_CXX11_TENSOR_TENSOR_DIMENSION_LIST_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \internal
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h
index f0f1e83..6fc2aa8 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h
@@ -11,6 +11,8 @@
 #define EIGEN_CXX11_TENSOR_TENSOR_DIMENSIONS_H
 
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \internal
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h b/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h
index a48d035..6ced0e8 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
 #define EIGEN_CXX11_TENSOR_TENSOR_EVAL_TO_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorForcedEval
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h b/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h
index 3aff7fa..eed7ecf 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_EVALUATOR_H
 #define EIGEN_CXX11_TENSOR_TENSOR_EVALUATOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorEvaluator
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h b/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h
index c52fb77..279be34 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_EXECUTOR_H
 #define EIGEN_CXX11_TENSOR_TENSOR_EXECUTOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /**
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorExpr.h b/unsupported/Eigen/CXX11/src/Tensor/TensorExpr.h
index c9bccfc..bd26311 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorExpr.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorExpr.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_EXPR_H
 #define EIGEN_CXX11_TENSOR_TENSOR_EXPR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorExpr
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h b/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h
index 4a1a068..0635612 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_FFT_H
 #define EIGEN_CXX11_TENSOR_TENSOR_FFT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorFFT
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h b/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h
index ca39bb8..325fa6d 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_FIXED_SIZE_H
 #define EIGEN_CXX11_TENSOR_TENSOR_FIXED_SIZE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorFixedSize
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h b/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h
index e800ded..3514060 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_FORCED_EVAL_H
 #define EIGEN_CXX11_TENSOR_TENSOR_FORCED_EVAL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorForcedEval
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h b/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h
index 139384a..9fce0f0 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_FORWARD_DECLARATIONS_H
 #define EIGEN_CXX11_TENSOR_TENSOR_FORWARD_DECLARATIONS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // MakePointer class is used as a container of the address space of the pointer
@@ -29,7 +31,7 @@
 }
 
 // The StorageMemory class is a container of the device specific pointer
-// used for refering to a Pointer on TensorEvaluator class. While the TensorExpression
+// used for referring to a Pointer on TensorEvaluator class. While the TensorExpression
 // is a device-agnostic type and need MakePointer class for type conversion,
 // the TensorEvaluator class can be specialized for a device, hence it is possible
 // to construct different types of temproray storage memory in TensorEvaluator
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h b/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
index b99edd4..ddd2c87 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_FUNCTORS_H
 #define EIGEN_CXX11_TENSOR_TENSOR_FUNCTORS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorGenerator.h b/unsupported/Eigen/CXX11/src/Tensor/TensorGenerator.h
index 174bf06..dfbb3f9 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorGenerator.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorGenerator.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_GENERATOR_H
 #define EIGEN_CXX11_TENSOR_TENSOR_GENERATOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorGeneratorOp
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorGlobalFunctions.h b/unsupported/Eigen/CXX11/src/Tensor/TensorGlobalFunctions.h
index 665b861..65052a2 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorGlobalFunctions.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorGlobalFunctions.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_GLOBAL_FUNCTIONS_H
 #define EIGEN_CXX11_TENSOR_TENSOR_GLOBAL_FUNCTIONS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \cpp11 \returns an expression of the coefficient-wise betainc(\a x, \a a, \a b) to the given tensors.
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h
index a901c5d..f47973b 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_IO_H
 #define EIGEN_CXX11_TENSOR_TENSOR_IO_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorImagePatch.h b/unsupported/Eigen/CXX11/src/Tensor/TensorImagePatch.h
index dd51850..9f99b73 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorImagePatch.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorImagePatch.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_IMAGE_PATCH_H
 #define EIGEN_CXX11_TENSOR_TENSOR_IMAGE_PATCH_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorImagePatch
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h
index 2d8c7b9..170fc6a 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h
@@ -10,6 +10,7 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H
 #define EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H
 
+#include "./InternalHeaderCheck.h"
 
 #if EIGEN_HAS_CONSTEXPR && EIGEN_HAS_VARIADIC_TEMPLATES
 
@@ -379,10 +380,10 @@
 };
 
 template<typename FirstType, typename... OtherTypes> struct array_size<IndexPairList<FirstType, OtherTypes...> > {
-  static const size_t value = std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value;
+  static const size_t value = 1 + sizeof...(OtherTypes);
 };
 template<typename FirstType, typename... OtherTypes> struct array_size<const IndexPairList<FirstType, OtherTypes...> > {
-  static const size_t value = std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value;
+  static const size_t value = 1 + sizeof...(OtherTypes);
 };
 
 template<Index N, typename FirstType, typename... OtherTypes> EIGEN_DEVICE_FUNC constexpr Index array_get(IndexList<FirstType, OtherTypes...>& a) {
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorInflation.h b/unsupported/Eigen/CXX11/src/Tensor/TensorInflation.h
index c5cb61a..39c40a6 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorInflation.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorInflation.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_INFLATION_H
 #define EIGEN_CXX11_TENSOR_TENSOR_INFLATION_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorInflation
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h b/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h
index 26a3818..fc177a8 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h
@@ -14,6 +14,8 @@
 
 #include <initializer_list>
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorInitializer
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h
index 6d5cce4..aafbe4c 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h
@@ -11,6 +11,8 @@
 #define EIGEN_CXX11_TENSOR_TENSOR_INTDIV_H
 
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \internal
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorLayoutSwap.h b/unsupported/Eigen/CXX11/src/Tensor/TensorLayoutSwap.h
index 80106c1..ee89621 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorLayoutSwap.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorLayoutSwap.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_LAYOUT_SWAP_H
 #define EIGEN_CXX11_TENSOR_TENSOR_LAYOUT_SWAP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorLayoutSwap
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h
index 6834c97..85dade6 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_MAP_H
 #define EIGEN_CXX11_TENSOR_TENSOR_MAP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // FIXME use proper doxygen documentation (e.g. \tparam MakePointer_)
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h
index e13ec09..b3f4a1c 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_META_H
 #define EIGEN_CXX11_TENSOR_TENSOR_META_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<bool cond> struct Cond {};
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h
index b3f00f7..7b36b5f 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_MORPHING_H
 #define EIGEN_CXX11_TENSOR_TENSOR_MORPHING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorReshaping
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h b/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h
index ee44382..d48b714 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_PADDING_H
 #define EIGEN_CXX11_TENSOR_TENSOR_PADDING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorPadding
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorPatch.h b/unsupported/Eigen/CXX11/src/Tensor/TensorPatch.h
index 413d25d..92de981 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorPatch.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorPatch.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_PATCH_H
 #define EIGEN_CXX11_TENSOR_TENSOR_PATCH_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorPatch
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h b/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h
index 37c1d1c..748ba0a 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_RANDOM_H
 #define EIGEN_CXX11_TENSOR_TENSOR_RANDOM_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
@@ -131,7 +133,7 @@
     m_state = PCG_XSH_RS_state(seed);
     #ifdef EIGEN_USE_SYCL
     // In SYCL it is not possible to build PCG_XSH_RS_state in one step.
-    // Therefor, we need two step to initializate the m_state.
+    // Therefore, we need two steps to initializate the m_state.
     // IN SYCL, the constructor of the functor is s called on the CPU
     // and we get the clock seed here from the CPU. However, This seed is
     //the same for all the thread. As unlike CUDA, the thread.ID, BlockID, etc is not a global function.
@@ -140,7 +142,7 @@
     // but for SYCL ((CLOCK * 6364136223846793005ULL) + 0xda3e39cb94b95bdbULL) is passed to each thread and each thread adds
     // the  (global_thread_id* 6364136223846793005ULL) for itself only once, in order to complete the construction
     // similar to CUDA Therefore, the thread Id injection is not available at this stage.
-    //However when the operator() is called the thread ID will be avilable. So inside the opeator,
+    //However when the operator() is called the thread ID will be available. So inside the opeator,
     // we add the thrreadID, BlockId,... (which is equivalent of i)
     //to the seed and construct the unique m_state per thead similar to cuda.
     m_exec_once =false;
@@ -244,13 +246,13 @@
     m_state = PCG_XSH_RS_state(seed);
     #ifdef EIGEN_USE_SYCL
     // In SYCL it is not possible to build PCG_XSH_RS_state in one step.
-    // Therefor, we need two steps to initializate the m_state.
+    // Therefore, we need two steps to initializate the m_state.
     // IN SYCL, the constructor of the functor is s called on the CPU
     // and we get the clock seed here from the CPU. However, This seed is
     //the same for all the thread. As unlike CUDA, the thread.ID, BlockID, etc is not a global function.
     // and only  available on the Operator() function (which is called on the GPU).
     // Therefore, the thread Id injection is not available at this stage. However when the operator()
-    //is called the thread ID will be avilable. So inside the opeator,
+    //is called the thread ID will be available. So inside the operator,
     // we add the thrreadID, BlockId,... (which is equivalent of i)
     //to the seed and construct the unique m_state per thead similar to cuda.
     m_exec_once =false;
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h b/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h
index 583f462..aef2b43 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h
@@ -22,6 +22,8 @@
 #endif
 
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorReductionGpu.h b/unsupported/Eigen/CXX11/src/Tensor/TensorReductionGpu.h
index 315ccc1..a73bc78 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorReductionGpu.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorReductionGpu.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_REDUCTION_GPU_H
 #define EIGEN_CXX11_TENSOR_TENSOR_REDUCTION_GPU_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h b/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h
index 474eba0..0f65fc6 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h
@@ -27,6 +27,8 @@
 
 #ifndef UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSOR_REDUCTION_SYCL_HPP
 #define UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSOR_REDUCTION_SYCL_HPP
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace TensorSycl {
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorRef.h b/unsupported/Eigen/CXX11/src/Tensor/TensorRef.h
index a27d364..a2e1af7 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorRef.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorRef.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_REF_H
 #define EIGEN_CXX11_TENSOR_TENSOR_REF_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h b/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h
index 586ce68..9c2d146 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h
@@ -10,6 +10,8 @@
 
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_REVERSE_H
 #define EIGEN_CXX11_TENSOR_TENSOR_REVERSE_H
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorReverse
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorScan.h b/unsupported/Eigen/CXX11/src/Tensor/TensorScan.h
index beae854..497e9c0 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorScan.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorScan.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_SCAN_H
 #define EIGEN_CXX11_TENSOR_TENSOR_SCAN_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorScanSycl.h b/unsupported/Eigen/CXX11/src/Tensor/TensorScanSycl.h
index 7f68ecb..5b4942b 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorScanSycl.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorScanSycl.h
@@ -25,7 +25,7 @@
  * buffer is given as an input and all the threads within a work-group scan and
  * reduces the boundaries between the blocks (generated from the previous
  * kernel). and write the data on the temporary buffer. If the second kernel is
- * required, the third and final kerenl (ScanAdjustmentKernelFunctor) will
+ * required, the third and final kernel (ScanAdjustmentKernelFunctor) will
  * adjust the final result into the output buffer.
  * The original algorithm for the parallel prefix sum can be found here:
  *
@@ -37,6 +37,8 @@
 #ifndef UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSOR_SYCL_SYCL_HPP
 #define UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSOR_SYCL_SYCL_HPP
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace TensorSycl {
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h b/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h
index e5e5efd..be02a08 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_SHUFFLING_H
 #define EIGEN_CXX11_TENSOR_TENSOR_SHUFFLING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorShuffling
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h b/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
index 5ff0880..5ec81a6 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
@@ -17,6 +17,8 @@
   #define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN
 #endif
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \internal
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h b/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h
index 2f62a66..e3f9d8f 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_STRIDING_H
 #define EIGEN_CXX11_TENSOR_TENSOR_STRIDING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorStriding
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorTrace.h b/unsupported/Eigen/CXX11/src/Tensor/TensorTrace.h
index 926ecdd..524990d 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorTrace.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorTrace.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_TRACE_H
 #define EIGEN_CXX11_TENSOR_TENSOR_TRACE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorTrace
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h b/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h
index 87dc418..1a4f4e8 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_TRAITS_H
 #define EIGEN_CXX11_TENSOR_TENSOR_TRAITS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h b/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h
index d23f2e4..f525bd3 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_UINT128_H
 #define EIGEN_CXX11_TENSOR_TENSOR_UINT128_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorVolumePatch.h b/unsupported/Eigen/CXX11/src/Tensor/TensorVolumePatch.h
index 0beb9ff..c34b7f3 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorVolumePatch.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorVolumePatch.h
@@ -4,6 +4,8 @@
 #ifndef EIGEN_CXX11_TENSOR_TENSOR_VOLUME_PATCH_H
 #define EIGEN_CXX11_TENSOR_TENSOR_VOLUME_PATCH_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \class TensorVolumePatch
diff --git a/unsupported/Eigen/CXX11/src/TensorSymmetry/DynamicSymmetry.h b/unsupported/Eigen/CXX11/src/TensorSymmetry/DynamicSymmetry.h
index bc4f202..200f588 100644
--- a/unsupported/Eigen/CXX11/src/TensorSymmetry/DynamicSymmetry.h
+++ b/unsupported/Eigen/CXX11/src/TensorSymmetry/DynamicSymmetry.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H
 #define EIGEN_CXX11_TENSORSYMMETRY_DYNAMICSYMMETRY_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 class DynamicSGroup
diff --git a/unsupported/Eigen/CXX11/src/TensorSymmetry/InternalHeaderCheck.h b/unsupported/Eigen/CXX11/src/TensorSymmetry/InternalHeaderCheck.h
new file mode 100644
index 0000000..b0affe6
--- /dev/null
+++ b/unsupported/Eigen/CXX11/src/TensorSymmetry/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_CXX11_TENSORSYMMETRY_MODULE_H
+#error "Please include unsupported/Eigen/CXX11/TensorSymmetry instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/CXX11/src/TensorSymmetry/StaticSymmetry.h b/unsupported/Eigen/CXX11/src/TensorSymmetry/StaticSymmetry.h
index 942293b..e87403a 100644
--- a/unsupported/Eigen/CXX11/src/TensorSymmetry/StaticSymmetry.h
+++ b/unsupported/Eigen/CXX11/src/TensorSymmetry/StaticSymmetry.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSORSYMMETRY_STATICSYMMETRY_H
 #define EIGEN_CXX11_TENSORSYMMETRY_STATICSYMMETRY_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/TensorSymmetry/Symmetry.h b/unsupported/Eigen/CXX11/src/TensorSymmetry/Symmetry.h
index 879d6cd..d47f28e 100644
--- a/unsupported/Eigen/CXX11/src/TensorSymmetry/Symmetry.h
+++ b/unsupported/Eigen/CXX11/src/TensorSymmetry/Symmetry.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSORSYMMETRY_SYMMETRY_H
 #define EIGEN_CXX11_TENSORSYMMETRY_SYMMETRY_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 enum {
diff --git a/unsupported/Eigen/CXX11/src/TensorSymmetry/util/TemplateGroupTheory.h b/unsupported/Eigen/CXX11/src/TensorSymmetry/util/TemplateGroupTheory.h
index 61113fe..a404c39 100644
--- a/unsupported/Eigen/CXX11/src/TensorSymmetry/util/TemplateGroupTheory.h
+++ b/unsupported/Eigen/CXX11/src/TensorSymmetry/util/TemplateGroupTheory.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_TENSORSYMMETRY_TEMPLATEGROUPTHEORY_H
 #define EIGEN_CXX11_TENSORSYMMETRY_TEMPLATEGROUPTHEORY_H
 
+#include "../InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/Barrier.h b/unsupported/Eigen/CXX11/src/ThreadPool/Barrier.h
index d491972..df58d87 100644
--- a/unsupported/Eigen/CXX11/src/ThreadPool/Barrier.h
+++ b/unsupported/Eigen/CXX11/src/ThreadPool/Barrier.h
@@ -13,6 +13,8 @@
 #ifndef EIGEN_CXX11_THREADPOOL_BARRIER_H
 #define EIGEN_CXX11_THREADPOOL_BARRIER_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 class Barrier {
diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/EventCount.h b/unsupported/Eigen/CXX11/src/ThreadPool/EventCount.h
index 2ac1e67..54d0b18 100644
--- a/unsupported/Eigen/CXX11/src/ThreadPool/EventCount.h
+++ b/unsupported/Eigen/CXX11/src/ThreadPool/EventCount.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_THREADPOOL_EVENTCOUNT_H_
 #define EIGEN_CXX11_THREADPOOL_EVENTCOUNT_H_
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // EventCount allows to wait for arbitrary predicates in non-blocking
@@ -85,7 +87,7 @@
       CheckState(state, true);
       uint64_t newstate;
       if ((state & kSignalMask) != 0) {
-        // Consume the signal and return immidiately.
+        // Consume the signal and return immediately.
         newstate = state - kWaiterInc - kSignalInc;
       } else {
         // Remove this thread from pre-wait counter and add to the waiter stack.
@@ -112,7 +114,7 @@
       CheckState(state, true);
       uint64_t newstate = state - kWaiterInc;
       // We don't know if the thread was also notified or not,
-      // so we should not consume a signal unconditionaly.
+      // so we should not consume a signal unconditionally.
       // Only if number of waiters is equal to number of signals,
       // we know that the thread was notified and we must take away the signal.
       if (((state & kWaiterMask) >> kWaiterShift) ==
diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/InternalHeaderCheck.h b/unsupported/Eigen/CXX11/src/ThreadPool/InternalHeaderCheck.h
new file mode 100644
index 0000000..82a89a9
--- /dev/null
+++ b/unsupported/Eigen/CXX11/src/ThreadPool/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_CXX11_THREADPOOL_MODULE_H
+#error "Please include unsupported/Eigen/CXX11/ThreadPool instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h b/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h
index ec5e83f..40f2f3f 100644
--- a/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h
+++ b/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_THREADPOOL_NONBLOCKING_THREAD_POOL_H
 #define EIGEN_CXX11_THREADPOOL_NONBLOCKING_THREAD_POOL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template <typename Environment>
diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h b/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h
index 3b65d82..772835c 100644
--- a/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h
+++ b/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_THREADPOOL_RUNQUEUE_H_
 #define EIGEN_CXX11_THREADPOOL_RUNQUEUE_H_
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // RunQueue is a fixed-size, partially non-blocking deque or Work items.
diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h
index d94a064..02ec366 100644
--- a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h
+++ b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_THREADPOOL_THREAD_ENVIRONMENT_H
 #define EIGEN_CXX11_THREADPOOL_THREAD_ENVIRONMENT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 struct StlThreadEnvironment {
diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadLocal.h b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadLocal.h
index 4b66ac9..d6cca42 100644
--- a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadLocal.h
+++ b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadLocal.h
@@ -62,6 +62,8 @@
 
 #endif  // EIGEN_AVOID_THREAD_LOCAL
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h
index 25030dc..e6750a9 100644
--- a/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h
+++ b/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_CXX11_THREADPOOL_THREAD_POOL_INTERFACE_H
 #define EIGEN_CXX11_THREADPOOL_THREAD_POOL_INTERFACE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 // This defines an interface that ThreadPoolDevice can take to use
diff --git a/unsupported/Eigen/CXX11/src/util/EmulateArray.h b/unsupported/Eigen/CXX11/src/util/EmulateArray.h
index 834b20b..c5f9b88 100644
--- a/unsupported/Eigen/CXX11/src/util/EmulateArray.h
+++ b/unsupported/Eigen/CXX11/src/util/EmulateArray.h
@@ -10,8 +10,6 @@
 #ifndef EIGEN_EMULATE_ARRAY_H
 #define EIGEN_EMULATE_ARRAY_H
 
-
-
 // The array class is only available starting with cxx11. Emulate our own here
 // if needed. Beware, msvc still doesn't advertise itself as a c++11 compiler!
 // Moreover, CUDA doesn't support the STL containers, so we use our own instead.
@@ -226,6 +224,7 @@
 
 // The compiler supports c++11, and we're not targeting cuda: use std::array as Eigen::array
 #include <array>
+
 namespace Eigen {
 
 template <typename T, std::size_t N> using array = std::array<T, N>;
diff --git a/unsupported/Eigen/FFT b/unsupported/Eigen/FFT
index e16a7d9..c9d6938 100644
--- a/unsupported/Eigen/FFT
+++ b/unsupported/Eigen/FFT
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_FFT_H
-#define EIGEN_FFT_H
+#ifndef EIGEN_FFT_MODULE_H
+#define EIGEN_FFT_MODULE_H
 
 #include <complex>
 #include <vector>
diff --git a/unsupported/Eigen/KroneckerProduct b/unsupported/Eigen/KroneckerProduct
index 5f5afb8..9643ae2 100644
--- a/unsupported/Eigen/KroneckerProduct
+++ b/unsupported/Eigen/KroneckerProduct
@@ -10,10 +10,7 @@
 #define EIGEN_KRONECKER_PRODUCT_MODULE_H
 
 #include "../../Eigen/Core"
-
-#include "../../Eigen/src/Core/util/DisableStupidWarnings.h"
-
-#include "../../Eigen/src/SparseCore/SparseUtil.h"
+#include "../../Eigen/SparseCore"
 
 namespace Eigen {
 
diff --git a/unsupported/Eigen/LevenbergMarquardt b/unsupported/Eigen/LevenbergMarquardt
index 1090505..b5ace56 100644
--- a/unsupported/Eigen/LevenbergMarquardt
+++ b/unsupported/Eigen/LevenbergMarquardt
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_LEVENBERGMARQUARDT_MODULE
-#define EIGEN_LEVENBERGMARQUARDT_MODULE
+#ifndef EIGEN_LEVENBERGMARQUARDT_MODULE_H
+#define EIGEN_LEVENBERGMARQUARDT_MODULE_H
 
 // #include <vector>
 
@@ -46,4 +46,4 @@
 
 #include "../../Eigen/src/Core/util/ReenableStupidWarnings.h"
 
-#endif // EIGEN_LEVENBERGMARQUARDT_MODULE
+#endif // EIGEN_LEVENBERGMARQUARDT_MODULE_H
diff --git a/unsupported/Eigen/MatrixFunctions b/unsupported/Eigen/MatrixFunctions
index 20c23d1..dddedb4 100644
--- a/unsupported/Eigen/MatrixFunctions
+++ b/unsupported/Eigen/MatrixFunctions
@@ -8,8 +8,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_MATRIX_FUNCTIONS
-#define EIGEN_MATRIX_FUNCTIONS
+#ifndef EIGEN_MATRIX_FUNCTIONS_MODULE_H
+#define EIGEN_MATRIX_FUNCTIONS_MODULE_H
 
 #include <cfloat>
 #include <list>
@@ -500,5 +500,4 @@
 
 */
 
-#endif // EIGEN_MATRIX_FUNCTIONS
-
+#endif // EIGEN_MATRIX_FUNCTIONS_MODULE_H
diff --git a/unsupported/Eigen/NonLinearOptimization b/unsupported/Eigen/NonLinearOptimization
index 961f192..6bf566e 100644
--- a/unsupported/Eigen/NonLinearOptimization
+++ b/unsupported/Eigen/NonLinearOptimization
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_NONLINEAROPTIMIZATION_MODULE
-#define EIGEN_NONLINEAROPTIMIZATION_MODULE
+#ifndef EIGEN_NONLINEAROPTIMIZATION_MODULE_H
+#define EIGEN_NONLINEAROPTIMIZATION_MODULE_H
 
 #include <vector>
 
@@ -137,4 +137,4 @@
 #include "src/NonLinearOptimization/LevenbergMarquardt.h"
 
 
-#endif // EIGEN_NONLINEAROPTIMIZATION_MODULE
+#endif // EIGEN_NONLINEAROPTIMIZATION_MODULE_H
diff --git a/unsupported/Eigen/NumericalDiff b/unsupported/Eigen/NumericalDiff
index 0668f96..9d6270a 100644
--- a/unsupported/Eigen/NumericalDiff
+++ b/unsupported/Eigen/NumericalDiff
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_NUMERICALDIFF_MODULE
-#define EIGEN_NUMERICALDIFF_MODULE
+#ifndef EIGEN_NUMERICALDIFF_MODULE_H
+#define EIGEN_NUMERICALDIFF_MODULE_H
 
 #include "../../Eigen/Core"
 
@@ -53,4 +53,4 @@
 //@}
 
 
-#endif // EIGEN_NUMERICALDIFF_MODULE
+#endif // EIGEN_NUMERICALDIFF_MODULE_H
diff --git a/unsupported/Eigen/OpenGLSupport b/unsupported/Eigen/OpenGLSupport
index f8c2130..2468333 100644
--- a/unsupported/Eigen/OpenGLSupport
+++ b/unsupported/Eigen/OpenGLSupport
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_OPENGL_MODULE
-#define EIGEN_OPENGL_MODULE
+#ifndef EIGEN_OPENGL_MODULE_H
+#define EIGEN_OPENGL_MODULE_H
 
 #include "../../Eigen/Geometry"
 
@@ -319,4 +319,4 @@
 
 }
 
-#endif // EIGEN_OPENGL_MODULE
+#endif // EIGEN_OPENGL_MODULE_H
diff --git a/unsupported/Eigen/SpecialFunctions b/unsupported/Eigen/SpecialFunctions
index f6a2460..41a3631 100644
--- a/unsupported/Eigen/SpecialFunctions
+++ b/unsupported/Eigen/SpecialFunctions
@@ -7,8 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-#ifndef EIGEN_SPECIALFUNCTIONS_MODULE
-#define EIGEN_SPECIALFUNCTIONS_MODULE
+#ifndef EIGEN_SPECIALFUNCTIONS_MODULE_H
+#define EIGEN_SPECIALFUNCTIONS_MODULE_H
 
 #include <math.h>
 
@@ -100,4 +100,4 @@
 
 #include "../../Eigen/src/Core/util/ReenableStupidWarnings.h"
 
-#endif // EIGEN_SPECIALFUNCTIONS_MODULE
+#endif // EIGEN_SPECIALFUNCTIONS_MODULE_H
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h b/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h
index 33b6c39..5020f22 100644
--- a/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h
+++ b/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_AUTODIFF_JACOBIAN_H
 #define EIGEN_AUTODIFF_JACOBIAN_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen
 {
 
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
index 0f166e3..855e83c 100755
--- a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
+++ b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_AUTODIFF_SCALAR_H
 #define EIGEN_AUTODIFF_SCALAR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
@@ -178,12 +180,12 @@
     template<typename OtherDerType> inline bool operator==(const AutoDiffScalar<OtherDerType>& b) const  { return m_value == b.value(); }
     template<typename OtherDerType> inline bool operator!=(const AutoDiffScalar<OtherDerType>& b) const  { return m_value != b.value(); }
 
-    inline const AutoDiffScalar<DerType&> operator+(const Scalar& other) const
+    inline AutoDiffScalar<DerType&> operator+(const Scalar& other) const
     {
       return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);
     }
 
-    friend inline const AutoDiffScalar<DerType&> operator+(const Scalar& a, const AutoDiffScalar& b)
+    friend inline AutoDiffScalar<DerType&> operator+(const Scalar& a, const AutoDiffScalar& b)
     {
       return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
     }
@@ -205,7 +207,7 @@
     }
 
     template<typename OtherDerType>
-    inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const typename internal::remove_all<OtherDerType>::type> >
+    inline AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const typename internal::remove_all<OtherDerType>::type> >
     operator+(const AutoDiffScalar<OtherDerType>& other) const
     {
       internal::make_coherent(m_derivatives, other.derivatives());
@@ -222,12 +224,12 @@
       return *this;
     }
 
-    inline const AutoDiffScalar<DerType&> operator-(const Scalar& b) const
+    inline AutoDiffScalar<DerType&> operator-(const Scalar& b) const
     {
       return AutoDiffScalar<DerType&>(m_value - b, m_derivatives);
     }
 
-    friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
+    friend inline AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
     operator-(const Scalar& a, const AutoDiffScalar& b)
     {
       return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
@@ -241,7 +243,7 @@
     }
 
     template<typename OtherDerType>
-    inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const typename internal::remove_all<OtherDerType>::type> >
+    inline AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const typename internal::remove_all<OtherDerType>::type> >
     operator-(const AutoDiffScalar<OtherDerType>& other) const
     {
       internal::make_coherent(m_derivatives, other.derivatives());
@@ -258,7 +260,7 @@
       return *this;
     }
 
-    inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
+    inline AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >
     operator-() const
     {
       return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >(
@@ -266,13 +268,13 @@
         -m_derivatives);
     }
 
-    inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
+    inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
     operator*(const Scalar& other) const
     {
       return MakeAutoDiffScalar(m_value * other, m_derivatives * other);
     }
 
-    friend inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
+    friend inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
     operator*(const Scalar& other, const AutoDiffScalar& a)
     {
       return MakeAutoDiffScalar(a.value() * other, a.derivatives() * other);
@@ -294,13 +296,13 @@
 //         a.derivatives() * other);
 //     }
 
-    inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
+    inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
     operator/(const Scalar& other) const
     {
       return MakeAutoDiffScalar(m_value / other, (m_derivatives * (Scalar(1)/other)));
     }
 
-    friend inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
+    friend inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) >
     operator/(const Scalar& other, const AutoDiffScalar& a)
     {
       return MakeAutoDiffScalar(other / a.value(), a.derivatives() * (Scalar(-other) / (a.value()*a.value())));
@@ -323,7 +325,7 @@
 //     }
 
     template<typename OtherDerType>
-    inline const AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(
+    inline AutoDiffScalar<EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(
         CwiseBinaryOp<internal::scalar_difference_op<Scalar> EIGEN_COMMA
           const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product) EIGEN_COMMA
           const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<OtherDerType>::type,Scalar,product) >,Scalar,product) >
@@ -337,7 +339,7 @@
     }
 
     template<typename OtherDerType>
-    inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
+    inline AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
         const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DerType,Scalar,product),
         const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<OtherDerType>::type,Scalar,product) > >
     operator*(const AutoDiffScalar<OtherDerType>& other) const
@@ -405,12 +407,12 @@
   AutoDiffScalar<DerivativeType>& derived() { return *static_cast<AutoDiffScalar<DerivativeType>*>(this); }
 
 
-  inline const AutoDiffScalar<DerType&> operator+(const Real& other) const
+  inline AutoDiffScalar<DerType&> operator+(const Real& other) const
   {
     return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());
   }
 
-  friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar<DerivativeType>& b)
+  friend inline AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar<DerivativeType>& b)
   {
     return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());
   }
@@ -422,7 +424,7 @@
   }
 
 
-  inline const AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar,Real> >, DerType>::Type >
+  inline AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar,Real> >, DerType>::Type >
   operator*(const Real& other) const
   {
     return AutoDiffScalar<typename CwiseUnaryOp<bind2nd_op<scalar_product_op<Scalar,Real> >, DerType>::Type >(
@@ -430,7 +432,7 @@
       derived().derivatives() * other);
   }
 
-  friend inline const AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real,Scalar> >, DerType>::Type >
+  friend inline AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real,Scalar> >, DerType>::Type >
   operator*(const Real& other, const AutoDiffScalar<DerivativeType>& a)
   {
     return AutoDiffScalar<typename CwiseUnaryOp<bind1st_op<scalar_product_op<Real,Scalar> >, DerType>::Type >(
@@ -556,7 +558,7 @@
 
 #define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \
   template<typename DerType> \
-  inline const Eigen::AutoDiffScalar< \
+  inline Eigen::AutoDiffScalar< \
   EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename Eigen::internal::remove_all<DerType>::type, typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar, product) > \
   FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \
     using namespace Eigen; \
@@ -639,7 +641,7 @@
   return Eigen::MakeAutoDiffScalar(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)
 
 template<typename DerType>
-inline const Eigen::AutoDiffScalar<
+inline Eigen::AutoDiffScalar<
 EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(typename internal::remove_all<DerType>::type,typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar,product) >
 pow(const Eigen::AutoDiffScalar<DerType> &x, const typename internal::traits<typename internal::remove_all<DerType>::type>::Scalar &y)
 {
@@ -650,7 +652,7 @@
 
 
 template<typename DerTypeA,typename DerTypeB>
-inline const AutoDiffScalar<Matrix<typename internal::traits<typename internal::remove_all<DerTypeA>::type>::Scalar,Dynamic,1> >
+inline AutoDiffScalar<Matrix<typename internal::traits<typename internal::remove_all<DerTypeA>::type>::Scalar,Dynamic,1> >
 atan2(const AutoDiffScalar<DerTypeA>& a, const AutoDiffScalar<DerTypeB>& b)
 {
   using std::atan2;
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h b/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
index 8c2d048..c544422 100644
--- a/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
+++ b/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_AUTODIFF_VECTOR_H
 #define EIGEN_AUTODIFF_VECTOR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /* \class AutoDiffScalar
diff --git a/unsupported/Eigen/src/AutoDiff/InternalHeaderCheck.h b/unsupported/Eigen/src/AutoDiff/InternalHeaderCheck.h
new file mode 100644
index 0000000..1584337
--- /dev/null
+++ b/unsupported/Eigen/src/AutoDiff/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_AUTODIFF_MODULE_H
+#error "Please include unsupported/Eigen/AutoDiff instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/BVH/BVAlgorithms.h b/unsupported/Eigen/src/BVH/BVAlgorithms.h
index 994c8af..7c83a5f 100644
--- a/unsupported/Eigen/src/BVH/BVAlgorithms.h
+++ b/unsupported/Eigen/src/BVH/BVAlgorithms.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_BVALGORITHMS_H
 #define EIGEN_BVALGORITHMS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/BVH/InternalHeaderCheck.h b/unsupported/Eigen/src/BVH/InternalHeaderCheck.h
new file mode 100644
index 0000000..7aade9b
--- /dev/null
+++ b/unsupported/Eigen/src/BVH/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_BVH_MODULE_H
+#error "Please include unsupported/Eigen/BVH instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/BVH/KdBVH.h b/unsupported/Eigen/src/BVH/KdBVH.h
index 034fec7..e7d6684 100644
--- a/unsupported/Eigen/src/BVH/KdBVH.h
+++ b/unsupported/Eigen/src/BVH/KdBVH.h
@@ -10,6 +10,8 @@
 #ifndef KDBVH_H_INCLUDED
 #define KDBVH_H_INCLUDED
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h b/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h
index 0fbd847..b74449f 100644
--- a/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h
+++ b/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h
@@ -12,6 +12,8 @@
 
 #include "../../../../Eigen/Dense"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/Eigenvalues/InternalHeaderCheck.h b/unsupported/Eigen/src/Eigenvalues/InternalHeaderCheck.h
new file mode 100644
index 0000000..c00cb57
--- /dev/null
+++ b/unsupported/Eigen/src/Eigenvalues/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_EIGENVALUES_MODULE_H
+#error "Please include unsupported/Eigen/Eigenvalues instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/EulerAngles/EulerAngles.h b/unsupported/Eigen/src/EulerAngles/EulerAngles.h
index 7f4535d..252be42 100644
--- a/unsupported/Eigen/src/EulerAngles/EulerAngles.h
+++ b/unsupported/Eigen/src/EulerAngles/EulerAngles.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_EULERANGLESCLASS_H// TODO: Fix previous "EIGEN_EULERANGLES_H" definition?
 #define EIGEN_EULERANGLESCLASS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen
 {
   /** \class EulerAngles
diff --git a/unsupported/Eigen/src/EulerAngles/EulerSystem.h b/unsupported/Eigen/src/EulerAngles/EulerSystem.h
index 3b06d01..34c121e 100644
--- a/unsupported/Eigen/src/EulerAngles/EulerSystem.h
+++ b/unsupported/Eigen/src/EulerAngles/EulerSystem.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_EULERSYSTEM_H
 #define EIGEN_EULERSYSTEM_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen
 {
   // Forward declarations
diff --git a/unsupported/Eigen/src/EulerAngles/InternalHeaderCheck.h b/unsupported/Eigen/src/EulerAngles/InternalHeaderCheck.h
new file mode 100644
index 0000000..0c00a30
--- /dev/null
+++ b/unsupported/Eigen/src/EulerAngles/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_EULERANGLES_MODULE_H
+#error "Please include unsupported/Eigen/EulerAngles instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/FFT/InternalHeaderCheck.h b/unsupported/Eigen/src/FFT/InternalHeaderCheck.h
new file mode 100644
index 0000000..801e245
--- /dev/null
+++ b/unsupported/Eigen/src/FFT/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_FFT_MODULE_H
+#error "Please include unsupported/Eigen/FFT instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/FFT/ei_fftw_impl.h b/unsupported/Eigen/src/FFT/ei_fftw_impl.h
index b9e760b..f188027 100644
--- a/unsupported/Eigen/src/FFT/ei_fftw_impl.h
+++ b/unsupported/Eigen/src/FFT/ei_fftw_impl.h
@@ -7,6 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h b/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
index bcecb63..90e6690 100644
--- a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
+++ b/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
@@ -7,6 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/IterativeSolvers/DGMRES.h b/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
index 9114b16..91e60d8 100644
--- a/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
+++ b/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
@@ -12,6 +12,8 @@
 
 #include "../../../../Eigen/Eigenvalues"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
   
 template< typename MatrixType_,
diff --git a/unsupported/Eigen/src/IterativeSolvers/GMRES.h b/unsupported/Eigen/src/IterativeSolvers/GMRES.h
index 4bd5904..741d9fe 100644
--- a/unsupported/Eigen/src/IterativeSolvers/GMRES.h
+++ b/unsupported/Eigen/src/IterativeSolvers/GMRES.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_GMRES_H
 #define EIGEN_GMRES_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/src/IterativeSolvers/IDRS.h b/unsupported/Eigen/src/IterativeSolvers/IDRS.h
index 5d62439..63d7cb8 100755
--- a/unsupported/Eigen/src/IterativeSolvers/IDRS.h
+++ b/unsupported/Eigen/src/IterativeSolvers/IDRS.h
@@ -13,12 +13,14 @@
 #ifndef EIGEN_IDRS_H
 #define EIGEN_IDRS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen
 {
 
 	namespace internal
 	{
-		/**     \internal Low-level Induced Dimension Reduction algoritm
+		/**     \internal Low-level Induced Dimension Reduction algorithm
 		        \param A The matrix A
 		        \param b The right hand side vector b
 		        \param x On input and initial solution, on output the computed solution.
@@ -370,7 +372,7 @@
 
 			/** \internal */
 			/**     Loops over the number of columns of b and does the following:
-			                1. sets the tolerence and maxIterations
+			                1. sets the tolerance and maxIterations
 			                2. Calls the function that has the core solver routine
 			*/
 			template <typename Rhs, typename Dest>
diff --git a/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h b/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h
index c528aa8..3bf564c 100644
--- a/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h
+++ b/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_INCOMPLETE_LU_H
 #define EIGEN_INCOMPLETE_LU_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template <typename Scalar_>
diff --git a/unsupported/Eigen/src/IterativeSolvers/InternalHeaderCheck.h b/unsupported/Eigen/src/IterativeSolvers/InternalHeaderCheck.h
new file mode 100644
index 0000000..679c7fa
--- /dev/null
+++ b/unsupported/Eigen/src/IterativeSolvers/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_ITERATIVE_SOLVERS_MODULE_H
+#error "Please include unsupported/Eigen/IterativeSolvers instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/IterativeSolvers/MINRES.h b/unsupported/Eigen/src/IterativeSolvers/MINRES.h
index f36c2c0..907e635 100644
--- a/unsupported/Eigen/src/IterativeSolvers/MINRES.h
+++ b/unsupported/Eigen/src/IterativeSolvers/MINRES.h
@@ -14,6 +14,8 @@
 #define EIGEN_MINRES_H_
 
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
     
     namespace internal {
diff --git a/unsupported/Eigen/src/IterativeSolvers/Scaling.h b/unsupported/Eigen/src/IterativeSolvers/Scaling.h
index 848f572..9400e81 100644
--- a/unsupported/Eigen/src/IterativeSolvers/Scaling.h
+++ b/unsupported/Eigen/src/IterativeSolvers/Scaling.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_ITERSCALING_H
 #define EIGEN_ITERSCALING_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /**
diff --git a/unsupported/Eigen/src/KroneckerProduct/InternalHeaderCheck.h b/unsupported/Eigen/src/KroneckerProduct/InternalHeaderCheck.h
new file mode 100644
index 0000000..3db2edc
--- /dev/null
+++ b/unsupported/Eigen/src/KroneckerProduct/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_KRONECKER_PRODUCT_MODULE_H
+#error "Please include unsupported/Eigen/KroneckerProduct instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h b/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h
index c14ca0c..5524e3e 100644
--- a/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h
+++ b/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h
@@ -12,6 +12,8 @@
 #ifndef KRONECKER_TENSOR_PRODUCT_H
 #define KRONECKER_TENSOR_PRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /*!
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/InternalHeaderCheck.h b/unsupported/Eigen/src/LevenbergMarquardt/InternalHeaderCheck.h
new file mode 100644
index 0000000..bc76f4e
--- /dev/null
+++ b/unsupported/Eigen/src/LevenbergMarquardt/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_LEVENBERGMARQUARDT_MODULE_H
+#error "Please include unsupported/Eigen/LevenbergMarquardt instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h b/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h
index b75bea2..344c22e 100644
--- a/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h
+++ b/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_LMCOVAR_H
 #define EIGEN_LMCOVAR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h b/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
index 25b32ec..92cb6f6 100644
--- a/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
+++ b/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
@@ -14,6 +14,8 @@
 #ifndef EIGEN_LMONESTEP_H
 #define EIGEN_LMONESTEP_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename FunctorType>
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h b/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h
index 9a48365..74acc9a 100644
--- a/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h
+++ b/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h
@@ -12,6 +12,8 @@
 #ifndef EIGEN_LMPAR_H
 #define EIGEN_LMPAR_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h b/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h
index bbf6ac1..385b7b5 100644
--- a/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h
+++ b/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h
@@ -15,6 +15,8 @@
 #ifndef EIGEN_LMQRSOLV_H
 #define EIGEN_LMQRSOLV_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h b/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h
index ac004f5..f823ae0 100644
--- a/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h
@@ -20,6 +20,8 @@
 #define EIGEN_LEVENBERGMARQUARDT_H
 
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace LevenbergMarquardtSpace {
     enum Status {
diff --git a/unsupported/Eigen/src/MatrixFunctions/InternalHeaderCheck.h b/unsupported/Eigen/src/MatrixFunctions/InternalHeaderCheck.h
new file mode 100644
index 0000000..b737f3c
--- /dev/null
+++ b/unsupported/Eigen/src/MatrixFunctions/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_MATRIX_FUNCTIONS_MODULE_H
+#error "Please include unsupported/Eigen/MatrixFunctions instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
index 02284b0..ab6284a 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
@@ -13,6 +13,8 @@
 
 #include "StemFunction.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
index cc12ab6..bd32275 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
@@ -13,6 +13,8 @@
 #include "StemFunction.h"
 
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h b/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
index e917013..63e4dad 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_MATRIX_LOGARITHM
 #define EIGEN_MATRIX_LOGARITHM
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal { 
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
index d7672d7..4eb8651 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_MATRIX_POWER
 #define EIGEN_MATRIX_POWER
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 template<typename MatrixType> class MatrixPower;
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h b/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
index e363e77..5e184ea 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_MATRIX_SQUARE_ROOT
 #define EIGEN_MATRIX_SQUARE_ROOT
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/MatrixFunctions/StemFunction.h b/unsupported/Eigen/src/MatrixFunctions/StemFunction.h
index 7604df9..25a3ef2 100644
--- a/unsupported/Eigen/src/MatrixFunctions/StemFunction.h
+++ b/unsupported/Eigen/src/MatrixFunctions/StemFunction.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_STEM_FUNCTION
 #define EIGEN_STEM_FUNCTION
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/MoreVectorization/InternalHeaderCheck.h b/unsupported/Eigen/src/MoreVectorization/InternalHeaderCheck.h
new file mode 100644
index 0000000..3c294b3
--- /dev/null
+++ b/unsupported/Eigen/src/MoreVectorization/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_MOREVECTORIZATION_MODULE_H
+#error "Please include unsupported/Eigen/MoreVectorization instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/MoreVectorization/MathFunctions.h b/unsupported/Eigen/src/MoreVectorization/MathFunctions.h
index 63cb28d..559d0a8 100644
--- a/unsupported/Eigen/src/MoreVectorization/MathFunctions.h
+++ b/unsupported/Eigen/src/MoreVectorization/MathFunctions.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_MOREVECTORIZATION_MATHFUNCTIONS_H
 #define EIGEN_MOREVECTORIZATION_MATHFUNCTIONS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
index 07c5ef0..7acd01a 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
@@ -13,6 +13,8 @@
 #ifndef EIGEN_HYBRIDNONLINEARSOLVER_H
 #define EIGEN_HYBRIDNONLINEARSOLVER_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace HybridNonLinearSolverSpace { 
diff --git a/unsupported/Eigen/src/NonLinearOptimization/InternalHeaderCheck.h b/unsupported/Eigen/src/NonLinearOptimization/InternalHeaderCheck.h
new file mode 100644
index 0000000..5b2276c
--- /dev/null
+++ b/unsupported/Eigen/src/NonLinearOptimization/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_NONLINEAROPTIMIZATION_MODULE_H
+#error "Please include unsupported/Eigen/NonLinearOptimization instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
index fe3b79c..a176c25 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
@@ -13,6 +13,8 @@
 #ifndef EIGEN_LEVENBERGMARQUARDT__H
 #define EIGEN_LEVENBERGMARQUARDT__H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace LevenbergMarquardtSpace {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/chkder.h b/unsupported/Eigen/src/NonLinearOptimization/chkder.h
index db8ff7d..d0974a0 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/chkder.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/chkder.h
@@ -1,6 +1,8 @@
 #define chkder_log10e 0.43429448190325182765
 #define chkder_factor 100.
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/covar.h b/unsupported/Eigen/src/NonLinearOptimization/covar.h
index 68260d1..181c4f3 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/covar.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/covar.h
@@ -1,3 +1,5 @@
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/dogleg.h b/unsupported/Eigen/src/NonLinearOptimization/dogleg.h
index 80c5d27..7c170a2 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/dogleg.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/dogleg.h
@@ -1,3 +1,5 @@
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h b/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h
index bb7cf26..317b157 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h
@@ -1,3 +1,5 @@
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
index 4c17d4c..64af0fd 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
@@ -1,3 +1,5 @@
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
index 4f2f560..1cdcd4e 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
@@ -1,3 +1,5 @@
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h b/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
index 36ff700..37ef258 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
@@ -1,3 +1,5 @@
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/r1updt.h b/unsupported/Eigen/src/NonLinearOptimization/r1updt.h
index 09fc652..7b3a599 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/r1updt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/r1updt.h
@@ -1,3 +1,5 @@
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h b/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h
index 6ebf856..f9ca504 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h
@@ -1,3 +1,5 @@
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/NumericalDiff/InternalHeaderCheck.h b/unsupported/Eigen/src/NumericalDiff/InternalHeaderCheck.h
new file mode 100644
index 0000000..8c513d2
--- /dev/null
+++ b/unsupported/Eigen/src/NumericalDiff/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_NUMERICALDIFF_MODULE_H
+#error "Please include unsupported/Eigen/NumericalDiff instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h b/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
index 796d0bc..daa4210 100644
--- a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
+++ b/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
@@ -13,6 +13,8 @@
 #ifndef EIGEN_NUMERICAL_DIFF_H
 #define EIGEN_NUMERICAL_DIFF_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 enum NumericalDiffMode {
diff --git a/unsupported/Eigen/src/Polynomials/Companion.h b/unsupported/Eigen/src/Polynomials/Companion.h
index 3c9a164..91bdea8 100644
--- a/unsupported/Eigen/src/Polynomials/Companion.h
+++ b/unsupported/Eigen/src/Polynomials/Companion.h
@@ -14,6 +14,8 @@
 // * Eigen/Core
 // * Eigen/src/PolynomialSolver.h
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal {
diff --git a/unsupported/Eigen/src/Polynomials/InternalHeaderCheck.h b/unsupported/Eigen/src/Polynomials/InternalHeaderCheck.h
new file mode 100644
index 0000000..b3aa50c
--- /dev/null
+++ b/unsupported/Eigen/src/Polynomials/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_POLYNOMIALS_MODULE_H
+#error "Please include unsupported/Eigen/Polynomials instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/Polynomials/PolynomialSolver.h b/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
index a9e8212..fb3e38c 100644
--- a/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
+++ b/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_POLYNOMIAL_SOLVER_H
 #define EIGEN_POLYNOMIAL_SOLVER_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \ingroup Polynomials_Module
diff --git a/unsupported/Eigen/src/Polynomials/PolynomialUtils.h b/unsupported/Eigen/src/Polynomials/PolynomialUtils.h
index 394e857..6af8613 100644
--- a/unsupported/Eigen/src/Polynomials/PolynomialUtils.h
+++ b/unsupported/Eigen/src/Polynomials/PolynomialUtils.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_POLYNOMIAL_UTILS_H
 #define EIGEN_POLYNOMIAL_UTILS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \ingroup Polynomials_Module
diff --git a/unsupported/Eigen/src/Skyline/InternalHeaderCheck.h b/unsupported/Eigen/src/Skyline/InternalHeaderCheck.h
new file mode 100644
index 0000000..bddf0b0
--- /dev/null
+++ b/unsupported/Eigen/src/Skyline/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SKYLINE_MODULE_H
+#error "Please include unsupported/Eigen/Skyline instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h b/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
index 7dce840..ef90438 100644
--- a/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
+++ b/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SKYLINEINPLACELU_H
 #define EIGEN_SKYLINEINPLACELU_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \ingroup Skyline_Module
diff --git a/unsupported/Eigen/src/Skyline/SkylineMatrix.h b/unsupported/Eigen/src/Skyline/SkylineMatrix.h
index 060843f..887bf83 100644
--- a/unsupported/Eigen/src/Skyline/SkylineMatrix.h
+++ b/unsupported/Eigen/src/Skyline/SkylineMatrix.h
@@ -13,6 +13,8 @@
 #include "SkylineStorage.h"
 #include "SkylineMatrixBase.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** \ingroup Skyline_Module
diff --git a/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h b/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h
index b0d5e10..cc41175 100644
--- a/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h
+++ b/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h
@@ -12,6 +12,8 @@
 
 #include "SkylineUtil.h"
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \ingroup Skyline_Module
diff --git a/unsupported/Eigen/src/Skyline/SkylineProduct.h b/unsupported/Eigen/src/Skyline/SkylineProduct.h
index 5da66af..4b41e10 100644
--- a/unsupported/Eigen/src/Skyline/SkylineProduct.h
+++ b/unsupported/Eigen/src/Skyline/SkylineProduct.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SKYLINEPRODUCT_H
 #define EIGEN_SKYLINEPRODUCT_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 template<typename Lhs, typename Rhs, int ProductMode>
diff --git a/unsupported/Eigen/src/Skyline/SkylineStorage.h b/unsupported/Eigen/src/Skyline/SkylineStorage.h
index 9c55f29..73b15a6 100644
--- a/unsupported/Eigen/src/Skyline/SkylineStorage.h
+++ b/unsupported/Eigen/src/Skyline/SkylineStorage.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SKYLINE_STORAGE_H
 #define EIGEN_SKYLINE_STORAGE_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 /** Stores a skyline set of values in three structures :
diff --git a/unsupported/Eigen/src/Skyline/SkylineUtil.h b/unsupported/Eigen/src/Skyline/SkylineUtil.h
index 4446d73..d90c918 100644
--- a/unsupported/Eigen/src/Skyline/SkylineUtil.h
+++ b/unsupported/Eigen/src/Skyline/SkylineUtil.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SKYLINEUTIL_H
 #define EIGEN_SKYLINEUTIL_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 #ifdef NDEBUG
diff --git a/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h b/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h
index 6b4f8a1..60e90ba 100644
--- a/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h
+++ b/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SPARSEBLOCKMATRIX_H
 #define EIGEN_SPARSEBLOCKMATRIX_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 /** \ingroup SparseCore_Module
   *
diff --git a/unsupported/Eigen/src/SparseExtra/InternalHeaderCheck.h b/unsupported/Eigen/src/SparseExtra/InternalHeaderCheck.h
new file mode 100644
index 0000000..0e55251
--- /dev/null
+++ b/unsupported/Eigen/src/SparseExtra/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SPARSE_EXTRA_MODULE_H
+#error "Please include unsupported/Eigen/SparseExtra instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/SparseExtra/MarketIO.h b/unsupported/Eigen/src/SparseExtra/MarketIO.h
index 8df2556..cf5828e 100644
--- a/unsupported/Eigen/src/SparseExtra/MarketIO.h
+++ b/unsupported/Eigen/src/SparseExtra/MarketIO.h
@@ -14,6 +14,8 @@
 #include <iostream>
 #include <vector>
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen { 
 
 namespace internal 
diff --git a/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h b/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h
index 02916ea..12e4cb4 100644
--- a/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h
+++ b/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_BROWSE_MATRICES_H
 #define EIGEN_BROWSE_MATRICES_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 enum {
diff --git a/unsupported/Eigen/src/SparseExtra/RandomSetter.h b/unsupported/Eigen/src/SparseExtra/RandomSetter.h
index f6ab095..656ea05 100644
--- a/unsupported/Eigen/src/SparseExtra/RandomSetter.h
+++ b/unsupported/Eigen/src/SparseExtra/RandomSetter.h
@@ -16,6 +16,8 @@
 namespace google {}
 #endif
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** Represents a std::map
diff --git a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsArrayAPI.h b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsArrayAPI.h
index 41d2bf6..7fa85e2 100644
--- a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsArrayAPI.h
+++ b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsArrayAPI.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_BESSELFUNCTIONS_ARRAYAPI_H
 #define EIGEN_BESSELFUNCTIONS_ARRAYAPI_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \returns an expression of the coefficient-wise i0(\a x) to the given
diff --git a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsBFloat16.h b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsBFloat16.h
index 6049cc2..c016004 100644
--- a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsBFloat16.h
+++ b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsBFloat16.h
@@ -8,6 +8,8 @@
 #ifndef EIGEN_BESSELFUNCTIONS_BFLOAT16_H
 #define EIGEN_BESSELFUNCTIONS_BFLOAT16_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace numext {
 
diff --git a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsFunctors.h b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsFunctors.h
index 8606a9f..623f0b9 100644
--- a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsFunctors.h
+++ b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsFunctors.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_BESSELFUNCTIONS_FUNCTORS_H
 #define EIGEN_BESSELFUNCTIONS_FUNCTORS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsHalf.h b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsHalf.h
index 8930d1a..4d50503 100644
--- a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsHalf.h
+++ b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsHalf.h
@@ -8,6 +8,8 @@
 #ifndef EIGEN_BESSELFUNCTIONS_HALF_H
 #define EIGEN_BESSELFUNCTIONS_HALF_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace numext {
 
diff --git a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsImpl.h b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsImpl.h
index 24812be..b600079 100644
--- a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsImpl.h
+++ b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsImpl.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_BESSEL_FUNCTIONS_H
 #define EIGEN_BESSEL_FUNCTIONS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
@@ -48,10 +50,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_i0e {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -239,10 +241,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type >
 struct generic_i1e {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -434,10 +436,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_k0e {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -597,10 +599,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_k0 {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -769,10 +771,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_k1e {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -925,10 +927,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_k1 {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -1091,10 +1093,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_j0 {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -1291,10 +1293,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_y0 {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -1489,10 +1491,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_j1 {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
@@ -1680,10 +1682,10 @@
 
 template <typename T, typename ScalarType = typename unpacket_traits<T>::type>
 struct generic_y1 {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE T run(const T&) {
-    EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<T, T>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T run(const T&) {
     return ScalarType(0);
   }
 };
diff --git a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsPacketMath.h b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsPacketMath.h
index 943d10f..ac8c57b 100644
--- a/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsPacketMath.h
+++ b/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsPacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_BESSELFUNCTIONS_PACKETMATH_H
 #define EIGEN_BESSELFUNCTIONS_PACKETMATH_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/src/SpecialFunctions/HipVectorCompatibility.h b/unsupported/Eigen/src/SpecialFunctions/HipVectorCompatibility.h
index d7b231a..bc6f912 100644
--- a/unsupported/Eigen/src/SpecialFunctions/HipVectorCompatibility.h
+++ b/unsupported/Eigen/src/SpecialFunctions/HipVectorCompatibility.h
@@ -5,6 +5,8 @@
   template <typename, typename, unsigned int> struct Scalar_accessor;
 }   // end namespace hip_impl
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
diff --git a/unsupported/Eigen/src/SpecialFunctions/InternalHeaderCheck.h b/unsupported/Eigen/src/SpecialFunctions/InternalHeaderCheck.h
new file mode 100644
index 0000000..c80ebd8
--- /dev/null
+++ b/unsupported/Eigen/src/SpecialFunctions/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SPECIALFUNCTIONS_MODULE_H
+#error "Please include unsupported/Eigen/SpecialFunctions instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsArrayAPI.h b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsArrayAPI.h
index 691ff4d..4429333 100644
--- a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsArrayAPI.h
+++ b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsArrayAPI.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SPECIALFUNCTIONS_ARRAYAPI_H
 #define EIGEN_SPECIALFUNCTIONS_ARRAYAPI_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 /** \cpp11 \returns an expression of the coefficient-wise igamma(\a a, \a x) to the given arrays.
diff --git a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsBFloat16.h b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsBFloat16.h
index 2d94231..56e0b95 100644
--- a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsBFloat16.h
+++ b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsBFloat16.h
@@ -8,6 +8,8 @@
 #ifndef EIGEN_SPECIALFUNCTIONS_BFLOAT16_H
 #define EIGEN_SPECIALFUNCTIONS_BFLOAT16_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace numext {
 
diff --git a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsFunctors.h b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsFunctors.h
index abefe99..125f1b9 100644
--- a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsFunctors.h
+++ b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsFunctors.h
@@ -11,6 +11,8 @@
 #ifndef EIGEN_SPECIALFUNCTIONS_FUNCTORS_H
 #define EIGEN_SPECIALFUNCTIONS_FUNCTORS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsHalf.h b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsHalf.h
index 2a3a531..4b8a35f 100644
--- a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsHalf.h
+++ b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsHalf.h
@@ -8,6 +8,8 @@
 #ifndef EIGEN_SPECIALFUNCTIONS_HALF_H
 #define EIGEN_SPECIALFUNCTIONS_HALF_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace numext {
 
diff --git a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h
index f1c260e..e618042 100644
--- a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h
+++ b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPECIAL_FUNCTIONS_H
 #define EIGEN_SPECIAL_FUNCTIONS_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 namespace internal {
 
@@ -43,10 +45,10 @@
 
 template <typename Scalar>
 struct lgamma_impl {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
     return Scalar(0);
   }
 };
@@ -126,10 +128,10 @@
  */
 template <typename Scalar>
 struct digamma_impl_maybe_poly {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                        THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
     return Scalar(0);
   }
 };
@@ -390,10 +392,10 @@
 
 template <typename Scalar>
 struct erfc_impl {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
     return Scalar(0);
   }
 };
@@ -650,10 +652,10 @@
 
 template <typename Scalar>
 struct ndtri_impl {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
     return Scalar(0);
   }
 };
@@ -786,7 +788,7 @@
     Scalar ax = main_igamma_term<Scalar>(a, x);
     // This is independent of mode. If this value is zero,
     // then the function value is zero. If the function value is zero,
-    // then we are in a neighborhood where the function value evalutes to zero,
+    // then we are in a neighborhood where the function value evaluates to zero,
     // so the derivative is zero.
     if (ax == zero) {
       return zero;
@@ -897,7 +899,7 @@
 
     // This is independent of mode. If this value is zero,
     // then the function value is zero. If the function value is zero,
-    // then we are in a neighborhood where the function value evalutes to zero,
+    // then we are in a neighborhood where the function value evaluates to zero,
     // so the derivative is zero.
     if (ax == zero) {
       return zero;
@@ -952,10 +954,10 @@
 
 template <typename Scalar>
 struct igammac_impl {
-  EIGEN_DEVICE_FUNC
-  static Scalar run(Scalar a, Scalar x) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static Scalar run(Scalar a, Scalar x) {
     return Scalar(0);
   }
 };
@@ -1051,10 +1053,10 @@
 
 template <typename Scalar, IgammaComputationMode mode>
 struct igamma_generic_impl {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar x) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar x) {
     return Scalar(0);
   }
 };
@@ -1255,10 +1257,10 @@
 
 template <typename Scalar>
 struct zeta_impl_series {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Scalar) {
     return Scalar(0);
   }
 };
@@ -1466,10 +1468,10 @@
 
 template <typename Scalar>
 struct polygamma_impl {
-    EIGEN_DEVICE_FUNC
-    static EIGEN_STRONG_INLINE Scalar run(Scalar n, Scalar x) {
-        EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                            THIS_TYPE_IS_NOT_SUPPORTED);
+    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                        THIS_TYPE_IS_NOT_SUPPORTED)
+
+    EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(Scalar n, Scalar x) {
         return Scalar(0);
     }
 };
@@ -1515,10 +1517,10 @@
 
 template <typename Scalar>
 struct betainc_impl {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar b, Scalar x) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar b, Scalar x) {
     return Scalar(0);
   }
 };
@@ -1527,8 +1529,10 @@
 
 template <typename Scalar>
 struct betainc_impl {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(Scalar, Scalar, Scalar) {
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(Scalar, Scalar, Scalar) {
     /*	betaincf.c
      *
      *	Incomplete beta integral
@@ -1597,9 +1601,6 @@
      * incbet domain      x<0, x>1          nan
      * incbet underflow                     nan
      */
-
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, Scalar>::value == false),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
     return Scalar(0);
   }
 };
@@ -1609,11 +1610,11 @@
  */
 template <typename Scalar>
 struct incbeta_cfe {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar b, Scalar x, bool small_branch) {
-    EIGEN_STATIC_ASSERT((internal::is_same<Scalar, float>::value ||
-                         internal::is_same<Scalar, double>::value),
-                        THIS_TYPE_IS_NOT_SUPPORTED);
+  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, float>::value ||
+                       internal::is_same<Scalar, double>::value),
+                      THIS_TYPE_IS_NOT_SUPPORTED)
+
+  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(Scalar a, Scalar b, Scalar x, bool small_branch) {
     const Scalar big = cephes_helper<Scalar>::big();
     const Scalar machep = cephes_helper<Scalar>::machep();
     const Scalar biginv = cephes_helper<Scalar>::biginv();
diff --git a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsPacketMath.h b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsPacketMath.h
index 2bb0179..651457f 100644
--- a/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsPacketMath.h
+++ b/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsPacketMath.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPECIALFUNCTIONS_PACKETMATH_H
 #define EIGEN_SPECIALFUNCTIONS_PACKETMATH_H
 
+#include "./InternalHeaderCheck.h"
+
 namespace Eigen {
 
 namespace internal {
diff --git a/unsupported/Eigen/src/Splines/InternalHeaderCheck.h b/unsupported/Eigen/src/Splines/InternalHeaderCheck.h
new file mode 100644
index 0000000..4a6087e
--- /dev/null
+++ b/unsupported/Eigen/src/Splines/InternalHeaderCheck.h
@@ -0,0 +1,3 @@
+#ifndef EIGEN_SPLINES_MODULE_H
+#error "Please include unsupported/Eigen/Splines instead of including headers inside the src directory directly."
+#endif
diff --git a/unsupported/Eigen/src/Splines/Spline.h b/unsupported/Eigen/src/Splines/Spline.h
index e61ee30..2e66ec3 100644
--- a/unsupported/Eigen/src/Splines/Spline.h
+++ b/unsupported/Eigen/src/Splines/Spline.h
@@ -10,6 +10,8 @@
 #ifndef EIGEN_SPLINE_H
 #define EIGEN_SPLINE_H
 
+#include "./InternalHeaderCheck.h"
+
 #include "SplineFwd.h"
 
 namespace Eigen
diff --git a/unsupported/Eigen/src/Splines/SplineFitting.h b/unsupported/Eigen/src/Splines/SplineFitting.h
index 9f6e8af..fe70658 100644
--- a/unsupported/Eigen/src/Splines/SplineFitting.h
+++ b/unsupported/Eigen/src/Splines/SplineFitting.h
@@ -15,11 +15,14 @@
 #include <numeric>
 #include <vector>
 
+#include "./InternalHeaderCheck.h"
+
 #include "SplineFwd.h"
 
 #include "../../../../Eigen/LU"
 #include "../../../../Eigen/QR"
 
+
 namespace Eigen
 {
   /**
diff --git a/unsupported/Eigen/src/Splines/SplineFwd.h b/unsupported/Eigen/src/Splines/SplineFwd.h
index 35b31f3..0348eba 100644
--- a/unsupported/Eigen/src/Splines/SplineFwd.h
+++ b/unsupported/Eigen/src/Splines/SplineFwd.h
@@ -10,6 +10,7 @@
 #ifndef EIGEN_SPLINES_FWD_H
 #define EIGEN_SPLINES_FWD_H
 
+#include "./InternalHeaderCheck.h"
 #include "../../../../Eigen/Core"
 
 namespace Eigen
diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index fffd001..8aa524d 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -284,8 +284,7 @@
 
 endif()
 
-# These tests needs nvcc
-find_package(CUDA 7.0)
+find_package(CUDA 9.0)
 if(CUDA_FOUND AND EIGEN_TEST_CUDA)
   # Make sure to compile without the -pedantic, -Wundef, -Wnon-virtual-dtor
   # and -fno-check-new flags since they trigger thousands of compilation warnings
@@ -295,29 +294,32 @@
   string(REPLACE "-Wnon-virtual-dtor" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
   string(REPLACE "-fno-check-new" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
 
-  message(STATUS "Flags used to compile cuda code: " ${CMAKE_CXX_FLAGS})
-
-  if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-    set(CUDA_NVCC_FLAGS "-ccbin ${CMAKE_C_COMPILER}" CACHE STRING "nvcc flags" FORCE)
-  endif()
   if(EIGEN_TEST_CUDA_CLANG)
     string(APPEND CMAKE_CXX_FLAGS " --cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
     foreach(ARCH IN LISTS EIGEN_CUDA_COMPUTE_ARCH)
         string(APPEND CMAKE_CXX_FLAGS " --cuda-gpu-arch=sm_${ARCH}")
     endforeach()
+    string(APPEND CMAKE_CXX_FLAGS " ${EIGEN_CUDA_CXX_FLAGS}")
+  else()
+    set(CUDA_PROPAGATE_HOST_FLAGS OFF)
+    set(NVCC_ARCH_FLAGS)
+    # Define an -arch=sm_<arch>, otherwise if GPU does not exactly match one of
+    # those in the arch list for -gencode, the kernels will fail to run with
+    #    cudaErrorNoKernelImageForDevice
+    # This can happen with newer cards (e.g. sm_75) and compiling with older
+    # versions of nvcc (e.g. 9.2) that do not support their specific arch.
+    list(LENGTH EIGEN_CUDA_COMPUTE_ARCH EIGEN_CUDA_COMPUTE_ARCH_SIZE)
+    if(EIGEN_CUDA_COMPUTE_ARCH_SIZE)
+      list(GET EIGEN_CUDA_COMPUTE_ARCH 0 EIGEN_CUDA_COMPUTE_DEFAULT)
+      set(NVCC_ARCH_FLAGS " -arch=sm_${EIGEN_CUDA_COMPUTE_DEFAULT}")
+    endif()
+    foreach(ARCH IN LISTS EIGEN_CUDA_COMPUTE_ARCH)
+      string(APPEND NVCC_ARCH_FLAGS " -gencode arch=compute_${ARCH},code=sm_${ARCH}")
+    endforeach()
+    set(CUDA_NVCC_FLAGS  "--expt-relaxed-constexpr -Xcudafe \"--display_error_number\" ${NVCC_ARCH_FLAGS} ${CUDA_NVCC_FLAGS} ${EIGEN_CUDA_CXX_FLAGS}")
+    cuda_include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}/include")
   endif()
-
-  set(EIGEN_CUDA_RELAXED_CONSTEXPR "--expt-relaxed-constexpr")
-  if (${CUDA_VERSION} STREQUAL "7.0")
-    set(EIGEN_CUDA_RELAXED_CONSTEXPR "--relaxed-constexpr")
-  endif()
-
-  set(NVCC_ARCH_FLAGS)
-  foreach(ARCH IN LISTS EIGEN_CUDA_COMPUTE_ARCH)
-    string(APPEND NVCC_ARCH_FLAGS " -gencode arch=compute_${ARCH},code=sm_${ARCH}")
-  endforeach()
-  set(CUDA_NVCC_FLAGS  "${EIGEN_CUDA_RELAXED_CONSTEXPR} -Xcudafe \"--display_error_number\" ${NVCC_ARCH_FLAGS} ${CUDA_NVCC_FLAGS}")
-  cuda_include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}/include")
+  
   set(EIGEN_ADD_TEST_FILENAME_EXTENSION "cu")
 
   ei_add_test(cxx11_tensor_complex_gpu)
diff --git a/unsupported/test/alignedvector3.cpp b/unsupported/test/alignedvector3.cpp
index f442e41..1fc6d62 100644
--- a/unsupported/test/alignedvector3.cpp
+++ b/unsupported/test/alignedvector3.cpp
@@ -7,6 +7,8 @@
 // Public License v. 2.0. If a copy of the MPL was not distributed
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+#define EIGEN_NO_STATIC_ASSERT
+
 #include "main.h"
 #include <unsupported/Eigen/AlignedVector3>
 
diff --git a/unsupported/test/cxx11_tensor_builtins_sycl.cpp b/unsupported/test/cxx11_tensor_builtins_sycl.cpp
index 72cb62f..df142fe 100644
--- a/unsupported/test/cxx11_tensor_builtins_sycl.cpp
+++ b/unsupported/test/cxx11_tensor_builtins_sycl.cpp
@@ -38,24 +38,24 @@
 }
 }
 
-struct EqualAssignement {
+struct EqualAssignment {
   template <typename Lhs, typename Rhs>
   void operator()(Lhs& lhs, const Rhs& rhs) { lhs = rhs; }
 };
 
-struct PlusEqualAssignement {
+struct PlusEqualAssignment {
   template <typename Lhs, typename Rhs>
   void operator()(Lhs& lhs, const Rhs& rhs) { lhs += rhs; }
 };
 
 template <typename DataType, int DataLayout,
-          typename Assignement, typename Operator>
+          typename Assignment, typename Operator>
 void test_unary_builtins_for_scalar(const Eigen::SyclDevice& sycl_device,
                                     const array<int64_t, 3>& tensor_range) {
   Operator op;
-  Assignement asgn;
+  Assignment asgn;
   {
-    /* Assignement(out, Operator(in)) */
+    /* Assignment(out, Operator(in)) */
     Tensor<DataType, 3, DataLayout, int64_t> in(tensor_range);
     Tensor<DataType, 3, DataLayout, int64_t> out(tensor_range);
     in = in.random() + DataType(0.01);
@@ -84,7 +84,7 @@
     sycl_device.deallocate(gpu_data_out);
   }
   {
-    /* Assignement(out, Operator(out)) */
+    /* Assignment(out, Operator(out)) */
     Tensor<DataType, 3, DataLayout, int64_t> out(tensor_range);
     out = out.random() + DataType(0.01);
     Tensor<DataType, 3, DataLayout, int64_t> reference(out);
@@ -137,11 +137,11 @@
 DECLARE_UNARY_STRUCT(isfinite)
 DECLARE_UNARY_STRUCT(isinf)
 
-template <typename DataType, int DataLayout, typename Assignement>
+template <typename DataType, int DataLayout, typename Assignment>
 void test_unary_builtins_for_assignement(const Eigen::SyclDevice& sycl_device,
                                          const array<int64_t, 3>& tensor_range) {
 #define RUN_UNARY_TEST(FUNC) \
-  test_unary_builtins_for_scalar<DataType, DataLayout, Assignement, \
+  test_unary_builtins_for_scalar<DataType, DataLayout, Assignment, \
                                  op_##FUNC>(sycl_device, tensor_range)
   RUN_UNARY_TEST(abs);
   RUN_UNARY_TEST(sqrt);
@@ -190,9 +190,9 @@
 void test_unary_builtins(const Eigen::SyclDevice& sycl_device,
                          const array<int64_t, 3>& tensor_range) {
   test_unary_builtins_for_assignement<DataType, DataLayout,
-                                      PlusEqualAssignement>(sycl_device, tensor_range);
+                                      PlusEqualAssignment>(sycl_device, tensor_range);
   test_unary_builtins_for_assignement<DataType, DataLayout,
-                                      EqualAssignement>(sycl_device, tensor_range);
+                                      EqualAssignment>(sycl_device, tensor_range);
   test_unary_builtins_return_bool<DataType, DataLayout,
                                   op_isnan>(sycl_device, tensor_range);
   test_unary_builtins_return_bool<DataType, DataLayout,