Add custom ODR-safe assert.
diff --git a/Eigen/Core b/Eigen/Core
index cb5ef55..af71891 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -82,9 +82,6 @@
 #include <cstddef>
 #include <cstdlib>
 #include <cmath>
-#ifndef __SYCL_DEVICE_ONLY__
-#include <cassert>
-#endif
 #include <functional>
 #ifndef EIGEN_NO_IO
   #include <sstream>
@@ -160,6 +157,7 @@
 
 #include "src/Core/util/Constants.h"
 #include "src/Core/util/Meta.h"
+#include "src/Core/util/Assert.h"
 #include "src/Core/util/ForwardDeclarations.h"
 #include "src/Core/util/StaticAssert.h"
 #include "src/Core/util/XprHelper.h"
diff --git a/Eigen/src/Core/util/Assert.h b/Eigen/src/Core/util/Assert.h
new file mode 100644
index 0000000..f8ba632
--- /dev/null
+++ b/Eigen/src/Core/util/Assert.h
@@ -0,0 +1,166 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2022, The Eigen authors.
+//
+// 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_CORE_UTIL_ASSERT_H
+#define EIGEN_CORE_UTIL_ASSERT_H
+
+// Eigen custom assert function.
+//
+// The combination of Eigen's relative includes and cassert's `assert` function
+// (or any usage of the __FILE__ macro) can lead to ODR issues:
+// a header included using different relative paths in two different TUs will
+// have two different token-for-token definitions, since __FILE__ is expanded
+// as an in-line string with different values.  Normally this would be
+// harmless - the linker would just choose one definition. However, it breaks
+// with C++20 modules when functions in different modules have different
+// definitions.
+//
+// To get around this, we need to use __builtin_FILE() when available, which is
+// considered a single token, and thus satisfies the ODR.
+
+// Only define eigen_plain_assert if we are debugging, and either
+//  - we are not compiling for GPU, or
+//  - gpu debugging is enabled.
+#if !defined(EIGEN_NO_DEBUG) && (!defined(EIGEN_GPU_COMPILE_PHASE) || !defined(EIGEN_NO_DEBUG_GPU))
+
+#include <cassert>
+
+#ifndef EIGEN_USE_CUSTOM_PLAIN_ASSERT
+// Disable new custom asserts by default for now.
+#define EIGEN_USE_CUSTOM_PLAIN_ASSERT  0
+#endif
+
+#if EIGEN_USE_CUSTOM_PLAIN_ASSERT
+
+#ifndef EIGEN_HAS_BUILTIN_FILE
+// Clang can check if __builtin_FILE() is supported.
+// GCC > 5, MSVC 2019 14.26 (1926) all have __builtin_FILE().
+// 
+// For NVCC, it's more complicated.  Through trial-and-error:
+//   - nvcc+gcc supports __builtin_FILE() on host, and on device after CUDA 11.
+//   - nvcc+msvc supports __builtin_FILE() only after CUDA 11.
+#if (EIGEN_HAS_BUILTIN(__builtin_FILE) && (EIGEN_COMP_CLANG || !defined(EIGEN_CUDA_ARCH))) || \
+    (EIGEN_GNUC_STRICT_AT_LEAST(5, 0, 0) && (EIGEN_COMP_NVCC >= 110000 || !defined(EIGEN_CUDA_ARCH))) || \
+    (EIGEN_COMP_MSVC >= 1926 && (!EIGEN_COMP_NVCC || EIGEN_COMP_NVCC >= 110000))
+#define EIGEN_HAS_BUILTIN_FILE 1
+#else
+#define EIGEN_HAS_BUILTIN_FILE 0
+#endif
+#endif  // EIGEN_HAS_BUILTIN_FILE
+
+#if EIGEN_HAS_BUILTIN_FILE
+#  define EIGEN_BUILTIN_FILE __builtin_FILE()
+#  define EIGEN_BUILTIN_LINE __builtin_LINE()
+#else
+// Default (potentially unsafe) values.
+#  define EIGEN_BUILTIN_FILE __FILE__
+#  define EIGEN_BUILTIN_LINE __LINE__
+#endif
+
+// Use __PRETTY_FUNCTION__ when available, since it is more descriptive, as
+// __builtin_FUNCTION() only returns the undecorated function name.
+// This should still be okay ODR-wise since it is a compiler-specific fixed
+// value.  Mixing compilers will likely lead to ODR violations anyways.
+#if EIGEN_COMP_MSVC
+#  define EIGEN_BUILTIN_FUNCTION __FUNCSIG__
+#elif EIGEN_COMP_GNUC
+#  define EIGEN_BUILTIN_FUNCTION __PRETTY_FUNCTION__
+#else
+#  define EIGEN_BUILTIN_FUNCTION __func__
+#endif
+
+namespace Eigen {
+namespace internal {
+
+// Generic default assert handler.
+template<typename EnableIf = void, typename... EmptyArgs>
+struct assert_handler_impl {
+  EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE
+  static inline void run(const char* expression, const char* file, unsigned line, const char* function) {
+#ifdef EIGEN_GPU_COMPILE_PHASE
+    // GPU device code doesn't allow stderr or abort, so use printf and raise an
+    // illegal instruction exception to trigger a kernel failure.
+#ifndef EIGEN_NO_IO
+    printf("Assertion failed at %s:%u in %s: %s\n",
+      file == nullptr ? "<file>" : file,
+      line,
+      function == nullptr ? "<function>" : function,
+      expression);
+#endif
+    __trap();
+      
+#else  // EIGEN_GPU_COMPILE_PHASE
+
+    // Print to stderr and abort, as specified in <cassert>.
+#ifndef EIGEN_NO_IO
+    fprintf(stderr, "Assertion failed at %s:%u in %s: %s\n",
+      file == nullptr ? "<file>" : file,
+      line,
+      function == nullptr ? "<function>" : function,
+      expression);
+#endif
+    std::abort();
+    
+#endif  // EIGEN_GPU_COMPILE_PHASE
+  }
+};
+
+// Use POSIX __assert_fail handler when available.
+//
+// This allows us to integrate with systems that have custom handlers.
+//
+// NOTE: this handler is not always available on all POSIX systems (otherwise
+// we could simply test for __unix__ or similar).  The handler function name
+// seems to depend on the specific toolchain implementation, and differs between
+// compilers, platforms, OSes, etc.  Hence, we detect support via SFINAE.
+template<typename... EmptyArgs>
+struct assert_handler_impl<
+    void_t<decltype(__assert_fail(
+        (const char*)nullptr,         // expression
+        (const char*)nullptr,         // file
+        0,                            // line
+        (const char*)nullptr,         // function
+        std::declval<EmptyArgs>()...  // Empty substitution required for SFINAE.
+    ))>, EmptyArgs... > {
+  EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE
+  static inline void run(const char* expression, const char* file, unsigned line, const char* function) {
+    // GCC requires this call to be dependent on the template parameters.
+    __assert_fail(expression, file, line, function, std::declval<EmptyArgs>()...);
+  }
+};
+
+EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE
+inline void __assert_handler(const char* expression, const char* file, unsigned line, const char* function) {
+  assert_handler_impl<>::run(expression, file, line, function);
+}
+
+}  // namespace internal
+}  // namespace Eigen
+
+#define eigen_plain_assert(expression)                     \
+  (EIGEN_PREDICT_FALSE(!(expression)) ?                    \
+    Eigen::internal::__assert_handler(#expression,         \
+                                      EIGEN_BUILTIN_FILE,  \
+                                      EIGEN_BUILTIN_LINE,  \
+                                      EIGEN_BUILTIN_FUNCTION) : (void)0)
+
+#else  // EIGEN_USE_CUSTOM_PLAIN_ASSERT
+
+// Use regular assert.
+#define eigen_plain_assert(condition) assert(condition)
+
+#endif  // EIGEN_USE_CUSTOM_PLAIN_ASSERT
+
+#else   // EIGEN_NO_DEBUG
+
+#define eigen_plain_assert(condition) ((void)0)
+
+#endif  // EIGEN_NO_DEBUG
+
+#endif  // EIGEN_CORE_UTIL_ASSERT_H
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index 026d174..819fa12 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -848,8 +848,8 @@
 
 // GPU stuff
 
