ONE - On-device Neural Engine
Loading...
Searching...
No Matches
Driver.cpp File Reference
#include "RecordMinMax.h"
#include <arser/arser.h>
#include <vconone/vconone.h>
#include <luci/UserSettings.h>
#include <luci/Log.h>

Go to the source code of this file.

Functions

void print_version (void)
 
template<typename T >
get_values_from (arser::Arser &arser, const std::string arg, const T default_value)
 
int entry (const int argc, char **argv)
 Dump IR for given arguments.
 

Function Documentation

◆ entry()

int entry ( const int  argc,
char **  argv 
)

Dump IR for given arguments.

Call example: $ ./build/compiler/encodump/encodump \ –frontend build/compiler/enco/frontend/caffe/libenco_caffe_frontend.so \ –frontend-arg build/compiler/enco/test/caffe/Convolution_003.prototxt \ –frontend-arg build/compiler/enco/test/caffe/Convolution_003.caffemodel

HDF5 layout is like below

GROUP "/" ㄴGROUP "name" ㄴATTRIBUTE "0" ㄴDATA (0): "input_01:0" ㄴATTRIBUTE "1" ㄴDATA (0): "input_02:0" ㄴGROUP "value" ㄴDATASET "0" ㄴDATA ... ㄴDATASET "1" ㄴDATA ...

Definition at line 42 of file Driver.cpp.

