| 4072 | // ggml_mul_mat |
| 4073 | |
| 4074 | struct ggml_tensor * ggml_mul_mat( |
| 4075 | struct ggml_context * ctx, |
| 4076 | struct ggml_tensor * a, |
| 4077 | struct ggml_tensor * b) { |
| 4078 | GGML_ASSERT(ggml_can_mul_mat(a, b)); |
| 4079 | GGML_ASSERT(!ggml_is_transposed(a)); |
| 4080 | |
| 4081 | bool is_node = false; |
| 4082 | |
| 4083 | if (a->grad || b->grad) { |
| 4084 | is_node = true; |
| 4085 | } |
| 4086 | |
| 4087 | const int64_t ne[4] = { a->ne[1], b->ne[1], b->ne[2], b->ne[3] }; |
| 4088 | struct ggml_tensor * result = ggml_new_tensor(ctx, GGML_TYPE_F32, MAX(a->n_dims, b->n_dims), ne); |
| 4089 | |
| 4090 | result->op = GGML_OP_MUL_MAT; |
| 4091 | result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL; |
| 4092 | result->src[0] = a; |
| 4093 | result->src[1] = b; |
| 4094 | result->src[2] = NULL; |
| 4095 | result->src[3] = NULL; |
| 4096 | |
| 4097 | return result; |
| 4098 | } |
| 4099 | |
| 4100 | struct ggml_tensor * ggml_mul_mat_idx_upscale( |
| 4101 | struct ggml_context * ctx, |