Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
Loading...
Searching...
No Matches
lapacke_helpers.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2021 Erik Schultheis <[email protected]>
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
22namespace Eigen {
23namespace internal {
28namespace 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.
35template <typename Scalar>
36struct translate_type_imp;
37template <>
38struct translate_type_imp<float> {
39 using type = float;
40};
41template <>
42struct translate_type_imp<double> {
43 using type = double;
44};
45template <>
46struct translate_type_imp<std::complex<double>> {
47 using type = lapack_complex_double;
48};
49template <>
50struct translate_type_imp<std::complex<float>> {
51 using type = lapack_complex_float;
52};
53
55template <typename Scalar>
56using translated_type = typename translate_type_imp<Scalar>::type;
57
60template <typename Source, typename Target = translated_type<Source>>
61EIGEN_ALWAYS_INLINE auto to_lapack(Source value) {
62 return static_cast<Target>(value);
63}
64
67template <typename Source, typename Target = translated_type<Source>>
68EIGEN_ALWAYS_INLINE auto to_lapack(Source *value) {
69 return reinterpret_cast<Target *>(value);
70}
71
74EIGEN_ALWAYS_INLINE lapack_int to_lapack(Index index) { return convert_index<lapack_int>(index); }
75
77template <typename Derived>
78EIGEN_ALWAYS_INLINE EIGEN_CONSTEXPR lapack_int lapack_storage_of(const EigenBase<Derived> &) {
79 return Derived::IsRowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR;
80}
81
82// ---------------------------------------------------------------------------------------------------------------------
83// Automatic generation of low-level wrappers
84// ---------------------------------------------------------------------------------------------------------------------
85
96template <typename DoubleFn, typename SingleFn, typename DoubleCpxFn, typename SingleCpxFn>
97struct WrappingHelper {
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
131template <typename DoubleFn, typename SingleFn, typename DoubleCpxFn, typename SingleCpxFn, typename... Args>
132EIGEN_ALWAYS_INLINE auto call_wrapper(DoubleFn df, SingleFn sf, DoubleCpxFn dcf, SingleCpxFn scf, Args &&...args) {
133 WrappingHelper<DoubleFn, SingleFn, DoubleCpxFn, SingleCpxFn> helper{df, sf, dcf, scf};
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
153EIGEN_MAKE_LAPACKE_WRAPPER(potrf)
154EIGEN_MAKE_LAPACKE_WRAPPER(getrf)
155EIGEN_MAKE_LAPACKE_WRAPPER(geqrf)
156EIGEN_MAKE_LAPACKE_WRAPPER(gesdd)
157
158#undef EIGEN_MAKE_LAPACKE_WRAPPER
159} // namespace lapacke_helpers
160} // namespace internal
161} // namespace Eigen
162
163#endif // EIGEN_LAPACKE_HELPERS_H
Namespace containing all symbols from the Eigen library.
Definition Core:137