Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Kokkos_ViewFactory.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef KOKKOS_VIEW_FACTORY_HPP
11 #define KOKKOS_VIEW_FACTORY_HPP
12 
13 #include <type_traits>
14 
15 #include "Sacado_Traits.hpp"
16 #include "KokkosExp_View_Fad.hpp"
18 
19 namespace Kokkos {
20 
21 namespace Impl {
22 
23 // Class to determine the value_type for a view as a function of one or more
24 // input views
25 template <class ... ViewPack>
26 struct ViewFactoryType {};
27 
28 template <class View>
30  typedef typename View::value_type type;
31 };
32 
33 template <class View, class ... ViewPack>
34 struct ViewFactoryType<View,ViewPack...> {
35  typedef typename Sacado::Promote<
36  typename View::value_type,
37  typename ViewFactoryType<ViewPack...>::type
39 };
40 
41 }
42 
43 // Function to compute the scalar dimension (e.g., Fad dimesion) from one or
44 // more views. It relies on the overload for a single view provided by Sacado
45 
46 // Traits class used to create a view for a given rank and dimension as a
47 // function of one or more views. The value_type for the view is determined
48 // by value_type, and the view is created through the create_view() function.
49 // The calling code must determine the rank and dimensions of the view to create
50 // however internal Sacado dimension will be determined automatically.
51 template <class ... ViewPack>
52 struct ViewFactory {
53 
54  typedef typename Impl::ViewFactoryType<ViewPack...>::type value_type;
55 
56  template<class T>
57  struct IsCtorProp : std::false_type{};
58  template<class ... Args>
59  struct IsCtorProp<Kokkos::Impl::ViewCtorProp<Args...>> : std::true_type{};
60 
61  template <class ResultView, class CtorProp, class ... Dims>
62  static ResultView
63  create_view(const ViewPack& ... views,
64  const CtorProp& prop,
65  const Dims ... dims) {
66 
67  using nc_value_type = typename ResultView::non_const_value_type;
68  constexpr bool is_scalar = Sacado::IsScalarType<nc_value_type>::value;
69  constexpr bool is_dyn_rank = is_dyn_rank_view<ResultView>::value;
70 
71  // rank == number of arguments
72  constexpr unsigned rank = sizeof...(Dims);
73 
74  // Check rank is valid
75  static_assert( rank <= 7, "Invalid rank...too many dimension arguments" );
76 
77  // Create layout from our dimension arguments
78  typename ResultView::array_layout layout(dims...);
79 
80  // Set scalar dimension
81  layout.dimension[rank] = dimension_scalar(views...);
82 
83  // Handle the case where all of the input view's are scalar's, but the
84  // result isn't (e.g., a Fad), in which case we have to specify a valid
85  // scalar dimension
86  if (!is_scalar && layout.dimension[rank] == 0)
87  layout.dimension[rank] = 1;
88 
89  // Reconstruct layout for dynamic rank
90  if (is_dyn_rank) {
91  constexpr unsigned r = is_scalar ? rank : rank + 1;
92  layout = Impl::reconstructLayout(layout, r);
93  }
94 
95 #ifdef SACADO_HAS_NEW_KOKKOS_VIEW_IMPL
96  if constexpr (is_view_fad<ResultView>::value) {
97  size_t fad_size = dimension_scalar(views...);
98  if (fad_size == 0) fad_size = 1;
99  if (!is_scalar) layout.dimension[rank] = is_dyn_rank ? KOKKOS_INVALID_INDEX : KOKKOS_IMPL_CTOR_DEFAULT_ARG;
100  // turns out CtorProp can be just a pointer or a label...
101  if constexpr (IsCtorProp<CtorProp>::value) {
102  return ResultView(Kokkos::Impl::with_properties_if_unset(prop, Kokkos::Impl::AccessorArg_t{fad_size}), layout);
103  } else {
104  if constexpr (std::is_pointer_v<CtorProp> && !std::is_convertible_v<CtorProp, const char*>) {
105  return ResultView(Kokkos::view_wrap(prop, Kokkos::Impl::AccessorArg_t{fad_size}), layout);
106  } else {
107  return ResultView(Kokkos::view_alloc(prop, Kokkos::Impl::AccessorArg_t{fad_size}), layout);
108  }
109  }
110  } else {
111  return ResultView(prop, layout);
112  }
113 #else
114  return ResultView(prop, layout);
115 #endif
116  }
117 
118 };
119 
121 template <typename ResultViewType, typename InputViewType, typename CtorProp,
122  typename ... Dims>
123 typename std::enable_if<
125  ResultViewType>::type
126 createDynRankViewWithType(const InputViewType& a,
127  const CtorProp& prop,
128  const Dims... dims)
129 {
130  using view_factory = Kokkos::ViewFactory<InputViewType>;
131  return view_factory::template create_view<ResultViewType>(a,prop,dims...);
132 }
133 
134 namespace Impl {
135  // Helper type trait to determine type of resulting DynRankView from
136  // createDynRankView below
137  template <typename InputView>
139  // Allow for use of LayoutStride in InputViewType. We don't want to create
140  // a new view with LayoutStride, so replace it with the default layout
141  // instead.
142  using input_value = typename InputView::non_const_value_type;
143  using input_layout = typename InputView::array_layout;
144  using input_device = typename InputView::device_type;
145  using default_layout = typename input_device::execution_space::array_layout;
146  using result_layout =
147  typename std::conditional<
151  using type =
152  Kokkos::DynRankView<input_value, result_layout, input_device>;
153  };
154 
155 }
156 
158 template <typename InputViewType, typename CtorProp, typename ... Dims >
159 typename std::enable_if<
162  >::type
163 createDynRankView(const InputViewType& a,
164  const CtorProp& prop,
165  const Dims... dims)
166 {
167  using ResultViewType = typename Impl::ResultDynRankView<InputViewType>::type;
168  return createDynRankViewWithType<ResultViewType>(a, prop, dims...);
169 }
170 
172 template <typename ResultViewType, typename InputViewType, typename CtorProp,
173  typename ... Dims>
174 typename std::enable_if<
176  ResultViewType>::type
177 createViewWithType(const InputViewType& a,
178  const CtorProp& prop,
179  const Dims... dims)
180 {
181  using view_factory = Kokkos::ViewFactory<InputViewType>;
182  return view_factory::template create_view<ResultViewType>(a,prop,dims...);
183 }
184 
185 }
186 
187 #endif /* #ifndef KOKKOS_VIEW_FACTORY_HPP */
typename InputView::device_type input_device
std::enable_if< is_view< InputViewType >::value||is_dyn_rank_view< InputViewType >::value, typename Impl::ResultDynRankView< InputViewType >::type >::type createDynRankView(const InputViewType &a, const CtorProp &prop, const Dims...dims)
Wrapper to simplify use of Sacado ViewFactory.
typename std::conditional< std::is_same< input_layout, Kokkos::LayoutStride >::value, default_layout, input_layout >::type result_layout
Impl::ViewFactoryType< ViewPack...>::type value_type
typename input_device::execution_space::array_layout default_layout
Sacado::Promote< typename View::value_type, typename ViewFactoryType< ViewPack...>::type >::type type
std::enable_if< is_view< InputViewType >::value||is_dyn_rank_view< InputViewType >::value, ResultViewType >::type createDynRankViewWithType(const InputViewType &a, const CtorProp &prop, const Dims...dims)
Wrapper to simplify use of Sacado ViewFactory.
int value
Kokkos::DynRankView< input_value, result_layout, input_device > type
typename InputView::array_layout input_layout
std::enable_if< is_view< InputViewType >::value||is_dyn_rank_view< InputViewType >::value, ResultViewType >::type createViewWithType(const InputViewType &a, const CtorProp &prop, const Dims...dims)
Wrapper to simplify use of Sacado ViewFactory.
static ResultView create_view(const ViewPack &...views, const CtorProp &prop, const Dims...dims)
typename InputView::non_const_value_type input_value
Base template specification for IsScalarType.
Base template specification for Promote.