Tpetra parallel linear algebra  Version of the Day
Tpetra_Details_Blas.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) 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 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_DETAILS_BLAS_HPP
43 #define TPETRA_DETAILS_BLAS_HPP
44 
52 
53 #include "TpetraCore_config.h"
54 #include "Kokkos_Core.hpp"
55 #include "Kokkos_Complex.hpp"
56 #include <type_traits>
57 
58 namespace Tpetra {
59 namespace Details {
60 namespace Blas {
61 
67 template<class ScalarType>
69  static constexpr bool value =
70  std::is_same<ScalarType, float>::value ||
71  std::is_same<ScalarType, double>::value ||
72  std::is_same<ScalarType, ::Kokkos::complex<float> >::value ||
73  std::is_same<ScalarType, ::Kokkos::complex<double> >::value;
74 };
75 
81 template<class LayoutType>
83  static constexpr bool value =
84  std::is_same<LayoutType, ::Kokkos::LayoutLeft>::value;
85 };
86 
88 template<class ViewType,
89  class IndexType = int>
90 IndexType
91 getStride2DView (const ViewType& A)
92 {
93  static_assert (ViewType::Rank == 2, "A must be a rank-2 Kokkos::View.");
94  static_assert (std::is_same<typename ViewType::array_layout, Kokkos::LayoutLeft>::value ||
95  std::is_same<typename ViewType::array_layout, Kokkos::LayoutRight>::value ||
96  std::is_same<typename ViewType::array_layout, Kokkos::LayoutStride>::value,
97  "A's layout must be either LayoutLeft, LayoutRight, or LayoutStride.");
98  static_assert (std::is_integral<IndexType>::value,
99  "IndexType must be a built-in integer type.");
100  IndexType stride[8];
101  A.stride (stride);
102  // BLAS implementations do not like zero LDA, even if (e.g.,) the
103  // number of rows is actually zero. See e.g., GitHub Issue #3235.
104  const auto LDA = (A.extent (1) > 1) ? stride[1] : A.extent (0);
105  return LDA == 0 ? IndexType (1) : LDA;
106 }
107 
108 namespace Impl {
109 
110 template<class ViewType,
111  class ArrayLayout,
112  class IndexType>
113 struct GetStride1DView {
114  typedef ArrayLayout array_layout;
115 
116  static IndexType getStride (const ViewType& x)
117  {
118  static_assert (ViewType::Rank == 1, "x must be a rank-1 Kokkos::View.");
119  static_assert (std::is_same<typename ViewType::array_layout, Kokkos::LayoutLeft>::value ||
120  std::is_same<typename ViewType::array_layout, Kokkos::LayoutRight>::value ||
121  std::is_same<typename ViewType::array_layout, Kokkos::LayoutStride>::value,
122  "x's layout must be either LayoutLeft, LayoutRight, or LayoutStride.");
123  static_assert (std::is_same<typename ViewType::array_layout, array_layout>::value,
124  "ViewType::array_layout must be the same as array_layout.");
125  static_assert (std::is_integral<IndexType>::value,
126  "IndexType must be a built-in integer type.");
127  IndexType stride[8];
128  x.stride (stride);
129  return stride[0];
130  }
131 };
132 
133 template<class ViewType,
134  class IndexType>
135 struct GetStride1DView<ViewType, Kokkos::LayoutLeft, IndexType> {
136  typedef Kokkos::LayoutLeft array_layout;
137 
138  static IndexType getStride (const ViewType&)
139  {
140  static_assert (ViewType::Rank == 1, "x must be a rank-1 Kokkos::View.");
141  static_assert (std::is_same<typename ViewType::array_layout, array_layout>::value,
142  "ViewType::array_layout must be the same as array_layout.");
143  static_assert (std::is_integral<IndexType>::value,
144  "IndexType must be a built-in integer type.");
145  return static_cast<IndexType> (1);
146  }
147 };
148 
149 template<class ViewType,
150  class IndexType>
151 struct GetStride1DView<ViewType, Kokkos::LayoutRight, IndexType> {
152  typedef Kokkos::LayoutRight array_layout;
153 
154  static IndexType getStride (const ViewType&)
155  {
156  static_assert (ViewType::Rank == 1, "x must be a rank-1 Kokkos::View.");
157  static_assert (std::is_same<typename ViewType::array_layout, array_layout>::value,
158  "ViewType::array_layout must be the same as array_layout.");
159  static_assert (std::is_integral<IndexType>::value,
160  "IndexType must be a built-in integer type.");
161  return static_cast<IndexType> (1);
162  }
163 };
164 
165 } // namespace Impl
166 
168 template<class ViewType,
169  class IndexType = int>
170 IndexType
171 getStride1DView (const ViewType& x)
172 {
173  typedef Impl::GetStride1DView<ViewType, typename ViewType::array_layout, IndexType> impl_type;
174  return impl_type::getStride (x);
175 }
176 
177 } // namespace Blas
178 } // namespace Details
179 } // namespace Tpetra
180 
181 #endif // TPETRA_DETAILS_BLAS_HPP
IndexType getStride1DView(const ViewType &x)
Get the stride ("INCX" in BLAS terms) of the 1-D Kokkos::View x.
IndexType getStride2DView(const ViewType &A)
Get the stride (leading dimension) of the 2-D Kokkos::View A.
Implementation details of Tpetra.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Do BLAS libraries (all that are compliant with the BLAS Standard) support the given Kokkos array layo...
Do BLAS libraries (all that are compliant with the BLAS Standard) support the given "scalar" (matrix ...