lapacke_helpers.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2021 Erik Schultheis <erik.schultheis@aalto.fi>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_LAPACKE_HELPERS_H
11 #define EIGEN_LAPACKE_HELPERS_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 #ifdef EIGEN_USE_MKL
17 #include "mkl_lapacke.h"
18 #else
19 #include "lapacke.h"
20 #endif
21 
22 namespace Eigen {
23 namespace internal {
28 namespace lapacke_helpers {
29 
30 // ---------------------------------------------------------------------------------------------------------------------
31 // Translation from Eigen to Lapacke for types and constants
32 // ---------------------------------------------------------------------------------------------------------------------
33 
34 // For complex numbers, the types in Eigen and Lapacke are different, but layout compatible.
35 template <typename Scalar>
37 template <>
38 struct translate_type_imp<float> {
39  using type = float;
40 };
41 template <>
43  using type = double;
44 };
45 template <>
46 struct translate_type_imp<std::complex<double>> {
48 };
49 template <>
50 struct translate_type_imp<std::complex<float>> {
52 };
53 
55 template <typename Scalar>
57 
60 template <typename Source, typename Target = translated_type<Source>>
62  return static_cast<Target>(value);
63 }
64 
67 template <typename Source, typename Target = translated_type<Source>>
69  return reinterpret_cast<Target *>(value);
70 }
71 
74 EIGEN_ALWAYS_INLINE lapack_int to_lapack(Index index) { return convert_index<lapack_int>(index); }
75 
77 template <typename Derived>
79  return Derived::IsRowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR;
80 }
81 
82 // ---------------------------------------------------------------------------------------------------------------------
83 // Automatic generation of low-level wrappers
84 // ---------------------------------------------------------------------------------------------------------------------
85 
96 template <typename DoubleFn, typename SingleFn, typename DoubleCpxFn, typename SingleCpxFn>
98  // The naming of double, single, double complex and single complex is purely for readability
99  // and doesn't actually affect the workings of this class. In principle, the arguments can
100  // be supplied in any permuted order.
101  DoubleFn double_;
102  SingleFn single_;
103  DoubleCpxFn double_cpx_;
104  SingleCpxFn single_cpx_;
105 
106  template <typename... Args>
107  auto call(Args &&...args) -> decltype(double_(std::forward<Args>(args)...)) {
108  return double_(std::forward<Args>(args)...);
109  }
110 
111  template <typename... Args>
112  auto call(Args &&...args) -> decltype(single_(std::forward<Args>(args)...)) {
113  return single_(std::forward<Args>(args)...);
114  }
115 
116  template <typename... Args>
117  auto call(Args &&...args) -> decltype(double_cpx_(std::forward<Args>(args)...)) {
118  return double_cpx_(std::forward<Args>(args)...);
119  }
120 
121  template <typename... Args>
122  auto call(Args &&...args) -> decltype(single_cpx_(std::forward<Args>(args)...)) {
123  return single_cpx_(std::forward<Args>(args)...);
124  }
125 };
126 
131 template <typename DoubleFn, typename SingleFn, typename DoubleCpxFn, typename SingleCpxFn, typename... Args>
132 EIGEN_ALWAYS_INLINE auto call_wrapper(DoubleFn df, SingleFn sf, DoubleCpxFn dcf, SingleCpxFn scf, Args &&...args) {
134  return helper.call(std::forward<Args>(args)...);
135 }
136 
142 #define EIGEN_MAKE_LAPACKE_WRAPPER(FUNCTION) \
143  template <typename... Args> \
144  EIGEN_ALWAYS_INLINE auto FUNCTION(Args &&...args) { \
145  return call_wrapper(LAPACKE_d##FUNCTION, LAPACKE_s##FUNCTION, LAPACKE_z##FUNCTION, LAPACKE_c##FUNCTION, \
146  std::forward<Args>(args)...); \
147  }
148 
149 // Now with this macro and the helper wrappers, we can generate the dispatch for all the lapacke functions that are
150 // used in Eigen.
151 // We define these here instead of in the files where they are used because this allows us to #undef the macro again
152 // right here
157 
158 #undef EIGEN_MAKE_LAPACKE_WRAPPER
159 } // namespace lapacke_helpers
160 } // namespace internal
161 } // namespace Eigen
162 
163 #endif // EIGEN_LAPACKE_HELPERS_H
#define EIGEN_ALWAYS_INLINE
Definition: Macros.h:845
#define EIGEN_CONSTEXPR
Definition: Macros.h:758
Definition: Source.h:14
#define LAPACK_COL_MAJOR
Definition: lapacke.h:124
#define lapack_int
Definition: lapacke.h:52
#define LAPACK_ROW_MAJOR
Definition: lapacke.h:123
#define lapack_complex_double
Definition: lapacke.h:94
#define lapack_complex_float
Definition: lapacke.h:79
#define EIGEN_MAKE_LAPACKE_WRAPPER(FUNCTION)
Definition: lapacke_helpers.h:142
@ Target
Definition: Constants.h:495
EIGEN_ALWAYS_INLINE auto to_lapack(Source value)
Definition: lapacke_helpers.h:61
typename translate_type_imp< Scalar >::type translated_type
Given an Eigen types, this is defined to be the corresponding, layout-compatible lapack type.
Definition: lapacke_helpers.h:56
EIGEN_ALWAYS_INLINE EIGEN_CONSTEXPR lapack_int lapack_storage_of(const EigenBase< Derived > &)
translates storage order of the given Eigen object to the corresponding lapack constant
Definition: lapacke_helpers.h:78
EIGEN_ALWAYS_INLINE auto call_wrapper(DoubleFn df, SingleFn sf, DoubleCpxFn dcf, SingleCpxFn scf, Args &&...args)
Definition: lapacke_helpers.h:132
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
squared absolute value
Definition: GlobalFunctions.h:87
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
args
Definition: compute_granudrum_aor.py:143
Definition: Eigen_Colamd.h:49
Definition: EigenBase.h:33
Helper type to facilitate the wrapping of raw LAPACKE functions for different types into a single,...
Definition: lapacke_helpers.h:97
auto call(Args &&...args) -> decltype(double_(std::forward< Args >(args)...))
Definition: lapacke_helpers.h:107
DoubleCpxFn double_cpx_
Definition: lapacke_helpers.h:103
SingleFn single_
Definition: lapacke_helpers.h:102
DoubleFn double_
Definition: lapacke_helpers.h:101
auto call(Args &&...args) -> decltype(single_(std::forward< Args >(args)...))
Definition: lapacke_helpers.h:112
SingleCpxFn single_cpx_
Definition: lapacke_helpers.h:104
auto call(Args &&...args) -> decltype(double_cpx_(std::forward< Args >(args)...))
Definition: lapacke_helpers.h:117
auto call(Args &&...args) -> decltype(single_cpx_(std::forward< Args >(args)...))
Definition: lapacke_helpers.h:122
lapack_complex_double type
Definition: lapacke_helpers.h:47
lapack_complex_float type
Definition: lapacke_helpers.h:51
Definition: datatypes.h:12