diff options
author | Xusong Wang <xusongw@google.com> | 2019-06-10 17:29:38 -0700 |
---|---|---|
committer | Xusong Wang <xusongw@google.com> | 2019-06-11 11:00:53 -0700 |
commit | f0b6c450af089a1d1078f070001581e5ea2c7cf3 (patch) | |
tree | 10db90d5dcb96f3f061a614456d60f4950cf6a95 | |
parent | 92dfcd3899bba47d1db562365635c165292fa514 (diff) | |
download | ml-f0b6c450af089a1d1078f070001581e5ea2c7cf3.tar.gz |
Relax the tolerable range for quant and boolean values.
Before this CL, the quant tolerable range is too strict for complex
operations such as HEATMAP_MAX_KEYPOINT. The absolute tolerance, bias,
and MSE criteria for quantized tensors are slightly relaxed.
Before this CL, the accuracy checker does not allow any boolean value
mismatch. However, there are several cases that two floating point values
are very close to each other, and the result of comparison operations, e.g.
GREATER, ends up to be flipped because of the accumulated error. With
this CL, we only expect the number of mismatches does not exceed a
certain ratio.
Bug: 134801089
Test: NNT_static_fuzzing
Change-Id: I7faabafce91b245f525b4ef39736862d82f38edc
-rw-r--r-- | nn/runtime/test/fuzzing/RandomGraphGenerator.cpp | 21 | ||||
-rw-r--r-- | nn/runtime/test/fuzzing/TestRandomGraph.cpp | 24 |
2 files changed, 27 insertions, 18 deletions
diff --git a/nn/runtime/test/fuzzing/RandomGraphGenerator.cpp b/nn/runtime/test/fuzzing/RandomGraphGenerator.cpp index 96ac5d11d..6c21b7eea 100644 --- a/nn/runtime/test/fuzzing/RandomGraphGenerator.cpp +++ b/nn/runtime/test/fuzzing/RandomGraphGenerator.cpp @@ -320,17 +320,26 @@ void expectNear(const RandomOperand& op, const OperandBuffer& test, EXPECT_LE(mse, criterion.mse); } -void expectBooleanEqual(const RandomOperand& op, const OperandBuffer& test) { +// For boolean values, we expect the number of mismatches does not exceed a certain ratio. +void expectBooleanNearlyEqual(const RandomOperand& op, const OperandBuffer& test, + float allowedErrorRatio) { const bool8* actual = reinterpret_cast<const bool8*>(test.data()); const bool8* expected = reinterpret_cast<const bool8*>(op.buffer.data()); uint32_t len = op.getNumberOfElements(); uint32_t numErrors = 0; + std::stringstream errorMsg; for (uint32_t i = 0; i < len; i++) { - SCOPED_TRACE(testing::Message() << "When comparing element " << i); - if (numErrors < kMaxNumberOfPrintedErrors) EXPECT_EQ(expected[i], actual[i]); - if (expected[i] != actual[i]) numErrors++; + if (expected[i] != actual[i]) { + if (numErrors < kMaxNumberOfPrintedErrors) + errorMsg << " Expected: " << expected[i] << ", actual: " << actual[i] + << ", when comparing element " << i << "\n"; + numErrors++; + } } - EXPECT_EQ(numErrors, 0u); + // When |len| is small, the allowedErrorCount will intentionally ceil at 1, which allows for + // greater tolerance. + uint32_t allowedErrorCount = static_cast<uint32_t>(std::ceil(allowedErrorRatio * len)); + EXPECT_LE(numErrors, allowedErrorCount) << errorMsg.str(); } void RandomGraph::checkResults(const std::vector<OperandBuffer>& buffers, @@ -367,7 +376,7 @@ void RandomGraph::checkResults(const std::vector<OperandBuffer>& buffers, expectNear<int16_t>(*op, buffers[i], criteria.quant16Symm); break; case Type::TENSOR_BOOL8: - expectBooleanEqual(*op, buffers[i]); + expectBooleanNearlyEqual(*op, buffers[i], /*allowedErrorRatio=*/0.01); break; default: NN_FUZZER_CHECK(false) << "Data type not supported."; diff --git a/nn/runtime/test/fuzzing/TestRandomGraph.cpp b/nn/runtime/test/fuzzing/TestRandomGraph.cpp index eb6d4c663..4135bc6f2 100644 --- a/nn/runtime/test/fuzzing/TestRandomGraph.cpp +++ b/nn/runtime/test/fuzzing/TestRandomGraph.cpp @@ -413,10 +413,10 @@ const AccuracyCriteria kRelaxedCriteria = { .float32 = {.atol = 1e-3f, .rtol = 1e-3f, .bias = 2e-5f, .mse = 1e-7f}, .float16 = {.atol = 1.0f, .rtol = 1.0f, .bias = 5e-3f, .mse = 1e-4f}, .int32 = {.atol = 1}, - .quant8Asymm = {.atol = 8, .bias = 1, .mse = 1}, - .quant8Symm = {.atol = 8, .bias = 1, .mse = 1}, - .quant16Asymm = {.atol = 8, .bias = 1, .mse = 1}, - .quant16Symm = {.atol = 8, .bias = 1, .mse = 1}}; + .quant8Asymm = {.atol = 10, .bias = 1.5, .mse = 1.5}, + .quant8Symm = {.atol = 10, .bias = 1.5, .mse = 1.5}, + .quant16Asymm = {.atol = 10, .bias = 1.5, .mse = 1.5}, + .quant16Symm = {.atol = 10, .bias = 1.5, .mse = 1.5}}; /*-- NNAPI 1.0 Operations ---------------------------------------------------*/ @@ -565,19 +565,19 @@ const AccuracyCriteria kSmallGraphCriteria = { .float32 = {.atol = 1e-2f, .rtol = 1e-2f, .bias = 2e-5f, .mse = 1e-7f}, .float16 = {.atol = 1.0f, .rtol = 1.0f, .bias = 5e-3f, .mse = 1e-4f}, .int32 = {.atol = 1}, - .quant8Asymm = {.atol = 8, .bias = 1, .mse = 1}, - .quant8Symm = {.atol = 8, .bias = 1, .mse = 1}, - .quant16Asymm = {.atol = 8, .bias = 1, .mse = 1}, - .quant16Symm = {.atol = 8, .bias = 1, .mse = 1}}; + .quant8Asymm = {.atol = 12, .bias = 2, .mse = 2}, + .quant8Symm = {.atol = 12, .bias = 2, .mse = 2}, + .quant16Asymm = {.atol = 12, .bias = 2, .mse = 2}, + .quant16Symm = {.atol = 12, .bias = 2, .mse = 2}}; const AccuracyCriteria kLargeGraphCriteria = { .float32 = {.atol = 1e-1f, .rtol = 1e-1f, .bias = 1e-2f, .mse = 1e-4f}, .float16 = {.atol = 1.0f, .rtol = 1.0f, .bias = 1e-1f, .mse = 5e-2f}, .int32 = {.atol = 1}, - .quant8Asymm = {.atol = 10, .bias = 2, .mse = 2}, - .quant8Symm = {.atol = 10, .bias = 2, .mse = 2}, - .quant16Asymm = {.atol = 10, .bias = 2, .mse = 2}, - .quant16Symm = {.atol = 10, .bias = 2, .mse = 2}}; + .quant8Asymm = {.atol = 12, .bias = 2, .mse = 2}, + .quant8Symm = {.atol = 12, .bias = 2, .mse = 2}, + .quant16Asymm = {.atol = 12, .bias = 2, .mse = 2}, + .quant16Symm = {.atol = 12, .bias = 2, .mse = 2}}; // Due to the limitation of the random graph generator, graphs generated with mixed-type or // mixed-rank operations are likely to result in a disconnected network. Thus, we filter the |