1313import cutlass .cute as cute
1414from cutlass import Float32 , Int32 , const_expr
1515
16- from quack import copy_utils
16+ from quack import copy_utils , layout_utils
1717from quack .cache_utils import jit_cache
1818from quack .compile_utils import make_fake_tensor as fake_tensor
1919from quack .cute_dsl_utils import torch2cute_dtype_map
@@ -25,7 +25,7 @@ def _next_power_of_2(n: int) -> int:
2525
2626def _num_threads_for_log_n (log_n : int ) -> int :
2727 # Same schedule as fast-hadamard-transform / TileLang for power-of-two sizes.
28- return [0 , 1 , 1 , 1 , 2 , 4 , 8 , 16 , 32 , 32 , 128 , 256 , 256 , 256 , 256 , 256 ][log_n ]
28+ return [0 , 1 , 1 , 1 , 2 , 4 , 8 , 16 , 32 , 32 , 32 , 32 , 32 , 256 , 256 , 1024 ][log_n ]
2929
3030
3131def _ensure_last_dim_contiguous (t : Tensor ) -> Tensor :
@@ -52,24 +52,6 @@ def _hadamard_thread(
5252 vals [idx + stride , c ] = a - b
5353
5454
55- @cute .jit
56- def _hadamard_chunks (
57- vals : cute .Tensor ,
58- vecsize : cutlass .Constexpr [int ],
59- log_n : cutlass .Constexpr [int ],
60- ) -> None :
61- for step in cutlass .range_constexpr (log_n ):
62- stride = const_expr (1 << step )
63- for j in cutlass .range_constexpr (1 << (log_n - 1 )):
64- lo = const_expr (j & (stride - 1 ))
65- idx = const_expr ((j - lo ) * 2 + lo )
66- for i in cutlass .range_constexpr (vecsize ):
67- a = vals [i , idx ]
68- b = vals [i , idx + stride ]
69- vals [i , idx ] = a + b
70- vals [i , idx + stride ] = a - b
71-
72-
7355@cute .jit
7456def _hadamard_warp (
7557 vals : cute .Tensor ,
@@ -271,7 +253,10 @@ def kernel(
271253 copy_exch (s_exchange [None , (lane_id , warp_id ), c ], x_vals [None , chunk ])
272254
273255 if const_expr (self .num_chunks > 1 ):
274- _hadamard_chunks (x_vals , self .vecsize , self .log_chunks )
256+ # x_vals is laid out as (vec, chunk), while _hadamard_thread transforms its
257+ # first mode and iterates over its second. Select modes [1, 0] to get a
258+ # metadata-only (chunk, vec) view and reuse the same butterfly loop nest.
259+ _hadamard_thread (layout_utils .select (x_vals , [1 , 0 ]), self .vecsize , self .log_chunks )
275260
276261 for c in cutlass .range_constexpr (self .num_chunks ):
277262 for i in cutlass .range_constexpr (self .vecsize ):
0 commit comments