diff --git a/source/adios2/common/ADIOSTypes.h b/source/adios2/common/ADIOSTypes.h index d93acad679..bfc0ef6df0 100644 --- a/source/adios2/common/ADIOSTypes.h +++ b/source/adios2/common/ADIOSTypes.h @@ -427,6 +427,8 @@ constexpr char MDR[] = "mdr"; namespace mdr { +constexpr double DOUBLE_ROUNDING_ERROR_LIMIT = 5.0e-16; +constexpr double FLOAT_ROUNDING_ERROR_LIMIT = 3.0e-7; namespace key {} } diff --git a/source/adios2/operator/refactor/RefactorMDR.cpp b/source/adios2/operator/refactor/RefactorMDR.cpp index a78c2e012c..b2a5518bfa 100644 --- a/source/adios2/operator/refactor/RefactorMDR.cpp +++ b/source/adios2/operator/refactor/RefactorMDR.cpp @@ -462,7 +462,16 @@ size_t RefactorMDR::ReconstructV1(const char *bufferIn, const size_t sizeIn, cha std::cout << ")\n"; }*/ - m_AccuracyProvided.error = m_AccuracyRequested.error; + if (type == DataType::FloatComplex || type == DataType::Float) + { + m_AccuracyProvided.error = + std::max(m_AccuracyRequested.error, adios2::ops::mdr::FLOAT_ROUNDING_ERROR_LIMIT); + } + else + { + m_AccuracyProvided.error = + std::max(m_AccuracyRequested.error, adios2::ops::mdr::DOUBLE_ROUNDING_ERROR_LIMIT); + } m_AccuracyProvided.norm = m_AccuracyRequested.norm; m_AccuracyProvided.relative = false; // should be m_AccuracyRequested.relative diff --git a/testing/adios2/engine/bp/operations/TestBPWriteReadMGARDMDR.cpp b/testing/adios2/engine/bp/operations/TestBPWriteReadMGARDMDR.cpp index f99042b67c..084e21631b 100644 --- a/testing/adios2/engine/bp/operations/TestBPWriteReadMGARDMDR.cpp +++ b/testing/adios2/engine/bp/operations/TestBPWriteReadMGARDMDR.cpp @@ -24,9 +24,6 @@ class BPWriteReadMGARDMDR : public ::testing::TestWithParam virtual void TearDown(){}; }; -constexpr double DOUBLE_ERROR_TOLERANCE = 5.0e-16; -constexpr float FLOAT_ERROR_TOLERANCE = 3.0e-7; - TEST_F(BPWriteReadMGARDMDR, BPWRMGARD1D) { // Refactor a dataset with MDR, then @@ -141,15 +138,19 @@ TEST_F(BPWriteReadMGARDMDR, BPWRMGARD1D) bpReader.Get(var_r32, read32s, adios2::Mode::Sync); bpReader.Get(var_r64, read64s, adios2::Mode::Sync); - auto accuracyGot = var_r32.GetAccuracy(); - assert(accuracyGot.error == accuracyRequested.error); - assert(accuracyGot.norm == accuracyRequested.norm); - assert(accuracyGot.relative == accuracyRequested.relative); + auto accuracyGot32 = var_r32.GetAccuracy(); + assert(accuracyGot32.error <= + std::max(accuracyRequested.error, + adios2::ops::mdr::FLOAT_ROUNDING_ERROR_LIMIT)); + assert(accuracyGot32.norm == accuracyRequested.norm); + assert(accuracyGot32.relative == accuracyRequested.relative); - accuracyGot = var_r64.GetAccuracy(); - assert(accuracyGot.error == accuracyRequested.error); - assert(accuracyGot.norm == accuracyRequested.norm); - assert(accuracyGot.relative == accuracyRequested.relative); + auto accuracyGot64 = var_r64.GetAccuracy(); + assert(accuracyGot64.error <= + std::max(accuracyRequested.error, + adios2::ops::mdr::DOUBLE_ROUNDING_ERROR_LIMIT)); + assert(accuracyGot64.norm == accuracyRequested.norm); + assert(accuracyGot64.relative == accuracyRequested.relative); double maxDiff = 0.0, relativeMaxDiff = 0.0; size_t maxDiffPos = 0; @@ -167,10 +168,10 @@ TEST_F(BPWriteReadMGARDMDR, BPWRMGARD1D) auto r64s_Max = std::max_element(r64s.begin(), r64s.end()); relativeMaxDiff = maxDiff / *r64s_Max; std::cout << "double array: Relative Max Diff " << relativeMaxDiff << " Max Diff " - << maxDiff << " requested error " << error << " max diff pos " - << maxDiffPos << " orig value " << r64s[maxDiffPos] << " read value " - << read64s[maxDiffPos] << "\n"; - ASSERT_LE(maxDiff, error + DOUBLE_ERROR_TOLERANCE); + << maxDiff << " requested error " << error << " result error " + << accuracyGot64.error << " max diff pos " << maxDiffPos << " orig value " + << r64s[maxDiffPos] << " read value " << read64s[maxDiffPos] << "\n"; + ASSERT_LE(maxDiff, accuracyGot64.error); for (size_t i = 0; i < Nx; ++i) { @@ -178,6 +179,7 @@ TEST_F(BPWriteReadMGARDMDR, BPWRMGARD1D) if (diff > maxDiff) { maxDiff = diff; + maxDiffPos = i; } } @@ -185,8 +187,10 @@ TEST_F(BPWriteReadMGARDMDR, BPWRMGARD1D) relativeMaxDiff = maxDiff / *r32s_Max; std::cout << "float array: Relative Max Diff " << relativeMaxDiff << " Max Diff " - << maxDiff << " requested error " << error << "\n"; - ASSERT_LE(maxDiff, error + FLOAT_ERROR_TOLERANCE); + << maxDiff << " requested error " << error << " result error " + << accuracyGot32.error << " max diff pos " << maxDiffPos << " orig value " + << r32s[maxDiffPos] << " read value " << read32s[maxDiffPos] << "\n"; + ASSERT_LE(maxDiff, accuracyGot32.error); } bpReader.EndStep(); ++t;