@@ -17,9 +17,10 @@ CUDA_INLINE uint2 fused_dequant_single_for_mxfp4<Float8E4M3>(const uint32_t qb,
1717 uint32_t exp_offset_buffer1 = (exp_offset * 0x08080800 ) + ((0x03020100 << 2 ) - 0x00000400 );
1818 uint32_t exp_offset_buffer2 = (exp_offset * 0x08080808 ) + (0x07060504 << 2 );
1919
20+ uint32_t qb_selectors = qb & 0x77777777 ;
2021 uint32_t exp_offsets[2 ] = {
21- __byte_perm (exp_offset_buffer1, exp_offset_buffer2, qb ),
22- __byte_perm (exp_offset_buffer1, exp_offset_buffer2, qb >> 16 )};
22+ prmt (exp_offset_buffer1, exp_offset_buffer2, qb_selectors ),
23+ prmt (exp_offset_buffer1, exp_offset_buffer2, qb_selectors >> 16 )};
2324
2425 uint32_t res[2 ] = {
2526 lop3_and_or (qb << 4 , 0x80808080 , exp_offsets[0 ]),
@@ -36,13 +37,14 @@ CUDA_INLINE uint2 fused_dequant_single_for_mxfp4<Int8>(const uint32_t qb, const
3637
3738 uint32_t res[2 ];
3839 uint32_t signs[2 ] = {qb >> 3 , qb >> 7 };
40+ uint32_t qb_selectors = qb & 0x77777777 ;
3941 uint32_t int8s[2 ] = {
40- __byte_perm (buffer1, buffer2, qb ),
41- __byte_perm (buffer1, buffer2, qb >> 16 )};
42+ prmt (buffer1, buffer2, qb_selectors ),
43+ prmt (buffer1, buffer2, qb_selectors >> 16 )};
4244
4345 PRAGMA_UNROLL
4446 for (uint32_t i = 0 ; i < 2 ; i++) {
45- uint32_t val = __byte_perm (int8s[0 ], int8s[1 ], 0x6420 + 0x1111 * i);
47+ uint32_t val = prmt (int8s[0 ], int8s[1 ], 0x6420 + 0x1111 * i);
4648 uint32_t flag = signs[i] & 0x01010101 ;
4749 uint32_t mask = flag * 0xFF ;
4850 res[i] = (val - flag) ^ mask;
@@ -55,7 +57,9 @@ template <class TargetType, uint32_t kCount, bool kUseWgmma>
5557CUDA_INLINE void fused_dequant_for_mxfp4 (const uint32_t *qb_ptrs, uint32_t *res_ptrs, uint32_t *scales_ptr) {
5658 PRAGMA_UNROLL
5759 for (uint32_t i = 0 ; i < kCount * 2 ; i++) {
58- uint32_t exp_offset = reinterpret_cast <uint8_t *>(scales_ptr)[i];
60+ uint32_t scale_word = scales_ptr[i / 4 ];
61+ uint32_t byte_selector = 1u << (8 * (i % 4 ));
62+ uint32_t exp_offset = __dp4a (scale_word, byte_selector, 0u );
5963 uint2 res = fused_dequant_single_for_mxfp4<TargetType>(qb_ptrs[i], exp_offset);
6064 res_ptrs[i * 2 ] = res.x ;
6165 res_ptrs[i * 2 + 1 ] = res.y ;
0 commit comments