From 5abfd160c76ee3a17f52136b4a015294e6d228dd Mon Sep 17 00:00:00 2001 From: "Nakasaka, Masato" Date: Tue, 28 Oct 2025 17:28:10 +0900 Subject: [PATCH 1/6] Experimenting crash fix --- ggml/src/ggml-vulkan/ggml-vulkan.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp index 21bd052255564..8f40ef2edee39 100644 --- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -5097,15 +5097,22 @@ static vk_matmul_pipeline ggml_vk_get_mul_mat_mat_id_pipeline(ggml_backend_vk_co // XXX TODO 'prec' is not actually allowed in mul_mat_id. bool prefer_fp16acc = ctx->device->fp16 /*&& prec == GGML_PREC_DEFAULT*/; - bool support_fp16acc = ctx->device->pipeline_dequant_mul_mat_mat_id[src0_type].f16acc != nullptr; - bool support_fp32acc = ctx->device->pipeline_dequant_mul_mat_mat_id[src0_type].f32acc != nullptr; - - if (support_fp16acc && (prefer_fp16acc || !support_fp32acc)) { - return ctx->device->pipeline_dequant_mul_mat_mat_id[src0_type].f16acc; - } else { - GGML_ASSERT(support_fp32acc); - return ctx->device->pipeline_dequant_mul_mat_mat_id[src0_type].f32acc; + auto& mmp = ctx->device->pipeline_dequant_mul_mat_mat_id[src0_type]; + if (ctx->device->coopmat_support) { + // coopmat may or may not have f16acc and f32acc. It may also lack some child pipelines + if (ctx->device->coopmat_acc_f16_support && prefer_fp16acc) { + return mmp.f16acc; + } else if (ctx->device->coopmat_acc_f32_support) { + return mmp.f32acc; + } else { + // No supported pipeline + return nullptr; + } } + // coopmat2 or no coopmat. + // coopmat2 should support both f16acc and f32acc by default with all child pipelines. + // No coopmat should support both f16acc and f32acc when FP16 is preferred, but only f32acc when not preferred. + return prefer_fp16acc ? mmp.f16acc : mmp.f32acc; } static vk_pipeline ggml_vk_get_dequantize_mul_mat_vec_id(ggml_backend_vk_context * ctx, ggml_type a_type, ggml_type b_type) { From c5474a68b0e0f720950535ca830a71772d8a306e Mon Sep 17 00:00:00 2001 From: "Nakasaka, Masato" Date: Wed, 29 Oct 2025 10:12:51 +0900 Subject: [PATCH 2/6] added assert for aborting and fixed comment --- ggml/src/ggml-vulkan/ggml-vulkan.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp index 8f40ef2edee39..e9ef47d796758 100644 --- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -5105,13 +5105,13 @@ static vk_matmul_pipeline ggml_vk_get_mul_mat_mat_id_pipeline(ggml_backend_vk_co } else if (ctx->device->coopmat_acc_f32_support) { return mmp.f32acc; } else { - // No supported pipeline - return nullptr; + // f16acc nor f32acc is supported so we just abort + GGML_ASSERT(false); } } - // coopmat2 or no coopmat. + // coopmat2 or no coopmat comes here. // coopmat2 should support both f16acc and f32acc by default with all child pipelines. - // No coopmat should support both f16acc and f32acc when FP16 is preferred, but only f32acc when not preferred. + // No coopmat should support both f16acc and f32acc when FP16 is preferred, but only f32acc when FP16 is not preferred. return prefer_fp16acc ? mmp.f16acc : mmp.f32acc; } From 21915e277da5a526d48f6522e8e6cddb6da1748c Mon Sep 17 00:00:00 2001 From: "Nakasaka, Masato" Date: Thu, 30 Oct 2025 10:26:25 +0900 Subject: [PATCH 3/6] changed to check if a pipeline is empty or not --- ggml/src/ggml-vulkan/ggml-vulkan.cpp | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp index a5b3d971ef590..6121dcadd4ba8 100644 --- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -145,8 +145,15 @@ static void ggml_vk_destroy_pipeline(vk::Device& device, vk_pipeline& pipeline); struct vk_matmul_pipeline_struct { vk_pipeline l, m, s; vk_pipeline a_l, a_m, a_s; + // Returns true when all member pipelines are null + bool is_empty() const; }; +bool vk_matmul_pipeline_struct::is_empty() const { + return l == nullptr && m == nullptr && s == nullptr && + a_l == nullptr && a_m == nullptr && a_s == nullptr; +} + typedef std::shared_ptr vk_matmul_pipeline; struct vk_matmul_pipeline2 { @@ -4930,7 +4937,7 @@ static vk_matmul_pipeline ggml_vk_get_mul_mat_mat_pipeline(ggml_backend_vk_conte if (src1_type == GGML_TYPE_Q8_1) { vk_matmul_pipeline pipelines = (ctx->device->fp16 && prec == GGML_PREC_DEFAULT) ? ctx->device->pipeline_dequant_mul_mat_mat_q8_1[src0_type].f16acc : ctx->device->pipeline_dequant_mul_mat_mat_q8_1[src0_type].f32acc; - if (pipelines->s == nullptr && pipelines->m == nullptr && pipelines->l == nullptr) { + if (pipelines->is_empty()) { return nullptr; } @@ -5103,24 +5110,18 @@ static vk_matmul_pipeline ggml_vk_get_mul_mat_mat_id_pipeline(ggml_backend_vk_co return nullptr; } + vk_matmul_pipeline2& mmp = ctx->device->pipeline_dequant_mul_mat_mat_id[src0_type]; // XXX TODO 'prec' is not actually allowed in mul_mat_id. bool prefer_fp16acc = ctx->device->fp16 /*&& prec == GGML_PREC_DEFAULT*/; - auto& mmp = ctx->device->pipeline_dequant_mul_mat_mat_id[src0_type]; - if (ctx->device->coopmat_support) { - // coopmat may or may not have f16acc and f32acc. It may also lack some child pipelines - if (ctx->device->coopmat_acc_f16_support && prefer_fp16acc) { - return mmp.f16acc; - } else if (ctx->device->coopmat_acc_f32_support) { - return mmp.f32acc; - } else { - // f16acc nor f32acc is supported so we just abort - GGML_ASSERT(false); - } + bool support_fp16acc = !mmp.f16acc->is_empty(); + bool support_fp32acc = !mmp.f32acc->is_empty(); + + if (support_fp16acc && (prefer_fp16acc || !support_fp32acc)) { + return mmp.f16acc; + } else { + GGML_ASSERT(support_fp32acc); + return mmp.f32acc; } - // coopmat2 or no coopmat comes here. - // coopmat2 should support both f16acc and f32acc by default with all child pipelines. - // No coopmat should support both f16acc and f32acc when FP16 is preferred, but only f32acc when FP16 is not preferred. - return prefer_fp16acc ? mmp.f16acc : mmp.f32acc; } static vk_pipeline ggml_vk_get_dequantize_mul_mat_vec_id(ggml_backend_vk_context * ctx, ggml_type a_type, ggml_type b_type) { From f89fdb7db56b661c9c822f258f0ed28330693ba7 Mon Sep 17 00:00:00 2001 From: "Nakasaka, Masato" Date: Thu, 30 Oct 2025 10:38:02 +0900 Subject: [PATCH 4/6] Moved function in class definition --- ggml/src/ggml-vulkan/ggml-vulkan.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp index 6121dcadd4ba8..18925a9ee4d88 100644 --- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -146,14 +146,11 @@ struct vk_matmul_pipeline_struct { vk_pipeline l, m, s; vk_pipeline a_l, a_m, a_s; // Returns true when all member pipelines are null - bool is_empty() const; + bool is_empty() const { + return l == nullptr && m == nullptr && s == nullptr && + a_l == nullptr && a_m == nullptr && a_s == nullptr; + } }; - -bool vk_matmul_pipeline_struct::is_empty() const { - return l == nullptr && m == nullptr && s == nullptr && - a_l == nullptr && a_m == nullptr && a_s == nullptr; -} - typedef std::shared_ptr vk_matmul_pipeline; struct vk_matmul_pipeline2 { From 358eb97e416579c166e10afb8f7308e9c64210b6 Mon Sep 17 00:00:00 2001 From: "Nakasaka, Masato" Date: Thu, 30 Oct 2025 11:20:48 +0900 Subject: [PATCH 5/6] replaced with is_empty --- ggml/src/ggml-vulkan/ggml-vulkan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp index c20bf3d35afe7..13fd4cc7f7d88 100644 --- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -5230,7 +5230,7 @@ static vk_matmul_pipeline ggml_vk_get_mul_mat_mat_id_pipeline(ggml_backend_vk_co if (src1_type == GGML_TYPE_Q8_1) { vk_matmul_pipeline pipelines = ctx->device->pipeline_dequant_mul_mat_mat_id_q8_1[src0_type].f32acc; - if (pipelines->s == nullptr && pipelines->m == nullptr && pipelines->l == nullptr) { + if (pipelines->is_empty()) { return nullptr; } From 00faab11d1a1d6a1e60cddc4e864c46c24dcc9dd Mon Sep 17 00:00:00 2001 From: "Nakasaka, Masato" Date: Fri, 31 Oct 2025 14:20:51 +0900 Subject: [PATCH 6/6] Modified is_empty to check only unaligned pipelines --- ggml/src/ggml-vulkan/ggml-vulkan.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp index 55d029882a87e..c3e5a9eccc3aa 100644 --- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -145,10 +145,11 @@ static void ggml_vk_destroy_pipeline(vk::Device& device, vk_pipeline& pipeline); struct vk_matmul_pipeline_struct { vk_pipeline l, m, s; vk_pipeline a_l, a_m, a_s; - // Returns true when all member pipelines are null + // Returns true when all unaligned pipelines are null. + // We only check for unaligned variants since one of the unaligned pipelines must exist + // while aligned pipelines are optional bool is_empty() const { - return l == nullptr && m == nullptr && s == nullptr && - a_l == nullptr && a_m == nullptr && a_s == nullptr; + return l == nullptr && m == nullptr && s == nullptr; } }; typedef std::shared_ptr vk_matmul_pipeline;