Fix TensorReduction warnings and error bound for sum accuracy test.

The sum accuracy test currently uses the default test precision for
the given scalar type.  However, scalars are generated via a normal
distribution, and given a large enough count and strong enough random
generator, the expected sum is zero.  This causes the test to
periodically fail.

Here we estimate an upper-bound for the error as `sqrt(N) * prec` for
summing N values, with each having an approximate epsilon of `prec`.

Also fixed a few warnings generated by MSVC when compiling the
reduction test.
This commit is contained in:
Antonio Sanchez 2021-10-29 22:03:44 +00:00 committed by Antonio Sanchez
parent b3bea43a2d
commit f6c8cc0e99
3 changed files with 8 additions and 4 deletions

View File

@ -76,7 +76,7 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp
typedef typename Base::CoeffReturnType CoeffReturnType; typedef typename Base::CoeffReturnType CoeffReturnType;
enum { enum {
IsAligned = bool(EIGEN_MAX_ALIGN_BYTES>0) & !(Options_&DontAlign), IsAligned = (EIGEN_MAX_ALIGN_BYTES>0) && !(Options_&DontAlign),
Layout = Options_ & RowMajor ? RowMajor : ColMajor, Layout = Options_ & RowMajor ? RowMajor : ColMajor,
CoordAccess = true, CoordAccess = true,
RawAccess = true RawAccess = true

View File

@ -633,7 +633,7 @@ static const bool RunningOnGPU = false;
m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]); m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]);
} }
} else { } else {
m_outputStrides[NumOutputDims - 1] = 1; m_outputStrides[static_cast<size_t>(NumOutputDims - 1)] = 1;
for (int i = NumOutputDims - 2; i >= 0; --i) { for (int i = NumOutputDims - 2; i >= 0; --i) {
m_outputStrides[i] = m_outputStrides[i + 1] * m_dimensions[i + 1]; m_outputStrides[i] = m_outputStrides[i + 1] * m_dimensions[i + 1];
m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]); m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]);
@ -680,7 +680,7 @@ static const bool RunningOnGPU = false;
? internal::array_prod(input_dims) ? internal::array_prod(input_dims)
: (static_cast<int>(Layout) == static_cast<int>(ColMajor)) : (static_cast<int>(Layout) == static_cast<int>(ColMajor))
? m_preservedStrides[0] ? m_preservedStrides[0]
: m_preservedStrides[NumOutputDims - 1]; : m_preservedStrides[static_cast<size_t>(NumOutputDims - 1)];
} }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }

View File

@ -504,7 +504,11 @@ void test_sum_accuracy() {
for (int i = 0; i < num_elements; ++i) { for (int i = 0; i < num_elements; ++i) {
expected_sum += static_cast<double>(tensor(i)); expected_sum += static_cast<double>(tensor(i));
} }
VERIFY_IS_APPROX(sum(), static_cast<ScalarType>(expected_sum)); // Scale tolerance to account for # elements. Otherwise, we periodically fail, since
// E[sum] == prescribed_mean == 0 for the first iteration.
double err = Eigen::numext::abs(static_cast<double>(sum()) - expected_sum);
double tol = Eigen::numext::sqrt(num_elements) * static_cast<double>(test_precision<ScalarType>()) * numext::maxi(1.0, prescribed_mean);
VERIFY(err < tol);
} }
} }