| 459 | |
| 460 | #if MGB_ENABLE_GRAD |
| 461 | MGB_IMPL_OPR_GRAD(Elemwise) { |
| 462 | SymbolVar i[5]; |
| 463 | SymbolVar i0(opr.input(0)), i1, i2, out(opr.output(0)), og{out_grad.at(0)}, result; |
| 464 | for (size_t t = 0; t < opr.input().size(); ++t) |
| 465 | i[t] = opr.input()[t]; |
| 466 | if (opr.input().size() >= 2) |
| 467 | i1 = opr.input(1); |
| 468 | if (opr.input().size() >= 3) |
| 469 | i2 = opr.input(2); |
| 470 | |
| 471 | // negate after reduce, for better performance |
| 472 | bool negate_result = false; |
| 473 | #define RET(_v) \ |
| 474 | result = (_v); \ |
| 475 | break |
| 476 | #define EL1(_mode, _a) Elemwise::make({_a}, Mode::_mode) |
| 477 | #define EL2(_mode, _a, _b) Elemwise::make({_a, _b}, Mode::_mode) |
| 478 | #define EL3(_mode, _a, _b, _c) Elemwise::make({_a, _b, _c}, Mode::_mode) |
| 479 | #define RET_INVALID() return InvalidGrad::make(opr, wrt_idx) |
| 480 | |
| 481 | using Mode = Elemwise::Mode; |
| 482 | |
| 483 | switch (opr.param().mode) { |
| 484 | // unary |
| 485 | case Mode::RELU: |
| 486 | case Mode::FUSE_ADD_RELU: |
| 487 | RET(EL2(SWITCH_GT0, out, og)); |
| 488 | case Mode::ABS: |
| 489 | RET(EL2(ABS_GRAD, i0, og)); |
| 490 | case Mode::ACOS: |
| 491 | negate_result = true; |
| 492 | RET(og / EL1(SIN, out)); |
| 493 | case Mode::ASIN: |
| 494 | RET(og / EL1(COS, out)); |
| 495 | case Mode::ATAN2: |
| 496 | if (wrt_idx) { |
| 497 | negate_result = true; |
| 498 | } |
| 499 | RET(og * i[!wrt_idx] / (i0 * i0 + i1 * i1)); |
| 500 | case Mode::CEIL: |
| 501 | return nullptr; |
| 502 | case Mode::COS: |
| 503 | negate_result = true; |
| 504 | RET(EL1(SIN, i0) * og); |
| 505 | case Mode::EXP: |
| 506 | RET(og * out); |
| 507 | case Mode::EXPM1: |
| 508 | RET(og * EL1(EXP, i0)); |
| 509 | case Mode::FLOOR: |
| 510 | return nullptr; |
| 511 | case Mode::LOG: |
| 512 | RET(og / i0); |
| 513 | case Mode::LOG1P: |
| 514 | RET(og / (i0 + 1)); |
| 515 | case Mode::NEGATE: |
| 516 | negate_result = true; |
| 517 | RET(og); |
| 518 | case Mode::SIGMOID: |
nothing calls this directly
no test coverage detected