| 3146 | // ggml_add |
| 3147 | |
| 3148 | static struct ggml_tensor * ggml_add_impl( |
| 3149 | struct ggml_context * ctx, |
| 3150 | struct ggml_tensor * a, |
| 3151 | struct ggml_tensor * b, |
| 3152 | bool inplace) { |
| 3153 | // TODO: support less-strict constraint |
| 3154 | // GGML_ASSERT(ggml_can_repeat(b, a)); |
| 3155 | GGML_ASSERT(ggml_can_repeat_rows(b, a)); |
| 3156 | |
| 3157 | bool is_node = false; |
| 3158 | |
| 3159 | if (!inplace && (a->grad || b->grad)) { |
| 3160 | // TODO: support backward pass for broadcasting |
| 3161 | GGML_ASSERT(ggml_are_same_shape(a, b)); |
| 3162 | is_node = true; |
| 3163 | } |
| 3164 | |
| 3165 | struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a); |
| 3166 | |
| 3167 | result->op = GGML_OP_ADD; |
| 3168 | result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL; |
| 3169 | result->src[0] = a; |
| 3170 | result->src[1] = b; |
| 3171 | result->src[2] = NULL; |
| 3172 | |
| 3173 | return result; |
| 3174 | } |
| 3175 | |
| 3176 | struct ggml_tensor * ggml_add( |
| 3177 | struct ggml_context * ctx, |
no test coverage detected