@@ -54,7 +54,8 @@ public:
5454
5555 template <bool kShouldAdvance = true >
5656 CUDA_INLINE void load (int4 *smem_ptr, void *mbar_ptr) {
57- if constexpr (Ctx::kUseRawWeight && !kUseTma ) load_raw (smem_ptr);
57+ if constexpr (Ctx::kUseFlatWeight && !kUseTma ) load_flat (smem_ptr);
58+ else if constexpr (Ctx::kUseRawWeight && !kUseTma ) load_raw (smem_ptr);
5859 else if constexpr (kUseAiu ) load_aiu (smem_ptr);
5960 else if constexpr (kUseTma ) load_tma (smem_ptr, mbar_ptr);
6061 else load_legacy (smem_ptr);
@@ -76,22 +77,21 @@ public:
7677 CUDA_INLINE
7778 void load_tma (int4 *smem_ptr, void *mbar_ptr) {
7879 if (ctx.load_thread_id () == 0 ) {
79- if constexpr (Ctx::kUseRawWeight ) {
80+ if constexpr (Ctx::kUseFlatWeight ) {
81+ uint32_t expert_k = col_offset / ProblemShape::N * ProblemShape::K + row_offset;
82+ if (cluster_rank == 0 )
83+ tma_load_5d<kMultiCastSizeB >(tensor_map_ptr, smem_ptr, mbar_ptr,
84+ 0 , col_offset % 64 / 16 , col_offset % ProblemShape::N / 64 , 0 , expert_k * ElementQB::kBits / 128 );
85+ } else if constexpr (Ctx::kUseRawWeight ) {
8086 constexpr uint32_t kCoordinateBits = SharedStorage::kExpandUmmaWeight ? 1 : 32 / ElementQB::kBits ;
8187 uint32_t start_k = kCoordinateBits == 1 ? row_offset / 128 * 128 : row_offset;
82- if constexpr (Ctx::kUseWgmmaTmaKPack ) {
83- if (cluster_rank == 0 )
84- tma_load_5d<kMultiCastSizeB >(tensor_map_ptr, smem_ptr, mbar_ptr,
85- 0 , 0 , col_offset / Ctx::WarpShape::N, 0 , start_k / kSwizzleK );
86- } else {
88+ PRAGMA_UNROLL
89+ for (uint32_t k = 0 ; k < SharedStorage::kWeightStageK ; k += kSwizzleK ) {
8790 PRAGMA_UNROLL
88- for (uint32_t k = 0 ; k < SharedStorage::kWeightStageK ; k += kSwizzleK ) {
89- PRAGMA_UNROLL
90- for (uint32_t n = 0 ; n < SharedStorage::kWeightStageN ; n += 256 ) {
91- uint32_t offset = (k / kSwizzleK * SharedStorage::kWeightStageN + n) * kSwizzleBytes / sizeof (int4 );
92- if (cluster_rank == 0 ) tma_load_2d<kMultiCastSizeB , kEvictWeightsFirst , Ctx::kUseUmmaCooperativeTma ? 2 : 1 >(
93- tensor_map_ptr, smem_ptr + offset, mbar_ptr, (start_k + k) / kCoordinateBits , col_offset + n);
94- }
91+ for (uint32_t n = 0 ; n < SharedStorage::kWeightStageN ; n += 256 ) {
92+ uint32_t offset = (k / kSwizzleK * SharedStorage::kWeightStageN + n) * kSwizzleBytes / sizeof (int4 );
93+ if (cluster_rank == 0 ) tma_load_2d<kMultiCastSizeB , kEvictWeightsFirst , Ctx::kUseUmmaCooperativeTma ? 2 : 1 >(
94+ tensor_map_ptr, smem_ptr + offset, mbar_ptr, (start_k + k) / kCoordinateBits , col_offset + n);
9595 }
9696 }
9797 } else if constexpr (kMultiCastSizeB == 1 ) {
@@ -106,12 +106,12 @@ public:
106106 void prefetch_tma () {
107107 if constexpr (kUseTma && kMultiCastSizeB == 1 ) {
108108 if (ctx.load_thread_id () == 0 ) {
109- if constexpr (!Ctx::kUseRawWeight ) tma_prefetch_3d (tensor_map_ptr, 0 , col_offset, row_offset);
109+ if constexpr (!Ctx::kUseRawWeight && !Ctx:: kUseFlatWeight ) tma_prefetch_3d (tensor_map_ptr, 0 , col_offset, row_offset);
110110 }
111111 }
112112 }
113113
114- CUDA_INLINE static uint32_t permute_raw_ss_row (uint32_t row) {
114+ CUDA_INLINE static uint32_t permute_wgmma_ss_row (uint32_t row) {
115115 constexpr uint32_t kWarpN = Ctx::WarpShape::N;
116116 constexpr uint32_t kGroupN = 4 * kWarpN ;
117117 uint32_t row_in_group = row % kGroupN ;
@@ -127,36 +127,34 @@ public:
127127 constexpr uint32_t kGlobalRowInt4s = ProblemShape::K * ElementQB::kBits / 128 ;
128128 constexpr uint32_t kSwizzleInt4s = kSwizzleBytes / sizeof (int4 );
129129 uint32_t smem_base = cast_smem_ptr_to_uint (smem_ptr) / 128 ;
130- constexpr uint32_t kRowsPerIteration = kNumLoadThreads / kRowInt4s ;
131- constexpr bool kPowerOfTwoRows = kRowsPerIteration != 0 && (kRowsPerIteration & (kRowsPerIteration - 1 )) == 0 ;
132- constexpr bool kPowerOfTwoWarpN = (Ctx::WarpShape::N & (Ctx::WarpShape::N - 1 )) == 0 ;
133- constexpr bool kSplitRowPermutation =
134- Ctx::kUseWgmmaCpAsyncNPermute && kNumLoadThreads % kRowInt4s == 0 && kPowerOfTwoRows && kPowerOfTwoWarpN ;
135- uint32_t permuted_thread_row = 0 ;
136- if constexpr (kSplitRowPermutation ) {
137- // The thread and unrolled iteration own disjoint row bits. Permute
138- // thread bits once; the iteration contribution folds to constants.
139- uint32_t thread_row = (ctx.load_thread_id () / kRowInt4s ) % kRowsPerIteration ;
140- permuted_thread_row = permute_raw_ss_row (thread_row);
141- }
142130 PRAGMA_UNROLL
143131 for (uint32_t i = 0 ; i < CEIL_DIV (BlockShape::N * kRowInt4s , kNumLoadThreads ); ++i) {
144132 uint32_t index = i * kNumLoadThreads + ctx.load_thread_id ();
145133 uint32_t row = index / kRowInt4s ;
146134 uint32_t col = index % kRowInt4s ;
147- uint32_t smem_row = row;
148- if constexpr (Ctx::kUseWgmmaCpAsyncNPermute ) {
149- if constexpr (kSplitRowPermutation ) {
150- smem_row = permuted_thread_row + permute_raw_ss_row (i * kRowsPerIteration );
151- } else smem_row = permute_raw_ss_row (row);
152- }
153- uint32_t offset = (col / kSwizzleInt4s * BlockShape::N + smem_row) * kSwizzleInt4s + col % kSwizzleInt4s ;
135+ uint32_t offset = (col / kSwizzleInt4s * BlockShape::N + row) * kSwizzleInt4s + col % kSwizzleInt4s ;
154136 uint32_t swizzled_offset = offset ^ ((smem_base + offset / 8 ) % kSwizzleInt4s );
155137 legacy_load_pred<kUseCpAsync >(gmem_ptr + row * kGlobalRowInt4s + col,
156138 smem_ptr + swizzled_offset, row < BlockShape::N);
157139 }
158140 }
159141
142+ CUDA_INLINE
143+ void load_flat (int4 *smem_ptr) {
144+ constexpr uint32_t kChunkRows = MIN (64u , BlockShape::N);
145+ constexpr uint32_t kTileInt4s = kChunkRows * BlockShape::K * ElementQB::kBits / 128 ;
146+ PRAGMA_UNROLL
147+ for (uint32_t i = 0 ; i < CEIL_DIV (kNumInt4s , kNumLoadThreads ); ++i) {
148+ uint32_t index = i * kNumLoadThreads + ctx.load_thread_id ();
149+ uint32_t row = index / kTileInt4s * 64 + index % kChunkRows ;
150+ uint32_t col = index % kTileInt4s / kChunkRows ;
151+ if constexpr (Ctx::kUseWgmmaCpAsyncNPermute ) row = permute_wgmma_ss_row (row);
152+ uint32_t offset = col * BlockShape::N + row;
153+ uint32_t gmem_offset = col * ProblemShape::N + index / kTileInt4s * 64 + index % kChunkRows ;
154+ legacy_load_pred<kUseCpAsync >(gmem_ptr + gmem_offset, smem_ptr + offset, index < kNumInt4s );
155+ }
156+ }
157+
160158 CUDA_INLINE
161159 void load_raw_aiu (int4 *smem_ptr) {
162160 const uint32_t warp_id = ctx.load_thread_id () / 32 ;
@@ -179,9 +177,9 @@ public:
179177
180178 CUDA_INLINE
181179 void advance () {
182- if constexpr (Ctx::kUseRawWeight ) {
180+ if constexpr (Ctx::kUseRawWeight || Ctx:: kUseFlatWeight ) {
183181 row_offset += BlockShape::K;
184- if constexpr (!kUseTma ) gmem_ptr += BlockShape::K * ElementQB::kBits / 128 ;
182+ if constexpr (!kUseTma ) gmem_ptr += BlockShape::K * ElementQB::kBits / 128 * (Ctx:: kUseFlatWeight ? ProblemShape::N : 1 ) ;
185183 return ;
186184 }
187185 row_offset += BlockShape::K / kPackSizeK ;
@@ -190,12 +188,18 @@ public:
190188
191189 CUDA_INLINE
192190 void seek (uint32_t expert_id, uint32_t n_block_id, uint32_t k_block_id) {
193- if constexpr (Ctx::kUseRawWeight ) {
191+ if constexpr (Ctx::kUseRawWeight || Ctx:: kUseFlatWeight ) {
194192 row_offset = k_block_id * BlockShape::K;
195193 col_offset = expert_id * ProblemShape::N + n_block_id * BlockShape::N;
196194 if constexpr (!kUseTma ) {
197- uint64_t offset = uint64_t (col_offset) * ProblemShape::K + row_offset;
198- gmem_ptr = gmem_ptr_raw + offset * ElementQB::kBits / 128 ;
195+ if constexpr (Ctx::kUseFlatWeight ) {
196+ uint64_t expert_offset = uint64_t (expert_id) * ProblemShape::N * ProblemShape::K;
197+ uint64_t offset = expert_offset + uint64_t (row_offset) * ProblemShape::N;
198+ gmem_ptr = gmem_ptr_raw + offset * ElementQB::kBits / 128 + n_block_id * BlockShape::N;
199+ } else {
200+ uint64_t offset = uint64_t (col_offset) * ProblemShape::K + row_offset;
201+ gmem_ptr = gmem_ptr_raw + offset * ElementQB::kBits / 128 ;
202+ }
199203 }
200204 return ;
201205 }
0 commit comments