1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #pragma once
7
8 #include <armnn/IRuntime.hpp>
9 #include <armnn/Types.hpp>
10 #include <armnn/Logging.hpp>
11 #include <armnn/utility/StringUtils.hpp>
12
13 #include <mapbox/variant.hpp>
14
15 #include <iostream>
16 #include <fstream>
17
18
19 std::vector<unsigned int> ParseArray(std::istream& stream);
20
21 /// Splits a given string at every accurance of delimiter into a vector of string
22 std::vector<std::string> ParseStringList(const std::string& inputString, const char* delimiter);
23
24 struct TensorPrinter
25 {
26 TensorPrinter(const std::string& binding,
27 const armnn::TensorInfo& info,
28 const std::string& outputTensorFile,
29 bool dequantizeOutput);
30
31 void operator()(const std::vector<float>& values);
32
33 void operator()(const std::vector<uint8_t>& values);
34
35 void operator()(const std::vector<int>& values);
36
37 private:
38 template<typename Container, typename Delegate>
39 void ForEachValue(const Container& c, Delegate delegate);
40
41 template<typename T>
42 void WriteToFile(const std::vector<T>& values);
43
44 std::string m_OutputBinding;
45 float m_Scale;
46 int m_Offset;
47 std::string m_OutputTensorFile;
48 bool m_DequantizeOutput;
49 };
50
51 using TContainer = mapbox::util::variant<std::vector<float>, std::vector<int>, std::vector<unsigned char>>;
52 using QuantizationParams = std::pair<float, int32_t>;
53
54 void PopulateTensorWithData(TContainer& tensorData,
55 unsigned int numElements,
56 const std::string& dataTypeStr,
57 const armnn::Optional<QuantizationParams>& qParams,
58 const armnn::Optional<std::string>& dataFile);
59
60 /**
61 * Verifies if the given string is a valid path. Reports invalid paths to std::err.
62 * @param file string - A string containing the path to check
63 * @param expectFile bool - If true, checks for a regular file.
64 * @return bool - True if given string is a valid path., false otherwise.
65 * */
66 bool ValidatePath(const std::string& file, const bool expectFile);
67
68 /**
69 * Verifies if a given vector of strings are valid paths. Reports invalid paths to std::err.
70 * @param fileVec vector of string - A vector of string containing the paths to check
71 * @param expectFile bool - If true, checks for a regular file.
72 * @return bool - True if all given strings are valid paths., false otherwise.
73 * */
74 bool ValidatePaths(const std::vector<std::string>& fileVec, const bool expectFile);
75
76 template<typename T, typename TParseElementFunc>
ParseArrayImpl(std::istream & stream,TParseElementFunc parseElementFunc,const char * chars="\\t ,:")77 std::vector<T> ParseArrayImpl(std::istream& stream, TParseElementFunc parseElementFunc, const char* chars = "\t ,:")
78 {
79 std::vector<T> result;
80 // Processes line-by-line.
81 std::string line;
82 while (std::getline(stream, line))
83 {
84 std::vector<std::string> tokens = armnn::stringUtils::StringTokenizer(line, chars);
85 for (const std::string& token : tokens)
86 {
87 if (!token.empty()) // See https://stackoverflow.com/questions/10437406/
88 {
89 try
90 {
91 result.push_back(parseElementFunc(token));
92 }
93 catch (const std::exception&)
94 {
95 ARMNN_LOG(error) << "'" << token << "' is not a valid number. It has been ignored.";
96 }
97 }
98 }
99 }
100
101 return result;
102 }
103
104 template <typename T, typename TParseElementFunc>
PopulateTensorWithDataGeneric(std::vector<T> & tensorData,unsigned int numElements,const armnn::Optional<std::string> & dataFile,TParseElementFunc parseFunction)105 void PopulateTensorWithDataGeneric(std::vector<T>& tensorData,
106 unsigned int numElements,
107 const armnn::Optional<std::string>& dataFile,
108 TParseElementFunc parseFunction)
109 {
110 const bool readFromFile = dataFile.has_value() && !dataFile.value().empty();
111
112 std::ifstream inputTensorFile;
113 if (readFromFile)
114 {
115 inputTensorFile = std::ifstream(dataFile.value());
116 }
117
118 tensorData = readFromFile ?
119 ParseArrayImpl<T>(inputTensorFile, parseFunction) :
120 std::vector<T>(numElements, static_cast<T>(0));
121 }
122