| 506 | REGISTER_GRADIENT_OP("AddN", AddNGrad); |
| 507 | |
| 508 | Status PowGrad(const Scope& scope, const Operation& op, |
| 509 | const std::vector<Output>& grad_inputs, |
| 510 | std::vector<Output>* grad_outputs) { |
| 511 | auto x = ConjugateHelper(scope, op.input(0)); |
| 512 | auto y = ConjugateHelper(scope, op.input(1)); |
| 513 | auto z = ConjugateHelper(scope, op.output(0)); |
| 514 | auto grad = grad_inputs[0]; |
| 515 | // grad * y * pow(x, y - 1) |
| 516 | auto one = Cast(scope, Const(scope, 1.0), y.type()); |
| 517 | auto gx_1 = Mul(scope, |
| 518 | Mul(scope, grad, y), |
| 519 | Pow(scope, x, Sub(scope, y, one))); |
| 520 | // Avoid false singularity at x = 0 |
| 521 | DataType x_dtype = x.type(); |
| 522 | auto zero = Cast(scope, Const(scope, 0.0), x_dtype); |
| 523 | if (x_dtype == DT_COMPLEX64 || x_dtype == DT_COMPLEX128) { |
| 524 | // real(x) < 0 is fine for the complex case |
| 525 | auto log_x = Where3(scope, |
| 526 | NotEqual(scope, x, zero), |
| 527 | Log(scope, x), |
| 528 | ZerosLike(scope, x)); |
| 529 | auto gy_1 = Mul(scope, Mul(scope, grad, z), log_x); |
| 530 | return BinaryGradCommon(scope, op, grad_outputs, gx_1, gy_1); |
| 531 | } else { |
| 532 | // There's no sensible real value to return if x < 0, so return 0 |
| 533 | auto log_x = Where3(scope, |
| 534 | Greater(scope, x, zero), |
| 535 | Log(scope, x), |
| 536 | ZerosLike(scope, x)); |
| 537 | auto gy_1 = Mul(scope, Mul(scope, grad, z), log_x); |
| 538 | return BinaryGradCommon(scope, op, grad_outputs, gx_1, gy_1); |
| 539 | } |
| 540 | } |
| 541 | REGISTER_GRADIENT_OP("Pow", PowGrad); |
| 542 | |
| 543 | // MaximumMinimumGradCommon adds shared ops to calculate gradients for |
nothing calls this directly
no test coverage detected