From 5d68d57483689c6a7cc6fc5c34f61f4de930a5ea Mon Sep 17 00:00:00 2001 From: Jongsoo Park Date: Tue, 13 Nov 2018 23:40:59 -0800 Subject: [PATCH] consistent rounding Summary: The vectorized code was rounding to even in halfway cases with _mm256_round_ps + (_MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC) (see more details in https://software.intel.com/en-us/node/523819), but we were still using std::round in a couple of places which does rounding away from zero in halfway cases. With this diff, we use std::nearbyint in all scalar code (except a few cases where we don't care exact rounding mode and uses rint which is the fastest in general) to be more consistent. nearbyint is the same as what the vectorized code does only when the current rounding mode is FE_TONEAREST but in practice this is OK because we almost always use the default rounding mode FE_TONEAREST. This is inspired by Marat's diff for mobile quantization. Reviewed By: dskhudia Differential Revision: D13017719 fbshipit-source-id: 3f5f4677b597663e1a34461feaacce71ac0e6c29 --- src/PackWithQuantRowOffset.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PackWithQuantRowOffset.cc b/src/PackWithQuantRowOffset.cc index 15cd737df1..a3d7e0f3eb 100644 --- a/src/PackWithQuantRowOffset.cc +++ b/src/PackWithQuantRowOffset.cc @@ -181,7 +181,7 @@ void PackAWithQuantRowOffset::pack(const block_type_t& block) { float clipped = std::min( std::max(transformed, std::numeric_limits::min()), std::numeric_limits::max()); - T res = round(clipped); + T res = nearbyint(clipped); row_sum += res; out[i * BaseType::blockColSize() + j] = res; }