mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Vectorize BLAS level 1/2 routines with Eigen expressions
libeigen/eigen!2404 Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
@@ -25,15 +25,19 @@ struct functor_traits<scalar_norm1_op> {
|
||||
// computes the sum of magnitudes of all vector elements or, for a complex vector x, the sum
|
||||
// res = |Rex1| + |Imx1| + |Rex2| + |Imx2| + ... + |Rexn| + |Imxn|, where x is a vector of order n
|
||||
extern "C" RealScalar EIGEN_CAT(REAL_SCALAR_SUFFIX, EIGEN_BLAS_FUNC_NAME(asum))(int *n, RealScalar *px, int *incx) {
|
||||
// std::cerr << "__asum " << *n << " " << *incx << "\n";
|
||||
Complex *x = reinterpret_cast<Complex *>(px);
|
||||
|
||||
if (*n <= 0) return 0;
|
||||
|
||||
// std::complex<T> is layout-compatible with T[2], so we can reinterpret
|
||||
// a complex vector of length n as a real vector of length 2*n and use
|
||||
// the fully vectorized cwiseAbs().sum() path.
|
||||
if (*incx == 1)
|
||||
return make_vector(x, *n).unaryExpr<scalar_norm1_op>().sum();
|
||||
else
|
||||
return make_vector(px, 2 * *n).cwiseAbs().sum();
|
||||
else {
|
||||
// For non-unit stride, fall back to the scalar_norm1_op approach since
|
||||
// the real components are not contiguous across complex elements.
|
||||
Complex *x = reinterpret_cast<Complex *>(px);
|
||||
return make_vector(x, *n, std::abs(*incx)).unaryExpr<scalar_norm1_op>().sum();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int EIGEN_CAT(i, EIGEN_BLAS_FUNC_NAME(amax))(int *n, RealScalar *px, int *incx) {
|
||||
|
||||
Reference in New Issue
Block a user