34#ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_BLAS_H
35#define EIGEN_SELFADJOINT_MATRIX_MATRIX_BLAS_H
38#include "../InternalHeaderCheck.h"
46#define EIGEN_BLAS_SYMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
47 template <typename Index, int LhsStorageOrder, bool ConjugateLhs, int RhsStorageOrder, bool ConjugateRhs> \
48 struct product_selfadjoint_matrix<EIGTYPE, Index, LhsStorageOrder, true, ConjugateLhs, RhsStorageOrder, false, \
49 ConjugateRhs, ColMajor, 1> { \
50 static void run(Index rows, Index cols, const EIGTYPE* _lhs, Index lhsStride, const EIGTYPE* _rhs, \
51 Index rhsStride, EIGTYPE* res, Index resIncr, Index resStride, EIGTYPE alpha, \
52 level3_blocking<EIGTYPE, EIGTYPE>& ) { \
53 if (rows == 0 || cols == 0) return; \
54 EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \
55 eigen_assert(resIncr == 1); \
56 char side = 'L', uplo = 'L'; \
57 BlasIndex m, n, lda, ldb, ldc; \
58 const EIGTYPE *a, *b; \
60 MatrixX##EIGPREFIX b_tmp; \
64 m = convert_index<BlasIndex>(rows); \
65 n = convert_index<BlasIndex>(cols); \
68 lda = convert_index<BlasIndex>(lhsStride); \
69 ldb = convert_index<BlasIndex>(rhsStride); \
70 ldc = convert_index<BlasIndex>(resStride); \
73 EIGEN_IF_CONSTEXPR (LhsStorageOrder == RowMajor) { \
78 EIGEN_IF_CONSTEXPR (RhsStorageOrder == RowMajor) { \
79 Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs, n, m, OuterStride<>(rhsStride)); \
80 b_tmp = rhs.adjoint(); \
82 ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
86 BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, \
87 (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
91#define EIGEN_BLAS_HEMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
92 template <typename Index, int LhsStorageOrder, bool ConjugateLhs, int RhsStorageOrder, bool ConjugateRhs> \
93 struct product_selfadjoint_matrix<EIGTYPE, Index, LhsStorageOrder, true, ConjugateLhs, RhsStorageOrder, false, \
94 ConjugateRhs, ColMajor, 1> { \
95 static void run(Index rows, Index cols, const EIGTYPE* _lhs, Index lhsStride, const EIGTYPE* _rhs, \
96 Index rhsStride, EIGTYPE* res, Index resIncr, Index resStride, EIGTYPE alpha, \
97 level3_blocking<EIGTYPE, EIGTYPE>& ) { \
98 if (rows == 0 || cols == 0) return; \
99 EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \
100 eigen_assert(resIncr == 1); \
101 char side = 'L', uplo = 'L'; \
102 BlasIndex m, n, lda, ldb, ldc; \
103 const EIGTYPE *a, *b; \
105 MatrixX##EIGPREFIX b_tmp; \
106 Matrix<EIGTYPE, Dynamic, Dynamic, LhsStorageOrder> a_tmp; \
110 m = convert_index<BlasIndex>(rows); \
111 n = convert_index<BlasIndex>(cols); \
114 lda = convert_index<BlasIndex>(lhsStride); \
115 ldb = convert_index<BlasIndex>(rhsStride); \
116 ldc = convert_index<BlasIndex>(resStride); \
119 EIGEN_IF_CONSTEXPR (((LhsStorageOrder == ColMajor) && ConjugateLhs) || \
120 ((LhsStorageOrder == RowMajor) && (!ConjugateLhs))) { \
121 Map<const Matrix<EIGTYPE, Dynamic, Dynamic, LhsStorageOrder>, 0, OuterStride<> > lhs( \
122 _lhs, m, m, OuterStride<>(lhsStride)); \
123 a_tmp = lhs.conjugate(); \
125 lda = convert_index<BlasIndex>(a_tmp.outerStride()); \
128 EIGEN_IF_CONSTEXPR (LhsStorageOrder == RowMajor) { \
132 EIGEN_IF_CONSTEXPR (RhsStorageOrder == ColMajor && (!ConjugateRhs)) { \
135 EIGEN_IF_CONSTEXPR (RhsStorageOrder == ColMajor && ConjugateRhs) { \
136 Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs, m, n, OuterStride<>(rhsStride)); \
137 b_tmp = rhs.conjugate(); \
138 } else EIGEN_IF_CONSTEXPR (ConjugateRhs) { \
139 Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs, n, m, OuterStride<>(rhsStride)); \
140 b_tmp = rhs.adjoint(); \
142 Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > rhs(_rhs, n, m, OuterStride<>(rhsStride)); \
143 b_tmp = rhs.transpose(); \
146 ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
149 BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, \
150 (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
155EIGEN_BLAS_SYMM_L(
double,
double, d, dsymm)
156EIGEN_BLAS_SYMM_L(
float,
float, f, ssymm)
157EIGEN_BLAS_HEMM_L(dcomplex, MKL_Complex16, cd, zhemm)
158EIGEN_BLAS_HEMM_L(scomplex, MKL_Complex8, cf, chemm)
160EIGEN_BLAS_SYMM_L(
double,
double, d, EIGEN_BLAS_SYM(dsymm))
161EIGEN_BLAS_SYMM_L(
float,
float, f, EIGEN_BLAS_SYM(ssymm))
162EIGEN_BLAS_HEMM_L(dcomplex,
double, cd, EIGEN_BLAS_SYM(zhemm))
163EIGEN_BLAS_HEMM_L(scomplex,
float, cf, EIGEN_BLAS_SYM(chemm))
168#define EIGEN_BLAS_SYMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
169 template <typename Index, int LhsStorageOrder, bool ConjugateLhs, int RhsStorageOrder, bool ConjugateRhs> \
170 struct product_selfadjoint_matrix<EIGTYPE, Index, LhsStorageOrder, false, ConjugateLhs, RhsStorageOrder, true, \
171 ConjugateRhs, ColMajor, 1> { \
172 static void run(Index rows, Index cols, const EIGTYPE* _lhs, Index lhsStride, const EIGTYPE* _rhs, \
173 Index rhsStride, EIGTYPE* res, Index resIncr, Index resStride, EIGTYPE alpha, \
174 level3_blocking<EIGTYPE, EIGTYPE>& ) { \
175 if (rows == 0 || cols == 0) return; \
176 EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \
177 eigen_assert(resIncr == 1); \
178 char side = 'R', uplo = 'L'; \
179 BlasIndex m, n, lda, ldb, ldc; \
180 const EIGTYPE *a, *b; \
182 MatrixX##EIGPREFIX b_tmp; \
185 m = convert_index<BlasIndex>(rows); \
186 n = convert_index<BlasIndex>(cols); \
189 lda = convert_index<BlasIndex>(rhsStride); \
190 ldb = convert_index<BlasIndex>(lhsStride); \
191 ldc = convert_index<BlasIndex>(resStride); \
194 EIGEN_IF_CONSTEXPR (RhsStorageOrder == RowMajor) { \
199 EIGEN_IF_CONSTEXPR (LhsStorageOrder == RowMajor) { \
200 Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs, n, m, OuterStride<>(rhsStride)); \
201 b_tmp = lhs.adjoint(); \
203 ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
207 BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, \
208 (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
212#define EIGEN_BLAS_HEMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
213 template <typename Index, int LhsStorageOrder, bool ConjugateLhs, int RhsStorageOrder, bool ConjugateRhs> \
214 struct product_selfadjoint_matrix<EIGTYPE, Index, LhsStorageOrder, false, ConjugateLhs, RhsStorageOrder, true, \
215 ConjugateRhs, ColMajor, 1> { \
216 static void run(Index rows, Index cols, const EIGTYPE* _lhs, Index lhsStride, const EIGTYPE* _rhs, \
217 Index rhsStride, EIGTYPE* res, Index resIncr, Index resStride, EIGTYPE alpha, \
218 level3_blocking<EIGTYPE, EIGTYPE>& ) { \
219 EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \
220 eigen_assert(resIncr == 1); \
221 char side = 'R', uplo = 'L'; \
222 BlasIndex m, n, lda, ldb, ldc; \
223 const EIGTYPE *a, *b; \
225 MatrixX##EIGPREFIX b_tmp; \
226 Matrix<EIGTYPE, Dynamic, Dynamic, RhsStorageOrder> a_tmp; \
229 m = convert_index<BlasIndex>(rows); \
230 n = convert_index<BlasIndex>(cols); \
233 lda = convert_index<BlasIndex>(rhsStride); \
234 ldb = convert_index<BlasIndex>(lhsStride); \
235 ldc = convert_index<BlasIndex>(resStride); \
238 EIGEN_IF_CONSTEXPR (((RhsStorageOrder == ColMajor) && ConjugateRhs) || \
239 ((RhsStorageOrder == RowMajor) && (!ConjugateRhs))) { \
240 Map<const Matrix<EIGTYPE, Dynamic, Dynamic, RhsStorageOrder>, 0, OuterStride<> > rhs( \
241 _rhs, n, n, OuterStride<>(rhsStride)); \
242 a_tmp = rhs.conjugate(); \
244 lda = convert_index<BlasIndex>(a_tmp.outerStride()); \
247 EIGEN_IF_CONSTEXPR (RhsStorageOrder == RowMajor) { \
251 EIGEN_IF_CONSTEXPR (LhsStorageOrder == ColMajor && (!ConjugateLhs)) { \
254 EIGEN_IF_CONSTEXPR (LhsStorageOrder == ColMajor && ConjugateLhs) { \
255 Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs, m, n, OuterStride<>(lhsStride)); \
256 b_tmp = lhs.conjugate(); \
257 } else EIGEN_IF_CONSTEXPR (ConjugateLhs) { \
258 Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs, n, m, OuterStride<>(lhsStride)); \
259 b_tmp = lhs.adjoint(); \
261 Map<const MatrixX##EIGPREFIX, 0, OuterStride<> > lhs(_lhs, n, m, OuterStride<>(lhsStride)); \
262 b_tmp = lhs.transpose(); \
265 ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
268 BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, \
269 (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
274EIGEN_BLAS_SYMM_R(
double,
double, d, dsymm)
275EIGEN_BLAS_SYMM_R(
float,
float, f, ssymm)
276EIGEN_BLAS_HEMM_R(dcomplex, MKL_Complex16, cd, zhemm)
277EIGEN_BLAS_HEMM_R(scomplex, MKL_Complex8, cf, chemm)
279EIGEN_BLAS_SYMM_R(
double,
double, d, EIGEN_BLAS_SYM(dsymm))
280EIGEN_BLAS_SYMM_R(
float,
float, f, EIGEN_BLAS_SYM(ssymm))
281EIGEN_BLAS_HEMM_R(dcomplex,
double, cd, EIGEN_BLAS_SYM(zhemm))
282EIGEN_BLAS_HEMM_R(scomplex,
float, cf, EIGEN_BLAS_SYM(chemm))
285#undef EIGEN_BLAS_SYMM_L
286#undef EIGEN_BLAS_SYMM_R
287#undef EIGEN_BLAS_HEMM_L
288#undef EIGEN_BLAS_HEMM_R