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