1 //=================================================================================================
2 /*!
3 //  \file blaze/math/lapack/clapack/getrs.h
4 //  \brief Header file for the CLAPACK getrs wrapper functions
5 //
6 //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 //  This file is part of the Blaze library. You can redistribute it and/or modify it under
9 //  the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 //  forms, with or without modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //  1. Redistributions of source code must retain the above copyright notice, this list of
14 //     conditions and the following disclaimer.
15 //  2. Redistributions in binary form must reproduce the above copyright notice, this list
16 //     of conditions and the following disclaimer in the documentation and/or other materials
17 //     provided with the distribution.
18 //  3. Neither the names of the Blaze development group nor the names of its contributors
19 //     may be used to endorse or promote products derived from this software without specific
20 //     prior written permission.
21 //
22 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 //  DAMAGE.
32 */
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_LAPACK_CLAPACK_GETRS_H_
36 #define _BLAZE_MATH_LAPACK_CLAPACK_GETRS_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/blas/Types.h>
44 #include <blaze/util/Complex.h>
45 #include <blaze/util/StaticAssert.h>
46 #include <blaze/util/Types.h>
47 
48 
49 //=================================================================================================
50 //
51 //  LAPACK FORWARD DECLARATIONS
52 //
53 //=================================================================================================
54 
55 //*************************************************************************************************
56 /*! \cond BLAZE_INTERNAL */
57 #if !defined(INTEL_MKL_VERSION) && !defined(BLAS_H)
58 extern "C" {
59 
60 void sgetrs_( char* trans, blaze::blas_int_t* n, blaze::blas_int_t* nrhs, float* A,
61               blaze::blas_int_t* lda, blaze::blas_int_t* ipiv, float* B, blaze::blas_int_t* ldb,
62               blaze::blas_int_t* info, blaze::fortran_charlen_t ntrans );
63 void dgetrs_( char* trans, blaze::blas_int_t* n, blaze::blas_int_t* nrhs, double* A,
64               blaze::blas_int_t* lda, blaze::blas_int_t* ipiv, double* B, blaze::blas_int_t* ldb,
65               blaze::blas_int_t* info, blaze::fortran_charlen_t ntrans );
66 void cgetrs_( char* trans, blaze::blas_int_t* n, blaze::blas_int_t* nrhs, float* A,
67               blaze::blas_int_t* lda, blaze::blas_int_t* ipiv, float* B, blaze::blas_int_t* ldb,
68               blaze::blas_int_t* info, blaze::fortran_charlen_t ntrans );
69 void zgetrs_( char* trans, blaze::blas_int_t* n, blaze::blas_int_t* nrhs, double* A,
70               blaze::blas_int_t* lda, blaze::blas_int_t* ipiv, double* B, blaze::blas_int_t* ldb,
71               blaze::blas_int_t* info, blaze::fortran_charlen_t ntrans );
72 
73 }
74 #endif
75 /*! \endcond */
76 //*************************************************************************************************
77 
78 
79 
80 
81 namespace blaze {
82 
83 //=================================================================================================
84 //
85 //  LAPACK LU-BASED SUBSTITUTION FUNCTIONS (GETRS)
86 //
87 //=================================================================================================
88 
89 //*************************************************************************************************
90 /*!\name LAPACK LU-based substitution functions (getrs) */
91 //@{
92 void getrs( char trans, blas_int_t n, blas_int_t nrhs, const float* A,
93             blas_int_t lda, const blas_int_t* ipiv, float* B,
94             blas_int_t ldb, blas_int_t* info );
95 
96 void getrs( char trans, blas_int_t n, blas_int_t nrhs, const double* A,
97             blas_int_t lda, const blas_int_t* ipiv, double* B,
98             blas_int_t ldb, blas_int_t* info );
99 
100 void getrs( char trans, blas_int_t n, blas_int_t nrhs, const complex<float>* A,
101             blas_int_t lda, const blas_int_t* ipiv, complex<float>* B,
102             blas_int_t ldb, blas_int_t* info );
103 
104 void getrs( char trans, blas_int_t n, blas_int_t nrhs, const complex<double>* A,
105             blas_int_t lda, const blas_int_t* ipiv, complex<double>* B,
106             blas_int_t ldb, blas_int_t* info );
107 //@}
108 //*************************************************************************************************
109 
110 
111 //*************************************************************************************************
112 /*!\brief LAPACK kernel for the substitution step of solving a general single precision linear
113 //        system of equations (\f$ A*X=B \f$).
114 // \ingroup lapack_substitution
115 //
116 // \param trans \c 'N' for \f$ A*X=B \f$, \c 'T' for \f$ A^T*X=B \f$, and \c C for \f$ A^H*X=B \f$.
117 // \param n The number of rows/columns of the column-major matrix \f$[0..\infty)\f$.
118 // \param nrhs The number of right-hand side vectors \f$[0..\infty)\f$.
119 // \param A Pointer to the first element of the single precision column-major square matrix.
120 // \param lda The total number of elements between two columns of the matrix \f$[0..\infty)\f$.
121 // \param ipiv Auxiliary array of size \a n for the pivot indices.
122 // \param B Pointer to the first element of the column-major matrix.
123 // \param ldb The total number of elements between two columns of matrix \a B \f$[0..\infty)\f$.
124 // \param info Return code of the function call.
125 // \return void
126 //
127 // This function uses the LAPACK sgetrs() function to perform the substitution step to compute
128 // the solution to the general system of linear equations \f$ A*X=B \f$, \f$ A^{T}*X=B \f$, or
129 // \f$ A^{H}*X=B \f$, where \a A is a \a n-by-\a n matrix that has already been factorized by the
130 // sgetrf() function and \a X and \a B are column-major \a n-by-\a nrhs matrices. The \a trans
131 // argument specifies the form of the linear system of equations:
132 //
133 //   - 'N': \f$ A*X=B \f$ (no transpose)
134 //   - 'T': \f$ A^{T}*X=B \f$ (transpose)
135 //   - 'C': \f$ A^{H}*X=B \f$ (conjugate transpose)
136 //
137 // The \a info argument provides feedback on the success of the function call:
138 //
139 //   - = 0: The function finished successfully.
140 //   - < 0: If info = -i, the i-th argument had an illegal value.
141 //
142 // For more information on the sgetrs() function, see the LAPACK online documentation browser:
143 //
144 //        http://www.netlib.org/lapack/explore-html/
145 //
146 // \note This function can only be used if a fitting LAPACK library, which supports this function,
147 // is available and linked to the executable. Otherwise a call to this function will result in a
148 // linker error.
149 */
getrs(char trans,blas_int_t n,blas_int_t nrhs,const float * A,blas_int_t lda,const blas_int_t * ipiv,float * B,blas_int_t ldb,blas_int_t * info)150 inline void getrs( char trans, blas_int_t n, blas_int_t nrhs, const float* A,
151                    blas_int_t lda, const blas_int_t* ipiv, float* B,
152                    blas_int_t ldb, blas_int_t* info )
153 {
154 #if defined(INTEL_MKL_VERSION)
155    BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
156 #endif
157 
158    sgetrs_( &trans, &n, &nrhs, const_cast<float*>( A ), &lda,
159             const_cast<blas_int_t*>( ipiv ), B, &ldb, info
160 #if !defined(INTEL_MKL_VERSION) && !defined(BLAS_H)
161           , blaze::fortran_charlen_t(1)
162 #endif
163           );
164 }
165 //*************************************************************************************************
166 
167 
168 //*************************************************************************************************
169 /*!\brief LAPACK kernel for the substitution step of solving a general double precision linear
170 //        system of equations (\f$ A*X=B \f$).
171 // \ingroup lapack_substitution
172 //
173 // \param trans \c 'N' for \f$ A*X=B \f$, \c 'T' for \f$ A^T*X=B \f$, and \c C for \f$ A^H*X=B \f$.
174 // \param n The number of rows/columns of the column-major matrix \f$[0..\infty)\f$.
175 // \param nrhs The number of right-hand side vectors \f$[0..\infty)\f$.
176 // \param A Pointer to the first element of the double precision column-major square matrix.
177 // \param lda The total number of elements between two columns of the matrix \f$[0..\infty)\f$.
178 // \param ipiv Auxiliary array of size \a n for the pivot indices.
179 // \param B Pointer to the first element of the column-major matrix.
180 // \param ldb The total number of elements between two columns of matrix \a B \f$[0..\infty)\f$.
181 // \param info Return code of the function call.
182 // \return void
183 //
184 // This function uses the LAPACK dgetrs() function to perform the substitution step to compute
185 // the solution to the general system of linear equations \f$ A*X=B \f$, \f$ A^{T}*X=B \f$, or
186 // \f$ A^{H}*X=B \f$, where \a A is a \a n-by-\a n matrix that has already been factorized by the
187 // dgetrf() function and \a X and \a B are column-major \a n-by-\a nrhs matrices. The \a trans
188 // argument specifies the form of the linear system of equations:
189 //
190 //   - 'N': \f$ A*X=B \f$ (no transpose)
191 //   - 'T': \f$ A^{T}*X=B \f$ (transpose)
192 //   - 'C': \f$ A^{H}*X=B \f$ (conjugate transpose)
193 //
194 // The \a info argument provides feedback on the success of the function call:
195 //
196 //   - = 0: The function finished successfully.
197 //   - < 0: If info = -i, the i-th argument had an illegal value.
198 //
199 // For more information on the dgetrs() function, see the LAPACK online documentation browser:
200 //
201 //        http://www.netlib.org/lapack/explore-html/
202 //
203 // \note This function can only be used if a fitting LAPACK library, which supports this function,
204 // is available and linked to the executable. Otherwise a call to this function will result in a
205 // linker error.
206 */
getrs(char trans,blas_int_t n,blas_int_t nrhs,const double * A,blas_int_t lda,const blas_int_t * ipiv,double * B,blas_int_t ldb,blas_int_t * info)207 inline void getrs( char trans, blas_int_t n, blas_int_t nrhs, const double* A,
208                    blas_int_t lda, const blas_int_t* ipiv, double* B,
209                    blas_int_t ldb, blas_int_t* info )
210 {
211 #if defined(INTEL_MKL_VERSION)
212    BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
213 #endif
214 
215    dgetrs_( &trans, &n, &nrhs, const_cast<double*>( A ), &lda,
216             const_cast<blas_int_t*>( ipiv ), B, &ldb, info
217 #if !defined(INTEL_MKL_VERSION) && !defined(BLAS_H)
218           , blaze::fortran_charlen_t(1)
219 #endif
220           );
221 }
222 //*************************************************************************************************
223 
224 
225 //*************************************************************************************************
226 /*!\brief LAPACK kernel for the substitution step of solving a general single precision complex
227 //        linear system of equations (\f$ A*X=B \f$).
228 // \ingroup lapack_substitution
229 //
230 // \param trans \c 'N' for \f$ A*X=B \f$, \c 'T' for \f$ A^T*X=B \f$, and \c C for \f$ A^H*X=B \f$.
231 // \param n The number of rows/columns of the column-major matrix \f$[0..\infty)\f$.
232 // \param nrhs The number of right-hand side vectors \f$[0..\infty)\f$.
233 // \param A Pointer to the first element of the single precision complex column-major square matrix.
234 // \param lda The total number of elements between two columns of the matrix \f$[0..\infty)\f$.
235 // \param ipiv Auxiliary array of size \a n for the pivot indices.
236 // \param B Pointer to the first element of the column-major matrix.
237 // \param ldb The total number of elements between two columns of matrix \a B \f$[0..\infty)\f$.
238 // \param info Return code of the function call.
239 // \return void
240 //
241 // This function uses the LAPACK cgetrs() function to perform the substitution step to compute
242 // the solution to the general system of linear equations \f$ A*X=B \f$, \f$ A^{T}*X=B \f$, or
243 // \f$ A^{H}*X=B \f$, where \a A is a \a n-by-\a n matrix that has already been factorized by the
244 // cgetrf() function and \a X and \a B are column-major \a n-by-\a nrhs matrices. The \a trans
245 // argument specifies the form of the linear system of equations:
246 //
247 //   - 'N': \f$ A*X=B \f$ (no transpose)
248 //   - 'T': \f$ A^{T}*X=B \f$ (transpose)
249 //   - 'C': \f$ A^{H}*X=B \f$ (conjugate transpose)
250 //
251 // The \a info argument provides feedback on the success of the function call:
252 //
253 //   - = 0: The function finished successfully.
254 //   - < 0: If info = -i, the i-th argument had an illegal value.
255 //
256 // For more information on the cgetrs() function, see the LAPACK online documentation browser:
257 //
258 //        http://www.netlib.org/lapack/explore-html/
259 //
260 // \note This function can only be used if a fitting LAPACK library, which supports this function,
261 // is available and linked to the executable. Otherwise a call to this function will result in a
262 // linker error.
263 */
getrs(char trans,blas_int_t n,blas_int_t nrhs,const complex<float> * A,blas_int_t lda,const blas_int_t * ipiv,complex<float> * B,blas_int_t ldb,blas_int_t * info)264 inline void getrs( char trans, blas_int_t n, blas_int_t nrhs, const complex<float>* A,
265                    blas_int_t lda, const blas_int_t* ipiv, complex<float>* B,
266                    blas_int_t ldb, blas_int_t* info )
267 {
268    BLAZE_STATIC_ASSERT( sizeof( complex<float> ) == 2UL*sizeof( float ) );
269 
270 #if defined(INTEL_MKL_VERSION)
271    BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
272    BLAZE_STATIC_ASSERT( sizeof( MKL_Complex8 ) == sizeof( complex<float> ) );
273    using ET = MKL_Complex8;
274 #else
275    using ET = float;
276 #endif
277 
278    cgetrs_( &trans, &n, &nrhs, const_cast<ET*>( reinterpret_cast<const ET*>( A ) ),
279             &lda, const_cast<blas_int_t*>( ipiv ), reinterpret_cast<ET*>( B ), &ldb, info
280 #if !defined(INTEL_MKL_VERSION) && !defined(BLAS_H)
281           , blaze::fortran_charlen_t(1)
282 #endif
283           );
284 }
285 //*************************************************************************************************
286 
287 
288 //*************************************************************************************************
289 /*!\brief LAPACK kernel for the substitution step of solving a general double precision complex
290 //        linear system of equations (\f$ A*X=B \f$).
291 // \ingroup lapack_substitution
292 //
293 // \param trans \c 'N' for \f$ A*X=B \f$, \c 'T' for \f$ A^T*X=B \f$, and \c C for \f$ A^H*X=B \f$.
294 // \param n The number of rows/columns of the column-major matrix \f$[0..\infty)\f$.
295 // \param nrhs The number of right-hand side vectors \f$[0..\infty)\f$.
296 // \param A Pointer to the first element of the double precision complex column-major square matrix.
297 // \param lda The total number of elements between two columns of the matrix \f$[0..\infty)\f$.
298 // \param ipiv Auxiliary array of size \a n for the pivot indices.
299 // \param B Pointer to the first element of the column-major matrix.
300 // \param ldb The total number of elements between two columns of matrix \a B \f$[0..\infty)\f$.
301 // \param info Return code of the function call.
302 // \return void
303 //
304 // This function uses the LAPACK zgetrs() function to perform the substitution step to compute
305 // the solution to the general system of linear equations \f$ A*X=B \f$, \f$ A^{T}*X=B \f$, or
306 // \f$ A^{H}*X=B \f$, where \a A is a \a n-by-\a n matrix that has already been factorized by the
307 // zgetrf() function and \a X and \a B are column-major \a n-by-\a nrhs matrices. The \a trans
308 // argument specifies the form of the linear system of equations:
309 //
310 //   - 'N': \f$ A*X=B \f$ (no transpose)
311 //   - 'T': \f$ A^{T}*X=B \f$ (transpose)
312 //   - 'C': \f$ A^{H}*X=B \f$ (conjugate transpose)
313 //
314 // The \a info argument provides feedback on the success of the function call:
315 //
316 //   - = 0: The function finished successfully.
317 //   - < 0: If info = -i, the i-th argument had an illegal value.
318 //
319 // For more information on the zgetrs() function, see the LAPACK online documentation browser:
320 //
321 //        http://www.netlib.org/lapack/explore-html/
322 //
323 // \note This function can only be used if a fitting LAPACK library, which supports this function,
324 // is available and linked to the executable. Otherwise a call to this function will result in a
325 // linker error.
326 */
getrs(char trans,blas_int_t n,blas_int_t nrhs,const complex<double> * A,blas_int_t lda,const blas_int_t * ipiv,complex<double> * B,blas_int_t ldb,blas_int_t * info)327 inline void getrs( char trans, blas_int_t n, blas_int_t nrhs, const complex<double>* A,
328                    blas_int_t lda, const blas_int_t* ipiv, complex<double>* B,
329                    blas_int_t ldb, blas_int_t* info )
330 {
331    BLAZE_STATIC_ASSERT( sizeof( complex<double> ) == 2UL*sizeof( double ) );
332 
333 #if defined(INTEL_MKL_VERSION)
334    BLAZE_STATIC_ASSERT( sizeof( MKL_INT ) == sizeof( blas_int_t ) );
335    BLAZE_STATIC_ASSERT( sizeof( MKL_Complex16 ) == sizeof( complex<double> ) );
336    using ET = MKL_Complex16;
337 #else
338    using ET = double;
339 #endif
340 
341    zgetrs_( &trans, &n, &nrhs, const_cast<ET*>( reinterpret_cast<const ET*>( A ) ),
342             &lda, const_cast<blas_int_t*>( ipiv ), reinterpret_cast<ET*>( B ), &ldb, info
343 #if !defined(INTEL_MKL_VERSION) && !defined(BLAS_H)
344           , blaze::fortran_charlen_t(1)
345 #endif
346           );
347 }
348 //*************************************************************************************************
349 
350 } // namespace blaze
351 
352 #endif
353