[Mlir-commits] [mlir] 1c0374e - [mlir] Add polynomial approximation for math::Log1p
Eugene Zhulenev
llvmlistbot at llvm.org
Mon May 3 15:11:44 PDT 2021
Author: Emilio Cota
Date: 2021-05-03T15:11:37-07:00
New Revision: 1c0374e770956037764f9cae8a5e35ec7cefcdc5
URL: https://github.com/llvm/llvm-project/commit/1c0374e770956037764f9cae8a5e35ec7cefcdc5
DIFF: https://github.com/llvm/llvm-project/commit/1c0374e770956037764f9cae8a5e35ec7cefcdc5.diff
LOG: [mlir] Add polynomial approximation for math::Log1p
This approximation matches the one in Eigen.
```
name old cpu/op new cpu/op delta
BM_mlir_Log1p_f32/10 83.2ns ± 7% 34.8ns ± 5% -58.19% (p=0.000 n=84+71)
BM_mlir_Log1p_f32/100 664ns ± 4% 129ns ± 4% -80.57% (p=0.000 n=82+82)
BM_mlir_Log1p_f32/1k 6.75µs ± 4% 0.81µs ± 3% -88.07% (p=0.000 n=88+79)
BM_mlir_Log1p_f32/10k 76.5µs ± 3% 7.8µs ± 4% -89.84% (p=0.000 n=80+80)
BM_eigen_s_Log1p_f32/10 70.1ns ±14% 72.6ns ±14% +3.49% (p=0.000 n=116+112)
BM_eigen_s_Log1p_f32/100 706ns ± 9% 717ns ± 3% +1.60% (p=0.018 n=117+80)
BM_eigen_s_Log1p_f32/1k 8.26µs ± 1% 8.26µs ± 1% ~ (p=0.567 n=84+86)
BM_eigen_s_Log1p_f32/10k 92.1µs ± 5% 92.6µs ± 6% +0.60% (p=0.047 n=115+115)
BM_eigen_v_Log1p_f32/10 31.8ns ±24% 34.9ns ±17% +9.72% (p=0.000 n=98+96)
BM_eigen_v_Log1p_f32/100 169ns ±10% 177ns ± 5% +4.66% (p=0.000 n=119+81)
BM_eigen_v_Log1p_f32/1k 1.42µs ± 4% 1.46µs ± 8% +2.70% (p=0.000 n=93+113)
BM_eigen_v_Log1p_f32/10k 14.4µs ± 5% 14.9µs ± 8% +3.61% (p=0.000 n=115+110)
```
Reviewed By: ezhulenev, ftynse
Differential Revision: https://reviews.llvm.org/D101765
Added:
Modified:
mlir/lib/Dialect/Math/Transforms/PolynomialApproximation.cpp
mlir/test/Dialect/Math/polynomial-approximation.mlir
mlir/test/mlir-cpu-runner/math_polynomial_approx.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/Math/Transforms/PolynomialApproximation.cpp b/mlir/lib/Dialect/Math/Transforms/PolynomialApproximation.cpp
index d9c78f527c8a..79856b9596dc 100644
--- a/mlir/lib/Dialect/Math/Transforms/PolynomialApproximation.cpp
+++ b/mlir/lib/Dialect/Math/Transforms/PolynomialApproximation.cpp
@@ -413,6 +413,53 @@ struct Log2Approximation : public LogApproximationBase<math::Log2Op> {
};
} // namespace
+//----------------------------------------------------------------------------//
+// Log1p approximation.
+//----------------------------------------------------------------------------//
+
+namespace {
+struct Log1pApproximation : public OpRewritePattern<math::Log1pOp> {
+public:
+ using OpRewritePattern::OpRewritePattern;
+
+ LogicalResult matchAndRewrite(math::Log1pOp op,
+ PatternRewriter &rewriter) const final;
+};
+} // namespace
+
+// Approximate log(1+x).
+LogicalResult
+Log1pApproximation::matchAndRewrite(math::Log1pOp op,
+ PatternRewriter &rewriter) const {
+ auto width = vectorWidth(op.operand().getType(), isF32);
+ if (!width.hasValue())
+ return rewriter.notifyMatchFailure(op, "unsupported operand type");
+
+ ImplicitLocOpBuilder builder(op->getLoc(), rewriter);
+ auto bcast = [&](Value value) -> Value {
+ return broadcast(builder, value, *width);
+ };
+
+ // Approximate log(1+x) using the following, due to W. Kahan:
+ // u = x + 1.0;
+ // if (u == 1.0 || u == inf) return x;
+ // return x * log(u) / (u - 1.0);
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // "logLarge" below.
+ Value cstOne = bcast(f32Cst(builder, 1.0f));
+ Value x = op.operand();
+ Value u = builder.create<AddFOp>(x, cstOne);
+ Value uSmall = builder.create<CmpFOp>(CmpFPredicate::OEQ, u, cstOne);
+ Value logU = builder.create<math::LogOp>(u);
+ Value uInf = builder.create<CmpFOp>(CmpFPredicate::OEQ, u, logU);
+ Value logLarge = builder.create<MulFOp>(
+ x, builder.create<DivFOp>(logU, builder.create<SubFOp>(u, cstOne)));
+ Value approximation = builder.create<SelectOp>(
+ builder.create<LLVM::OrOp>(uSmall, uInf), x, logLarge);
+ rewriter.replaceOp(op, approximation);
+ return success();
+}
+
//----------------------------------------------------------------------------//
// Exp approximation.
//----------------------------------------------------------------------------//
@@ -534,5 +581,5 @@ ExpApproximation::matchAndRewrite(math::ExpOp op,
void mlir::populateMathPolynomialApproximationPatterns(
RewritePatternSet &patterns) {
patterns.add<TanhApproximation, LogApproximation, Log2Approximation,
- ExpApproximation>(patterns.getContext());
+ Log1pApproximation, ExpApproximation>(patterns.getContext());
}
diff --git a/mlir/test/Dialect/Math/polynomial-approximation.mlir b/mlir/test/Dialect/Math/polynomial-approximation.mlir
index 5e3b3098cfac..5a54d4a7f10a 100644
--- a/mlir/test/Dialect/Math/polynomial-approximation.mlir
+++ b/mlir/test/Dialect/Math/polynomial-approximation.mlir
@@ -10,7 +10,8 @@ func @scalar(%arg0: f32) -> f32 {
// CHECK-NOT: log
%1 = math.log %0 : f32
%2 = math.log2 %1 : f32
- return %2 : f32
+ %3 = math.log1p %2 : f32
+ return %3 : f32
}
// CHECK-LABEL: @vector
@@ -20,7 +21,8 @@ func @vector(%arg0: vector<8xf32>) -> vector<8xf32> {
// CHECK-NOT: log
%1 = math.log %0 : vector<8xf32>
%2 = math.log2 %1 : vector<8xf32>
- return %2 : vector<8xf32>
+ %3 = math.log1p %2 : vector<8xf32>
+ return %3 : vector<8xf32>
}
// CHECK-LABEL: @exp_scalar
diff --git a/mlir/test/mlir-cpu-runner/math_polynomial_approx.mlir b/mlir/test/mlir-cpu-runner/math_polynomial_approx.mlir
index 02fc5241f452..558bc949283a 100644
--- a/mlir/test/mlir-cpu-runner/math_polynomial_approx.mlir
+++ b/mlir/test/mlir-cpu-runner/math_polynomial_approx.mlir
@@ -110,6 +110,45 @@ func @log2() {
return
}
+func @log1p() {
+ // CHECK: 0.00995033
+ %0 = constant 0.01 : f32
+ %1 = math.log1p %0 : f32
+ vector.print %1 : f32
+
+ // CHECK: -4.60517, -0.693147, 0, 1.38629
+ %2 = constant dense<[-0.99, -0.5, 0.0, 3.0]> : vector<4xf32>
+ %3 = math.log1p %2 : vector<4xf32>
+ vector.print %3 : vector<4xf32>
+
+ // CHECK: 0.0953102, 0.182322, 0.262364, 0.336472, 0.405465, 0.470004, 0.530628, 0.587787
+ %4 = constant dense<[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]> : vector<8xf32>
+ %5 = math.log1p %4 : vector<8xf32>
+ vector.print %5 : vector<8xf32>
+
+ // CHECK: -inf
+ %neg_one = constant -1.0 : f32
+ %log_neg_one = math.log1p %neg_one : f32
+ vector.print %log_neg_one : f32
+
+ // CHECK: nan
+ %neg_two = constant -2.0 : f32
+ %log_neg_two = math.log1p %neg_two : f32
+ vector.print %log_neg_two : f32
+
+ // CHECK: inf
+ %inf = constant 0x7f800000 : f32
+ %log_inf = math.log1p %inf : f32
+ vector.print %log_inf : f32
+
+ // CHECK: -inf, nan, inf, 9.99995e-06
+ %special_vec = constant dense<[-1.0, -1.1, 0x7f800000, 0.00001]> : vector<4xf32>
+ %log_special_vec = math.log1p %special_vec : vector<4xf32>
+ vector.print %log_special_vec : vector<4xf32>
+
+ return
+}
+
// -------------------------------------------------------------------------- //
// Exp.
// -------------------------------------------------------------------------- //
@@ -151,6 +190,7 @@ func @main() {
call @tanh(): () -> ()
call @log(): () -> ()
call @log2(): () -> ()
+ call @log1p(): () -> ()
call @exp(): () -> ()
return
}
More information about the Mlir-commits
mailing list