• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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