@@ -54,10 +54,12 @@ __global__ static void gather_or_scatter_along_first_dim_kernel(
5454 int M = cute::get<0 >(problem_shape);
5555 int N = cute::get<1 >(problem_shape);
5656 int K = cute::get<2 >(problem_shape);
57+ int L = cute::get<3 >(problem_shape);
5758
5859 static_assert (cute::is_static<TileShape>::value);
5960 constexpr int kBlkNOrM = cute::size<0 >(tile_shape);
6061 constexpr int kBlkK = cute::size<1 >(tile_shape);
62+ constexpr int kBlkL = cute::size<2 >(tile_shape);
6163
6264 using SmemT = SharedStorage<kBlkNOrM , DataType, IndexType, SmemLayout>;
6365 constexpr int kPipeMax = SmemT::kPipeMax ;
@@ -79,15 +81,17 @@ __global__ static void gather_or_scatter_along_first_dim_kernel(
7981
8082 if (threadIdx .x == 0 ) {
8183 // Tensors on HBM.
82- cute::Tensor gA = tma_load_input.get_tma_tensor (cute::make_shape (M, K));
83- cute::Tensor gB = tma_store_output.get_tma_tensor (cute::make_shape (N, K));
84+ cute::Tensor gA = tma_load_input.get_tma_tensor (cute::make_shape (M, K, L));
85+ cute::Tensor gB =
86+ tma_store_output.get_tma_tensor (cute::make_shape (N, K, L));
8487 // Tensors on SMEM.
8588 cute::Tensor sA = cute::make_tensor (
8689 cute::make_smem_ptr (smem.data .data ()), cute::group<0 , 2 >(SmemLayout{}));
8790
88- constexpr int kTmaTransactionBytes = kBlkK * sizeof (DataType);
91+ constexpr int kTmaTransactionBytes = kBlkK * kBlkL * sizeof (DataType);
8992 const int kNumKTiles = ((K + kBlkK - 1 ) / kBlkK );
90- const int kNumNOrMKTiles = kBlkNOrM * kNumKTiles ;
93+ const int kNumNOrMKTiles =
94+ std::min (kBlkNOrM , indexing_dim - n_or_m_offset) * kNumKTiles ;
9195 const int kNumIterations = kNumNOrMKTiles + kPipeMax - 1 ;
9296
9397 for (int iteration = 0 ; iteration < kNumIterations ; ++iteration) {
@@ -110,12 +114,12 @@ __global__ static void gather_or_scatter_along_first_dim_kernel(
110114
111115 cute::Tensor tAgA = cute::local_tile (
112116 gA ,
113- cute::Tile<cute::_1, cute::Int<kBlkK >>{},
114- cute::make_coord (m, k));
117+ cute::Tile<cute::_1, cute::Int<kBlkK >, cute::Int< kBlkL > >{},
118+ cute::make_coord (m, k, 0 ));
115119 cute::Tensor tAsA = cute::local_tile (
116120 sA ,
117- cute::Tile<cute::_1, cute::Int<kBlkK >>{},
118- cute::make_coord (load_pipe, 0 ));
121+ cute::Tile<cute::_1, cute::Int<kBlkK >, cute::Int< kBlkL > >{},
122+ cute::make_coord (load_pipe, 0 , 0 ));
119123
120124 auto & tma_load_mbar = smem.tma_load_barrier [load_pipe];
121125 cute::initialize_barrier (smem.tma_load_barrier [load_pipe], 1 );
@@ -149,12 +153,12 @@ __global__ static void gather_or_scatter_along_first_dim_kernel(
149153
150154 cute::Tensor tAgB = cute::local_tile (
151155 gB ,
152- cute::Tile<cute::_1, cute::Int<kBlkK >>{},
153- cute::make_coord (n, k));
156+ cute::Tile<cute::_1, cute::Int<kBlkK >, cute::Int< kBlkL > >{},
157+ cute::make_coord (n, k, 0 ));
154158 cute::Tensor tAsA = cute::local_tile (
155159 sA ,
156- cute::Tile<cute::_1, cute::Int<kBlkK >>{},
157- cute::make_coord (store_pipe, 0 ));
160+ cute::Tile<cute::_1, cute::Int<kBlkK >, cute::Int< kBlkL > >{},
161+ cute::make_coord (store_pipe, 0 , 0 ));
158162
159163 auto tma_store_per_cta = tma_store_output.get_slice (0 );
160164 cute::copy (
@@ -205,36 +209,51 @@ void gather_or_scatter_along_first_dim(
205209 assert (dst.dtype () == TorchDTypeTrait<DataType>::dtype ());
206210 assert (index.dtype () == TorchDTypeTrait<IndexType>::dtype ());
207211
212+ constexpr int L = 256 ;
208213 const int M = src.size (0 );
209- const int K = src.size (1 );
210214 const int N = dst.size (0 );
215+ const int K = src.size (1 ) / L;
211216
212- auto src_gmem_layout =
213- cute::make_layout ( cute:: make_shape (M, K), cute::make_stride (K, 1 ));
217+ auto src_gmem_layout = cute::make_layout (
218+ cute::make_shape (M, K, L ), cute::make_stride (K * L, L , 1 ));
214219 auto src_gmem_tensor = cute::make_tensor (
215220 cute::make_gmem_ptr (reinterpret_cast <DataType*>(src.data_ptr ())),
216221 src_gmem_layout);
217222
218- auto dst_gmem_layout =
219- cute::make_layout ( cute:: make_shape (N, K), cute::make_stride (K, 1 ));
223+ auto dst_gmem_layout = cute::make_layout (
224+ cute::make_shape (N, K, L ), cute::make_stride (K * L, L , 1 ));
220225 auto dst_gmem_tensor = cute::make_tensor (
221226 cute::make_gmem_ptr (reinterpret_cast <DataType*>(dst.data_ptr ())),
222227 dst_gmem_layout);
223228
224229 constexpr int kBlkNOrM = 1 ;
225- constexpr int kBlkK = 256 ;
226- constexpr int kPipeMax = 4 ;
230+ constexpr int kBlkK = 4 ;
231+ constexpr int kBlkL = L;
232+ constexpr int kPipeMax = 3 ;
227233
228234 auto smem_layout = cute::make_layout (
229- cute::make_shape (cute::Int<kPipeMax >{}, cute::_1{}, cute::Int<kBlkK >{}),
230- cute::make_stride (cute::Int<kBlkK >{}, cute::Int<kBlkK >{}, cute::_1{}));
235+ cute::make_shape (
236+ cute::Int<kPipeMax >{},
237+ cute::_1{},
238+ cute::Int<kBlkK >{},
239+ cute::Int<kBlkL >{}),
240+ cute::make_stride (
241+ cute::Int<kBlkK * kBlkL >{},
242+ cute::Int<kBlkK * kBlkL >{},
243+ cute::Int<kBlkL >{},
244+ cute::_1{}));
231245 auto tma_load = cute::make_tma_copy (
232- cute::SM90_TMA_LOAD {}, src_gmem_tensor, smem_layout (0 , cute::_, cute::_));
246+ cute::SM90_TMA_LOAD {},
247+ src_gmem_tensor,
248+ smem_layout (0 , cute::_, cute::_, cute::_));
233249 auto tma_store = cute::make_tma_copy (
234- TMAStoreInst{}, dst_gmem_tensor, smem_layout (0 , cute::_, cute::_));
250+ TMAStoreInst{},
251+ dst_gmem_tensor,
252+ smem_layout (0 , cute::_, cute::_, cute::_));
235253
236- auto problem_shape = cute::make_shape (M, N, K);
237- auto tile_shape = cute::make_shape (cute::Int<kBlkNOrM >{}, cute::Int<kBlkK >{});
254+ auto problem_shape = cute::make_shape (M, N, K, L);
255+ auto tile_shape = cute::make_shape (
256+ cute::Int<kBlkNOrM >{}, cute::Int<kBlkK >{}, cute::Int<kBlkL >{});
238257
239258 using SmemT =
240259 SharedStorage<kBlkNOrM , DataType, IndexType, decltype (smem_layout)>;
0 commit comments