• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "CommandLineProcessor.hpp"
7 #include <Filesystem.hpp>
8 
9 #include <cxxopts/cxxopts.hpp>
10 
11 namespace armnnQuantizer
12 {
13 
ValidateOutputDirectory(std::string & dir)14 bool ValidateOutputDirectory(std::string& dir)
15 {
16     if (dir.empty())
17     {
18         std::cerr << "No output directory specified" << std::endl;
19         return false;
20     }
21 
22     if (dir[dir.length() - 1] != '/')
23     {
24         dir += "/";
25     }
26 
27     if (!fs::exists(dir))
28     {
29         std::cerr << "Output directory [" << dir << "] does not exist" << std::endl;
30         return false;
31     }
32 
33     if (!fs::is_directory(dir))
34     {
35         std::cerr << "Given output directory [" << dir << "] is not a directory" << std::endl;
36         return false;
37     }
38 
39     return true;
40 }
41 
ValidateProvidedFile(const std::string & inputFileName)42 bool ValidateProvidedFile(const std::string& inputFileName)
43 {
44     if (!fs::exists(inputFileName))
45     {
46         std::cerr << "Provided file [" << inputFileName << "] does not exist" << std::endl;
47         return false;
48     }
49 
50     if (fs::is_directory(inputFileName))
51     {
52         std::cerr << "Given file [" << inputFileName << "] is a directory" << std::endl;
53         return false;
54     }
55 
56     return true;
57 }
58 
ValidateQuantizationScheme(const std::string & scheme)59 bool ValidateQuantizationScheme(const std::string& scheme)
60 {
61     if (scheme.empty())
62     {
63         std::cerr << "No Quantization Scheme specified" << std::endl;
64         return false;
65     }
66 
67     std::vector<std::string> supportedSchemes =
68     {
69         "QAsymmS8",
70         "QAsymmU8",
71         "QSymm16"
72     };
73 
74     auto iterator = std::find(supportedSchemes.begin(), supportedSchemes.end(), scheme);
75     if (iterator == supportedSchemes.end())
76     {
77         std::cerr << "Quantization Scheme [" << scheme << "] is not supported" << std::endl;
78         return false;
79     }
80 
81     return true;
82 }
83 
ProcessCommandLine(int argc,char * argv[])84 bool CommandLineProcessor::ProcessCommandLine(int argc, char* argv[])
85 {
86     try
87     {
88         cxxopts::Options options("ArmnnQuantizer","Convert a Fp32 ArmNN model to a quantized ArmNN model.");
89 
90         options.add_options()
91             ("h,help", "Display help messages")
92             ("f,infile",
93                 "Input file containing float 32 ArmNN Input Graph",
94                 cxxopts::value<std::string>(m_InputFileName))
95             ("s,scheme",
96                 "Quantization scheme,"
97                 " \"QAsymmU8\" or \"QAsymmS8\" or \"QSymm16\","
98                 " default value QAsymmU8",
99                 cxxopts::value<std::string>(m_QuantizationScheme)->default_value("QAsymmU8"))
100             ("c,csvfile",
101                 "CSV file containing paths for RAW input tensors",
102                 cxxopts::value<std::string>(m_CsvFileName)->default_value(""))
103             ("p,preserve-data-type",
104                 "Preserve the input and output data types",
105                 cxxopts::value<bool>(m_PreserveDataType)->default_value("false"))
106             ("d,outdir",
107                 "Directory that output file will be written to",
108                 cxxopts::value<std::string>(m_OutputDirectory))
109             ("o,outfile",
110                 "ArmNN output file name",
111                 cxxopts::value<std::string>(m_OutputFileName));
112 
113         auto result = options.parse(argc, argv);
114 
115         if (result.count("help") > 0 || argc <= 1)
116         {
117             std::cout << options.help() << std::endl;
118             return false;
119         }
120 
121         // Check for mandatory single options.
122         std::string mandatorySingleParameters[] = { "infile", "outdir", "outfile" };
123         for (auto param : mandatorySingleParameters)
124         {
125             if (result.count(param) != 1)
126             {
127                 std::cerr << "Parameter \'--" << param << "\' is required but missing." << std::endl;
128                 return false;
129             }
130         }
131     }
132     catch (const cxxopts::OptionException& e)
133     {
134         std::cerr << e.what() << std::endl << std::endl;
135         return false;
136     }
137     catch (const std::exception& e)
138     {
139         std::cerr << "Fatal internal error: [" << e.what() << "]" << std::endl;
140         return false;
141     }
142 
143     if (!armnnQuantizer::ValidateProvidedFile(m_InputFileName))
144     {
145         return false;
146     }
147 
148     if (!ValidateQuantizationScheme(m_QuantizationScheme))
149     {
150         return false;
151     }
152 
153     if (m_CsvFileName != "")
154     {
155         if (!armnnQuantizer::ValidateProvidedFile(m_CsvFileName))
156         {
157             return false;
158         }
159         else
160         {
161             fs::path csvFilePath(m_CsvFileName);
162             m_CsvFileDirectory = csvFilePath.parent_path().c_str();
163         }
164 
165         // If CSV file is defined, create a QuantizationDataSet for specified CSV file.
166         m_QuantizationDataSet = QuantizationDataSet(m_CsvFileName);
167     }
168 
169     if (!armnnQuantizer::ValidateOutputDirectory(m_OutputDirectory))
170     {
171         return false;
172     }
173 
174     std::string output(m_OutputDirectory);
175     output.append(m_OutputFileName);
176 
177     if (fs::exists(output))
178     {
179         std::cerr << "Output file [" << output << "] already exists" << std::endl;
180         return false;
181     }
182 
183     return true;
184 }
185 
186 } // namespace armnnQuantizer