BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
lapacktools.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California, through
4 * Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
19
20#ifndef BELFEM_LAPACKTOOLS_HPP
21#define BELFEM_LAPACKTOOLS_HPP
22
23#include <algorithm>
24#include <complex>
25#include <limits>
26#include <type_traits>
27
28#include "typedefs.hpp"
29#include "assert.hpp"
30#include "cl_Matrix.hpp"
31
32#ifdef BELFEM_MKL
33#include <mkl_types.h>
34#endif
35
36#ifdef BELFEM_BLAZE
37#include <blaze/math/blas/Types.h>
38#endif
39
40
41namespace belfem
42{
43 namespace lapack
44 {
45//------------------------------------------------------------------------------
46
47 // helper for compile-time errors in unsupported template instantiations
48 template< typename T >
49 constexpr bool dependent_false = false ;
50
51//------------------------------------------------------------------------------
52
53 // underlying real type of a scalar: T for real T, T::value_type for
54 // std::complex< T >. LAPACK keeps some arrays real valued even in
55 // the complex flavors ( e.g. the singular values and rwork of gesvd )
56 template< typename T >
57 struct real_type { typedef T type ; };
58
59 template< typename T >
60 struct real_type< std::complex< T > > { typedef T type ; };
61
62 template< typename T >
63 using real_t = typename real_type< T >::type ;
64
65 // complementary complex type of a scalar: std::complex<T> for real
66 // T, T itself for std::complex<T> — e.g. the eigenvalues of geev
67 // are complex valued in all flavors
68 template< typename T >
69 struct cplx_type { typedef std::complex< T > type ; };
70
71 template< typename T >
72 struct cplx_type< std::complex< T > > { typedef std::complex< T > type ; };
73
74 template< typename T >
75 using cplx_t = typename cplx_type< T >::type ;
76
77//------------------------------------------------------------------------------
78
79 // complex datatype for the extern "C" prototypes: MKL declares its
80 // LAPACK interface with MKL_Complex8/16, everything else uses the
81 // Fortran real-pair convention ( two consecutive floats/doubles ).
82 // Under Blaze, Blaze's own clapack headers put real-pair prototypes
83 // into every TU ( mkl_cblas.h does not define INTEL_MKL_VERSION, so
84 // Blaze never suppresses them ) — the glue must match Blaze there,
85 // also when MKL is the linked library
86#if defined( BELFEM_MKL ) && ! defined( BELFEM_BLAZE )
87 typedef MKL_Complex8 cplx_float_t ;
88 typedef MKL_Complex16 cplx_double_t ;
89#else
90 typedef float cplx_float_t ;
91 typedef double cplx_double_t ;
92#endif
93
94 // hidden Fortran argument carrying the length of char* parameters
95 // ( gfortran/ifort append it after the regular argument list;
96 // Blaze declares it explicitly, so we must match )
97#ifdef BELFEM_BLAZE
98 typedef blaze::fortran_charlen_t fortran_charlen_t ;
99#else
100 typedef size_t fortran_charlen_t ;
101#endif
102
103 // std::complex is guaranteed layout-compatible ( C++11, [complex.numbers] )
104#if defined( BELFEM_MKL ) && ! defined( BELFEM_BLAZE )
105 static_assert( sizeof( std::complex< float > ) == sizeof( cplx_float_t ),
106 "sizes of std::complex< float > and MKL_Complex8 do not match" );
107
108 static_assert( sizeof( std::complex< double > ) == sizeof( cplx_double_t ),
109 "sizes of std::complex< double > and MKL_Complex16 do not match" );
110#else
111 static_assert( sizeof( std::complex< float > ) == 2UL * sizeof( cplx_float_t ),
112 "std::complex< float > is not layout-compatible with LAPACK" );
113
114 static_assert( sizeof( std::complex< double > ) == 2UL * sizeof( cplx_double_t ),
115 "std::complex< double > is not layout-compatible with LAPACK" );
116#endif
117
118 // SCLS builds all third-party libraries with one consistent integer
119 // width, so int_t is also the LAPACK integer. These checks back up
120 // that invariant.
121#ifdef BELFEM_BLAZE
122 static_assert( sizeof( int_t ) == sizeof( blaze::blas_int_t ),
123 "sizes of belfem::int_t and blaze::blas_int_t do not match" );
124#endif
125
126#if defined( BELFEM_MKL ) && ( defined( MKL_ILP64 ) != defined( BELFEM_INT64 ) )
127#error "MKL_ILP64 and BELFEM_INT64 must be set together, check USE_MKL_64BIT_API"
128#endif
129
130#ifdef BELFEM_MKL
131 static_assert( sizeof( int_t ) == sizeof( MKL_INT ),
132 "sizes of belfem::int_t and MKL_INT do not match" );
133#endif
134
135//------------------------------------------------------------------------------
136
141 template< typename T >
142 int_t
144 {
145 BELFEM_ASSERT( A.length() <= ( size_t ) std::numeric_limits< int_t >::max(),
146 "vector length exceeds LAPACK integer range ( %lu )",
147 ( long unsigned int ) A.length() );
148
149 return std::max< int_t >( 1, ( int_t ) A.length() );
150 }
151
152//------------------------------------------------------------------------------
153
163 template< typename T >
164 int_t
166 {
167#ifdef BELFEM_ARMADILLO
168 BELFEM_ASSERT( A.n_rows() <= ( size_t ) std::numeric_limits< int_t >::max(),
169 "matrix row count exceeds LAPACK integer range ( %lu )",
170 ( long unsigned int ) A.n_rows() );
171
172 return std::max< int_t >( 1, ( int_t ) A.n_rows() );
173#elif BELFEM_BLAZE
174 BELFEM_ASSERT( A.matrix_data().spacing() <= ( size_t ) std::numeric_limits< int_t >::max(),
175 "matrix column stride exceeds LAPACK integer range ( %lu )",
176 ( long unsigned int ) A.matrix_data().spacing() );
177
178 return std::max< int_t >( 1, ( int_t ) A.matrix_data().spacing() );
179#else
180#error "leading_dimension() : no matrix backend selected"
181#endif
182 }
183
184//------------------------------------------------------------------------------
185
190 inline int_t
191 work_size( const float & aValue )
192 {
193 return static_cast< int_t >( aValue );
194 }
195
196// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
197
198 inline int_t
199 work_size( const double & aValue )
200 {
201 return static_cast< int_t >( aValue );
202 }
203
204// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
205
206 inline int_t
207 work_size( const std::complex< float > & aValue )
208 {
209 return static_cast< int_t >( aValue.real() );
210 }
211
212// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
213
214 inline int_t
215 work_size( const std::complex< double > & aValue )
216 {
217 return static_cast< int_t >( aValue.real() );
218 }
219
220//------------------------------------------------------------------------------
221 }
222}
223#endif //BELFEM_LAPACKTOOLS_HPP
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
Dense column-major matrix.
Definition cl_BZ_Matrix.hpp:28
MatrixType & matrix_data()
Definition cl_AR_Matrix.hpp:157
size_t n_rows() const
Definition cl_AR_Matrix.hpp:205
Column vector.
Definition cl_BZ_Vector.hpp:41
size_t length() const
get the length of the vector
Definition cl_AR_Vector.hpp:257
Definition fn_gees.hpp:33
constexpr bool dependent_false
Definition lapacktools.hpp:49
float cplx_float_t
Definition lapacktools.hpp:90
int_t leading_dimension(const Vector< T > &A)
logical length of a vector operand, as passed to LAPACK as LDB; vector storage is contiguous under bo...
Definition lapacktools.hpp:143
int_t work_size(const float &aValue)
lapack reports the optimal work size in the first entry of the work array, which stays real valued fo...
Definition lapacktools.hpp:191
size_t fortran_charlen_t
Definition lapacktools.hpp:100
double cplx_double_t
Definition lapacktools.hpp:91
typename real_type< T >::type real_t
Definition lapacktools.hpp:63
typename cplx_type< T >::type cplx_t
Definition lapacktools.hpp:75
USER GUIDES:
Definition cl_Capacitor.cpp:16
int32_t int_t
Definition typedefs.hpp:51
std::complex< T > type
Definition lapacktools.hpp:72
Definition lapacktools.hpp:69
std::complex< T > type
Definition lapacktools.hpp:69
T type
Definition lapacktools.hpp:60
Definition lapacktools.hpp:57
T type
Definition lapacktools.hpp:57