blob: aad07cb464ae98c15c0b47525838fba01864be62 [file] [log] [blame]
Eric Kunzee5e26762020-10-13 16:11:07 -07001
Jerry Ge9e94af82022-10-27 09:57:00 -07002// Copyright (c) 2020-2023, ARM Limited.
Eric Kunzee5e26762020-10-13 16:11:07 -07003//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
Matthew Sloyanba5fad32022-09-26 13:31:43 +010016#include "model_runner.h"
17#include "version.h"
Eric Kunzee5e26762020-10-13 16:11:07 -070018
Matthew Sloyanba5fad32022-09-26 13:31:43 +010019#include "command_line_utils.h"
Eric Kunzee5e26762020-10-13 16:11:07 -070020#include "ops/op_factory.h"
21#include "subgraph_traverser.h"
22#include "tosa_serialization_handler.h"
James Ward24dbc422022-10-19 12:20:31 +010023#include "arith_util.h"
Eric Kunzee5e26762020-10-13 16:11:07 -070024
Kevin Chengcd79f0e2021-06-03 15:00:34 -070025#include <fstream>
Matthew Sloyanba5fad32022-09-26 13:31:43 +010026#include <iostream>
27#include <stdio.h>
28#include <Eigen/CXX11/Tensor>
Kevin Chengcd79f0e2021-06-03 15:00:34 -070029#include <nlohmann/json.hpp>
30
Eric Kunzee5e26762020-10-13 16:11:07 -070031using namespace TosaReference;
32using namespace tosa;
Kevin Chengcd79f0e2021-06-03 15:00:34 -070033using json = nlohmann::json;
Eric Kunzee5e26762020-10-13 16:11:07 -070034
Kevin Chengcd79f0e2021-06-03 15:00:34 -070035int initTestDesc(json& test_desc);
36int readInputTensors(SubgraphTraverser& gt, json test_desc);
37int writeFinalTensors(SubgraphTraverser& gt, json test_desc);
38int loadGraph(TosaSerializationHandler& tsh, json test_desc);
Jerry Gea793f462023-04-11 00:05:02 +000039void parse_value(const std::string& text, tosa_level_t& value);
Eric Kunzee5e26762020-10-13 16:11:07 -070040
Eric Kunze286f8342022-06-22 11:30:23 -070041int main(int argc, char** argv)
Eric Kunzee5e26762020-10-13 16:11:07 -070042{
Matthew Sloyanba5fad32022-09-26 13:31:43 +010043 TosaVersion model_version(TOSA_REFERENCE_MODEL_VERSION_MAJOR,
44 TOSA_REFERENCE_MODEL_VERSION_MINOR,
45 TOSA_REFERENCE_MODEL_VERSION_PATCH,
46 TOSA_REFERENCE_MODEL_VERSION_DRAFT);
Kevin Cheng10096742021-10-20 19:51:41 +000047
Eric Kunzee5e26762020-10-13 16:11:07 -070048 // Initialize configuration and debug subsystems
Eric Kunze286f8342022-06-22 11:30:23 -070049 g_func_debug.init_debug(0);
Eric Kunzee5e26762020-10-13 16:11:07 -070050
Eric Kunze286f8342022-06-22 11:30:23 -070051 if (func_model_parse_cmd_line(g_func_config, g_func_debug, argc, argv, model_version.to_string().c_str()))
Eric Kunzee5e26762020-10-13 16:11:07 -070052 {
53 return 1;
54 }
55
Kevin Cheng10096742021-10-20 19:51:41 +000056 TosaSerializationHandler tsh;
57 TosaVersion::compat_t is_compat = model_version.is_compatible(tsh.GetVersion());
58 switch (is_compat)
59 {
60 case TosaVersion::compat_t::COMPLETELY_COMPATIBLE:
61 break;
62 case TosaVersion::compat_t::PARTIALLY_COMPATIBLE:
63 printf("WARNING: Reference model version %s is partially compatible with serializer version %s\n",
64 model_version.to_string().c_str(), tsh.GetVersion().to_string().c_str());
65 break;
66 case TosaVersion::compat_t::NOT_COMPATIBLE:
67 printf("ERROR: Reference model version %s is not compatible with serializer version %s\n",
68 model_version.to_string().c_str(), tsh.GetVersion().to_string().c_str());
69 return TOSA_VERSION_MISMATCH;
70 }
71
James Ward24dbc422022-10-19 12:20:31 +010072 g_func_config.float_is_big_endian = float_is_big_endian();
73
Kevin Chengcd79f0e2021-06-03 15:00:34 -070074 json test_desc;
75
76 // Initialize test descriptor
77 if (initTestDesc(test_desc))
78 {
Kevin Cheng903763c2021-09-28 16:14:52 -070079 FATAL_ERROR("Unable to load test json");
Kevin Chengcd79f0e2021-06-03 15:00:34 -070080 }
81
82 if (loadGraph(tsh, test_desc))
Eric Kunzee5e26762020-10-13 16:11:07 -070083 {
Kevin Cheng903763c2021-09-28 16:14:52 -070084 FATAL_ERROR("Unable to load graph");
Eric Kunzee5e26762020-10-13 16:11:07 -070085 }
86
Tai Lyabf87182023-04-08 01:58:58 +000087 SubgraphTraverser main_gt(tsh.GetMainRegion()->GetBlockByName("main"), &tsh, nullptr);
Eric Kunzee5e26762020-10-13 16:11:07 -070088
89 if (main_gt.initializeGraph())
90 {
Kevin Chengacb550f2021-06-29 15:32:19 -070091 WARNING("Unable to initialize main graph traverser.");
92 goto done;
Eric Kunzee5e26762020-10-13 16:11:07 -070093 }
94
95 if (main_gt.linkTensorsAndNodes())
96 {
Kevin Cheng903763c2021-09-28 16:14:52 -070097 WARNING("Failed to link tensors and nodes");
98 goto done;
Eric Kunzee5e26762020-10-13 16:11:07 -070099 }
100
101 if (main_gt.validateGraph())
102 {
Kevin Cheng6097c3d2021-09-23 15:25:24 -0700103 WARNING("Failed to validate graph. Evaluation aborted.");
Kevin Cheng6097c3d2021-09-23 15:25:24 -0700104 goto done;
Eric Kunzee5e26762020-10-13 16:11:07 -0700105 }
106
Kevin Chengcc61be32021-10-14 17:09:57 -0700107 if (main_gt.allocateTensor())
108 {
109 WARNING("Failed to allocate tensor. Evaluation aborted.");
110 goto done;
111 }
112
Eric Kunzee5e26762020-10-13 16:11:07 -0700113 if (g_func_config.validate_only)
114 {
115 goto done;
116 }
117
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700118 if (readInputTensors(main_gt, test_desc))
Eric Kunzee5e26762020-10-13 16:11:07 -0700119 {
Kevin Cheng903763c2021-09-28 16:14:52 -0700120 FATAL_ERROR("Unable to read input tensors");
Eric Kunzee5e26762020-10-13 16:11:07 -0700121 }
122
123 if (g_func_config.eval)
124 {
125
Kevin Chengacb550f2021-06-29 15:32:19 -0700126 // evaluateAll() returns 1 if graph evaluation is forced to be terminated earlier.
Eric Kunzee5e26762020-10-13 16:11:07 -0700127 if (main_gt.evaluateAll())
128 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700129 ASSERT_MSG(main_gt.getGraphStatus() != GraphStatus::TOSA_VALID,
130 "Upon evaluateAll() returning 1, graph can not be VALID.");
131 }
132 else
133 {
134 ASSERT_MSG(main_gt.getGraphStatus() == GraphStatus::TOSA_VALID ||
135 main_gt.getGraphStatus() == GraphStatus::TOSA_UNPREDICTABLE,
136 "Upon evaluateAll() returning 0, graph can only be VALID/UNPREDICTABLE.");
Eric Kunzee5e26762020-10-13 16:11:07 -0700137 }
138
Kevin Chengacb550f2021-06-29 15:32:19 -0700139 // Only generate output tensor if graph is valid.
140 if (main_gt.getGraphStatus() == GraphStatus::TOSA_VALID)
Eric Kunzee5e26762020-10-13 16:11:07 -0700141 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700142 // make sure output tensor is evaluated and show its value
143 int num_output_tensors = main_gt.getNumOutputTensors();
144 bool all_output_valid = true;
145 for (int i = 0; i < num_output_tensors; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700146 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700147 const Tensor* ct = main_gt.getOutputTensor(i);
148 ASSERT_MEM(ct);
149 if (!ct->getIsValid())
Eric Kunzee5e26762020-10-13 16:11:07 -0700150 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700151 ct->dumpTensorParams(g_func_debug.func_debug_file);
152 if (DEBUG_ENABLED(DEBUG_VERB_HIGH, GT))
153 {
154 ct->dumpTensor(g_func_debug.func_debug_file);
155 }
156 all_output_valid = false;
Eric Kunzee5e26762020-10-13 16:11:07 -0700157 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700158 }
Kevin Chengacb550f2021-06-29 15:32:19 -0700159 if (!all_output_valid)
Eric Kunzee5e26762020-10-13 16:11:07 -0700160 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700161 main_gt.dumpGraph(g_func_debug.func_debug_file);
Kevin Cheng903763c2021-09-28 16:14:52 -0700162 FATAL_ERROR(
Kevin Chengacb550f2021-06-29 15:32:19 -0700163 "SubgraphTraverser \"main\" error: Output tensors are not all valid at the end of evaluation.");
164 }
165
166 if (g_func_config.output_tensors)
167 {
168 if (writeFinalTensors(main_gt, test_desc))
169 {
170 WARNING("Errors encountered in saving output tensors");
171 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700172 }
173 }
174 }
175
176done:
Kevin Chengacb550f2021-06-29 15:32:19 -0700177 switch (main_gt.getGraphStatus())
178 {
179 case GraphStatus::TOSA_VALID:
180 // Result is valid.
181 break;
182 case GraphStatus::TOSA_UNPREDICTABLE:
183 fprintf(stderr, "Graph result: UNPREDICTABLE.\n");
184 break;
185 case GraphStatus::TOSA_ERROR:
186 fprintf(stderr, "Graph result: ERROR.\n");
187 break;
188 default:
189 fprintf(stderr, "Unknown graph status code=%d.\n", (int)main_gt.getGraphStatus());
190 }
191
Eric Kunze286f8342022-06-22 11:30:23 -0700192 g_func_debug.fini_debug();
Eric Kunzee5e26762020-10-13 16:11:07 -0700193
Kevin Chengacb550f2021-06-29 15:32:19 -0700194 return (int)main_gt.getGraphStatus();
Eric Kunzee5e26762020-10-13 16:11:07 -0700195}
196
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700197int loadGraph(TosaSerializationHandler& tsh, json test_desc)
Eric Kunzee5e26762020-10-13 16:11:07 -0700198{
199 char graph_fullname[1024];
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000200 const std::string error_msg1 = "Check \"tosa_file\" in .json specified by --tosa_desc";
201 const std::string error_msg2 = " or via arguments --tosa_file & --flatbuffer_dir";
202
203 if (strlen(test_desc["tosa_file"].get<std::string>().c_str()) <= 0)
204 {
205 FATAL_ERROR("Missing tosa_file.\n%s", error_msg1.c_str());
206 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700207
Eric Kunze286f8342022-06-22 11:30:23 -0700208 snprintf(graph_fullname, sizeof(graph_fullname), "%s/%s", g_func_config.flatbuffer_dir.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700209 test_desc["tosa_file"].get<std::string>().c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700210
Eric Kunzee5e26762020-10-13 16:11:07 -0700211 const char JSON_EXT[] = ".json";
212 int is_json = 0;
213 {
214 // look for JSON file extension
215 size_t suffix_len = strlen(JSON_EXT);
216 size_t str_len = strlen(graph_fullname);
217
218 if (str_len > suffix_len && strncasecmp(graph_fullname + (str_len - suffix_len), JSON_EXT, suffix_len) == 0)
219 {
220 is_json = 1;
221 }
222 }
223
224 if (is_json)
225 {
Eric Kunze286f8342022-06-22 11:30:23 -0700226 if (tsh.LoadFileSchema(g_func_config.operator_fbs.c_str()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700227 {
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000228 FATAL_ERROR("\nJSON file detected. Unable to load TOSA flatbuffer schema from: %s\nCheck --operator_fbs is set correctly",
Eric Kunze286f8342022-06-22 11:30:23 -0700229 g_func_config.operator_fbs.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700230 }
231
232 if (tsh.LoadFileJson(graph_fullname))
233 {
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000234 FATAL_ERROR("\nError loading JSON graph file: %s\n%s%s\nCheck --operator_fbs is using correct version",
235 graph_fullname, error_msg1.c_str(), error_msg2.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700236 }
237 }
238 else
239 {
240 if (tsh.LoadFileTosaFlatbuffer(graph_fullname))
241 {
Kevin Cheng903763c2021-09-28 16:14:52 -0700242 FATAL_ERROR(
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000243 "\nError loading TOSA flatbuffer file: %s\n%s%s",
244 graph_fullname, error_msg1.c_str(), error_msg2.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700245 }
246 }
247
248 return 0;
249}
250
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700251int readInputTensors(SubgraphTraverser& gt, json test_desc)
Eric Kunzee5e26762020-10-13 16:11:07 -0700252{
253 int tensorCount = gt.getNumInputTensors();
254 Tensor* tensor;
255 char filename[1024];
256
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700257 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700258 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700259 if ((tensorCount != (int)test_desc["ifm_name"].size()) || (tensorCount != (int)test_desc["ifm_file"].size()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700260 {
Eric Kunze286f8342022-06-22 11:30:23 -0700261 WARNING("Number of input tensors(%d) doesn't match name(%ld)/file(%ld) in test descriptor.", tensorCount,
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700262 test_desc["ifm_name"].size(), test_desc["ifm_file"].size());
Eric Kunzee5e26762020-10-13 16:11:07 -0700263 return 1;
264 }
265
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700266 for (int i = 0; i < tensorCount; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700267 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700268 tensor = gt.getInputTensorByName(test_desc["ifm_name"][i].get<std::string>());
269 if (!tensor)
Eric Kunzee5e26762020-10-13 16:11:07 -0700270 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700271 WARNING("Unable to find input tensor %s", test_desc["ifm_name"][i].get<std::string>().c_str());
272 return 1;
273 }
274
Eric Kunze286f8342022-06-22 11:30:23 -0700275 snprintf(filename, sizeof(filename), "%s/%s", g_func_config.flatbuffer_dir.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700276 test_desc["ifm_file"][i].get<std::string>().c_str());
277
278 DEBUG_MED(GT, "Loading input tensor %s from filename: %s", tensor->getName().c_str(), filename);
279
Kevin Chengcc61be32021-10-14 17:09:57 -0700280 if (!tensor->is_allocated())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700281 {
Kevin Chengcc61be32021-10-14 17:09:57 -0700282 WARNING("Tensor %s is not allocated before being initialized", tensor->getName().c_str());
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700283 return 1;
284 }
285
286 if (tensor->readFromNpyFile(filename))
287 {
288 WARNING("Unable to read input tensor %s from filename: %s", tensor->getName().c_str(), filename);
289 tensor->dumpTensorParams(g_func_debug.func_debug_file);
290 return 1;
291 }
292
293 // Push ready consumers to the next node list
294 for (auto gn : tensor->getConsumers())
295 {
296 if (gn->hasAllInputsReady() && !gn->getOnNextNodeList())
297 {
298 gt.addToNextNodeList(gn);
299 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700300 }
301 }
302 }
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700303 catch (nlohmann::json::type_error& e)
304 {
305 WARNING("Fail accessing test descriptor: %s", e.what());
306 return 1;
307 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700308
309 if (DEBUG_ENABLED(DEBUG_VERB_HIGH, GT))
310 {
311 gt.dumpNextNodeList(g_func_debug.func_debug_file);
312 }
313
314 return 0;
315}
316
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700317int writeFinalTensors(SubgraphTraverser& gt, json test_desc)
Eric Kunzee5e26762020-10-13 16:11:07 -0700318{
319 int tensorCount = gt.getNumOutputTensors();
320 const Tensor* tensor;
321 char filename[1024];
322
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700323 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700324 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700325 if ((tensorCount != (int)test_desc["ofm_name"].size()) || (tensorCount != (int)test_desc["ofm_file"].size()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700326 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700327 WARNING("Number of output tensors(%d) doesn't match name(%ld)/file(%ld) in test descriptor.", tensorCount,
328 test_desc["ofm_name"].size(), test_desc["ofm_file"].size());
Eric Kunzee5e26762020-10-13 16:11:07 -0700329 return 1;
330 }
331
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700332 for (int i = 0; i < tensorCount; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700333 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700334 tensor = gt.getOutputTensorByName(test_desc["ofm_name"][i].get<std::string>());
335 if (!tensor)
336 {
337 WARNING("Unable to find output tensor %s", test_desc["ofm_name"][i].get<std::string>().c_str());
338 return 1;
339 }
340
Eric Kunze286f8342022-06-22 11:30:23 -0700341 snprintf(filename, sizeof(filename), "%s/%s", g_func_config.output_dir.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700342 test_desc["ofm_file"][i].get<std::string>().c_str());
343
344 DEBUG_MED(GT, "Writing output tensor[%d] %s to filename: %s", i, tensor->getName().c_str(), filename);
345
346 if (tensor->writeToNpyFile(filename))
347 {
348 WARNING("Unable to write output tensor[%d] %s to filename: %s", i, tensor->getName().c_str(), filename);
349 return 1;
350 }
351 }
352 }
353 catch (nlohmann::json::type_error& e)
354 {
355 WARNING("Fail accessing test descriptor: %s", e.what());
356 return 1;
357 }
358
359 return 0;
360}
361
362// Read "foo,bar,..." and return std::vector({foo, bar, ...})
363std::vector<std::string> parseFromString(std::string raw_str)
364{
365 bool last_pair = false;
366 std::string::size_type start = 0, end;
367 std::string name;
368
369 std::vector<std::string> result;
370 do
371 {
372 end = raw_str.find(',', start);
373 if (end == std::string::npos)
374 last_pair = true;
375
376 name = raw_str.substr(start, end);
377
378 result.push_back(name);
379
380 start = end + 1; // skip comma
381 } while (!last_pair);
382
383 return result;
384}
385
386int initTestDesc(json& test_desc)
387{
388 std::ifstream ifs(g_func_config.test_desc);
389
390 if (ifs.good())
391 {
392 try
393 {
394 test_desc = nlohmann::json::parse(ifs);
395 }
396 catch (nlohmann::json::parse_error& e)
397 {
398 WARNING("Error parsing test descriptor json: %s", e.what());
Eric Kunzee5e26762020-10-13 16:11:07 -0700399 return 1;
400 }
401 }
Jared Smolens62a7b7f2022-03-19 05:42:27 +0000402 else
403 {
Eric Kunze286f8342022-06-22 11:30:23 -0700404 WARNING("Cannot open input file: %s", g_func_config.test_desc.c_str());
Jared Smolens62a7b7f2022-03-19 05:42:27 +0000405 return 1;
406 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700407
Kevin Chengd5934142021-06-28 16:23:24 -0700408 // Overwrite flatbuffer_dir/output_dir with dirname(g_func_config.test_desc) if it's not specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700409 if (g_func_config.flatbuffer_dir.empty() || g_func_config.output_dir.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700410 {
Eric Kunze286f8342022-06-22 11:30:23 -0700411 std::string test_dir = g_func_config.test_desc.substr(0, g_func_config.test_desc.find_last_of("/\\"));
412 if (g_func_config.flatbuffer_dir.empty())
Kevin Chengd5934142021-06-28 16:23:24 -0700413 {
Eric Kunze286f8342022-06-22 11:30:23 -0700414 g_func_config.flatbuffer_dir = test_dir;
Kevin Chengd5934142021-06-28 16:23:24 -0700415 }
Eric Kunze286f8342022-06-22 11:30:23 -0700416 if (g_func_config.output_dir.empty())
Kevin Chengd5934142021-06-28 16:23:24 -0700417 {
Eric Kunze286f8342022-06-22 11:30:23 -0700418 g_func_config.output_dir = test_dir;
Kevin Chengd5934142021-06-28 16:23:24 -0700419 }
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700420 }
421
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000422 // Overwrite test_desc["tosa_file"] if --tosa_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700423 if (!g_func_config.tosa_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700424 {
Eric Kunze286f8342022-06-22 11:30:23 -0700425 test_desc["tosa_file"] = g_func_config.tosa_file;
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700426 }
427
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000428 // Overwrite test_desc["ifm_name"] if --ifm_name specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700429 if (!g_func_config.ifm_name.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700430 {
Eric Kunze286f8342022-06-22 11:30:23 -0700431 std::vector<std::string> ifm_name_vec = parseFromString(g_func_config.ifm_name);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700432 test_desc["ifm_name"] = ifm_name_vec;
433 }
434
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000435 // Overwrite test_desc["ifm_file"] if --ifm_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700436 if (!g_func_config.ifm_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700437 {
Eric Kunze286f8342022-06-22 11:30:23 -0700438 std::vector<std::string> ifm_file_vec = parseFromString(g_func_config.ifm_file);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700439 test_desc["ifm_file"] = ifm_file_vec;
440 }
441
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000442 // Overwrite test_desc["ofm_name"] if --ofm_name specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700443 if (!g_func_config.ofm_name.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700444 {
Eric Kunze286f8342022-06-22 11:30:23 -0700445 std::vector<std::string> ofm_name_vec = parseFromString(g_func_config.ofm_name);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700446 test_desc["ofm_name"] = ofm_name_vec;
447 }
448
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000449 // Overwrite test_desc["ofm_file"] if --ofm_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700450 if (!g_func_config.ofm_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700451 {
Eric Kunze286f8342022-06-22 11:30:23 -0700452 std::vector<std::string> ofm_file_vec = parseFromString(g_func_config.ofm_file);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700453 test_desc["ofm_file"] = ofm_file_vec;
454 }
455
Eric Kunzee5e26762020-10-13 16:11:07 -0700456 return 0;
457}
Jerry Gea793f462023-04-11 00:05:02 +0000458
459void parse_value(const std::string& text, tosa_level_t& value)
460{
461
462 if (text == "NONE")
463 value = func_config_t::NONE;
464 else if (text == "EIGHTK")
465 value = func_config_t::EIGHTK;
466 else
467 throw cxxopts::argument_incorrect_type("TOSA_LEVEL");
468 return;
469}