From 6c3bc63c1dadf1a05bd9b908d3d16ed9b85b590b Mon Sep 17 00:00:00 2001
From: finkandreas <finkandreas@web.de>
Date: Thu, 15 Apr 2021 11:54:39 +0200
Subject: trilinos: fix build with cuda-11 and cxxstd=14 variant (#22972)

---
 .../packages/trilinos/fix_cxx14_cuda11.patch       | 110 +++++++++++++++++++++
 .../repos/builtin/packages/trilinos/package.py     |   4 +
 2 files changed, 114 insertions(+)
 create mode 100644 var/spack/repos/builtin/packages/trilinos/fix_cxx14_cuda11.patch

diff --git a/var/spack/repos/builtin/packages/trilinos/fix_cxx14_cuda11.patch b/var/spack/repos/builtin/packages/trilinos/fix_cxx14_cuda11.patch
new file mode 100644
index 0000000000..ae174d3524
--- /dev/null
+++ b/var/spack/repos/builtin/packages/trilinos/fix_cxx14_cuda11.patch
@@ -0,0 +1,110 @@
+diff -ur spack-src.orig/packages/tpetra/core/src/Tpetra_Details_checkPointer.cpp spack-src/packages/tpetra/core/src/Tpetra_Details_checkPointer.cpp
+--- spack-src.orig/packages/tpetra/core/src/Tpetra_Details_checkPointer.cpp	2021-04-13 05:21:37.000000000 +0000
++++ spack-src/packages/tpetra/core/src/Tpetra_Details_checkPointer.cpp	2021-04-13 12:01:46.976127920 +0000
+@@ -74,7 +74,7 @@
+     return EMemoryType::ERROR;
+   }
+ 
+-# if 1
++# if CUDA_VERSION < 11000
+   // cudaPointerAttributes::type doesn't exist yet in CUDA 9.2.  We
+   // must use memoryType, which does not distinguish between types of
+   // device memory.
+@@ -101,7 +101,7 @@
+     return EMemoryType::ERROR;
+   }
+ 
+-# else
++# else // >=CUDA-11
+ 
+   const enum cudaMemoryType theType = attr.type;
+   if (theType == cudaMemoryTypeManaged) {
+@@ -117,7 +117,7 @@
+     return EMemoryType::HOST;
+   }
+ 
+-# endif // 1
++# endif // < CUDA-11
+ #else // NOT HAVE_TPETRACORE_CUDA
+   return EMemoryType::HOST;
+ #endif // HAVE_TPETRACORE_CUDA
+diff -ur spack-src.orig/packages/tpetra/core/src/Tpetra_withLocalAccess.hpp spack-src/packages/tpetra/core/src/Tpetra_withLocalAccess.hpp
+--- spack-src.orig/packages/tpetra/core/src/Tpetra_withLocalAccess.hpp	2021-04-13 05:21:37.000000000 +0000
++++ spack-src/packages/tpetra/core/src/Tpetra_withLocalAccess.hpp	2021-04-13 12:37:34.557170771 +0000
+@@ -820,6 +820,58 @@
+       }
+     };
+ 
++
++    /// \brief Specialization of WithLocalAccess that implements the
++    ///   "base class" of the user providing one GlobalObject
++    ///   arguments, and a function that takes one arguments.
++    ///   Required to workaround a compile error with intel-19 in c++14 mode.
++    template<class FirstLocalAccessType>
++    struct WithLocalAccess<FirstLocalAccessType> {
++      using current_user_function_type =
++        typename ArgsToFunction<FirstLocalAccessType>::type;
++
++      static void
++      withLocalAccess (current_user_function_type userFunction,
++                       FirstLocalAccessType first)
++      {
++        // The "master" local object is the scope guard for local
++        // data.  Its constructor may allocate temporary storage, copy
++        // data to the desired memory space, etc.  Its destructor will
++        // put everything back.  "Put everything back" could be a
++        // no-op, or it could copy data back so where they need to go
++        // and/or free temporary storage.
++        //
++        // Users define this function and the type it returns by
++        // specializing GetMasterLocalObject for LocalAccess
++        // specializations.
++        auto first_lcl_master = getMasterLocalObject (first);
++
++        // The "nonowning" local object is a nonowning view of the
++        // "master" local object.  This is the only local object that
++        // users see, and they see it as input to their function.
++        // Subsequent slices / subviews view this nonowning local
++        // object.  All such nonowning views must have lifetime
++        // contained within the lifetime of the master local object.
++        //
++        // Users define this function and the type it returns by
++        // specializing GetNonowningLocalObject (see above).
++        //
++        // Constraining the nonowning views' lifetime to this scope
++        // means that master local object types may use low-cost
++        // ownership models, like that of std::unique_ptr.  There
++        // should be no need for reference counting (in the manner of
++        // std::shared_ptr) or Herb Sutter's deferred_heap.
++        auto first_lcl_view = getNonowningLocalObject (first, first_lcl_master);
++
++        // Curry the user's function by fixing the first argument.
++
++        WithLocalAccess<>::withLocalAccess
++          ([=] () {
++             userFunction (first_lcl_view);
++           });
++      }
++    };
++
+     /// \brief Specialization of WithLocalAccess that implements the
+     ///   "recursion case."
+     ///
+@@ -867,17 +919,6 @@
+ 
+         // Curry the user's function by fixing the first argument.
+ 
+-        // The commented-out implementation requires C++14, because it
+-        // uses a generic lambda (the special case where parameters
+-        // are "auto").  We do have the types of the arguments,
+-        // though, from ArgsToFunction, so we don't need this feature.
+-
+-        // WithLocalAccess<Rest...>::withLocalAccess
+-        //   (rest...,
+-        //    [=] (auto ... args) {
+-        //      userFunction (first_lcl_view, args...);
+-        //    });
+-
+         WithLocalAccess<Rest...>::withLocalAccess
+           ([=] (with_local_access_function_argument_type<Rest>... args) {
+              userFunction (first_lcl_view, args...);
diff --git a/var/spack/repos/builtin/packages/trilinos/package.py b/var/spack/repos/builtin/packages/trilinos/package.py
index 48101590e4..2b3dd1987d 100644
--- a/var/spack/repos/builtin/packages/trilinos/package.py
+++ b/var/spack/repos/builtin/packages/trilinos/package.py
@@ -429,6 +429,10 @@ class Trilinos(CMakePackage, CudaPackage):
     patch('cray_secas_12_12_1.patch', when='@12.12.1%cce')
     patch('cray_secas.patch', when='@12.14.1:12.18.1%cce')
 
+    # workaround an NVCC bug with c++14 (https://github.com/trilinos/Trilinos/issues/6954)
+    # avoid calling deprecated functions with CUDA-11
+    patch('fix_cxx14_cuda11.patch', when='@13.0.0:13.0.1 cxxstd=14 ^cuda@11:')
+
     def url_for_version(self, version):
         url = "https://github.com/trilinos/Trilinos/archive/trilinos-release-{0}.tar.gz"
         return url.format(version.dashed)
-- 
cgit v1.2.3-70-g09d2