| // IWYU pragma: private | |
| // SPDX-FileCopyrightText: The Eigen Authors | |
| // SPDX-License-Identifier: MPL-2.0 | |
| #include "../../InternalHeaderCheck.h" | |
| namespace Eigen { | |
| namespace internal { | |
| // The generic gebp_traits declares nr = 4, and until this header existed the SVE | |
| // backend took it: an SVE build measured a 6x4 register block where the NEON | |
| // build of the same source measured 6x8. Isolated by forcing the NEON build to | |
| // nr = 4, which cost it about 15% of its double GEMM rate -- the whole of the | |
| // remaining gap between the two backends once double was vectorized at all. | |
| // | |
| // Only nr is overridden. NEON additionally replaces the RHS machinery because | |
| // vfmaq_laneq_f64 needs an immediate lane index into a real vector; SVE's | |
| // equivalent selects a lane within each 128-bit segment rather than across the | |
| // vector, so it is not a drop-in at vector lengths above 128 bits, and the | |
| // generic QuadPacket path -- pbroadcast4 to svdup, madd to svmla -- already | |
| // emits what a hand-written version would. | |
| #ifndef EIGEN_SVE_GEBP_NR | |
| #define EIGEN_SVE_GEBP_NR 8 | |
| #endif | |
| template <> | |
| struct gebp_traits<float, float, false, false, Architecture::SVE, GEBPPacketFull> | |
| : gebp_traits<float, float, false, false, Architecture::Generic, GEBPPacketFull> { | |
| enum { nr = EIGEN_SVE_GEBP_NR }; | |
| }; | |
| template <> | |
| struct gebp_traits<double, double, false, false, Architecture::SVE, GEBPPacketFull> | |
| : gebp_traits<double, double, false, false, Architecture::Generic, GEBPPacketFull> { | |
| enum { nr = EIGEN_SVE_GEBP_NR }; | |
| }; | |
| } // namespace internal | |
| } // namespace Eigen |