From 87f64afa940cb2706589058daac90b3a135607c6 Mon Sep 17 00:00:00 2001
From: Daniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Date: Wed, 27 Feb 2019 11:45:57 +0100
Subject: [PATCH] Fix compiling with Sacado and CUDA

---
 include/deal.II/base/numbers.h                | 52 +++++++++++++++++--
 .../differentiation/ad/sacado_number_types.h  | 11 ++++
 source/base/tensor.cc                         |  1 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/include/deal.II/base/numbers.h b/include/deal.II/base/numbers.h
index 68bf74bef4..fca6430fd2 100644
--- a/include/deal.II/base/numbers.h
+++ b/include/deal.II/base/numbers.h
@@ -165,6 +165,15 @@ namespace numbers
    */
   static const double SQRT1_2 = 0.70710678118654752440;
 
+  /**
+   * Check whether the given type can be used in CUDA device code.
+   * If not, DEAL_II_CUDA_HOST_DEV needs to be disabled for functions
+   * that use this type.
+   */
+  template <typename Number, typename = void>
+  struct is_cuda_compatible : std::true_type
+  {};
+
   /**
    * Check whether a value is not a number.
    *
@@ -361,10 +370,21 @@ namespace numbers
      * general template is chosen for types not equal to std::complex, this
      * function simply returns the square of the given number.
      *
-     * @note This function can also be used in CUDA device code.
+     * @note If the template type can be used in CUDA device code, the same holds true
+     * for this function.
      */
-    static DEAL_II_CUDA_HOST_DEV real_type
-                                 abs_square(const number &x);
+    template <typename Dummy = number>
+    static DEAL_II_CUDA_HOST_DEV
+      typename std::enable_if<std::is_same<Dummy, number>::value &&
+                                is_cuda_compatible<Dummy>::value,
+                              real_type>::type
+      abs_square(const number &x);
+
+    template <typename Dummy = number>
+    static typename std::enable_if<std::is_same<Dummy, number>::value &&
+                                     !is_cuda_compatible<Dummy>::value,
+                                   real_type>::type
+    abs_square(const number &x);
 
     /**
      * Return the absolute value of a number.
@@ -423,12 +443,20 @@ namespace numbers
 
   // --------------- inline and template functions ---------------- //
 
+  template <typename Number>
+  struct is_cuda_compatible<std::complex<Number>, void> : std::false_type
+  {};
+
+
+
   inline bool
   is_nan(const double x)
   {
     return std::isnan(x);
   }
 
+
+
   inline bool
   is_finite(const double x)
   {
@@ -475,7 +503,23 @@ namespace numbers
 
 
   template <typename number>
-  DEAL_II_CUDA_HOST_DEV typename NumberTraits<number>::real_type
+  template <typename Dummy>
+  DEAL_II_CUDA_HOST_DEV
+    typename std::enable_if<std::is_same<Dummy, number>::value &&
+                              is_cuda_compatible<Dummy>::value,
+                            typename NumberTraits<number>::real_type>::type
+    NumberTraits<number>::abs_square(const number &x)
+  {
+    return x * x;
+  }
+
+
+
+  template <typename number>
+  template <typename Dummy>
+  typename std::enable_if<std::is_same<Dummy, number>::value &&
+                            !is_cuda_compatible<Dummy>::value,
+                          typename NumberTraits<number>::real_type>::type
   NumberTraits<number>::abs_square(const number &x)
   {
     return x * x;
diff --git a/include/deal.II/differentiation/ad/sacado_number_types.h b/include/deal.II/differentiation/ad/sacado_number_types.h
index 8781865c5f..907e830e1f 100644
--- a/include/deal.II/differentiation/ad/sacado_number_types.h
+++ b/include/deal.II/differentiation/ad/sacado_number_types.h
@@ -926,6 +926,17 @@ namespace Differentiation
   } // namespace AD
 } // namespace Differentiation
 
+
+namespace numbers
+{
+  template <typename NumberType>
+  struct is_cuda_compatible<
+    NumberType,
+    typename std::enable_if<dealii::Differentiation::AD::is_sacado_rad_number<
+      NumberType>::value>::type> : std::false_type
+  {};
+} // namespace numbers
+
 #  endif // DOXYGEN
 
 
diff --git a/source/base/tensor.cc b/source/base/tensor.cc
index 15cb6f3b5d..43dabdad75 100644
--- a/source/base/tensor.cc
+++ b/source/base/tensor.cc
@@ -19,6 +19,7 @@
 #include <deal.II/base/tensor.h>
 
 #include <deal.II/differentiation/ad/adolc_product_types.h>
+#include <deal.II/differentiation/ad/sacado_number_types.h>
 #include <deal.II/differentiation/ad/sacado_product_types.h>
 
 DEAL_II_NAMESPACE_OPEN
-- 
2.39.5