Sacado Package Browser (Single Doxygen Collection)  Version of the Day
Kokkos_ViewFactory.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 // @HEADER
29 
30 #ifndef KOKKOS_VIEW_FACTORY_HPP
31 #define KOKKOS_VIEW_FACTORY_HPP
32 
33 #include <type_traits>
34 
35 #include "Sacado_Traits.hpp"
36 #include "KokkosExp_View_Fad.hpp"
38 
39 namespace Kokkos {
40 
41 namespace Impl {
42 
43 // Class to determine the value_type for a view as a function of one or more
44 // input views
45 template <class ... ViewPack>
46 struct ViewFactoryType {};
47 
48 template <class View>
49 struct ViewFactoryType<View> {
50  typedef typename View::value_type type;
51 };
52 
53 template <class View, class ... ViewPack>
54 struct ViewFactoryType<View,ViewPack...> {
55  typedef typename Sacado::Promote<
56  typename View::value_type,
57  typename ViewFactoryType<ViewPack...>::type
59 };
60 
61 }
62 
63 // Function to compute the scalar dimension (e.g., Fad dimesion) from one or
64 // more views. It relies on the overload for a single view provided by Sacado
65 template <class View, class ... ViewPack>
66 unsigned dimension_scalar(const View& v, const ViewPack&... views) {
67  const unsigned dim0 = dimension_scalar(v);
68  const unsigned dim1 = dimension_scalar(views...);
69  return dim0 >= dim1 ? dim0 : dim1 ;
70 }
71 
72 // Traits class used to create a view for a given rank and dimension as a
73 // function of one or more views. The value_type for the view is determined
74 // by value_type, and the view is created through the create_view() function.
75 // The calling code must determine the rank and dimensions of the view to create
76 // however internal Sacado dimension will be determined automatically.
77 template <class ... ViewPack>
78 struct ViewFactory {
79 
80  typedef typename Impl::ViewFactoryType<ViewPack...>::type value_type;
81 
82  template <class ResultView, class CtorProp, class ... Dims>
83  static ResultView
84  create_view(const ViewPack& ... views,
85  const CtorProp& prop,
86  const Dims ... dims) {
87 
88  using value_type = typename ResultView::non_const_value_type;
89  constexpr bool is_scalar = Sacado::IsScalarType<value_type>::value;
90  constexpr bool is_dyn_rank = is_dyn_rank_view<ResultView>::value;
91 
92  // rank == number of arguments
93  constexpr unsigned rank = sizeof...(Dims);
94 
95  // Check rank is valid
96  static_assert( rank <= 7, "Invalid rank...too many dimension arguments" );
97 
98  // Create layout from our dimension arguments
99  typename ResultView::array_layout layout(dims...);
100 
101  // Set scalar dimension
102  layout.dimension[rank] = dimension_scalar(views...);
103 
104  // Handle the case where all of the input view's are scalar's, but the
105  // result isn't (e.g., a Fad), in which case we have to specify a valid
106  // scalar dimension
107  if (!is_scalar && layout.dimension[rank] == 0)
108  layout.dimension[rank] = 1;
109 
110  // Reconstruct layout for dynamic rank
111  if (is_dyn_rank) {
112  constexpr unsigned r = is_scalar ? rank : rank + 1;
113  layout = Experimental::Impl::reconstructLayout(layout, r);
114  }
115 
116  return ResultView(prop, layout);
117  }
118 
119 };
120 
122 template <typename ResultViewType, typename InputViewType, typename CtorProp,
123  typename ... Dims>
124 typename std::enable_if<
125  is_view<InputViewType>::value || is_dyn_rank_view<InputViewType>::value,
126  ResultViewType>::type
127 createDynRankViewWithType(const InputViewType& a,
128  const CtorProp& prop,
129  const Dims... dims)
130 {
131  using view_factory = Kokkos::ViewFactory<InputViewType>;
132  return view_factory::template create_view<ResultViewType>(a,prop,dims...);
133 }
134 
135 namespace Impl {
136  // Helper type trait to determine type of resulting DynRankView from
137  // createDynRankView below
138  template <typename InputView>
140  // Allow for use of LayoutStride in InputViewType. We don't want to create
141  // a new view with LayoutStride, so replace it with the default layout
142  // instead.
143  using input_value = typename InputView::non_const_value_type;
144  using input_layout = typename InputView::array_layout;
145  using input_device = typename InputView::device_type;
146  using default_layout = typename input_device::execution_space::array_layout;
147  using result_layout =
148  typename std::conditional<
149  std::is_same< input_layout, Kokkos::LayoutStride >::value,
152  using type =
153  Kokkos::DynRankView<input_value, result_layout, input_device>;
154  };
155 
156 }
157 
159 template <typename InputViewType, typename CtorProp, typename ... Dims >
160 typename std::enable_if<
161  is_view<InputViewType>::value || is_dyn_rank_view<InputViewType>::value,
163  >::type
164 createDynRankView(const InputViewType& a,
165  const CtorProp& prop,
166  const Dims... dims)
167 {
168  using ResultViewType = typename Impl::ResultDynRankView<InputViewType>::type;
169  return createDynRankViewWithType<ResultViewType>(a, prop, dims...);
170 }
171 
173 template <typename ResultViewType, typename InputViewType, typename CtorProp,
174  typename ... Dims>
175 typename std::enable_if<
176  is_view<InputViewType>::value || is_dyn_rank_view<InputViewType>::value,
177  ResultViewType>::type
178 createViewWithType(const InputViewType& a,
179  const CtorProp& prop,
180  const Dims... dims)
181 {
182  using view_factory = Kokkos::ViewFactory<InputViewType>;
183  return view_factory::template create_view<ResultViewType>(a,prop,dims...);
184 }
185 
186 }
187 
188 #endif /* #ifndef KOKKOS_VIEW_FACTORY_HPP */
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.
typename InputView::device_type input_device
typename std::conditional< std::is_same< input_layout, Kokkos::LayoutStride >::value, default_layout, input_layout >::type result_layout
Impl::ViewFactoryType< ViewPack... >::type value_type
static ResultView create_view(const ViewPack &... views, const CtorProp &prop, const Dims ... dims)
typename input_device::execution_space::array_layout default_layout
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.
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.
Kokkos::DynRankView< input_value, result_layout, input_device > type
typename InputView::array_layout input_layout
typename InputView::non_const_value_type input_value
Base template specification for IsScalarType.
unsigned dimension_scalar(const View &v, const ViewPack &... views)
Base template specification for Promote.