| 3218 | } |
| 3219 | |
| 3220 | static struct ggml_tensor * ggml_add_idx_impl( |
| 3221 | struct ggml_context * ctx, |
| 3222 | struct ggml_tensor * a, |
| 3223 | struct ggml_tensor * b, |
| 3224 | struct ggml_tensor * idx, |
| 3225 | bool inplace) { |
| 3226 | // TODO: support less-strict constraint |
| 3227 | // GGML_ASSERT(ggml_can_repeat(b, a)); |
| 3228 | // GGML_ASSERT(ggml_can_repeat_rows(b, a)); |
| 3229 | // printf("in add_idx\n"); |
| 3230 | if (a == NULL) |
| 3231 | return b; |
| 3232 | if (b == NULL) |
| 3233 | return a; |
| 3234 | |
| 3235 | bool is_node = false; |
| 3236 | |
| 3237 | if (!inplace && (a->grad || b->grad)) { |
| 3238 | // TODO: support backward pass for broadcasting |
| 3239 | GGML_ASSERT(ggml_are_same_shape(a, b)); |
| 3240 | is_node = true; |
| 3241 | } |
| 3242 | |
| 3243 | struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a); |
| 3244 | |
| 3245 | result->op = GGML_OP_ADD; |
| 3246 | result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL; |
| 3247 | result->src[0] = a; |
| 3248 | result->src[1] = b; |
| 3249 | result->src[2] = idx; |
| 3250 | |
| 3251 | return result; |
| 3252 | } |
| 3253 | // add for all gather |
| 3254 | struct ggml_tensor * ggml_add_idx( |
| 3255 | struct ggml_context * ctx, |
no test coverage detected