Gradient of Gamma sample from Gamma(a, 1) with respect to `a`.
| 1000 | |
| 1001 | // Gradient of Gamma sample from Gamma(a, 1) with respect to `a`. |
| 1002 | XlaOp RandomGammaGrad(XlaOp a, XlaOp x) { |
| 1003 | auto& b = *a.builder(); |
| 1004 | auto doit = [&b](XlaOp a, XlaOp x, PrimitiveType type) -> XlaOp { |
| 1005 | XlaOp is_nan = Or(IsNan(a), IsNan(x)); |
| 1006 | XlaOp x_is_zero = Eq(x, ScalarLike(x, 0)); |
| 1007 | XlaOp domain_error = Or(Lt(x, ScalarLike(x, 0)), Le(a, ScalarLike(a, 0))); |
| 1008 | XlaOp use_igammac = And(Gt(x, ScalarLike(x, 1)), Gt(x, a)); |
| 1009 | XlaOp ax = a * Log(x) - x - Lgamma(a); |
| 1010 | XlaOp underflow = Lt(ax, -Log(MaxFiniteValue(&b, type))); |
| 1011 | ax = Exp(ax); |
| 1012 | XlaOp enabled = Not(Or(Or(Or(x_is_zero, domain_error), underflow), is_nan)); |
| 1013 | const double nan = std::numeric_limits<double>::quiet_NaN(); |
| 1014 | XlaOp output = Select(use_igammac, |
| 1015 | -IgammacContinuedFraction<SAMPLE_DERIVATIVE>( |
| 1016 | ax, x, a, And(enabled, use_igammac), type), |
| 1017 | IgammaSeries<SAMPLE_DERIVATIVE>( |
| 1018 | ax, x, a, And(enabled, Not(use_igammac)), type)); |
| 1019 | output = Select(underflow, ZerosLike(output), output); |
| 1020 | output = Select(x_is_zero, ZerosLike(output), output); |
| 1021 | output = Select(Or(domain_error, is_nan), FullLike(a, nan), output); |
| 1022 | return output; |
| 1023 | }; |
| 1024 | return b.ReportErrorOrReturn([&]() -> StatusOr<XlaOp> { |
| 1025 | TF_ASSIGN_OR_RETURN(auto a_shape, b.GetShape(a)); |
| 1026 | TF_ASSIGN_OR_RETURN(auto x_shape, b.GetShape(x)); |
| 1027 | if (a_shape != x_shape) { |
| 1028 | return InvalidArgument( |
| 1029 | "Arguments to RandomGammaGrad must have equal shapes and types; got " |
| 1030 | "%s and %s", |
| 1031 | a_shape.ToString(), x_shape.ToString()); |
| 1032 | } |
| 1033 | TF_RETURN_IF_ERROR(EnsureOperandIsRealFp("RandomGammaGrad", a)); |
| 1034 | bool needs_upcast = |
| 1035 | a_shape.element_type() == F16 || a_shape.element_type() == BF16; |
| 1036 | |
| 1037 | if (needs_upcast) { |
| 1038 | a = ConvertElementType(a, F32); |
| 1039 | x = ConvertElementType(x, F32); |
| 1040 | } |
| 1041 | XlaOp result = doit(a, x, a_shape.element_type()); |
| 1042 | if (needs_upcast) { |
| 1043 | result = ConvertElementType(result, a_shape.element_type()); |
| 1044 | } |
| 1045 | return result; |
| 1046 | }); |
| 1047 | } |
| 1048 | |
| 1049 | XlaOp Igammac(XlaOp a, XlaOp x) { |
| 1050 | auto& b = *a.builder(); |
nothing calls this directly
no test coverage detected