| #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; |
| } |
| } |