@@ -44,13 +44,16 @@ class Lut {
4444 // Implementation details for transposition optimization
4545 static constexpr size_t kTransposeBy = HWY_LANES (T);
4646 static constexpr size_t kTransposeTail = kRows % kTransposeBy ;
47- static constexpr size_t kTransposeLength = (kRows - kTransposeTail ) * kCols ;
48-
4947 // Determine at compile-time if transposition optimization is viable
5048 static constexpr bool kInitTranspose = !HWY_HAVE_SCALABLE && (
5149 kRows / kTransposeBy > 0 && kCols % kTransposeBy == 0 &&
5250 (kTransposeBy == 2 || kTransposeBy == 4 ) // Currently supports 2x or 4x unrolling
5351 );
52+ // When kInitTranspose is false kTransposeLength would be 0 (kRows < kTransposeBy),
53+ // which would produce a zero-size array (MSVC forbid it) — use 1 as a placeholder instead.
54+ static constexpr size_t kTransposeLength = kInitTranspose
55+ ? (kRows - kTransposeTail ) * kCols
56+ : 1 ;
5457
5558 /* *
5659 * @brief Constructs the table from row arrays.
@@ -89,8 +92,19 @@ class Lut {
8992
9093#if !HWY_HAVE_SCALABLE
9194 // Try optimized transposed load first
92- if constexpr (kInitTranspose ) {
93- LoadTranspose_ (idx, out...);
95+ using DU = DFromV<VU >;
96+ const DU du;
97+ constexpr size_t kLanes = HWY_LANES (TU );
98+ // Try optimized transposed load first
99+ if constexpr (kInitTranspose && kLanes == kTransposeBy ) {
100+ HWY_ALIGN TU s_idx[kLanes ];
101+ Store (ShiftLeft<kTransposeBy /2 >(idx), du, s_idx);
102+ if constexpr (kTransposeBy == 2 ) {
103+ LoadTransposeX2_ (s_idx, idx, out...);
104+ }
105+ else {
106+ LoadTransposeX4_ (s_idx, idx, out...);
107+ }
94108 }
95109#else
96110 if constexpr (0 ) {}
@@ -137,33 +151,6 @@ class Lut {
137151 }
138152
139153 // --- Transposed Load Implementation ---
140-
141- template <size_t Off = 0 , typename VU , typename ... OutV>
142- HWY_INLINE void LoadTranspose_ (const VU &idx, OutV &...out) const {
143- using namespace hn ;
144- using DU = DFromV<VU >;
145- using TU = TFromD<DU >;
146- const DU du;
147-
148- constexpr size_t kLanes = Lanes (du);
149-
150- // Only use transposed load if vector lanes match the transpose blocking factor
151- if constexpr (kLanes == kTransposeBy ) {
152- HWY_ALIGN TU s_idx[kLanes ];
153- Store (ShiftLeft<kTransposeBy /2 >(idx), du, s_idx);
154- if constexpr (kTransposeBy == 2 ) {
155- LoadTransposeX2_ (s_idx, idx, out...);
156- }
157- else {
158- static_assert (kTransposeBy == 4 , " It's already guarded by kInitTranspose" );
159- LoadTransposeX4_ (s_idx, idx, out...);
160- }
161- }
162- else {
163- LoadRow_ (idx, out...);
164- }
165- }
166-
167154 // 2-wide transposed load optimization
168155 template <size_t Off = 0 , typename TU , typename VU , typename OutV0, typename ... OutV>
169156 HWY_INLINE void LoadTransposeX2_ (const TU *trans_idx, const VU &idx,
@@ -226,6 +213,7 @@ class Lut {
226213 // Selects the best row loading strategy based on vector size vs table width
227214 template <size_t Off = 0 , typename VU , typename ... OutV>
228215 HWY_INLINE void LoadRow_ (const VU & idx, OutV& ...out) const {
216+ #if !HWY_HAVE_SCALABLE
229217 using namespace hn ;
230218 using DU = DFromV<VU >;
231219 const DU du;
@@ -236,8 +224,7 @@ class Lut {
236224 using M = MFromD<D>;
237225 const D d;
238226
239- #if !HWY_HAVE_SCALABLE
240- constexpr size_t kLanes = Lanes (du);
227+ constexpr size_t kLanes = HWY_LANES (TI );
241228 // Strategy 1: Vector size equals table width (Single Table Lookup)
242229 if constexpr (kLanes == kCols ) {
243230 const auto ind = IndicesFromVec (d, idx);
0 commit comments