Implementation of FloorDiv. For floating-point values, simply returns floor(x / y). For integers, does: if ((x < 0) != (y < 0)) { T abs_x = std::abs(x); T abs_y = std::abs(y); return -(abs_x + abs_y - 1) / abs_y; } else { return x / y; }
| 112 | // return x / y; |
| 113 | // } |
| 114 | static xla::XlaOp FloorDivImpl(xla::XlaBuilder* b, DataType dtype, xla::XlaOp x, |
| 115 | xla::XlaOp y, const BCast& broadcast_helper) { |
| 116 | std::tie(x, y) = XlaBinaryOp::Broadcast(x, y, broadcast_helper); |
| 117 | if (DataTypeIsFloating(dtype)) { |
| 118 | if (dtype == DataType::DT_BFLOAT16) { |
| 119 | // The result of a BF16 division may produce the Ceil of what was |
| 120 | // computed by F32 division, so avoid end user confusion by doing the |
| 121 | // intermediate divide in F32. |
| 122 | return xla::ConvertElementType( |
| 123 | xla::Floor(xla::Div(xla::ConvertElementType(x, xla::F32), |
| 124 | xla::ConvertElementType(y, xla::F32))), |
| 125 | xla::BF16); |
| 126 | } else { |
| 127 | return xla::Floor(xla::Div(x, y)); |
| 128 | } |
| 129 | } |
| 130 | if (DataTypeIsUnsigned(dtype)) { |
| 131 | return xla::Div(x, y); |
| 132 | } |
| 133 | auto zero = XlaHelpers::Zero(b, dtype); |
| 134 | auto one = XlaHelpers::One(b, dtype); |
| 135 | auto different_sign = xla::Ne(xla::Lt(x, zero), xla::Lt(y, zero)); |
| 136 | auto abs_x = xla::Abs(x); |
| 137 | auto abs_y = xla::Abs(y); |
| 138 | auto t = xla::Neg(xla::Sub(xla::Add(abs_x, abs_y), one)); |
| 139 | return xla::Select(different_sign, xla::Div(t, abs_y), xla::Div(x, y)); |
| 140 | } |
| 141 | XLA_MAKE_BINARY(FloorDiv, |
| 142 | FloorDivImpl(b, input_type(0), lhs, rhs, broadcast_helper)); |
| 143 |
no test coverage detected