1818from flydsl ._mlir import ir
1919
2020from flydsl .expr import arith , gpu , buffer_ops , vector , rocdl
21- from flydsl .expr .arith import ArithValue
22- from flydsl .expr .typing import T
21+ from flydsl .expr .typing import T , Vector as Vec
2322
2423
2524from kernels .mfma_preshuffle_pipeline import (
@@ -124,6 +123,9 @@ def compile_blockscale_preshuffle_gemm(
124123 def _out_elem_type ():
125124 return T .bf16 if is_bf16_out else T .f16
126125
126+ def _out_elem_dtype ():
127+ return fx .BFloat16 if is_bf16_out else fx .Float16
128+
127129 epilog_tag = "cshuffle" if use_cshuffle_epilog else "direct"
128130
129131 module_name = (
@@ -168,10 +170,9 @@ def kernel_gemm(
168170 i32_m : fx .Int32 ,
169171 i32_n : fx .Int32 ,
170172 ):
171- c_m = arith .index_cast (T .index , i32_m )
172- c_n = arith .index_cast (T .index , i32_n )
173+ c_n = fx .Index (i32_n )
173174
174- acc_init = arith . constant_vector ( 0.0 , T . f32x4 )
175+ acc_init = fx . full ( 4 , 0.0 , fx . Float32 )
175176
176177 # ---- B layout (compile-time since N, K are known) ----
177178 n0_val = N // 16
@@ -189,7 +190,7 @@ def kernel_gemm(
189190 stride_lds = fx .make_stride (tile_k , 1 )
190191 layout_lds = fx .make_layout (shape_lds , stride_lds )
191192
192- k_blocks16 = arith . index ( tile_k_bytes // 16 )
193+ k_blocks16 = tile_k_bytes // 16
193194
194195 tx = gpu .thread_id ("x" )
195196 bx = gpu .block_id ("x" )
@@ -215,14 +216,14 @@ def kernel_gemm(
215216 lds_out = None
216217
217218 # ---- Buffer resources (explicit num_records_bytes for correct OOB on M tail) ----
218- rt_M = arith . index_cast ( T . index , i32_m )
219- rt_N = arith . index_cast ( T . index , i32_n )
220- a_nbytes = rt_M * fx . Index ( K ) # fp8: 1 byte/elem
219+ rt_M = fx . Index ( i32_m )
220+ rt_N = fx . Index ( i32_n )
221+ a_nbytes = rt_M * K # fp8: 1 byte/elem
221222 a_rsrc = buffer_ops .create_buffer_resource (arg_a , max_size = False , num_records_bytes = a_nbytes )
222223 out_elem_bytes = 2 # bf16/fp16
223- c_nbytes = rt_M * rt_N * fx . Index ( out_elem_bytes )
224+ c_nbytes = rt_M * rt_N * out_elem_bytes
224225 c_rsrc = buffer_ops .create_buffer_resource (arg_c , max_size = False , num_records_bytes = c_nbytes )
225- sa_nbytes = arith . index (K // 128 ) * rt_M * fx . Index ( 4 ) # [scale_k, M] f32
226+ sa_nbytes = (K // 128 ) * rt_M * 4 # [scale_k, M] f32
226227 scale_a_rsrc = buffer_ops .create_buffer_resource (arg_scale_a , max_size = False , num_records_bytes = sa_nbytes )
227228
228229 b_rsrc = buffer_ops .create_buffer_resource (arg_b , max_size = True )
@@ -268,7 +269,7 @@ def load_b_pack(base_k, ki_step, ni):
268269 )
269270
270271 c64_b = 64
271- _lds_k_dim_c = fx . Index ( tile_k )
272+ _lds_k_dim_c = tile_k
272273
273274 def load_b_packs_k64 (base_k , ku : int , ni : int ):
274275 base_k_bytes = base_k
@@ -282,9 +283,9 @@ def load_b_packs_k64(base_k, ku: int, ni: int):
282283 elem_type = T .f8 , vec_elems = 16 , elem_bytes = elem_bytes ,
283284 offset_in_bytes = True ,
284285 )
285- b_i64x2 = vector .bitcast (T . i64x2 , b16 )
286- b0_i64 = vector . extract ( b_i64x2 , static_position = [0 ], dynamic_position = [])
287- b1_i64 = vector . extract ( b_i64x2 , static_position = [1 ], dynamic_position = [])
286+ b_i64x2 = Vec ( b16 ) .bitcast (fx . Int64 )
287+ b0_i64 = b_i64x2 [0 ]
288+ b1_i64 = b_i64x2 [1 ]
288289 return b0_i64 , b1_i64
289290
290291 def load_b_tile (base_k ):
@@ -307,9 +308,9 @@ def lds_load_16b(curr_row_a_lds, col_base, lds_buffer):
307308
308309 def lds_load_packs_k64 (curr_row_a_lds , col_base , lds_buffer ):
309310 loaded_a16 = lds_load_16b (curr_row_a_lds , col_base , lds_buffer )
310- a_i64x2 = vector .bitcast (T . i64x2 , loaded_a16 )
311- a0_i64 = vector . extract ( a_i64x2 , static_position = [0 ], dynamic_position = [])
312- a1_i64 = vector . extract ( a_i64x2 , static_position = [1 ], dynamic_position = [])
311+ a_i64x2 = Vec ( loaded_a16 ) .bitcast (fx . Int64 )
312+ a0_i64 = a_i64x2 [0 ]
313+ a1_i64 = a_i64x2 [1 ]
313314 return a0_i64 , a1_i64
314315
315316 # ── A global→reg load ─────────────────────────────────────────────
@@ -318,8 +319,7 @@ def lds_load_packs_k64(curr_row_a_lds, col_base, lds_buffer):
318319 (tile_m , tile_k_dwords ), (tile_k_dwords , 1 )
319320 )
320321 chunk_i32_a = a_load_bytes // 4
321- c_chunk_a = fx .Index (chunk_i32_a )
322- tx_i32_base = tx * c_chunk_a
322+ tx_i32_base = tx * chunk_i32_a
323323
324324 def load_a (idx_i32 , a_load_bytes_v ):
325325 if const_expr (a_load_bytes_v == 16 ):
@@ -348,12 +348,12 @@ def load_a_tile(base_k_div4, a_load_bytes_v, tx_i32_base_v, chunk_i32_a_v):
348348 idx_i32 = row_a_global * _k_div4_factor + (base_k_div4 + col_a_local_i32 )
349349 a_vec = load_a (idx_i32 , a_load_bytes_v )
350350 if const_expr (a_load_bytes_v == 16 ):
351- parts .append (vector .bitcast (T . i32x4 , a_vec ))
351+ parts .append (Vec ( a_vec ) .bitcast (fx . Int32 ))
352352 else :
353353 parts .append (a_vec )
354354 return parts
355355
356- c4_bytes = fx . Index ( 4 ) # bytes per dword (always 4, used for LDS byte addressing)
356+ c4_bytes = 4 # bytes per dword (always 4, used for LDS byte addressing)
357357
358358 def store_a_tile_to_lds (vec_a_parts , lds_buffer , a_load_bytes_v , tx_i32_base_v , chunk_i32_a_v ):
359359 for i in range_constexpr (num_a_loads ):
@@ -365,7 +365,7 @@ def store_a_tile_to_lds(vec_a_parts, lds_buffer, a_load_bytes_v, tx_i32_base_v,
365365 layout_lds = layout_lds ,
366366 row_local = row_a_local , col_local_i32 = col_a_local_i32 ,
367367 tx_c4 = c4_bytes , k_blocks16 = k_blocks16 ,
368- lds_base = fx . Index ( 0 ) ,
368+ lds_base = 0 ,
369369 vec_part_i32x4 = vec_a_parts [i ], elem_bytes = elem_bytes ,
370370 )
371371 elif const_expr (a_load_bytes_v == 8 ):
@@ -375,7 +375,7 @@ def store_a_tile_to_lds(vec_a_parts, lds_buffer, a_load_bytes_v, tx_i32_base_v,
375375 layout_lds = layout_lds ,
376376 row_local = row_a_local , col_local_i32 = col_a_local_i32 ,
377377 tx_c4 = c4_bytes , k_blocks16 = k_blocks16 ,
378- lds_base = fx . Index ( 0 ) ,
378+ lds_base = 0 ,
379379 vec_part_i32x2 = vec_a_parts [i ],
380380 )
381381
@@ -402,20 +402,20 @@ def dma_a_tile_to_lds(base_k_div4, lds_buffer):
402402 col_a_local_sw = swizzle_xor16 (row_a_local , col_a_local_i32 * c4_bytes , k_blocks16 )
403403 row_a_global = bx_m + row_a_local
404404 global_byte_idx = row_a_global * k_bytes_factor + (base_k_div4 * c4_bytes + col_a_local_sw )
405- global_offset = arith . index_cast ( T . i32 , global_byte_idx )
405+ global_offset = fx . Int32 ( global_byte_idx )
406406
407407 if const_expr (i == 0 ):
408408 lds_addr = memref_dialect .extract_aligned_pointer_as_index (lds_buffer ) + wave_id * 64 * dma_bytes
409- lds_ptr_i64_lane0 = rocdl .readfirstlane (T .i64 , arith . index_cast ( T . i64 , lds_addr ))
409+ lds_ptr_i64_lane0 = rocdl .readfirstlane (T .i64 , fx . Int64 ( lds_addr ))
410410 else :
411411 lds_ptr_i64_lane0 += total_threads * dma_bytes
412412 lds_ptr_type = ir .Type .parse ("!llvm.ptr<3>" )
413413 lds_ptr = llvm .inttoptr (lds_ptr_type , lds_ptr_i64_lane0 )
414414
415- size_i32 = arith . constant (dma_bytes , type = T . i32 )
416- soffset = arith . constant ( 0 , type = T . i32 )
417- offset_imm = arith . constant ( 0 , type = T . i32 )
418- aux = arith . constant ( 1 , type = T . i32 )
415+ size_i32 = fx . Int32 (dma_bytes )
416+ soffset = fx . Int32 ( 0 )
417+ offset_imm = fx . Int32 ( 0 )
418+ aux = fx . Int32 ( 1 )
419419
420420 rocdl .raw_ptr_buffer_load_lds (
421421 a_rsrc ,
@@ -447,11 +447,8 @@ def _mfma_fn_placeholder(*args, **kwargs):
447447 mfma_fn = _mfma_fn_placeholder
448448
449449 if const_expr (_is_gfx950 ):
450- c0_i64 = arith .constant (0 , type = T .i64 )
451-
452450 def pack_i64x4_to_i32x8 (x0 , x1 , x2 , x3 ):
453- v4 = vector .from_elements (T .vec (4 , T .i64 ), [x0 , x1 , x2 , x3 ])
454- return vector .bitcast (T .vec (8 , T .i32 ), v4 )
451+ return Vec .from_elements ([x0 , x1 , x2 , x3 ], fx .Int64 ).bitcast (fx .Int32 )
455452 else :
456453 mfma_fn = rocdl .mfma_f32_16x16x32_fp8_fp8
457454
@@ -479,17 +476,17 @@ def load_scales_for_tile(k_base):
479476 sa_base_offset = kb * c_M
480477 s_a_vecs = []
481478 for mi in range_constexpr (m_repeat ):
482- row_base_m = bx_m + arith . index ( mi * 16 )
479+ row_base_m = bx_m + mi * 16
483480 row_g_base = row_base_m + row_off_base
484481 sa_idx = sa_base_offset + row_g_base
485482 s_a_vec = buffer_ops .buffer_load (
486483 scale_a_rsrc , sa_idx , vec_width = 4 , dtype = T .f32
487484 )
488- s_a_vecs .append (vector .bitcast (T . f32x4 , s_a_vec ))
485+ s_a_vecs .append (Vec ( s_a_vec ) .bitcast (fx . Float32 ))
489486
490487 s_b_vals = []
491488 for ni in range_constexpr (num_acc_n ):
492- col_base_ni = by_n + n_tile_base + arith . index ( ni * 16 )
489+ col_base_ni = by_n + n_tile_base + ni * 16
493490 n_block = col_base_ni // c_128
494491 sb_idx = n_block * c_scale_k + kb
495492 s_b_val = buffer_ops .buffer_load (
@@ -499,7 +496,7 @@ def load_scales_for_tile(k_base):
499496
500497 s_b_vecs = []
501498 for ni in range_constexpr (num_acc_n ):
502- s_b_vecs .append (vector . broadcast ( T . f32x4 , s_b_vals [ni ]))
499+ s_b_vecs .append (Vec . filled ( 4 , fx . Float32 ( s_b_vals [ni ]), fx . Float32 ))
503500
504501 combined_scales = []
505502 for mi in range_constexpr (m_repeat ):
@@ -611,28 +608,23 @@ def write_row_to_lds(
611608 col_local = col_base_local + (ni * 16 )
612609 acc_idx = mi * num_acc_n + ni
613610 acc = final_accs [acc_idx ]
614- val = vector .extract (
615- acc , static_position = [ii ], dynamic_position = []
616- )
617- v_out = arith .trunc_f (_out_elem_type (), val )
611+ val = Vec (acc )[ii ]
612+ v_out = val .to (_out_elem_dtype ())
618613 lds_idx = row_base_lds + col_local
619- v1 = vector .from_elements (vec1_out , [v_out ])
614+ v1 = Vec .from_elements ([v_out ], _out_elem_dtype () )
620615 vector .store (v1 , lds_out , [lds_idx ], alignment = 2 )
621616
622617 def store_pair (* , row_local , row , row_ctx , col_pair0 , col_g0 , frag ):
623618 idx_out = row * c_n + col_g0
624619 byte_off = idx_out * 2
625620 e_vec = 4 if (int (tile_n ) % (32 * 4 )) == 0 else 2
626621 if const_expr (e_vec == 4 ):
627- frag_i32x2 = vector .bitcast (T . vec ( 2 , T . i32 ), frag )
622+ frag_i32x2 = Vec ( frag ) .bitcast (fx . Int32 )
628623 buffer_ops .buffer_store (
629624 frag_i32x2 , c_rsrc , byte_off , offset_is_bytes = True
630625 )
631626 else :
632- frag_i32x1 = vector .bitcast (T .vec (1 , T .i32 ), frag )
633- frag_i32 = vector .extract (
634- frag_i32x1 , static_position = [0 ], dynamic_position = []
635- )
627+ frag_i32 = Vec (frag ).bitcast (fx .Int32 )[0 ]
636628 buffer_ops .buffer_store (
637629 frag_i32 , c_rsrc , byte_off , offset_is_bytes = True
638630 )
@@ -660,10 +652,8 @@ def body_row(*, mi, ii, row_in_tile, row):
660652 for ni in range_constexpr (num_acc_n ):
661653 acc_idx = mi * num_acc_n + ni
662654 acc = final_accs [acc_idx ]
663- val = vector .extract (
664- acc , static_position = [ii ], dynamic_position = []
665- )
666- val_out = arith .trunc_f (_out_elem_type (), val )
655+ val = Vec (acc )[ii ]
656+ val_out = val .to (_out_elem_dtype ())
667657 idx_out = idx_base + (ni * 16 )
668658 buffer_ops .buffer_store (val_out , c_rsrc , idx_out )
669659
@@ -784,7 +774,7 @@ def _load_a_to_lds(base_k, lds_buffer, a_load_bytes_v, tx_i32_base_v, chunk_i32_
784774 gpu .barrier ()
785775 a0_prefetch_pong = prefetch_a0_pack (lds_a_pong )
786776
787- last_k = arith . index ( K - tile_k )
777+ last_k = K - tile_k
788778 final_accs = compute_tile_blockscale (
789779 global_accs , b_tile_pong , lds_a_pong , scales_pong ,
790780 a0_prefetch = a0_prefetch_pong ,
@@ -826,8 +816,7 @@ def _load_a_to_lds(base_k, lds_buffer, a_load_bytes_v, tx_i32_base_v, chunk_i32_
826816 gpu .barrier ()
827817 a0_prefetch_pong = prefetch_a0_pack (lds_a_pong )
828818
829- last_k = arith .index (K - tile_k )
830- second_last_k = arith .index (K - tile_k * 2 )
819+ last_k = K - tile_k
831820
832821 _load_a_to_lds (last_k , lds_a_ping , a_load_bytes , tx_i32_base , chunk_i32_a )
833822 b_tile_ping = prefetch_b_tile (last_k )
0 commit comments