From 46e03ea0a309c8eca0734b5e734d075ea7c8b430 Mon Sep 17 00:00:00 2001
From: Bruno Turcksin <bruno.turcksin@gmail.com>
Date: Fri, 25 Oct 2024 15:46:46 -0400
Subject: [PATCH] Only use Kokkos::Array with Kokkos 3.7 or newer

---
 cmake/modules/FindDEAL_II_KOKKOS.cmake | 13 +++++++++----
 include/deal.II/base/tensor.h          | 14 ++++++++++++--
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/cmake/modules/FindDEAL_II_KOKKOS.cmake b/cmake/modules/FindDEAL_II_KOKKOS.cmake
index 02de0a98c1..e639a8b25c 100644
--- a/cmake/modules/FindDEAL_II_KOKKOS.cmake
+++ b/cmake/modules/FindDEAL_II_KOKKOS.cmake
@@ -47,6 +47,15 @@ endif()
 
 
 if(Kokkos_FOUND)
+  if (Kokkos_ENABLE_CUDA OR Kokkos_ENABLE_HIP)
+    # In version older than 3.7.0, Kokkos::Array::operator[] is not constexpr,
+    # so we use std::array instead.
+    if (KOKKOS_VERSION VERSION_LESS 3.7.0)
+      # We are using std::array in device code which calls the host-only function
+      # __glibcxx_requires_subscript when defining _GLIBCXX_ASSERTIONS 
+      list(REMOVE_ITEM DEAL_II_DEFINITIONS_DEBUG "_GLIBCXX_ASSERTIONS")
+    endif()
+  endif()
   if(Kokkos_ENABLE_CUDA)
     # We need to disable SIMD vectorization for CUDA device code.
     # Otherwise, nvcc compilers from version 9 on will emit an error message like:
@@ -60,10 +69,6 @@ if(Kokkos_FOUND)
     # __host__ constexpr functions in device code
     KOKKOS_CHECK(OPTIONS CUDA_LAMBDA CUDA_CONSTEXPR)
 
-    # We are using std::array in device code which calls the host-only function
-    # __glibcxx_requires_subscript when defining _GLIBCXX_ASSERTIONS 
-    list(REMOVE_ITEM DEAL_II_DEFINITIONS_DEBUG "_GLIBCXX_ASSERTIONS")
-
     # Disable a bunch of annoying warnings generated by boost, template code,
     # and in other random places:
     #
diff --git a/include/deal.II/base/tensor.h b/include/deal.II/base/tensor.h
index cd0b06b7ed..40ba24ba1c 100644
--- a/include/deal.II/base/tensor.h
+++ b/include/deal.II/base/tensor.h
@@ -24,7 +24,7 @@
 #include <deal.II/base/template_constraints.h>
 #include <deal.II/base/tensor_accessors.h>
 
-#include <Kokkos_Core.hpp>
+#include <Kokkos_Array.hpp>
 
 #ifdef DEAL_II_WITH_ADOLC
 #  include <adolc/adouble.h> // Taped double
@@ -839,9 +839,15 @@ private:
    * a rank-1 tensor, then we simply need an array of scalars.
    * Otherwise, it is an array of tensors one rank lower.
    */
+#if KOKKOS_VERSION >= 30700
   std::conditional_t<rank_ == 1,
                      Kokkos::Array<Number, dim>,
                      Kokkos::Array<Tensor<rank_ - 1, dim, Number>, dim>>
+#else
+  std::conditional_t<rank_ == 1,
+                     std::array<Number, dim>,
+                     std::array<Tensor<rank_ - 1, dim, Number>, dim>>
+#endif
     values;
 
   /**
@@ -1257,7 +1263,7 @@ Tensor<rank_, dim, Number>::Tensor()
       // brace-enclosed list of length 'dim'. There is no way in C++ to create
       // such a list in-place, but we can come up with a lambda function that
       // expands such a list via template-pack expansion, and then uses this
-      // list to initialize a Kokkos:Array which it then returns.
+      // list to initialize a Kokkos::Array which it then returns.
       //
       // The trick to come up with such a lambda function is to have a function
       // that takes an argument that depends on a template-pack of integers.
@@ -1319,7 +1325,11 @@ namespace internal
   namespace TensorInitialization
   {
     template <int rank, int dim, typename Number, std::size_t... I>
+#    if KOKKOS_VERSION >= 30700
     constexpr Kokkos::Array<typename Tensor<rank, dim, Number>::value_type, dim>
+#    else
+    constexpr std::array<typename Tensor<rank, dim, Number>::value_type, dim>
+#    endif
     make_zero_array(const std::index_sequence<I...> &)
     {
       static_assert(sizeof...(I) == dim, "This is bad.");
-- 
2.39.5