From f09c14d07d13fb62ad97bab1f580414f97b9d620 Mon Sep 17 00:00:00 2001 From: Kim Yang Date: Fri, 20 Mar 2026 14:21:06 +0800 Subject: [PATCH] fix: add SumsOf2 fallback for Highway < 1.1.0 compatibility SumsOf2 (pairwise widen-and-add) was introduced in Highway 1.1.0 but some distro packages ship older versions. Add a compile-time fallback that implements the same semantics via store/scalar-add/load, gated on HWY_MAJOR/HWY_MINOR. On Highway >= 1.1.0 the native op is used with zero overhead. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/simd.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/simd.cpp b/src/simd.cpp index 326ce998..e82df83d 100644 --- a/src/simd.cpp +++ b/src/simd.cpp @@ -12,6 +12,36 @@ namespace HWY_NAMESPACE { namespace hn = hwy::HWY_NAMESPACE; +// SumsOf2 pairwise-adds adjacent lanes into the next-wider type +// (u8 pairs -> u16, u16 pairs -> u32). Available since Highway 1.1.0; +// provide a portable fallback for older versions. +#if !defined(HWY_MAJOR) || HWY_MAJOR < 1 || (HWY_MAJOR == 1 && HWY_MINOR < 1) + +template +HWY_API hn::VFromD>, + hn::DFromV>> +SumsOf2Fallback(V v) { + using T = hn::TFromV; + using TW = hwy::MakeWide; + using D = hn::DFromV; + using DW = hn::Repartition; + const D d; + const DW dw; + const size_t N = hn::Lanes(d); + HWY_ALIGN T buf[hn::MaxLanes(d)]; + hn::Store(v, d, buf); + HWY_ALIGN TW wbuf[hn::MaxLanes(dw)]; + for (size_t i = 0; i < N / 2; ++i) { + wbuf[i] = static_cast(buf[2 * i]) + static_cast(buf[2 * i + 1]); + } + return hn::Load(dw, wbuf); +} +#define SumsOf2 SumsOf2Fallback + +#else +using hn::SumsOf2; +#endif + void CountQualityMetricsImpl(const char* qualstr, const char* seqstr, int len, char qualThreshold, int& lowQualNum, int& nBaseNum, int& totalQual) {