Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion ggml/src/ggml-cuda/mmq.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -4076,14 +4076,26 @@ void mul_mat_q_case(ggml_backend_cuda_context & ctx, const mmq_args & args, cuda
int mmq_x_best = 0;
int ntiles_x_best = INT_MAX;

// ncols_max assumes every token can land in a single tile column range; for MoE that is the
// worst case of all tokens routed to one expert, but experts typically receive only
// ncols_dst/nchannels_y tokens. Tiling over ~2x that average keeps the common per-expert
// tiles filled instead of mostly empty; the 2x covers routing imbalance and larger batches
// converge back to ncols_max.
// Restricted to RDNA3.5, the only arch this MoE tile sizing was tuned/validated on.
int64_t ncols_to_tile = args.ncols_max;
if (args.expert_bounds != nullptr && GGML_CUDA_CC_IS_RDNA3_5(cc)) {
const int64_t ncols_per_expert = (args.ncols_dst + args.nchannels_y - 1) / args.nchannels_y;
ncols_to_tile = 2*ncols_per_expert < args.ncols_max ? 2*ncols_per_expert : args.ncols_max;
}

for (int mmq_x = 8; mmq_x <= mmq_x_max && ntiles_x_best > 1; mmq_x += 8) {
const int granularity = mmq_get_granularity_host(mmq_x, cc);

if (mmq_x % granularity != 0 || mmq_get_nbytes_shared<type>(mmq_x, mmq_y, cc, warp_size, nwarps) > smpbo) {
continue;
}

const int ntiles_x = (args.ncols_max + mmq_x - 1) / mmq_x;
const int ntiles_x = (ncols_to_tile + mmq_x - 1) / mmq_x;

if (ntiles_x < ntiles_x_best) {
mmq_x_best = mmq_x;
Expand Down
Loading