26 const double& thresholdTime);
31 if (backendIds.empty())
39 for (
const auto& backendId : backendIds)
41 if (std::find(validBackendIds.begin(), validBackendIds.end(), backendId) == validBackendIds.end())
44 if (invalidBackendIds)
46 if (!invalidBackendIds.value().empty())
48 invalidBackendIds.value() +=
", ";
50 invalidBackendIds.value() += backendId;
57 std::vector<unsigned int>
ParseArray(std::istream& stream);
60 std::vector<std::string>
ParseStringList(
const std::string& inputString,
const char* delimiter);
67 std::vector<float>
DequantizeArray(
const void* array,
unsigned int numElements,
float scale, int32_t offset)
69 const T* quantizedArray =
reinterpret_cast<const T*
>(array);
70 std::vector<float> dequantizedVector;
71 dequantizedVector.reserve(numElements);
72 for (
unsigned int i = 0; i < numElements; ++i)
75 dequantizedVector.push_back(f);
77 return dequantizedVector;
88 bool ValidatePath(
const std::string& file,
const bool expectFile);
96 bool ValidatePaths(
const std::vector<std::string>& fileVec,
const bool expectFile);
99 template <typename Integer, typename std::enable_if_t<std::is_integral<Integer>::value>* =
nullptr>
105 template <typename Float, std::enable_if_t<std::is_floating_point<Float>::value>* =
nullptr>
108 return [](
const std::string& s) {
return std::stof(s); };
111 template <
typename T>
113 const unsigned int numElements,
115 const std::string& inputName)
117 const bool readFromFile = dataFile.
has_value() && !dataFile.
value().empty();
119 std::ifstream inputTensorFile;
122 std::fill(tensor, tensor + numElements, 0);
127 inputTensorFile = std::ifstream(dataFile.
value());
130 auto parseElementFunc = GetParseElementFunc<T>();
132 unsigned int index = 0;
133 while (std::getline(inputTensorFile, line))
136 for (
const std::string& token : tokens)
142 if (index == numElements)
144 ARMNN_LOG(error) <<
"Number of elements: " << (index +1) <<
" in file \"" << dataFile.
value()
145 <<
"\" does not match number of elements: " << numElements
146 <<
" for input \"" << inputName <<
"\".";
148 *(tensor + index) = parseElementFunc(token);
151 catch (
const std::exception&)
153 ARMNN_LOG(error) <<
"'" << token <<
"' is not a valid number. It has been ignored.";
159 if (index != numElements)
161 ARMNN_LOG(error) <<
"Number of elements: " << (index +1) <<
" in file \"" << inputName
162 <<
"\" does not match number of elements: " << numElements
163 <<
" for input \"" << inputName <<
"\".";
169 const std::string& outputName,
170 const T*
const array,
171 const unsigned int numElements)
173 std::ofstream outputTensorFile;
174 outputTensorFile.open(outputTensorFileName, std::ofstream::out | std::ofstream::trunc);
175 if (outputTensorFile.is_open())
177 outputTensorFile << outputName <<
": ";
178 std::copy(array, array + numElements, std::ostream_iterator<T>(outputTensorFile,
" "));
182 ARMNN_LOG(info) <<
"Output Tensor File: " << outputTensorFileName <<
" could not be opened!";
184 outputTensorFile.close();
195 template <
typename T>
212 printf(formatString, array[i]);
217 template <
typename T>
220 std::vector<float> dequantizedValues;
222 dequantizedValues = DequantizeArray<T>(tensor.GetMemoryArea(),
223 tensor.GetNumElements(),
224 tensor.GetInfo().GetQuantizationScale(),
225 tensor.GetInfo().GetQuantizationOffset());
231 dequantizedValues.data(),
232 tensor.GetNumElements());
237 std::for_each(dequantizedValues.begin(), dequantizedValues.end(), [&](
float value)
239 printf(
"%f ", value);
244 template<
typename T,
typename TParseElementFunc>
245 std::vector<T>
ParseArrayImpl(std::istream& stream, TParseElementFunc parseElementFunc,
const char* chars =
"\t ,:")
247 std::vector<T> result;
250 while (std::getline(stream, line))
253 for (
const std::string& token : tokens)
259 result.push_back(parseElementFunc(token));
261 catch (
const std::exception&)
263 ARMNN_LOG(error) <<
"'" << token <<
"' is not a valid number. It has been ignored.";
278 float ComputeRMSE(
const void* expected,
const void* actual,
const size_t size)
280 auto typedExpected =
reinterpret_cast<const T*
>(expected);
281 auto typedActual =
reinterpret_cast<const T*
>(actual);
285 for (
unsigned int i = 0; i < size; i++)
287 if (std::abs(typedExpected[i] - typedActual[i]) != 0)
291 errorSum += std::pow(std::abs(typedExpected[i] - typedActual[i]), 2);
294 float rmse = std::sqrt(armnn::numeric_cast<float>(errorSum) / armnn::numeric_cast<float>(size /
sizeof(T)));
std::vector< std::string > StringTokenizer(const std::string &str, const char *delimiters, bool tokenCompression=true)
Function to take a string and a list of delimiters and split the string into tokens based on those de...
float Dequantize(QuantizedType value, float scale, int32_t offset)
Dequantize an 8-bit data type into a floating point data type.
BackendIdSet GetBackendIds() const
std::unordered_set< BackendId > BackendIdSet
bool ValidatePath(const std::string &file, const bool expectFile)
Verifies if the given string is a valid path.
void PrintTensor(OutputWriteInfo &info, const char *formatString)
#define ARMNN_LOG(severity)
unsigned int GetNumElements() const
BackendRegistry & BackendRegistryInstance()
MemoryType GetMemoryArea() const
std::vector< unsigned int > ParseArray(std::istream &stream)
void PopulateTensorWithData(T *tensor, const unsigned int numElements, const armnn::Optional< std::string > &dataFile, const std::string &inputName)
std::vector< std::string > ParseStringList(const std::string &inputString, const char *delimiter)
Splits a given string at every accurance of delimiter into a vector of string.
std::vector< float > DequantizeArray(const void *array, unsigned int numElements, float scale, int32_t offset)
Dequantize an array of a given type.
const std::string & m_OutputName
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
std::function< Integer(const std::string &)> GetParseElementFunc()
Returns a function of read the given type as a string.
const armnn::Tensor & m_Tensor
bool has_value() const noexcept
bool CheckRequestedBackendsAreValid(const std::vector< armnn::BackendId > &backendIds, armnn::Optional< std::string &> invalidBackendIds=armnn::EmptyOptional())
const armnn::Optional< std::string > & m_OutputTensorFile
float ComputeRMSE(const void *expected, const void *actual, const size_t size)
Compute the root-mean-square error (RMSE)
void WriteToFile(const std::string &outputTensorFileName, const std::string &outputName, const T *const array, const unsigned int numElements)
bool CheckInferenceTimeThreshold(const std::chrono::duration< double, std::milli > &duration, const double &thresholdTime)
Given a measured duration and a threshold time tell the user whether we succeeded or not...
std::vector< T > ParseArrayImpl(std::istream &stream, TParseElementFunc parseElementFunc, const char *chars="\,:")
bool ValidatePaths(const std::vector< std::string > &fileVec, const bool expectFile)
Verifies if a given vector of strings are valid paths.
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
void LogAndThrow(std::string eMsg)
void PrintQuantizedTensor(OutputWriteInfo &info)
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)