metal : fix null-pipeline crash for F16 src1 mul_mat/mul_mat_id (#25648)

* metal : fail closed on mul_mat shapes with missing F16 kernels

* metal : abort on nil pipeline in encoder_set_pipeline

* metal : address review comments

* metal : share mul_mat mm dispatch with supports_op
This commit is contained in:
QuintinShaw
2026-08-30 08:56:35 +03:00
committed by GitHub
parent bdf3955159
commit d882575cc8
4 changed files with 59 additions and 18 deletions
+36 -1
View File
@@ -3,6 +3,7 @@
#import "ggml-impl.h"
#import "ggml-backend-impl.h"
#import "ggml-metal-impl.h"
#import "ggml-metal-common.h"
#include <Foundation/Foundation.h>
@@ -788,6 +789,10 @@ void ggml_metal_encoder_debug_group_pop (ggml_metal_encoder_t encoder) {
}
void ggml_metal_encoder_set_pipeline(ggml_metal_encoder_t encoder, struct ggml_metal_pipeline_with_params pipeline) {
if (!pipeline.pipeline) {
GGML_ABORT("%s: nil Metal pipeline (missing kernel; see compile_pipeline log above)\n", __func__);
}
[encoder->obj setComputePipelineState:pipeline.pipeline->obj];
}
@@ -1410,6 +1415,30 @@ void ggml_metal_device_get_memory(ggml_metal_device_t dev, size_t * free, size_t
}
}
static bool ggml_metal_supports_mul_mat_op(
bool has_simdgroup_reduction,
const struct ggml_tensor * op,
bool src0_f16_has_mv,
bool mm_path) {
if (!has_simdgroup_reduction || op->src[0]->type == GGML_TYPE_NVFP4) {
return false;
}
if (op->src[1]->type != GGML_TYPE_F16) {
return true;
}
if (op->src[0]->type == GGML_TYPE_BF16) {
return false;
}
if (src0_f16_has_mv && op->src[0]->type == GGML_TYPE_F16) {
return true;
}
return mm_path;
}
bool ggml_metal_device_supports_op(ggml_metal_device_t dev, const struct ggml_tensor * op) {
const bool has_simdgroup_mm = dev->props.has_simdgroup_mm;
const bool has_simdgroup_reduction = dev->props.has_simdgroup_reduction;
@@ -1713,9 +1742,15 @@ bool ggml_metal_device_supports_op(ggml_metal_device_t dev, const struct ggml_te
case GGML_OP_GATED_DELTA_NET:
return has_simdgroup_reduction && op->src[2]->ne[0] % 32 == 0;
case GGML_OP_SOLVE_TRI:
return has_simdgroup_reduction && op->src[0]->type == GGML_TYPE_F32;
case GGML_OP_MUL_MAT:
return ggml_metal_supports_mul_mat_op(
has_simdgroup_reduction, op, true,
ggml_metal_op_mul_mat_use_mm(op, has_simdgroup_mm));
case GGML_OP_MUL_MAT_ID:
return has_simdgroup_reduction && op->src[0]->type != GGML_TYPE_NVFP4;
return ggml_metal_supports_mul_mat_op(
has_simdgroup_reduction, op, false,
ggml_metal_op_mul_mat_id_use_mm(op, has_simdgroup_mm));
case GGML_OP_SET:
case GGML_OP_CPY:
case GGML_OP_DUP: