ArmNN
 20.08
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 #include "CsvReader.hpp"
8 
10 #include <Filesystem.hpp>
11 
12 namespace armnnQuantizer
13 {
14 
16 {
17 }
18 
19 QuantizationDataSet::QuantizationDataSet(const std::string csvFilePath):
20  m_QuantizationInputs(),
21  m_CsvFilePath(csvFilePath)
22 {
23  ParseCsvFile();
24 }
25 
26 void AddInputData(unsigned int passId,
27  armnn::LayerBindingId bindingId,
28  const std::string& inputFilePath,
29  std::map<unsigned int, QuantizationInput>& passIdToQuantizationInput)
30 {
31  auto iterator = passIdToQuantizationInput.find(passId);
32  if (iterator == passIdToQuantizationInput.end())
33  {
34  QuantizationInput input(passId, bindingId, inputFilePath);
35  passIdToQuantizationInput.emplace(passId, input);
36  }
37  else
38  {
39  auto existingQuantizationInput = iterator->second;
40  existingQuantizationInput.AddEntry(bindingId, inputFilePath);
41  }
42 }
43 
45 {
46 }
47 
50  const char* name)
51 {
52  armnn::IgnoreUnused(name);
53  m_TensorInfos.emplace(id, layer->GetOutputSlot(0).GetTensorInfo());
54 }
55 
57 {
58  auto iterator = m_TensorInfos.find(layerBindingId);
59  if (iterator != m_TensorInfos.end())
60  {
61  return m_TensorInfos.at(layerBindingId);
62  }
63  else
64  {
65  throw armnn::Exception("Could not retrieve tensor info for binding ID " + std::to_string(layerBindingId));
66  }
67 }
68 
69 
70 unsigned int GetPassIdFromCsvRow(std::vector<armnnUtils::CsvRow> csvRows, unsigned int rowIndex)
71 {
72  unsigned int passId;
73  try
74  {
75  passId = static_cast<unsigned int>(std::stoi(csvRows[rowIndex].values[0]));
76  }
77  catch (const std::invalid_argument&)
78  {
79  throw armnn::ParseException("Pass ID [" + csvRows[rowIndex].values[0] + "]" +
80  " is not correct format on CSV row " + std::to_string(rowIndex));
81  }
82  return passId;
83 }
84 
85 armnn::LayerBindingId GetBindingIdFromCsvRow(std::vector<armnnUtils::CsvRow> csvRows, unsigned int rowIndex)
86 {
87  armnn::LayerBindingId bindingId;
88  try
89  {
90  bindingId = std::stoi(csvRows[rowIndex].values[1]);
91  }
92  catch (const std::invalid_argument&)
93  {
94  throw armnn::ParseException("Binding ID [" + csvRows[rowIndex].values[0] + "]" +
95  " is not correct format on CSV row " + std::to_string(rowIndex));
96  }
97  return bindingId;
98 }
99 
100 std::string GetFileNameFromCsvRow(std::vector<armnnUtils::CsvRow> csvRows, unsigned int rowIndex)
101 {
102  std::string fileName = csvRows[rowIndex].values[2];
103 
104  if (!fs::exists(fileName))
105  {
106  throw armnn::ParseException("File [ " + fileName + "] provided on CSV row " + std::to_string(rowIndex) +
107  " does not exist.");
108  }
109 
110  if (fileName.empty())
111  {
112  throw armnn::ParseException("Filename cannot be empty on CSV row " + std::to_string(rowIndex));
113  }
114  return fileName;
115 }
116 
117 
118 void QuantizationDataSet::ParseCsvFile()
119 {
120  std::map<unsigned int, QuantizationInput> passIdToQuantizationInput;
121  armnnUtils::CsvReader reader;
122 
123  if (m_CsvFilePath == "")
124  {
125  throw armnn::Exception("CSV file not specified.");
126  }
127 
128  // Parse CSV file and extract data
129  std::vector<armnnUtils::CsvRow> csvRows = reader.ParseFile(m_CsvFilePath);
130  if (csvRows.empty())
131  {
132  throw armnn::Exception("CSV file [" + m_CsvFilePath + "] is empty.");
133  }
134 
135  for (unsigned int i = 0; i < csvRows.size(); ++i)
136  {
137  if (csvRows[i].values.size() != 3)
138  {
139  throw armnn::Exception("CSV file [" + m_CsvFilePath + "] does not have correct number of entries " +
140  "on line " + std::to_string(i) + ". Expected 3 entries " +
141  "but was " + std::to_string(csvRows[i].values.size()));
142  }
143 
144  unsigned int passId = GetPassIdFromCsvRow(csvRows, i);
145  armnn::LayerBindingId bindingId = GetBindingIdFromCsvRow(csvRows, i);
146  std::string rawFileName = GetFileNameFromCsvRow(csvRows, i);
147 
148  AddInputData(passId, bindingId, rawFileName, passIdToQuantizationInput);
149  }
150 
151  if (passIdToQuantizationInput.empty())
152  {
153  throw armnn::Exception("Could not parse CSV file.");
154  }
155 
156  // Once all entries in CSV file are parsed successfully and QuantizationInput map is populated, populate
157  // QuantizationInputs iterator for easier access and clear the map
158  for (auto itr = passIdToQuantizationInput.begin(); itr != passIdToQuantizationInput.end(); ++itr)
159  {
160  m_QuantizationInputs.emplace_back(itr->second);
161  }
162 }
163 
164 }
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:61
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...
armnn::LayerBindingId GetBindingIdFromCsvRow(std::vector< armnnUtils::CsvRow > csvRows, unsigned int rowIndex)
QuantizationInputs::iterator iterator
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:194
armnn::TensorInfo GetTensorInfo(armnn::LayerBindingId)
std::string GetFileNameFromCsvRow(std::vector< armnnUtils::CsvRow > csvRows, unsigned int rowIndex)
unsigned int GetPassIdFromCsvRow(std::vector< armnnUtils::CsvRow > csvRows, unsigned int rowIndex)
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.
static std::vector< CsvRow > ParseFile(const std::string &csvFile)
Definition: CsvReader.cpp:32