| 452 | } |
| 453 | |
| 454 | std::optional<ValueRefList> addAxis_grad_rule( |
| 455 | const OpDef& op, Span<ValueRef> inputs, Span<bool> inputs_require_grad, |
| 456 | CustomBackward& backward) { |
| 457 | auto&& addAxis = op.cast_final_safe<AddAxis>(); |
| 458 | mgb_assert(inputs.size() == 1); |
| 459 | bool flag = inputs_require_grad[0]; |
| 460 | auto&& grad_op = RemoveAxis::make(addAxis.axis); |
| 461 | std::sort(grad_op->axis.begin(), grad_op->axis.end(), std::greater<int32_t>()); |
| 462 | auto maker = CustomGradMaker(backward, inputs.size()); |
| 463 | maker.output_size(1).output_captured(0, false); |
| 464 | maker.backward([grad_op_ = std::move(grad_op), flag_ = flag](Span<ValueRef> grads) { |
| 465 | mgb_assert(grads.size() == 1); |
| 466 | ValueRef grad = grads[0]; |
| 467 | SmallVector<ValueRef> ret(1); |
| 468 | if (grad && flag_) { |
| 469 | ret[0] = imperative::apply(*grad_op_, grad)[0]; |
| 470 | } |
| 471 | return ret; |
| 472 | }); |
| 473 | maker.finalize(); |
| 474 | return imperative::apply(op, inputs); |
| 475 | } |
| 476 | |
| 477 | std::optional<ValueRefList> removeAxis_grad_rule( |
| 478 | const OpDef& op, Span<ValueRef> inputs, Span<bool> inputs_require_grad, |
nothing calls this directly
no test coverage detected