| 3406 | // ggml_mul |
| 3407 | |
| 3408 | static struct ggml_tensor * ggml_mul_impl( |
| 3409 | struct ggml_context * ctx, |
| 3410 | struct ggml_tensor * a, |
| 3411 | struct ggml_tensor * b, |
| 3412 | bool inplace) { |
| 3413 | // TODO: support less-strict constraint |
| 3414 | // GGML_ASSERT(ggml_can_repeat(b, a)); |
| 3415 | GGML_ASSERT(ggml_can_repeat_rows(b, a)); |
| 3416 | |
| 3417 | bool is_node = false; |
| 3418 | |
| 3419 | if (!inplace && (a->grad || b->grad)) { |
| 3420 | // TODO: support backward pass for broadcasting |
| 3421 | GGML_ASSERT(ggml_are_same_shape(a, b)); |
| 3422 | is_node = true; |
| 3423 | } |
| 3424 | |
| 3425 | if (inplace) { |
| 3426 | GGML_ASSERT(!is_node); |
| 3427 | } |
| 3428 | |
| 3429 | struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a); |
| 3430 | |
| 3431 | result->op = GGML_OP_MUL; |
| 3432 | result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL; |
| 3433 | result->src[0] = a; |
| 3434 | result->src[1] = b; |
| 3435 | |
| 3436 | return result; |
| 3437 | } |
| 3438 | |
| 3439 | struct ggml_tensor * ggml_mul( |
| 3440 | struct ggml_context * ctx, |
no test coverage detected