@@ -361,6 +361,10 @@ static int ggml_metal_op_encode_impl(ggml_metal_op_t ctx, int idx) {
361361 {
362362 n_fuse = ggml_metal_op_set_rows (ctx, idx);
363363 } break ;
364+ case GGML_OP_DIAG :
365+ {
366+ n_fuse = ggml_metal_op_diag (ctx, idx);
367+ } break ;
364368 case GGML_OP_L2_NORM :
365369 {
366370 n_fuse = ggml_metal_op_l2_norm (ctx, idx);
@@ -1259,6 +1263,48 @@ int ggml_metal_op_set_rows(ggml_metal_op_t ctx, int idx) {
12591263 return 1 ;
12601264}
12611265
1266+ int ggml_metal_op_diag (ggml_metal_op_t ctx, int idx) {
1267+ ggml_tensor * op = ctx->node (idx);
1268+
1269+ ggml_metal_library_t lib = ctx->lib ;
1270+ ggml_metal_encoder_t enc = ctx->enc ;
1271+
1272+ GGML_TENSOR_LOCALS (int32_t , ne0, op->src [0 ], ne);
1273+ GGML_TENSOR_LOCALS (uint64_t , nb0, op->src [0 ], nb);
1274+ GGML_TENSOR_LOCALS (int32_t , ne, op, ne);
1275+ GGML_TENSOR_LOCALS (uint64_t , nb, op, nb);
1276+
1277+ ggml_metal_kargs_diag args = {
1278+ /* .ne00 =*/ ne00,
1279+ /* .ne01 =*/ ne01,
1280+ /* .ne02 =*/ ne02,
1281+ /* .ne03 =*/ ne03,
1282+ /* .nb00 =*/ nb00,
1283+ /* .nb01 =*/ nb01,
1284+ /* .nb02 =*/ nb02,
1285+ /* .nb03 =*/ nb03,
1286+ /* .ne0 =*/ ne0,
1287+ /* .ne1 =*/ ne1,
1288+ /* .ne2 =*/ ne2,
1289+ /* .ne3 =*/ ne3,
1290+ /* .nb0 =*/ nb0,
1291+ /* .nb1 =*/ nb1,
1292+ /* .nb2 =*/ nb2,
1293+ /* .nb3 =*/ nb3,
1294+ };
1295+
1296+ auto pipeline = ggml_metal_library_get_pipeline_diag (lib, op);
1297+
1298+ ggml_metal_encoder_set_pipeline (enc, pipeline);
1299+ ggml_metal_encoder_set_bytes (enc, &args, sizeof (args), 0 );
1300+ ggml_metal_encoder_set_buffer (enc, ggml_metal_get_buffer_id (op->src [0 ]), 1 );
1301+ ggml_metal_encoder_set_buffer (enc, ggml_metal_get_buffer_id (op), 2 );
1302+
1303+ ggml_metal_encoder_dispatch_threadgroups (enc, ne1, ne2, ne3, 32 , 1 , 1 );
1304+
1305+ return 1 ;
1306+ }
1307+
12621308int ggml_metal_op_soft_max (ggml_metal_op_t ctx, int idx) {
12631309 ggml_tensor * op = ctx->node (idx);
12641310
0 commit comments