MCPcopy Create free account
hub / github.com/ROCm/AMDMIGraphX / apply

Method apply

src/fuse_attention.cpp:428–609  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

426 }
427
428 void apply(module_pass_manager& mpm, const match::matcher_result& r) const
429 {
430 auto& mm = mpm.get_module();
431 auto attn_group_ins = r.instructions["group"];
432 auto* submod = attn_group_ins->module_inputs().front();
433
434 // TODO: for this pass of flash decoding, if LSE attn, do not do flash decoding
435 auto return_ins = std::prev(submod->end());
436 assert(return_ins->name() == "@return" and
437 "Last instruction must be a @return instruction");
438 if(return_ins->inputs().size() > 1)
439 return;
440
441 // get gemm1 and gemm2
442 auto [gemm1, gemm2] = get_gemms(submod);
443
444 // TODO: for this first pass of flash decoding, assuming no input fusion / not supporting
445 auto q_param = gemm1->inputs()[0];
446 auto k_param = gemm1->inputs()[1];
447 auto v_param = gemm2->inputs()[1];
448 assert(q_param->name() == "@param" and "Q should be a parameter");
449 assert(k_param->name() == "@param" and "K should be a parameter");
450 assert(v_param->name() == "@param" and "V should be a parameter");
451
452 // check if N dimension is evenly divisible by num_splits
453 if(k_param->get_shape().lens().back() % groups != 0)
454 return;
455
456 // get Q, V, K shapes from gemms
457 auto qkv_shapes = get_qkv_shapes(q_param, k_param, v_param);
458
459 // check shapes are ok and get flash decoding transformed shapes (Q', V', K')
460 auto transform_info = get_transformed_shapes(qkv_shapes);
461
462 // create mapping from submodule params to main module inputs
463 auto group_inputs = attn_group_ins->inputs();
464 auto map_param_to_main = map_submod_params_to_inputs(submod, group_inputs);
465
466 // get actual Q, K, V instructions from main module
467 auto q = map_param_to_main.at(q_param);
468 auto k = map_param_to_main.at(k_param);
469 auto v = map_param_to_main.at(v_param);
470
471 // insert reshape operations before group, for Q, K, V
472 auto q_ndim = q->get_shape().lens().size();
473 int64_t g_axis = q_ndim - 2;
474
475 // Q: [B, M, k] -> [B, G, M, k] via unsqueeze + broadcast
476 auto q_unsqueeze =
477 mm.insert_instruction(attn_group_ins, make_op("unsqueeze", {{"axes", {g_axis}}}), q);
478 auto q_reshaped =
479 mm.insert_instruction(attn_group_ins,
480 make_op("multibroadcast", {{"out_lens", transform_info.q_shape}}),
481 q_unsqueeze);
482
483 // K: [B, k, N] -> [B, G, k, N/G] via reshape + transpose
484 auto k_reshaped_intermediate = mm.insert_instruction(
485 attn_group_ins, make_op("reshape", {{"dims", transform_info.k_intermediate}}), k);

Callers

nothing calls this directly

Calls 15

get_moduleMethod · 0.80
frontMethod · 0.80
backMethod · 0.80
lensMethod · 0.80
atMethod · 0.80
insert_instructionMethod · 0.80
set_bypassMethod · 0.80
add_parameterMethod · 0.80
replace_instructionMethod · 0.80
make_opFunction · 0.70
endMethod · 0.45
nameMethod · 0.45

Tested by

no test coverage detected