43{
44 using namespace record_minmax;
45
46 using DataSetFormat = RecordMinMax::DataSetFormat;
47
48 LOGGER(l);
49
51 "Embedding min/max values of activations to the circle model for post-training quantization");
52
55
56 arser.add_argument("--input_model").required(true).help("Input model filepath");
57
58 arser.add_argument("--input_data")
59 .help("Input data filepath. If not given, record-minmax will run with randomly generated data. "
60 "Note that the random dataset does not represent inference workload, leading to poor "
61 "model accuracy.");
62
63 arser.add_argument("--output_model").required(true).help("Output model filepath");
64
65 arser.add_argument("--min_percentile")
66 .type(arser::DataType::FLOAT)
67 .help("Record n'th percentile of min");
68
69 arser.add_argument("--num_threads")
70 .type(arser::DataType::INT32)
71 .help("Number of threads (default: 1)");
72
73 arser.add_argument("--max_percentile")
74 .type(arser::DataType::FLOAT)
75 .help("Record n'th percentile of max");
76
77 arser.add_argument("--moving_avg_batch")
78 .type(arser::DataType::INT32)
79 .help("Batch size of moving average algorithm (default: 16)");
80
81 arser.add_argument("--moving_avg_const")
82 .type(arser::DataType::FLOAT)
83 .help("Hyperparameter (C) to compute moving average (default: 0.1). Update equation: avg <- "
84 "avg + C * (curr_batch_avg - avg)");
85
86 arser.add_argument("--mode").help("Record mode. percentile (default) or moving_average");
87
88 arser.add_argument("--input_data_format")
89 .help("Input data format. h5/hdf5 (default) or list/filelist");
90
91 arser.add_argument("--generate_profile_data")
92 .nargs(0)
93 .default_value(false)
94 .help("This will turn on profiling data generation.");
95
96 try
97 {
98 arser.parse(argc, argv);
99 }
100 catch (const std::runtime_error &err)
101 {
102 std::cout << err.what() << std::endl;
103 std::cout << arser;
104 return 255;
105 }
106
107 if (arser.get<bool>("--verbose"))
108 {
109 // The third parameter of setenv means REPLACE.
110 // If REPLACE is zero, it does not overwrite an existing value.
111 setenv("LUCI_LOG", "100", 0);
112 }
113
114 auto settings = luci::UserSettings::settings();
115
116 auto input_model_path = arser.get<std::string>("--input_model");
117 auto output_model_path = arser.get<std::string>("--output_model");
118
119 float min_percentile = ::get_values_from<float>(arser, "--min_percentile", 1.0);
120 uint32_t num_threads = ::get_values_from<int>(arser, "--num_threads", 1);
121 if (num_threads < 1)
122 throw std::runtime_error("The number of threads must be greater than zero");
123 float max_percentile = ::get_values_from<float>(arser, "--max_percentile", 99.0);
124 std::string mode = ::get_values_from<std::string>(arser, "--mode", "percentile");
125 uint32_t moving_avg_batch = ::get_values_from<int>(arser, "--moving_avg_batch", 16);
126 float moving_avg_const = ::get_values_from<float>(arser, "--moving_avg_const", 0.1);
127 if (mode != "percentile" && mode != "moving_average")
128 throw std::runtime_error("Unsupported mode");
129 std::string input_data_format =
130 ::get_values_from<std::string>(arser, "--input_data_format", "h5");
131 if (arser["--generate_profile_data"])
133
134 std::unique_ptr<MinMaxComputer> computer;
135 {
136 if (mode == "percentile")
137 {
138 computer = make_percentile_computer(min_percentile, max_percentile);
139 }
140 else if (mode == "moving_average")
141 {
142 computer = make_moving_avg_computer(moving_avg_batch, moving_avg_const);
143 }
144 else
145 {
146 assert(false);
147 }
148 }
149
150 RecordMinMax rmm(num_threads, std::move(computer));
151
152 // TODO: support parallel record for profile with random data
153 if (num_threads > 1 and not arser["--input_data"])
154 {
155 throw std::runtime_error("Input data must be given for parallel recording");
156 }
157
158 // Initialize interpreter and observer
159 rmm.initialize(input_model_path);
160
161 if (arser["--input_data"])
162 {
163 auto input_data_path = arser.get<std::string>("--input_data");
164
165 rmm.setInputDataPath(input_data_path);
166
167 // TODO: support parallel record from file and dir input data format
168 if (num_threads > 1 and not(input_data_format == "h5") and not(input_data_format == "hdf5"))
169 {
170 throw std::runtime_error("Parallel recording is used only for h5 now");
171 }
172
173 if (input_data_format == "h5" || input_data_format == "hdf5")
174 {
175 // Profile min/max while executing the H5 data
176 if (num_threads == 1)
177 {
178 rmm.setDataSetFormat(DataSetFormat::H5);
179 }
180 else
181 {
182 INFO(l) << "Using parallel recording" << std::endl;
183 rmm.profileDataInParallel(input_data_path);
184
185 // Save profiled values to the model
186 rmm.saveModel(output_model_path);
187
188 return EXIT_SUCCESS;
189 }
190 }
191 // input_data is a text file having a file path in each line.
192 // Each data file is composed of inputs of a model, concatenated in
193 // the same order with the input index of the model
194 //
195 // For example, for a model with n inputs, the contents of each data
196 // file can be visualized as below
197 // [input 1][input 2]...[input n]
198 // |start............end of file|
199 else if (input_data_format == "list" || input_data_format == "filelist")
200 {
201 // Profile min/max while executing the list of Raw data
202 rmm.setDataSetFormat(DataSetFormat::LIST_FILE);
203 }
204 else if (input_data_format == "directory" || input_data_format == "dir")
205 {
206 // Profile min/max while executing all files under the given directory
207 // The contents of each file is same as the raw data in the 'list' type
208 rmm.setDataSetFormat(DataSetFormat::DIRECTORY);
209 }
210 else
211 {
212 throw std::runtime_error(
213 "Unsupported input data format (supported formats: h5/hdf5 (default), list/filelist)");
214 }
215 }
216 else
217 {
218 // Profile min/max while executing random input data
219 rmm.setDataSetFormat(DataSetFormat::RANDOM);
220 }
221
222 rmm.profileData();
223
224 // Save profiled values to the model
225 rmm.saveModel(output_model_path);
226
227 return EXIT_SUCCESS;
228}
#define LOGGER(name)
Definition Log.h:65
#define INFO(name)
Definition Log.h:68
static void add_version(Arser &arser, const std::function< void(void)> &func)
Definition arser.h:755
static void add_verbose(Arser &arser)
Definition arser.h:765
void print_version(void)
Definition Driver.cpp:36
Definition arser.h:39
std::unique_ptr< MinMaxComputer > make_percentile_computer(float min_percentile, float max_percentile)
std::unique_ptr< MinMaxComputer > make_moving_avg_computer(uint32_t batch_size, float moving_avg_const)
static UserSettings * settings()

References arser::Helper::add_verbose(), arser::Helper::add_version(), INFO, record_minmax::RecordMinMax::initialize(), LOGGER, print_version(), record_minmax::RecordMinMax::profileData(), record_minmax::RecordMinMax::profileDataInParallel(), luci::UserSettings::ProfilingDataGen, record_minmax::RecordMinMax::saveModel(), record_minmax::RecordMinMax::setDataSetFormat(), record_minmax::RecordMinMax::setInputDataPath(), and luci::UserSettings::settings().

◆ get_values_from()

template<typename T >
T get_values_from ( arser::Arser arser,
const std::string  arg,
const T  default_value 
)

Definition at line 34 of file Driver.cpp.

35{
36 if (arser[arg])
37 return arser.get<T>(arg);
38
39 return default_value;
40}

◆ print_version()

void print_version ( void  )

Definition at line 27 of file Driver.cpp.

28{
29 std::cout << "record-minmax version " << vconone::get_string() << std::endl;
30 std::cout << vconone::get_copyright() << std::endl;
31}
std::string get_copyright(void)
get_copyright will return copyright string
Definition version.cpp:54
std::string get_string(void)
get_string will return string of major.minor.patch (without build)
Definition version.cpp:44

References vconone::get_copyright(), and vconone::get_string().