aboutsummaryrefslogtreecommitdiff
path: root/src/backends/reference
diff options
context:
space:
mode:
Diffstat (limited to 'src/backends/reference')
-rw-r--r--src/backends/reference/RefWorkloadFactory.cpp11
-rw-r--r--src/backends/reference/test/RefDetectionPostProcessTests.cpp4
-rw-r--r--src/backends/reference/test/RefEndToEndTests.cpp166
-rw-r--r--src/backends/reference/workloads/DetectionPostProcess.cpp16
4 files changed, 186 insertions, 11 deletions
diff --git a/src/backends/reference/RefWorkloadFactory.cpp b/src/backends/reference/RefWorkloadFactory.cpp
index 9c1ce1e013..3bf83bd9be 100644
--- a/src/backends/reference/RefWorkloadFactory.cpp
+++ b/src/backends/reference/RefWorkloadFactory.cpp
@@ -154,7 +154,16 @@ std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDepthwiseConvolution2d(
std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDetectionPostProcess(
const armnn::DetectionPostProcessQueueDescriptor& descriptor, const armnn::WorkloadInfo& info) const
{
- return MakeWorkload<RefDetectionPostProcessFloat32Workload, RefDetectionPostProcessUint8Workload>(descriptor, info);
+ const DataType dataType = info.m_InputTensorInfos[0].GetDataType();
+ switch (dataType)
+ {
+ case DataType::Float32:
+ return std::make_unique<RefDetectionPostProcessFloat32Workload>(descriptor, info);
+ case DataType::QuantisedAsymm8:
+ return std::make_unique<RefDetectionPostProcessUint8Workload>(descriptor, info);
+ default:
+ return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info);
+ }
}
std::unique_ptr<armnn::IWorkload> RefWorkloadFactory::CreateNormalization(
diff --git a/src/backends/reference/test/RefDetectionPostProcessTests.cpp b/src/backends/reference/test/RefDetectionPostProcessTests.cpp
index 39403f0284..a9faff70b1 100644
--- a/src/backends/reference/test/RefDetectionPostProcessTests.cpp
+++ b/src/backends/reference/test/RefDetectionPostProcessTests.cpp
@@ -74,8 +74,8 @@ void DetectionPostProcessTestImpl(bool useRegularNms, const std::vector<float>&
const std::vector<float>& expectedNumDetections)
{
armnn::TensorInfo boxEncodingsInfo({ 1, 6, 4 }, armnn::DataType::Float32);
- armnn::TensorInfo scoresInfo({ 1, 6, 4 }, armnn::DataType::Float32);
- armnn::TensorInfo anchorsInfo({ 1, 6, 4 }, armnn::DataType::Float32);
+ armnn::TensorInfo scoresInfo({ 1, 6, 3 }, armnn::DataType::Float32);
+ armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::Float32);
armnn::TensorInfo detectionBoxesInfo({ 1, 3, 4 }, armnn::DataType::Float32);
armnn::TensorInfo detectionScoresInfo({ 1, 3 }, armnn::DataType::Float32);
diff --git a/src/backends/reference/test/RefEndToEndTests.cpp b/src/backends/reference/test/RefEndToEndTests.cpp
index 802167a3a0..c89e586f03 100644
--- a/src/backends/reference/test/RefEndToEndTests.cpp
+++ b/src/backends/reference/test/RefEndToEndTests.cpp
@@ -4,6 +4,8 @@
//
#include <backendsCommon/test/EndToEndTestImpl.hpp>
+
+#include <backendsCommon/test/DetectionPostProcessTestImpl.hpp>
#include <backendsCommon/test/GatherEndToEndTestImpl.hpp>
#include <backendsCommon/test/MergerTestImpl.hpp>
#include <backendsCommon/test/ArithmeticTestImpl.hpp>
@@ -453,4 +455,168 @@ BOOST_AUTO_TEST_CASE(RefGatherMultiDimUint8Test)
GatherMultiDimEndToEnd<armnn::DataType::QuantisedAsymm8>(defaultBackends);
}
+BOOST_AUTO_TEST_CASE(RefDetectionPostProcessRegularNmsTest)
+{
+ std::vector<float> boxEncodings({
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f
+ });
+ std::vector<float> scores({
+ 0.0f, 0.9f, 0.8f,
+ 0.0f, 0.75f, 0.72f,
+ 0.0f, 0.6f, 0.5f,
+ 0.0f, 0.93f, 0.95f,
+ 0.0f, 0.5f, 0.4f,
+ 0.0f, 0.3f, 0.2f
+ });
+ std::vector<float> anchors({
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 10.5f, 1.0f, 1.0f,
+ 0.5f, 10.5f, 1.0f, 1.0f,
+ 0.5f, 100.5f, 1.0f, 1.0f
+ });
+ DetectionPostProcessRegularNmsEndToEnd<armnn::DataType::Float32>(defaultBackends, boxEncodings, scores, anchors);
+}
+
+inline void QuantizeData(uint8_t* quant, const float* dequant, const TensorInfo& info)
+{
+ for (size_t i = 0; i < info.GetNumElements(); i++)
+ {
+ quant[i] = armnn::Quantize<uint8_t>(dequant[i], info.GetQuantizationScale(), info.GetQuantizationOffset());
+ }
+}
+
+BOOST_AUTO_TEST_CASE(RefDetectionPostProcessRegularNmsUint8Test)
+{
+ armnn::TensorInfo boxEncodingsInfo({ 1, 6, 4 }, armnn::DataType::Float32);
+ armnn::TensorInfo scoresInfo({ 1, 6, 3 }, armnn::DataType::Float32);
+ armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::Float32);
+
+ boxEncodingsInfo.SetQuantizationScale(1.0f);
+ boxEncodingsInfo.SetQuantizationOffset(1);
+ scoresInfo.SetQuantizationScale(0.01f);
+ scoresInfo.SetQuantizationOffset(0);
+ anchorsInfo.SetQuantizationScale(0.5f);
+ anchorsInfo.SetQuantizationOffset(0);
+
+ std::vector<float> boxEncodings({
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f
+ });
+ std::vector<float> scores({
+ 0.0f, 0.9f, 0.8f,
+ 0.0f, 0.75f, 0.72f,
+ 0.0f, 0.6f, 0.5f,
+ 0.0f, 0.93f, 0.95f,
+ 0.0f, 0.5f, 0.4f,
+ 0.0f, 0.3f, 0.2f
+ });
+ std::vector<float> anchors({
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 10.5f, 1.0f, 1.0f,
+ 0.5f, 10.5f, 1.0f, 1.0f,
+ 0.5f, 100.5f, 1.0f, 1.0f
+ });
+
+ std::vector<uint8_t> qBoxEncodings(boxEncodings.size(), 0);
+ std::vector<uint8_t> qScores(scores.size(), 0);
+ std::vector<uint8_t> qAnchors(anchors.size(), 0);
+ QuantizeData(qBoxEncodings.data(), boxEncodings.data(), boxEncodingsInfo);
+ QuantizeData(qScores.data(), scores.data(), scoresInfo);
+ QuantizeData(qAnchors.data(), anchors.data(), anchorsInfo);
+ DetectionPostProcessRegularNmsEndToEnd<armnn::DataType::QuantisedAsymm8>(defaultBackends, qBoxEncodings,
+ qScores, qAnchors,
+ 1.0f, 1, 0.01f, 0, 0.5f, 0);
+}
+
+BOOST_AUTO_TEST_CASE(RefDetectionPostProcessFastNmsTest)
+{
+ std::vector<float> boxEncodings({
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f
+ });
+ std::vector<float> scores({
+ 0.0f, 0.9f, 0.8f,
+ 0.0f, 0.75f, 0.72f,
+ 0.0f, 0.6f, 0.5f,
+ 0.0f, 0.93f, 0.95f,
+ 0.0f, 0.5f, 0.4f,
+ 0.0f, 0.3f, 0.2f
+ });
+ std::vector<float> anchors({
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 10.5f, 1.0f, 1.0f,
+ 0.5f, 10.5f, 1.0f, 1.0f,
+ 0.5f, 100.5f, 1.0f, 1.0f
+ });
+ DetectionPostProcessFastNmsEndToEnd<armnn::DataType::Float32>(defaultBackends, boxEncodings, scores, anchors);
+}
+
+BOOST_AUTO_TEST_CASE(RefDetectionPostProcessFastNmsUint8Test)
+{
+ armnn::TensorInfo boxEncodingsInfo({ 1, 6, 4 }, armnn::DataType::Float32);
+ armnn::TensorInfo scoresInfo({ 1, 6, 3 }, armnn::DataType::Float32);
+ armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::Float32);
+
+ boxEncodingsInfo.SetQuantizationScale(1.0f);
+ boxEncodingsInfo.SetQuantizationOffset(1);
+ scoresInfo.SetQuantizationScale(0.01f);
+ scoresInfo.SetQuantizationOffset(0);
+ anchorsInfo.SetQuantizationScale(0.5f);
+ anchorsInfo.SetQuantizationOffset(0);
+
+ std::vector<float> boxEncodings({
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f
+ });
+ std::vector<float> scores({
+ 0.0f, 0.9f, 0.8f,
+ 0.0f, 0.75f, 0.72f,
+ 0.0f, 0.6f, 0.5f,
+ 0.0f, 0.93f, 0.95f,
+ 0.0f, 0.5f, 0.4f,
+ 0.0f, 0.3f, 0.2f
+ });
+ std::vector<float> anchors({
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 0.5f, 1.0f, 1.0f,
+ 0.5f, 10.5f, 1.0f, 1.0f,
+ 0.5f, 10.5f, 1.0f, 1.0f,
+ 0.5f, 100.5f, 1.0f, 1.0f
+ });
+
+ std::vector<uint8_t> qBoxEncodings(boxEncodings.size(), 0);
+ std::vector<uint8_t> qScores(scores.size(), 0);
+ std::vector<uint8_t> qAnchors(anchors.size(), 0);
+ QuantizeData(qBoxEncodings.data(), boxEncodings.data(), boxEncodingsInfo);
+ QuantizeData(qScores.data(), scores.data(), scoresInfo);
+ QuantizeData(qAnchors.data(), anchors.data(), anchorsInfo);
+ DetectionPostProcessFastNmsEndToEnd<armnn::DataType::QuantisedAsymm8>(defaultBackends, qBoxEncodings,
+ qScores, qAnchors,
+ 1.0f, 1, 0.01f, 0, 0.5f, 0);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/backends/reference/workloads/DetectionPostProcess.cpp b/src/backends/reference/workloads/DetectionPostProcess.cpp
index 958de8294b..2eb35f5ffa 100644
--- a/src/backends/reference/workloads/DetectionPostProcess.cpp
+++ b/src/backends/reference/workloads/DetectionPostProcess.cpp
@@ -105,15 +105,15 @@ void AllocateOutputData(unsigned int numOutput, unsigned int numSelected, const
for (unsigned int i = 0; i < numOutput; ++i)
{
unsigned int boxIndex = i * 4;
- unsigned int boxConorIndex = selectedBoxes[outputIndices[i]] * 4;
if (i < numSelected)
{
+ unsigned int boxCornorIndex = selectedBoxes[outputIndices[i]] * 4;
detectionScores[i] = selectedScores[outputIndices[i]];
detectionClasses[i] = boost::numeric_cast<float>(selectedClasses[outputIndices[i]]);
- detectionBoxes[boxIndex] = boxCorners[boxConorIndex];
- detectionBoxes[boxIndex + 1] = boxCorners[boxConorIndex + 1];
- detectionBoxes[boxIndex + 2] = boxCorners[boxConorIndex + 2];
- detectionBoxes[boxIndex + 3] = boxCorners[boxConorIndex + 3];
+ detectionBoxes[boxIndex] = boxCorners[boxCornorIndex];
+ detectionBoxes[boxIndex + 1] = boxCorners[boxCornorIndex + 1];
+ detectionBoxes[boxIndex + 2] = boxCorners[boxCornorIndex + 2];
+ detectionBoxes[boxIndex + 3] = boxCorners[boxCornorIndex + 3];
}
else
{
@@ -125,7 +125,7 @@ void AllocateOutputData(unsigned int numOutput, unsigned int numSelected, const
detectionBoxes[boxIndex + 3] = 0.0f;
}
}
- numDetections[0] = boost::numeric_cast<float>(numOutput);
+ numDetections[0] = boost::numeric_cast<float>(numSelected);
}
} // anonymous namespace
@@ -216,7 +216,7 @@ void DetectionPostProcess(const TensorInfo& boxEncodingsInfo,
std::vector<unsigned int> outputIndices = GenerateRangeK(numSelected);
TopKSort(numOutput, outputIndices.data(), selectedScoresAfterNms.data(), numSelected);
- AllocateOutputData(numOutput, numSelected, boxCorners, outputIndices,
+ AllocateOutputData(detectionBoxesInfo.GetShape()[1], numOutput, boxCorners, outputIndices,
selectedBoxesAfterNms, selectedClasses, selectedScoresAfterNms,
detectionBoxes, detectionScores, detectionClasses, numDetections);
}
@@ -255,7 +255,7 @@ void DetectionPostProcess(const TensorInfo& boxEncodingsInfo,
unsigned int numSelected = boost::numeric_cast<unsigned int>(selectedIndices.size());
unsigned int numOutput = std::min(desc.m_MaxDetections, numSelected);
- AllocateOutputData(numOutput, numSelected, boxCorners, selectedIndices,
+ AllocateOutputData(detectionBoxesInfo.GetShape()[1], numOutput, boxCorners, selectedIndices,
boxIndices, maxScoreClasses, maxScores,
detectionBoxes, detectionScores, detectionClasses, numDetections);
}