@@ -3098,12 +3098,6 @@ static vk_fa_tuning_params get_fa_tuning_params_coopmat2(const vk_device& device
30983098}
30993099
31003100static vk_fa_tuning_params get_fa_tuning_params(const vk_device& device, uint32_t hsk, uint32_t hsv, uint32_t n_rows, uint32_t n_kv, ggml_type k_type, ggml_type v_type, bool f32acc) {
3101- // Mixed K/V is only implemented on the coopmat2 (flash_attn_cm2) path; never use scalar/cm1.
3102- if (k_type != v_type) {
3103- GGML_ASSERT(device->coopmat2);
3104- return get_fa_tuning_params_coopmat2(device, hsk, hsv, n_rows, n_kv, k_type, v_type, f32acc);
3105- }
3106-
31073101 FaCodePath path = device->coopmat2 ? FA_COOPMAT2 :
31083102 device->coopmat1_fa_support ? FA_COOPMAT1 : FA_SCALAR;
31093103
@@ -3115,7 +3109,7 @@ static vk_fa_tuning_params get_fa_tuning_params(const vk_device& device, uint32_
31153109 if (path == FA_COOPMAT1) {
31163110 bool shape_ok = (f32acc && device->coopmat_support_16x16x16_f32acc) ||
31173111 (!f32acc && device->coopmat_support_16x16x16_f16acc);
3118- const vk_fa_tuning_params params = get_fa_tuning_params_coopmat1(device, hsk, hsv, n_rows, n_kv, k_type, f32acc);
3112+ const vk_fa_tuning_params params = get_fa_tuning_params_coopmat1(device, hsk, hsv, n_rows, n_kv, k_type, v_type, f32acc);
31193113 bool shmem_ok = ggml_vk_flash_attn_coopmat_shmem_support(device, params, hsk, hsv, f32acc);
31203114
31213115 if (!shape_ok || !shmem_ok) {
@@ -3135,9 +3129,9 @@ static vk_fa_tuning_params get_fa_tuning_params(const vk_device& device, uint32_
31353129
31363130 switch (path) {
31373131 case FA_SCALAR:
3138- return get_fa_tuning_params_scalar(device, hsk, hsv, n_rows, n_kv, k_type, f32acc);
3132+ return get_fa_tuning_params_scalar(device, hsk, hsv, n_rows, n_kv, k_type, v_type, f32acc);
31393133 case FA_COOPMAT1:
3140- return get_fa_tuning_params_coopmat1(device, hsk, hsv, n_rows, n_kv, k_type, f32acc);
3134+ return get_fa_tuning_params_coopmat1(device, hsk, hsv, n_rows, n_kv, k_type, v_type, f32acc);
31413135 case FA_COOPMAT2:
31423136 return get_fa_tuning_params_coopmat2(device, hsk, hsv, n_rows, n_kv, k_type, v_type, f32acc);
31433137 default:
@@ -3731,35 +3725,29 @@ static void ggml_vk_load_shaders(vk_device& device) {
37313725#endif
37323726
37333727#if defined(VK_NV_cooperative_matrix2) && defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
3734- #define CREATE_FA_CM2_MIXED() \
3735- for (int fa_k_ty = 0; fa_k_ty < (int)GGML_TYPE_COUNT; ++fa_k_ty) { \
3736- for (auto &fa : device->pipeline_flash_attn_f32_f16[fa_k_ty]) { \
3737- FaCodePath path = fa.first.path; \
3738- uint32_t Br = fa.first.Br; \
3739- uint32_t Bc = fa.first.Bc; \
3740- bool aligned = fa.first.aligned; \
3741- bool f32acc = fa.first.f32acc; \
3742- if (path == FA_COOPMAT2) { \
3743- if (aligned) { \
3744- if (f32acc) { \
3745- ggml_vk_create_pipeline(device, fa.second, "flash_attn_f32_f16_mixed_aligned_f32acc_cm2", flash_attn_f32_f16_mixed_cm2_len, flash_attn_f32_f16_mixed_cm2_data, "main", 7, sizeof(vk_flash_attn_push_constants), {Br, 1, 1}, get_fa_spec_constants(fa.first), Bc, true, false, 0); \
3746- } else { \
3747- ggml_vk_create_pipeline(device, fa.second, "flash_attn_f32_f16_mixed_aligned_f16acc_cm2", flash_attn_f32_f16_mixed_f16acc_cm2_len, flash_attn_f32_f16_mixed_f16acc_cm2_data, "main", 7, sizeof(vk_flash_attn_push_constants), {Br, 1, 1}, get_fa_spec_constants(fa.first), Bc, true, false, 0); \
3748- } \
3749- } else { \
3750- if (f32acc) { \
3751- ggml_vk_create_pipeline(device, fa.second, "flash_attn_f32_f16_mixed_f32acc_cm2", flash_attn_f32_f16_mixed_cm2_len, flash_attn_f32_f16_mixed_cm2_data, "main", 7, sizeof(vk_flash_attn_push_constants), {Br, 1, 1}, get_fa_spec_constants(fa.first), 1, true, false, 0); \
3752- } else { \
3753- ggml_vk_create_pipeline(device, fa.second, "flash_attn_f32_f16_mixed_f16acc_cm2", flash_attn_f32_f16_mixed_f16acc_cm2_len, flash_attn_f32_f16_mixed_f16acc_cm2_data, "main", 7, sizeof(vk_flash_attn_push_constants), {Br, 1, 1}, get_fa_spec_constants(fa.first), 1, true, false, 0); \
3754- } \
3755- } \
3756- } \
3757- } \
3758- }
37593728 if (device->coopmat2) {
3760- CREATE_FA_CM2_MIXED();
3729+ for (auto &fa : device->pipeline_flash_attn_f32_f16) {
3730+ if (fa.first.path != FA_COOPMAT2) continue;
3731+ const uint32_t Br = fa.first.Br;
3732+ const uint32_t Bc = fa.first.Bc;
3733+ const bool aligned = fa.first.aligned;
3734+ const bool f32acc = fa.first.f32acc;
3735+
3736+ const void * spv_data;
3737+ size_t spv_size;
3738+ const char * name;
3739+ if (aligned) {
3740+ if (f32acc) { spv_data = flash_attn_f32_f16_cm2_data; spv_size = flash_attn_f32_f16_cm2_len; name = "flash_attn_f32_f16_aligned_f32acc_cm2"; }
3741+ else { spv_data = flash_attn_f32_f16_f16acc_cm2_data; spv_size = flash_attn_f32_f16_f16acc_cm2_len; name = "flash_attn_f32_f16_aligned_f16acc_cm2"; }
3742+ } else {
3743+ if (f32acc) { spv_data = flash_attn_f32_f16_cm2_data; spv_size = flash_attn_f32_f16_cm2_len; name = "flash_attn_f32_f16_f32acc_cm2"; }
3744+ else { spv_data = flash_attn_f32_f16_f16acc_cm2_data; spv_size = flash_attn_f32_f16_f16acc_cm2_len; name = "flash_attn_f32_f16_f16acc_cm2"; }
3745+ }
3746+ ggml_vk_create_pipeline(device, fa.second, name, spv_size, spv_data, "main", 7,
3747+ sizeof(vk_flash_attn_push_constants), {Br, 1, 1},
3748+ get_fa_spec_constants(fa.first), aligned ? Bc : 1, true, false, 0);
3749+ }
37613750 }
3762- #undef CREATE_FA_CM2_MIXED
37633751#endif
37643752
37653753 const int mul_mat_id_param_count = 5;
@@ -9313,10 +9301,6 @@ static void ggml_vk_flash_attn(ggml_backend_vk_context * ctx, vk_context& subctx
93139301
93149302 tuning_params = get_fa_tuning_params(ctx->device, HSK, HSV, N, KV, k->type, v->type, f32acc);
93159303
9316- if (tuning_params.path != FA_COOPMAT2) {
9317- GGML_ASSERT(k->type == v->type);
9318- }
9319-
93209304 const uint32_t q_stride = (uint32_t)(nbq1 / ggml_type_size(q->type));
93219305 uint32_t k_stride = (uint32_t)(nbk1 / ggml_type_size(k->type));
93229306 uint32_t v_stride = (uint32_t)(nbv1 / ggml_type_size(v->type));
@@ -16108,10 +16092,6 @@ static bool ggml_backend_vk_device_supports_op(ggml_backend_dev_t dev, const ggm
1610816092 if (op->src[3] && op->src[3]->type != GGML_TYPE_F16) {
1610916093 return false;
1611016094 }
16111- // mismatching K/V type is currently supported for coopmat2 only.
16112- if (op->src[1]->type != op->src[2]->type && !coopmat2) {
16113- return false;
16114- }
1611516095 auto fa_kv_ok = [coopmat2](ggml_type t) {
1611616096 switch (t) {
1611716097 case GGML_TYPE_F32:
0 commit comments