| 5438 | } |
| 5439 | |
| 5440 | struct ggml_tensor * ggml_conv_transpose_2d_p0( |
| 5441 | struct ggml_context * ctx, |
| 5442 | struct ggml_tensor * a, |
| 5443 | struct ggml_tensor * b, |
| 5444 | int stride) { |
| 5445 | GGML_ASSERT(a->ne[3] == b->ne[2]); |
| 5446 | |
| 5447 | bool is_node = false; |
| 5448 | |
| 5449 | if (a->grad || b->grad) { |
| 5450 | GGML_ASSERT(false); // TODO: implement backward |
| 5451 | is_node = true; |
| 5452 | } |
| 5453 | |
| 5454 | const int64_t ne[4] = { |
| 5455 | ggml_calc_conv_transpose_output_size(b->ne[0], a->ne[0], stride, 0 /*p0*/), |
| 5456 | ggml_calc_conv_transpose_output_size(b->ne[1], a->ne[1], stride, 0 /*p1*/), |
| 5457 | a->ne[2], b->ne[3], |
| 5458 | }; |
| 5459 | |
| 5460 | struct ggml_tensor* result = ggml_new_tensor(ctx, GGML_TYPE_F32, 4, ne); |
| 5461 | |
| 5462 | ggml_set_op_params_i32(result, 0, stride); |
| 5463 | |
| 5464 | result->op = GGML_OP_CONV_TRANSPOSE_2D; |
| 5465 | result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL; |
| 5466 | result->src[0] = a; |
| 5467 | result->src[1] = b; |
| 5468 | |
| 5469 | return result; |
| 5470 | } |
| 5471 | |
| 5472 | // ggml_pool_* |
| 5473 |
nothing calls this directly
no test coverage detected