diff options
author | Cathal Corbett <cathal.corbett@arm.com> | 2024-06-12 09:15:02 +0100 |
---|---|---|
committer | Cathal Corbett <cathal.corbett@arm.com> | 2024-06-12 16:20:10 +0000 |
commit | 1cb68e63da15c707126dbd71775f52cecd86b963 (patch) | |
tree | 3f2de07a8b70fbfa903ff358c12cb51c22c7046a /tests/NetworkExecutionUtils | |
parent | f404b174b53cd9fb5eec20de79825137e22362af (diff) | |
download | armnn-1cb68e63da15c707126dbd71775f52cecd86b963.tar.gz |
IVGCVSW-8289 Add Numpy Support to execute network
* Creates a numpy parser helper header
* Adds ability to parse numpy file in PopulateTensorWithData
* Reuse ExNet compare-output flag to compare against npy golden files.
* Reuse ExNet write-outputs-to-file flag to write output to npy file.
Signed-off-by: Cathal Corbett <cathal.corbett@arm.com>
Signed-off-by: Ryan OShea <ryan.oshea3@arm.com>
Change-Id: I52df822f72f6ce9d191ac4bd26ca5718ccaa7a4a
Diffstat (limited to 'tests/NetworkExecutionUtils')
-rw-r--r-- | tests/NetworkExecutionUtils/NetworkExecutionUtils.hpp | 130 |
1 files changed, 69 insertions, 61 deletions
diff --git a/tests/NetworkExecutionUtils/NetworkExecutionUtils.hpp b/tests/NetworkExecutionUtils/NetworkExecutionUtils.hpp index 0df3bf5ef5..1b881ed928 100644 --- a/tests/NetworkExecutionUtils/NetworkExecutionUtils.hpp +++ b/tests/NetworkExecutionUtils/NetworkExecutionUtils.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2022, 2023 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2022, 2023-2024 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -13,6 +13,7 @@ #include <armnn/Optional.hpp> // for Optional, EmptyOptional #include <armnn/Tensor.hpp> // for Tensor, TensorInfo #include <armnn/TypesUtils.hpp> // for Dequantize +#include <armnn/Numpy.hpp> // for Numpy #include <chrono> // for duration #include <functional> // for function #include <fstream> @@ -132,51 +133,75 @@ void PopulateTensorWithData(T* tensor, { const bool readFromFile = dataFile.has_value() && !dataFile.value().empty(); - std::ifstream inputTensorFile; if (!readFromFile) { std::fill(tensor, tensor + numElements, 0); return; } - else + + if (dataFile.value().find(".npy") == std::string::npos) { + std::ifstream inputTensorFile; inputTensorFile = std::ifstream(dataFile.value()); - } - auto parseElementFunc = GetParseElementFunc<T>(); - std::string line; - unsigned int index = 0; - while (std::getline(inputTensorFile, line)) - { - std::vector<std::string> tokens = armnn::stringUtils::StringTokenizer(line, "\t ,:"); - for (const std::string& token : tokens) + auto parseElementFunc = GetParseElementFunc<T>(); + std::string line; + unsigned int index = 0; + while (std::getline(inputTensorFile, line)) { - if (!token.empty()) // See https://stackoverflow.com/questions/10437406/ + std::vector<std::string> tokens = armnn::stringUtils::StringTokenizer(line, "\t ,:"); + for (const std::string &token: tokens) { - try + if (!token.empty()) // See https://stackoverflow.com/questions/10437406/ { - if (index == numElements) + try { - ARMNN_LOG(error) << "Number of elements: " << (index +1) << " in file \"" << dataFile.value() - << "\" does not match number of elements: " << numElements - << " for input \"" << inputName << "\"."; + if (index == numElements) + { + ARMNN_LOG(error) << "Number of elements: " << (index + 1) << " in file \"" + << dataFile.value() + << "\" does not match number of elements: " << numElements + << " for input \"" << inputName << "\"."; + } + *(tensor + index) = parseElementFunc(token); + index++; + } + catch (const std::exception &) + { + ARMNN_LOG(error) << "'" << token << "' is not a valid number. It has been ignored."; } - *(tensor + index) = parseElementFunc(token); - index++; - } - catch (const std::exception&) - { - ARMNN_LOG(error) << "'" << token << "' is not a valid number. It has been ignored."; } } } - } - if (index != numElements) + if (index != numElements) + { + ARMNN_LOG(error) << "Number of elements: " << (index + 1) << " in file \"" << inputName + << "\" does not match number of elements: " << numElements + << " for input \"" << inputName << "\"."; + } + } + else { - ARMNN_LOG(error) << "Number of elements: " << (index +1) << " in file \"" << inputName - << "\" does not match number of elements: " << numElements - << " for input \"" << inputName << "\"."; + std::ifstream ifStream(dataFile.value(), std::ifstream::binary); + + armnnNumpy::HeaderInfo headerInfo; + armnnNumpy::Header header; + + CreateHeaderInfo(ifStream, headerInfo); + CreateHeader(ifStream, headerInfo, header); + + if (!armnnNumpy::compareCTypes<T>(header.m_DescrString)) + { + ARMNN_LOG(error) << "Data type in numpy file " << inputName << " does not match expected data type."; + } + else if(numElements != armnnNumpy::getNumElements(header)) + { + ARMNN_LOG(error) << "Number of elements in numpy " << inputName + << " does not match expected number of elements."; + } + + armnnNumpy::ReadData<T>(ifStream, tensor, numElements); } } @@ -220,11 +245,22 @@ void PrintTensor(OutputWriteInfo& info, const char* formatString) if (info.m_OutputTensorFile.has_value()) { - WriteToFile(info.m_OutputTensorFile.value(), - info.m_OutputName, - array, - info.m_Tensor.GetNumElements(), - info.m_DataType); + if (info.m_OutputTensorFile.value().find(".npy") == std::string::npos) + { + WriteToFile(info.m_OutputTensorFile.value(), + info.m_OutputName, + array, + info.m_Tensor.GetNumElements(), + info.m_DataType); + } + else + { + armnnNumpy::WriteToNumpyFile(info.m_OutputTensorFile.value(), + array, + info.m_Tensor.GetNumElements(), + info.m_DataType, + info.m_Tensor.GetInfo().GetShape()); + } } if (info.m_PrintTensor) @@ -236,34 +272,6 @@ void PrintTensor(OutputWriteInfo& info, const char* formatString) } } -template <typename T> -void PrintQuantizedTensor(OutputWriteInfo& info) -{ - std::vector<float> dequantizedValues; - auto tensor = info.m_Tensor; - dequantizedValues = DequantizeArray<T>(tensor.GetMemoryArea(), - tensor.GetNumElements(), - tensor.GetInfo().GetQuantizationScale(), - tensor.GetInfo().GetQuantizationOffset()); - - if (info.m_OutputTensorFile.has_value()) - { - WriteToFile(info.m_OutputTensorFile.value(), - info.m_OutputName, - dequantizedValues.data(), - tensor.GetNumElements(), - info.m_DataType); - } - - if (info.m_PrintTensor) - { - std::for_each(dequantizedValues.begin(), dequantizedValues.end(), [&](float value) - { - printf("%f ", value); - }); - } -} - template<typename T, typename TParseElementFunc> std::vector<T> ParseArrayImpl(std::istream& stream, TParseElementFunc parseElementFunc, const char* chars = "\t ,:") { |