Skip to content

Commit 04ef34b

Browse files
Support EP plugins
1 parent 0a4a4dd commit 04ef34b

File tree

9 files changed

+235
-60
lines changed

9 files changed

+235
-60
lines changed

c_cxx/accuracy_tool/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ add_executable(accuracy_test src/main.cc
6666
src/cmd_args.cc
6767
src/ep_cmd_args/qnn_cmd_args.h
6868
src/ep_cmd_args/qnn_cmd_args.cc
69+
src/ep_cmd_args/plugin_cmd_args.h
70+
src/ep_cmd_args/plugin_cmd_args.cc
6971
src/basic_utils.h
7072
src/basic_utils.cc
7173
src/model_io_utils.h

c_cxx/accuracy_tool/README.md

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ models/
112112
|
113113
+--> resnet/
114114
| |
115-
| +--> model.onnx
116-
| +--> model.qdq.onnx (quantized model only required for certains EPs like QNN)
115+
| +--> model.onnx (see options --ground_truth_model_name and --ep_model_name)
117116
| |
118117
| +--> test_data_set_0/
119118
| | |
@@ -127,17 +126,16 @@ models/
127126
|
128127
+--> mobilenet/
129128
|
130-
+--> model.onnx
131-
+--> model.qdq.onnx
129+
+--> model.onnx (Note: same model name)
132130
|
133131
+--> test_data_set_0/
134132
+--> test_data_set_1/
135133
```
136134

137-
- All ONNX models must be named either `model.onnx` or `model.qdq.onnx`.
138-
- The `model.qdq.onnx` file is only necessary for execution providers that run quantized models (e.g., QNN).
135+
- By default, tool expects all ONNX models to be named `model.onnx`.
136+
- Use the option `--ground_truth_model_name` to set the name of the model used to get the expected (ground-truth) output with CPU EP. Defaults to `model.onnx`.
137+
- Use the option `--ep_model_name` to set the name of the model loaded by the EP under test. Defaults to `model.onnx`.
139138
- If the expected output files are not provided, the expected outputs will be obtained by running `model.onnx` on the CPU execution provider.
140-
- Both `model.qdq.onnx` and `model.onnx` must have the same input and output signature (i.e., same names, shapes, types, and ordering).
141139
- The dataset directories must be named `test_data_set_<index>/`, where `<index>` ranges from 0 to the number of dataset directories.
142140
- The raw input files must be named `input_<index>.raw`, where `<index>` corresponds to the input's index in the ONNX model.
143141
- The raw output files are not required if `model.onnx` is provided.
@@ -158,40 +156,52 @@ Usage: accuracy_test.exe [OPTIONS...] test_models_path
158156
Defaults to false.
159157
-s/--save_expected_outputs Save outputs from baseline model on CPU EP to disk as
160158
output_<index>.raw files. Defaults to false.
161-
-e/--execution_provider ep [EP_ARGS] The execution provider to test (e.g., qnn or cpu)
159+
-e/--execution_provider ep [EP_ARGS] The execution provider to test (e.g., qnn, cpu, or plugin)
162160
Defaults to CPU execution provider running QDQ model.
163161
-c/--session_configs "<key1>|<val1> <key2>|<val2>" Session configuration options for EP under test.
164162
Refer to onnxruntime_session_options_config_keys.h
165163
-o/--output_file path The output file into which to save accuracy results
166164
-a/--expected_accuracy_file path The file containing expected accuracy results
165+
--ep_model_name onnx_model_name The name of the ONNX model to test for EP.
166+
Defaults to 'model.onnx'.
167+
--ground_truth_model_name onnx_model_name The name of the ONNX model used to get
168+
expected output with CPU EP.
169+
Not used if expected outputs are
170+
loaded from file. Defaults to 'model.onnx'.
167171
--model model_name Model to test. Option can be specified multiple times.
168172
By default, all found models are tested.
169173

170-
[EP_ARGS]: Specify EP-specific runtime options as key value pairs.
171-
Example: -e <provider_name> "<key1>|<val1> <key2>|<val2>"
172-
[QNN only] [backend_path]: QNN backend path (e.g., 'C:\Path\QnnHtp.dll')
173-
[QNN only] [profiling_level]: QNN profiling level, options: 'basic', 'detailed',
174+
[EP_ARGS]: Specify EP-specific options.
175+
CPU EP: -e qnn
176+
QNN EP: -e qnn "<key1>|<val1> <key2>|<val2>"
177+
Valid QNN key/val pairs:
178+
[backend_path]: QNN backend path (e.g., 'C:\Path\QnnHtp.dll')
179+
[profiling_level]: QNN profiling level, options: 'basic', 'detailed',
174180
default 'off'.
175-
[QNN only] [rpc_control_latency]: QNN rpc control latency. default to 10.
176-
[QNN only] [vtcm_mb]: QNN VTCM size in MB. default to 0 (not set).
177-
[QNN only] [htp_performance_mode]: QNN performance mode, options: 'burst', 'balanced',
181+
[rpc_control_latency]: QNN rpc control latency. default to 10.
182+
[vtcm_mb]: QNN VTCM size in MB. default to 0 (not set).
183+
[htp_performance_mode]: QNN performance mode, options: 'burst', 'balanced',
178184
'default', 'high_performance', 'high_power_saver',
179185
'low_balanced', 'low_power_saver', 'power_saver',
180186
'sustained_high_performance'. Defaults to 'default'.
181-
[QNN only] [qnn_context_priority]: QNN context priority, options: 'low', 'normal',
187+
[qnn_context_priority]: QNN context priority, options: 'low', 'normal',
182188
'normal_high', 'high'. Defaults to 'normal'.
183-
[QNN only] [qnn_saver_path]: QNN Saver backend path. e.g 'C:\Path\QnnSaver.dll'.
184-
[QNN only] [htp_graph_finalization_optimization_mode]: QNN graph finalization
189+
[qnn_saver_path]: QNN Saver backend path. e.g 'C:\Path\QnnSaver.dll'.
190+
[htp_graph_finalization_optimization_mode]: QNN graph finalization
185191
optimization mode, options: '0', '1', '2', '3'. Default is '0'.
192+
Plugin EP: -e plugin <ep_name> <plugin_library_path> "<key1>|<val1> <key2>|<val2>"
193+
All key/value pairs are considered session options.
186194
```
187195
188196
## Usage examples
189197
### Measure accuracy of QDQ model on CPU EP
198+
- Assumes each model directory has both a `model.onnx` and a `model.qdq.onnx`.
190199
- The expected outputs are generated by running the float32 `model.onnx` on CPU EP.
200+
- The actual outputs are generated by running the QDQ `model.qdq.onnx` on CPU EP.
191201
- Accuracy results (SNR) are dumped to stdout
192202
193203
```shell
194-
$ .\accuracy_test -e cpu models
204+
$ .\accuracy_test -e cpu --ep_model_name model.qdq.onnx models
195205

196206
[INFO]: Accuracy Results (CSV format):
197207

@@ -203,15 +213,15 @@ model_a/test_data_set_2,16.712691432087745
203213
204214
Use the `-o` command-line option to write the accuracy results to file.
205215
```shell
206-
$ .\accuracy_test -o results.csv -e cpu models
216+
$ .\accuracy_test -o results.csv -e cpu --ep_model_name model.qdq.onnx models
207217

208218
[INFO]: Saved accuracy results to results.csv
209219
```
210220
211221
### Dump (and load) the expected outputs to disk
212222
Use the `-s` command-line option to dump the expected outputs to disk (e.g., output_0.raw). The expected outputs are obtained by running `model.onnx` on the CPU EP regardless of the EP passed to the `-e` command-line option.
213223
```shell
214-
$ .\accuracy_test -s -e cpu models
224+
$ .\accuracy_test -s -e cpu --ep_model_name model.qdq.onnx models
215225

216226
[INFO]: Accuracy Results (CSV format):
217227

@@ -221,7 +231,7 @@ model_a/test_data_set_0,17.640392603599537
221231
222232
Use the `-l` command-line option to load the expected outputs directly from `output_<index>.raw` files.
223233
```shell
224-
$ .\accuracy_test -l -e cpu models
234+
$ .\accuracy_test -l -e cpu --ep_model_name model.qdq.onnx models
225235

226236
[INFO]: Accuracy Results (CSV format):
227237

@@ -230,13 +240,15 @@ model_a/test_data_set_0,17.640392603599537
230240
```
231241
232242
### Measure accuracy of QDQ model on QNN EP and detect regressions
243+
- Assumes each model directory has both a `model.onnx` and a `model.qdq.onnx`.
233244
- The expected outputs are generated by running the float32 `model.onnx` on CPU EP.
245+
- The actual outputs are generated by running the QDQ `model.qdq.onnx` on QNN EP.
234246
- Accuracy results (SNR) are dumped to results_0.csv
235247
- Uses the `-c` command-line option to disable fallback to CPU EP (i.e., entire graph runs on QNN EP).
236248
- Note: can also use the `-s` or `-l` command-line options to save or load the expected outputs as demonstrated above.
237249
238250
```shell
239-
$ .\accuracy_test -e qnn "backend_path|QnnHtp.dll" -c "session.disable_cpu_ep_fallback|1" -o results_0.csv models
251+
$ .\accuracy_test -e qnn "backend_path|QnnHtp.dll" -c "session.disable_cpu_ep_fallback|1" -o results_0.csv --ep_model_name model.qdq.onnx models
240252

241253
[INFO]: Accuracy Results (CSV format):
242254

@@ -249,7 +261,7 @@ model_a/test_data_set_2,16.812691432087745
249261
Use the `-a` command-line option to compare subsequent runs with previous accuracy results (e.g., results_0.csv). This can help detect accuracy regressions.
250262
251263
```shell
252-
.\accuracy_test -a results_o.csv -e qnn "backend_path|QnnHtp.dll" -c "session.disable_cpu_ep_fallback|1" models
264+
.\accuracy_test -a results_o.csv -e qnn "backend_path|QnnHtp.dll" -c "session.disable_cpu_ep_fallback|1" --ep_model_name model.qdq.onnx models
253265

254266
[INFO]: Accuracy Results (CSV format):
255267

@@ -270,3 +282,22 @@ model_a/test_data_set_0,16.640392603599537
270282
[INFO]: 10/11 tests passed.
271283
[INFO]: 1/11 tests failed.
272284
```
285+
286+
### Measure accuracy of model with "plugin" EP
287+
- Assumes the models/ directory contains all models to test.
288+
- Assumes each individual model directory has a `model.onnx` file.
289+
- The expected outputs are generated by running the float32 `model.onnx` on CPU EP.
290+
- The actual outputs are generated by running the same `model.onnx` on the plugin EP.
291+
- Accuracy results (SNR) are dumped to stdout
292+
293+
```shell
294+
$ .\accuracy_test -e plugin outTreeEP outTreeEP.dll "key1|val1 key2|val2" --ep_model_name model.qdq.onnx models
295+
296+
[INFO]: Accuracy Results (CSV format):
297+
298+
model_a/test_data_set_0,17.640392603599537
299+
model_a/test_data_set_1,21.326599488217347
300+
model_a/test_data_set_2,16.712691432087745
301+
...
302+
```
303+

c_cxx/accuracy_tool/src/accuracy_tester.cc

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,29 +83,18 @@ bool RunAccuracyTest(Ort::Env& env, const AppArgs& app_args) {
8383
std::cout << "[INFO]: Testing model " << model_name << " (" << dataset_paths.size() << " datasets) ... "
8484
<< std::endl;
8585

86-
std::filesystem::path base_model_path = model_dir_path / "model.onnx";
87-
std::filesystem::path ep_model_path;
88-
89-
// Determine which model will be used by the EP under test.
90-
// Some EPs will need to use a QDQ model instead of the the original model.
91-
if (app_args.uses_qdq_model) {
92-
std::filesystem::path qdq_model_path = model_dir_path / "model.qdq.onnx";
93-
94-
if (!std::filesystem::is_regular_file(qdq_model_path)) {
95-
std::cerr << "[ERROR]: Execution provider '" << app_args.execution_provider << "' requires a QDQ model."
96-
<< std::endl;
97-
return false;
98-
}
99-
ep_model_path = std::move(qdq_model_path);
100-
} else {
101-
ep_model_path = base_model_path;
86+
std::filesystem::path ep_model_path = model_dir_path / app_args.ep_model_name;
87+
if (!std::filesystem::is_regular_file(ep_model_path)) {
88+
std::cerr << "[ERROR]: Cannot find ONNX model " << ep_model_path << " with which to test the EP." << std::endl;
89+
return false;
10290
}
10391

10492
std::vector<std::unique_ptr<char[]>> all_inputs;
10593
std::vector<std::unique_ptr<char[]>> all_outputs;
10694

10795
// Load expected outputs from base model running on CPU EP (unless user wants to use outputs from disk).
10896
if (!app_args.load_expected_outputs_from_disk) {
97+
std::filesystem::path base_model_path = model_dir_path / app_args.ground_truth_model_name;
10998
if (!std::filesystem::is_regular_file(base_model_path)) {
11099
std::cerr << "[ERROR]: Cannot find ONNX model " << base_model_path << " from which to get expected outputs."
111100
<< std::endl;

c_cxx/accuracy_tool/src/cmd_args.cc

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <thread>
1414
#include <unordered_set>
1515

16+
#include "ep_cmd_args/plugin_cmd_args.h"
1617
#include "ep_cmd_args/qnn_cmd_args.h"
1718

1819
void PrintUsage(std::ostream& stream, std::string_view prog_name) {
@@ -26,34 +27,45 @@ void PrintUsage(std::ostream& stream, std::string_view prog_name) {
2627
stream << " Defaults to false." << std::endl;
2728
stream << " -s/--save_expected_outputs Save outputs from baseline model on CPU EP to disk as " << std::endl;
2829
stream << " output_<index>.raw files. Defaults to false." << std::endl;
29-
stream << " -e/--execution_provider ep [EP_ARGS] The execution provider to test (e.g., qnn or cpu)" << std::endl;
30+
stream << " -e/--execution_provider ep [EP_ARGS] The execution provider to test (e.g., qnn, cpu, or plugin)"
31+
<< std::endl;
3032
stream << " Defaults to CPU execution provider running QDQ model." << std::endl;
3133
stream << " -c/--session_configs \"<key1>|<val1> <key2>|<val2>\" Session configuration options for EP under test."
3234
<< std::endl;
3335
stream << " Refer to onnxruntime_session_options_config_keys.h"
3436
<< std::endl;
3537
stream << " -o/--output_file path The output file into which to save accuracy results" << std::endl;
3638
stream << " -a/--expected_accuracy_file path The file containing expected accuracy results" << std::endl;
39+
stream << " --ep_model_name onnx_model_name The name of the ONNX model to test for EP." << std::endl;
40+
stream << " Defaults to 'model.onnx'." << std::endl;
41+
stream << " --ground_truth_model_name onnx_model_name The name of the ONNX model used to get" << std::endl;
42+
stream << " expected output with CPU EP." << std::endl;
43+
stream << " Not used if expected outputs are" << std::endl;
44+
stream << " loaded from file. Defaults to 'model.onnx'." << std::endl;
3745
stream << " --model model_name Model to test. Option can be specified multiple times."
3846
<< std::endl;
3947
stream << " By default, all found models are tested." << std::endl;
4048
stream << std::endl;
41-
stream << "[EP_ARGS]: Specify EP-specific runtime options as key value pairs." << std::endl;
42-
stream << " Example: -e <provider_name> \"<key1>|<val1> <key2>|<val2>\"" << std::endl;
43-
stream << " [QNN only] [backend_path]: QNN backend path (e.g., 'C:\\Path\\QnnHtp.dll')" << std::endl;
44-
stream << " [QNN only] [profiling_level]: QNN profiling level, options: 'basic', 'detailed'," << std::endl;
49+
stream << "[EP_ARGS]: Specify EP-specific options." << std::endl;
50+
stream << " CPU EP: -e qnn" << std::endl;
51+
stream << " QNN EP: -e qnn \"<key1>|<val1> <key2>|<val2>\"" << std::endl;
52+
stream << " Valid QNN key/val pairs:" << std::endl;
53+
stream << " [backend_path]: QNN backend path (e.g., 'C:\\Path\\QnnHtp.dll')" << std::endl;
54+
stream << " [profiling_level]: QNN profiling level, options: 'basic', 'detailed'," << std::endl;
4555
stream << " default 'off'." << std::endl;
46-
stream << " [QNN only] [rpc_control_latency]: QNN rpc control latency. default to 10." << std::endl;
47-
stream << " [QNN only] [vtcm_mb]: QNN VTCM size in MB. default to 0 (not set)." << std::endl;
48-
stream << " [QNN only] [htp_performance_mode]: QNN performance mode, options: 'burst', 'balanced', " << std::endl;
56+
stream << " [rpc_control_latency]: QNN rpc control latency. default to 10." << std::endl;
57+
stream << " [vtcm_mb]: QNN VTCM size in MB. default to 0 (not set)." << std::endl;
58+
stream << " [htp_performance_mode]: QNN performance mode, options: 'burst', 'balanced', " << std::endl;
4959
stream << " 'default', 'high_performance', 'high_power_saver'," << std::endl;
5060
stream << " 'low_balanced', 'low_power_saver', 'power_saver'," << std::endl;
5161
stream << " 'sustained_high_performance'. Defaults to 'default'." << std::endl;
52-
stream << " [QNN only] [qnn_context_priority]: QNN context priority, options: 'low', 'normal'," << std::endl;
62+
stream << " [qnn_context_priority]: QNN context priority, options: 'low', 'normal'," << std::endl;
5363
stream << " 'normal_high', 'high'. Defaults to 'normal'." << std::endl;
54-
stream << " [QNN only] [qnn_saver_path]: QNN Saver backend path. e.g 'C:\\Path\\QnnSaver.dll'." << std::endl;
55-
stream << " [QNN only] [htp_graph_finalization_optimization_mode]: QNN graph finalization" << std::endl;
64+
stream << " [qnn_saver_path]: QNN Saver backend path. e.g 'C:\\Path\\QnnSaver.dll'." << std::endl;
65+
stream << " [htp_graph_finalization_optimization_mode]: QNN graph finalization" << std::endl;
5666
stream << " optimization mode, options: '0', '1', '2', '3'. Default is '0'." << std::endl;
67+
stream << " Plugin EP: -e plugin <ep_name> <plugin_library_path> \"<key1>|<val1> <key2>|<val2>\"" << std::endl;
68+
stream << " All key/value pairs are considered session options." << std::endl;
5769
}
5870

5971
static bool ParseSessionConfigs(const std::string& configs_string,
@@ -90,7 +102,6 @@ static bool ParseSessionConfigs(const std::string& configs_string,
90102
}
91103

92104
static void SetDefaultCpuEpArgs(AppArgs& app_args) {
93-
app_args.uses_qdq_model = true; // TODO: Make configurable?
94105
app_args.supports_multithread_inference = true;
95106
app_args.execution_provider = "cpu";
96107
}
@@ -129,7 +140,7 @@ bool GetValidPath(std::string_view prog_name, std::string_view provided_path, bo
129140
return true;
130141
}
131142

132-
bool ParseCmdLineArgs(AppArgs& app_args, int argc, char** argv) {
143+
bool ParseCmdLineArgs(AppArgs& app_args, int argc, char** argv, Ort::Env& env) {
133144
CmdArgParser cmd_args(argc, argv);
134145
std::string_view prog_name = cmd_args.GetNext();
135146

@@ -150,6 +161,22 @@ bool ParseCmdLineArgs(AppArgs& app_args, int argc, char** argv) {
150161
}
151162

152163
app_args.output_file = cmd_args.GetNext();
164+
} else if (arg == "--ep_model_name") {
165+
if (!cmd_args.HasNext()) {
166+
std::cerr << "[ERROR]: Must provide an argument after the " << arg << " option" << std::endl;
167+
PrintUsage(std::cerr, prog_name);
168+
return false;
169+
}
170+
171+
app_args.ep_model_name = cmd_args.GetNext();
172+
} else if (arg == "--ground_truth_model_name") {
173+
if (!cmd_args.HasNext()) {
174+
std::cerr << "[ERROR]: Must provide an argument after the " << arg << " option" << std::endl;
175+
PrintUsage(std::cerr, prog_name);
176+
return false;
177+
}
178+
179+
app_args.ground_truth_model_name = cmd_args.GetNext();
153180
} else if (arg == "-j" || arg == "--num_threads") {
154181
if (!cmd_args.HasNext()) {
155182
std::cerr << "[ERROR]: Must provide an argument after the " << arg << " option" << std::endl;
@@ -199,6 +226,10 @@ bool ParseCmdLineArgs(AppArgs& app_args, int argc, char** argv) {
199226
}
200227
} else if (arg == "cpu") {
201228
SetDefaultCpuEpArgs(app_args);
229+
} else if (arg == "plugin") {
230+
if (!ParseEpPluginArgs(app_args, cmd_args, prog_name, env)) {
231+
return false;
232+
}
202233
} else {
203234
std::cerr << "[ERROR]: Unsupported execution provider: " << arg << std::endl;
204235
PrintUsage(std::cerr, prog_name);
@@ -246,6 +277,14 @@ bool ParseCmdLineArgs(AppArgs& app_args, int argc, char** argv) {
246277
return false;
247278
}
248279

280+
if (app_args.ep_model_name.empty()) {
281+
app_args.ep_model_name = "model.onnx";
282+
}
283+
284+
if (app_args.ground_truth_model_name.empty()) {
285+
app_args.ground_truth_model_name = "model.onnx";
286+
}
287+
249288
if (app_args.execution_provider.empty()) {
250289
SetDefaultCpuEpArgs(app_args);
251290
}

0 commit comments

Comments
 (0)