| #include <iostream> | |
| #include <random> | |
| #include "tanh.h" | |
| #include <gtest/gtest.h> | |
| #include "caffe2/core/logging.h" | |
| using namespace dnnlowp; | |
| using namespace std; | |
| TEST(Tanh, TanhUnitTest) { | |
| // For 8bit, we can go down to 0.0145631 | |
| // For 9bit in 8bit out, we can go down to 0.00976522 | |
| for (double max_abs_err = 0.02; max_abs_err <= 0.1; max_abs_err += 0.01) { | |
| Tanh<uint8_t> tanh_approx(max_abs_err); | |
| LOG(INFO) << "max_abs_err " << max_abs_err << " x_pq " | |
| << tanh_approx.GetPassRegionEndDequantized() << " x_sq " | |
| << tanh_approx.GetSaturationRegionBegin(); | |
| const int NSAMPLES = 1 << 16; | |
| std::uniform_real_distribution<float> distribution(-5., 5.); | |
| std::default_random_engine generator; | |
| float sq_err_sum = 0, max_err = 0; | |
| for (int i = 0; i < NSAMPLES; ++i) { | |
| float x = distribution(generator); | |
| uint8_t x_q = fbgemm::Quantize<uint8_t>( | |
| x, tanh_approx.GetInputQuantizationParams()); | |
| uint8_t y_q = tanh_approx.Compute(x_q); | |
| float y = fbgemm::Dequantize<uint8_t>( | |
| y_q, tanh_approx.GetOutputQuantizationParams()); | |
| float err = fabs(tanh(x) - y); | |
| sq_err_sum += err * err; | |
| max_err = std::max(err, max_err); | |
| if (err > max_abs_err) { | |
| LOG(INFO) << "x " << x << " tanh_real " << tanh(x) << " tanh_approx " | |
| << y << " err " << err << " x_q " << (int)x_q << " y_q " | |
| << (int)y_q; | |
| } | |
| EXPECT_LE(err, max_abs_err); | |
| } | |
| LOG(INFO) << "avg_l2_err " << std::sqrt(sq_err_sum) / NSAMPLES | |
| << " max_err " << max_err << endl; | |
| } | |
| } |