-// Disable some features when compiling with GPU compilers (NVCC/clang-cuda/SYCL/HIPCC)
-#if defined(EIGEN_CUDACC) || defined(SYCL_DEVICE_ONLY) || defined(EIGEN_HIPCC)
+// Disable some features when compiling with GPU compilers (SYCL/HIPCC)
+#if defined(SYCL_DEVICE_ONLY) || defined(EIGEN_HIP_DEVICE_COMPILE)
   // Do not try asserts on device code
   #ifndef EIGEN_NO_DEBUG
   #define EIGEN_NO_DEBUG
@@ -858,7 +858,10 @@
   #ifdef EIGEN_INTERNAL_DEBUGGING
   #undef EIGEN_INTERNAL_DEBUGGING
   #endif
+#endif
 
+// No exceptions on device.
+#if defined(SYCL_DEVICE_ONLY) || defined(EIGEN_GPU_COMPILE_PHASE)
   #ifdef EIGEN_EXCEPTIONS
   #undef EIGEN_EXCEPTIONS
   #endif
@@ -890,17 +893,6 @@
 # endif
 #endif
 
-// eigen_plain_assert is where we implement the workaround for the assert() bug in GCC <= 4.3, see bug 89
-#ifdef EIGEN_NO_DEBUG
-  #ifdef SYCL_DEVICE_ONLY // used to silence the warning on SYCL device
-    #define eigen_plain_assert(x) EIGEN_UNUSED_VARIABLE(x)
-  #else
-    #define eigen_plain_assert(x)
-  #endif
-#else
-    #define eigen_plain_assert(x) assert(x)
-#endif
-
 // eigen_assert can be overridden
 #ifndef eigen_assert
 #define eigen_assert(x) eigen_plain_assert(x)
@@ -912,7 +904,7 @@
 #define eigen_internal_assert(x) ((void)0)
 #endif
 
-#ifdef EIGEN_NO_DEBUG
+#if defined(EIGEN_NO_DEBUG) || (defined(EIGEN_GPU_COMPILE_PHASE) && defined(EIGEN_NO_DEBUG_GPU))
 #define EIGEN_ONLY_USED_FOR_DEBUG(x) EIGEN_UNUSED_VARIABLE(x)
 #else
 #define EIGEN_ONLY_USED_FOR_DEBUG(x)
diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h
index 9c02514..1a5d515 100644
--- a/Eigen/src/Core/util/Meta.h
+++ b/Eigen/src/Core/util/Meta.h
@@ -153,6 +153,21 @@
 template< class T >
 struct is_void : is_same<void, std::remove_const_t<T>> {};
 
+/** \internal
+  * Implementation of std::void_t for SFINAE.
+  *
+  * Pre C++17:
+  * Custom implementation.
+  *
+  * Post C++17: Uses std::void_t
+  */
+#if EIGEN_COMP_CXXVER >= 17
+using std::void_t;
+#else
+template<typename...>
+using void_t = void;
+#endif
+
 template<> struct is_arithmetic<signed long long>   { enum { value = true }; };
 template<> struct is_arithmetic<unsigned long long> { enum { value = true }; };
 using std::is_integral;