ArmNN
 20.02
ImageCSVFileGenerator.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include <boost/filesystem.hpp>
7 #include <boost/filesystem/operations.hpp>
8 #include <boost/filesystem/path.hpp>
9 #include <boost/program_options.hpp>
10 
11 #include <algorithm>
12 #include <fstream>
13 #include <iostream>
14 #include <string>
15 
16 namespace
17 {
18 
19 // parses the command line to extract
20 // * the directory -i to look through .raw files from (must exist)
21 // * the name of the file -o the output CSV file path (must not already exist)
22 class CommandLineProcessor
23 {
24 public:
25  bool ValidateDirectory(std::string& dir)
26  {
27  if (dir.empty())
28  {
29  std::cerr << "No directory specified" << std::endl;
30  return false;
31  }
32 
33  if (dir[dir.length() - 1] != '/')
34  {
35  dir += "/";
36  }
37 
38  if (!boost::filesystem::exists(dir))
39  {
40  std::cerr << "Directory [" << dir << "] does not exist" << std::endl;
41  return false;
42  }
43 
44  if (!boost::filesystem::is_directory(dir))
45  {
46  std::cerr << "Given directory [" << dir << "] is not a directory" << std::endl;
47  return false;
48  }
49 
50  return true;
51  }
52 
53  bool ValidateOutputFile(std::string& outputFileName)
54  {
55  if (outputFileName.empty())
56  {
57  std::cerr << "No output file name specified" << std::endl;
58  return false;
59  }
60 
61  if (boost::filesystem::exists(outputFileName))
62  {
63  std::cerr << "Output file [" << outputFileName << "] already exists" << std::endl;
64  return false;
65  }
66 
67  if (boost::filesystem::is_directory(outputFileName))
68  {
69  std::cerr << "Output file [" << outputFileName << "] is a directory" << std::endl;
70  return false;
71  }
72 
73  boost::filesystem::path outputPath(outputFileName);
74  if (!boost::filesystem::exists(outputPath.parent_path()))
75  {
76  std::cerr << "Directory [" << outputPath.parent_path().c_str() << "] does not exist" << std::endl;
77  return false;
78  }
79 
80  return true;
81  }
82 
83  bool ValidateBindingId(const std::string& id)
84  {
85  if (!std::all_of(id.begin(), id.end(), ::isdigit))
86  {
87  std::cerr << "Invalid input binding Id" << std::endl;
88  return false;
89  }
90 
91  return true;
92  }
93 
94  bool ProcessCommandLine(int argc, char* argv[])
95  {
96  namespace po = boost::program_options;
97 
98  po::options_description desc("Options");
99  try
100  {
101  desc.add_options()
102  ("help,h", "Display help messages")
103  ("indir,i", po::value<std::string>(&m_InputDirectory)->required(),
104  "Directory that .raw files are stored in")
105  ("outfile,o", po::value<std::string>(&m_OutputFileName)->required(),
106  "Output CSV file path")
107  ("layer-binding-id,l", po::value<std::string>(&m_InputBindingId)->default_value("0"),
108  "Input layer binding Id, Defaults to 0");
109  }
110  catch (const std::exception& e)
111  {
112  std::cerr << "Fatal internal error: [" << e.what() << "]" << std::endl;
113  return false;
114  }
115 
116  po::variables_map vm;
117 
118  try
119  {
120  po::store(po::parse_command_line(argc, argv, desc), vm);
121 
122  if (vm.count("help"))
123  {
124  std::cout << desc << std::endl;
125  return false;
126  }
127 
128  po::notify(vm);
129  }
130  catch (const po::error& e)
131  {
132  std::cerr << e.what() << std::endl << std::endl;
133  std::cerr << desc << std::endl;
134  return false;
135  }
136 
137  if (!ValidateDirectory(m_InputDirectory))
138  {
139  return false;
140  }
141 
142  if (!ValidateOutputFile(m_OutputFileName))
143  {
144  return false;
145  }
146 
147  if(!ValidateBindingId(m_InputBindingId))
148  {
149  return false;
150  }
151 
152  return true;
153  }
154 
155  std::string GetInputDirectory() {return m_InputDirectory;}
156  std::string GetOutputFileName() {return m_OutputFileName;}
157  std::string GetInputBindingId() {return m_InputBindingId;}
158 
159 private:
160  std::string m_InputDirectory;
161  std::string m_OutputFileName;
162  std::string m_InputBindingId;
163 };
164 
165 } // namespace anonymous
166 
167 int main(int argc, char* argv[])
168 {
169  CommandLineProcessor cmdline;
170  if (!cmdline.ProcessCommandLine(argc, argv))
171  {
172  return -1;
173  }
174 
175  namespace fs = boost::filesystem;
176 
177  const std::string fileFormat(".raw");
178 
179  const std::string rawDirectory(cmdline.GetInputDirectory());
180  const std::string outputPath(cmdline.GetOutputFileName());
181  const std::string bindingId(cmdline.GetInputBindingId());
182 
183  std::vector<fs::path> rawFiles;
184  for (auto& entry : boost::make_iterator_range(fs::directory_iterator(rawDirectory), {}))
185  {
186  if (entry.path().extension().c_str() == fileFormat)
187  {
188  rawFiles.push_back(entry.path());
189  }
190  }
191 
192  if (!rawFiles.empty())
193  {
194  unsigned int pass = 0;
195  std::ofstream refinementData;
196  refinementData.open(outputPath, std::ofstream::out);
197  if (refinementData.is_open())
198  {
199  for (auto const& raw : rawFiles)
200  {
201  refinementData << pass << ", " << bindingId << ", " << raw.c_str() << "\n";
202  if (!refinementData)
203  {
204  std::cerr << "Failed to write to output file: " << outputPath << std::endl;
205  continue;
206  }
207  ++pass;
208  }
209  refinementData.close();
210  }
211  else
212  {
213  std::cerr << "Failed to open output file: " << outputPath << std::endl;
214  return -1;
215  }
216  }
217  else
218  {
219  std::cerr << "No matching files with the \".raw\" extension found in the directory: "
220  << rawDirectory << std::endl;
221  return -1;
222  }
223 
224  return 0;
225 }
int main(int argc, char *argv[])
bool ValidateDirectory(std::string &dir)