Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_Details_temporaryViewUtils.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Tpetra: Templated Linear Algebra Services Package
4 //
5 // Copyright 2008 NTESS and the Tpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TPETRA_DETAILS_TEMPVIEWUTILS_HPP
11 #define TPETRA_DETAILS_TEMPVIEWUTILS_HPP
12 
13 #include "Kokkos_Core.hpp"
15 
16 namespace Tpetra {
17 namespace Details {
18 namespace TempView {
19 
20 template <typename MemorySpace>
21 struct AlwaysMPISafe {
22  enum : bool { value = false };
23 };
24 
25 template <>
26 struct AlwaysMPISafe<Kokkos::HostSpace> {
27  enum : bool { value = true };
28 };
29 
30 #ifdef KOKKOS_ENABLE_CUDA
31 template <>
32 struct AlwaysMPISafe<Kokkos::CudaHostPinnedSpace> {
33  enum : bool { value = true };
34 };
35 #endif
36 
37 #ifdef KOKKOS_ENABLE_HIP
38 template <>
39 struct AlwaysMPISafe<Kokkos::HIPHostPinnedSpace> {
40  enum : bool { value = true };
41 };
42 #endif
43 
45 template <typename View1, typename View2>
47  using L1 = typename View1::array_layout;
48  using L2 = typename View2::array_layout;
49  enum : bool { EitherLeft = std::is_same<L1, Kokkos::LayoutLeft>::value || std::is_same<L2, Kokkos::LayoutLeft>::value };
50  enum : bool { BothStride = std::is_same<L1, Kokkos::LayoutStride>::value && std::is_same<L2, Kokkos::LayoutStride>::value };
51  using type = typename std::conditional<EitherLeft || BothStride, Kokkos::LayoutLeft, Kokkos::LayoutRight>::type;
52 };
53 
55 template <typename SrcView, typename Layout, typename std::enable_if<!std::is_same<typename SrcView::array_layout, Layout>::value>::type* = nullptr>
56 Kokkos::View<typename SrcView::data_type, Layout, typename SrcView::device_type>
57 toLayout(const SrcView& src) {
58  static_assert(!std::is_same<Kokkos::LayoutStride, Layout>::value,
59  "TempView::toLayout: Layout must be contiguous (not LayoutStride)");
60  Layout layout(src.extent(0), src.extent(1));
61  Kokkos::View<typename SrcView::non_const_data_type, Layout, typename SrcView::device_type> dst(Kokkos::ViewAllocateWithoutInitializing(src.label()), layout);
62  Kokkos::deep_copy(dst, src);
63  return dst;
64 }
65 
66 template <typename SrcView, typename Layout, typename std::enable_if<std::is_same<typename SrcView::array_layout, Layout>::value>::type* = nullptr>
67 Kokkos::View<typename SrcView::data_type, Layout, typename SrcView::device_type>
68 toLayout(const SrcView& src) {
69  if (src.span_is_contiguous()) {
70  return src;
71  } else {
72  // Even though the layout is already correct, it's not contiguous.
73  Layout layout(src.extent(0), src.extent(1));
74  Kokkos::View<typename SrcView::non_const_data_type, Layout, typename SrcView::device_type>
75  result(Kokkos::ViewAllocateWithoutInitializing(src.label()), layout);
76  Kokkos::deep_copy(result, src);
77  return result;
78  }
79 }
80 
84 template <typename SrcView, bool AssumeGPUAware, typename = typename std::enable_if<AssumeGPUAware || AlwaysMPISafe<typename SrcView::memory_space>::value>::type>
85 SrcView
86 toMPISafe(const SrcView& src) {
87  using SrcLayout = typename SrcView::array_layout;
88  static_assert(!std::is_same<SrcLayout, Kokkos::LayoutStride>::value, "toMPISafe requires that SrcView is contiguous");
89  return toLayout<SrcView, SrcLayout>(src);
90 }
91 
92 template <typename SrcView, bool AssumeGPUAware, typename = typename std::enable_if<!(AssumeGPUAware || AlwaysMPISafe<typename SrcView::memory_space>::value)>::type>
93 decltype(Kokkos::create_mirror_view_and_copy(std::declval<Kokkos::HostSpace>(), std::declval<SrcView>()))
94 toMPISafe(const SrcView& src) {
95  using SrcLayout = typename SrcView::array_layout;
96  static_assert(!std::is_same<SrcLayout, Kokkos::LayoutStride>::value, "toMPISafe requires that SrcView is contiguous");
97  auto srcContig = toLayout<SrcView, SrcLayout>(src);
98  return Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), srcContig);
99 }
100 
101 } // namespace TempView
102 } // namespace Details
103 } // namespace Tpetra
104 
105 #endif
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
Declaration of Tpetra::Details::isInterComm.
Get the contiguous layout that matches as many of the given views as possible. If neither or both arg...