ArmNN
 21.02
QuantizationDataSet.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
7 
8 #include <fmt/format.h>
9 
12 #include <Filesystem.hpp>
13 
14 namespace armnnQuantizer
15 {
16 
18 {
19 }
20 
21 QuantizationDataSet::QuantizationDataSet(const std::string csvFilePath):
22  m_QuantizationInputs(),
23  m_CsvFilePath(csvFilePath)
24 {
25  ParseCsvFile();
26 }
27 
28 void AddInputData(unsigned int passId,
29  armnn::LayerBindingId bindingId,
30  const std::string& inputFilePath,
31  std::map<unsigned int, QuantizationInput>& passIdToQuantizationInput)
32 {
33  auto iterator = passIdToQuantizationInput.find(passId);
34  if (iterator == passIdToQuantizationInput.end())
35  {
36  QuantizationInput input(passId, bindingId, inputFilePath);
37  passIdToQuantizationInput.emplace(passId, input);
38  }
39  else
40  {
41  auto existingQuantizationInput = iterator->second;
42  existingQuantizationInput.AddEntry(bindingId, inputFilePath);
43  }
44 }
45 
47 {
48 }
49 
50 
51 /// Visitor class implementation to gather the TensorInfo for LayerBindingID for creation of ConstTensor for Refine.
52 
54  const armnn::BaseDescriptor& descriptor,
55  const std::vector<armnn::ConstTensor>& constants,
56  const char* name,
57  const armnn::LayerBindingId id)
58 {
59  armnn::IgnoreUnused(name, descriptor, constants);
60 
61  m_TensorInfos.emplace(id, layer->GetOutputSlot(0).GetTensorInfo());
62 }
63 
64 
65 
66 
68 {
69  auto iterator = m_TensorInfos.find(layerBindingId);
70  if (iterator != m_TensorInfos.end())
71  {
72  return m_TensorInfos.at(layerBindingId);
73  }
74  else
75  {
76  throw armnn::Exception("Could not retrieve tensor info for binding ID " + std::to_string(layerBindingId));
77  }
78 }
79 
82  const char* name)
83 {
84  armnn::IgnoreUnused(name);
85  m_TensorInfos.emplace(id, layer->GetOutputSlot(0).GetTensorInfo());
86 }
87 
89 {
90  auto iterator = m_TensorInfos.find(layerBindingId);
91  if (iterator != m_TensorInfos.end())
92  {
93  return m_TensorInfos.at(layerBindingId);
94  }
95  else
96  {
97  throw armnn::Exception("Could not retrieve tensor info for binding ID " + std::to_string(layerBindingId));
98  }
99 }
100 
101 
102 unsigned int GetPassIdFromCsvRow(std::vector<std::string> tokens, unsigned int lineIndex)
103 {
104  unsigned int passId;
105  try
106  {
107  passId = static_cast<unsigned int>(std::stoi(tokens[0]));
108  }
109  catch (const std::invalid_argument&)
110  {
111  throw armnn::ParseException(fmt::format("Pass ID [{}] is not correct format on CSV row {}",
112  tokens[0], lineIndex));
113  }
114  return passId;
115 }
116 
117 armnn::LayerBindingId GetBindingIdFromCsvRow(std::vector<std::string> tokens, unsigned int lineIndex)
118 {
119  armnn::LayerBindingId bindingId;
120  try
121  {
122  bindingId = std::stoi(tokens[1]);
123  }
124  catch (const std::invalid_argument&)
125  {
126  throw armnn::ParseException(fmt::format("Binding ID [{}] is not correct format on CSV row {}",
127  tokens[1], lineIndex));
128  }
129  return bindingId;
130 }
131 
132 std::string GetFileNameFromCsvRow(std::vector<std::string> tokens, unsigned int lineIndex)
133 {
134  std::string fileName = armnn::stringUtils::StringTrim(tokens[2]);
135 
136  if (!fs::exists(fileName))
137  {
138  throw armnn::ParseException(fmt::format("File [{}] provided on CSV row {} does not exist.",
139  fileName, lineIndex));
140  }
141 
142  if (fileName.empty())
143  {
144  throw armnn::ParseException(fmt::format("Filename cannot be empty on CSV row {} ", lineIndex));
145  }
146  return fileName;
147 }
148 
149 
150 void QuantizationDataSet::ParseCsvFile()
151 {
152  std::map<unsigned int, QuantizationInput> passIdToQuantizationInput;
153 
154  if (m_CsvFilePath == "")
155  {
156  throw armnn::Exception("CSV file not specified.");
157  }
158 
159  std::ifstream inf (m_CsvFilePath.c_str());
160  std::string line;
161  std::vector<std::string> tokens;
162  unsigned int lineIndex = 0;
163 
164  if (!inf)
165  {
166  throw armnn::Exception(fmt::format("CSV file {} not found.", m_CsvFilePath));
167  }
168 
169  while (getline(inf, line))
170  {
171  tokens = armnn::stringUtils::StringTokenizer(line, ",");
172 
173  if (tokens.size() != 3)
174  {
175  throw armnn::Exception(fmt::format("CSV file [{}] does not have correct number of entries" \
176  "on line {}. Expected 3 entries but was {}.",
177  m_CsvFilePath, lineIndex, tokens.size()));
178 
179  }
180 
181  unsigned int passId = GetPassIdFromCsvRow(tokens, lineIndex);
182  armnn::LayerBindingId bindingId = GetBindingIdFromCsvRow(tokens, lineIndex);
183  std::string rawFileName = GetFileNameFromCsvRow(tokens, lineIndex);
184 
185  AddInputData(passId, bindingId, rawFileName, passIdToQuantizationInput);
186 
187  ++lineIndex;
188  }
189 
190  if (passIdToQuantizationInput.empty())
191  {
192  throw armnn::Exception("Could not parse CSV file.");
193  }
194 
195  // Once all entries in CSV file are parsed successfully and QuantizationInput map is populated, populate
196  // QuantizationInputs iterator for easier access and clear the map
197  for (auto itr = passIdToQuantizationInput.begin(); itr != passIdToQuantizationInput.end(); ++itr)
198  {
199  m_QuantizationInputs.emplace_back(itr->second);
200  }
201 }
202 
203 }
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...
Definition: StringUtils.hpp:20
void AddInputData(unsigned int passId, armnn::LayerBindingId bindingId, const std::string &inputFilePath, std::map< unsigned int, QuantizationInput > &passIdToQuantizationInput)
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:62
std::string GetFileNameFromCsvRow(std::vector< std::string > tokens, unsigned int lineIndex)
void VisitInputLayer(const armnn::IConnectableLayer *layer, armnn::LayerBindingId id, const char *name)
Function that an InputLayer should call back to when its Accept(ILayerVisitor&) function is invoked...
QuantizationInputs::iterator iterator
armnn::LayerBindingId GetBindingIdFromCsvRow(std::vector< std::string > tokens, unsigned int lineIndex)
QuantizationInput for specific pass ID, can list a corresponding raw data file for each LayerBindingI...
void IgnoreUnused(Ts &&...)
int LayerBindingId
Type of identifiers for bindable layers (inputs, outputs).
Definition: Types.hpp:210
Base class for all descriptors.
Definition: Descriptors.hpp:22
armnn::TensorInfo GetTensorInfo(armnn::LayerBindingId)
armnn::TensorInfo GetTensorInfo(armnn::LayerBindingId)
unsigned int GetPassIdFromCsvRow(std::vector< std::string > tokens, unsigned int lineIndex)
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46
virtual const TensorInfo & GetTensorInfo() const =0
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
virtual void ExecuteStrategy(const armnn::IConnectableLayer *layer, const armnn::BaseDescriptor &descriptor, const std::vector< armnn::ConstTensor > &constants, const char *name, const armnn::LayerBindingId id=0) override
Visitor class implementation to gather the TensorInfo for LayerBindingID for creation of ConstTensor ...
std::string & StringTrim(std::string &str, const std::string &chars="\\\")
Trim from both the start and the end of a string.
Definition: StringUtils.hpp:77