blob: 55e6d67a28bed19cc11ec54a1a5e6e32a3e6b6d1 [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);
Tai Ly307392a2023-05-12 21:42:19 +000036int readInputTensors(SubgraphTraverser& gt, json& test_desc);
37int writeFinalTensors(SubgraphTraverser& gt, json& test_desc, const std::string& filename_prefix);
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);
Tai Ly307392a2023-05-12 21:42:19 +000040const std::string getResultFilenamePrefix();
41bool isComplianceModeDotProduct(json& test_desc);
Eric Kunzee5e26762020-10-13 16:11:07 -070042
Eric Kunze286f8342022-06-22 11:30:23 -070043int main(int argc, char** argv)
Eric Kunzee5e26762020-10-13 16:11:07 -070044{
Matthew Sloyanba5fad32022-09-26 13:31:43 +010045 TosaVersion model_version(TOSA_REFERENCE_MODEL_VERSION_MAJOR,
46 TOSA_REFERENCE_MODEL_VERSION_MINOR,
47 TOSA_REFERENCE_MODEL_VERSION_PATCH,
48 TOSA_REFERENCE_MODEL_VERSION_DRAFT);
Kevin Cheng10096742021-10-20 19:51:41 +000049
Eric Kunzee5e26762020-10-13 16:11:07 -070050 // Initialize configuration and debug subsystems
Eric Kunze286f8342022-06-22 11:30:23 -070051 g_func_debug.init_debug(0);
Eric Kunzee5e26762020-10-13 16:11:07 -070052
Eric Kunze286f8342022-06-22 11:30:23 -070053 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 -070054 {
55 return 1;
56 }
57
Kevin Cheng10096742021-10-20 19:51:41 +000058 TosaSerializationHandler tsh;
59 TosaVersion::compat_t is_compat = model_version.is_compatible(tsh.GetVersion());
60 switch (is_compat)
61 {
62 case TosaVersion::compat_t::COMPLETELY_COMPATIBLE:
63 break;
64 case TosaVersion::compat_t::PARTIALLY_COMPATIBLE:
65 printf("WARNING: Reference model version %s is partially compatible with serializer version %s\n",
66 model_version.to_string().c_str(), tsh.GetVersion().to_string().c_str());
67 break;
68 case TosaVersion::compat_t::NOT_COMPATIBLE:
69 printf("ERROR: Reference model version %s is not compatible with serializer version %s\n",
70 model_version.to_string().c_str(), tsh.GetVersion().to_string().c_str());
71 return TOSA_VERSION_MISMATCH;
72 }
73
James Ward24dbc422022-10-19 12:20:31 +010074 g_func_config.float_is_big_endian = float_is_big_endian();
75
Kevin Chengcd79f0e2021-06-03 15:00:34 -070076 json test_desc;
77
78 // Initialize test descriptor
79 if (initTestDesc(test_desc))
80 {
Kevin Cheng903763c2021-09-28 16:14:52 -070081 FATAL_ERROR("Unable to load test json");
Kevin Chengcd79f0e2021-06-03 15:00:34 -070082 }
83
84 if (loadGraph(tsh, test_desc))
Eric Kunzee5e26762020-10-13 16:11:07 -070085 {
Kevin Cheng903763c2021-09-28 16:14:52 -070086 FATAL_ERROR("Unable to load graph");
Eric Kunzee5e26762020-10-13 16:11:07 -070087 }
88
Tai Ly307392a2023-05-12 21:42:19 +000089 GraphStatus status = GraphStatus::TOSA_VALID;
Eric Kunzee5e26762020-10-13 16:11:07 -070090
Tai Ly307392a2023-05-12 21:42:19 +000091 // max of 2 runs, second run only happens when precise_mode is set, to do an abs_mode run
92 for (int run = 0; run < 2; run++)
Eric Kunzee5e26762020-10-13 16:11:07 -070093 {
Tai Ly307392a2023-05-12 21:42:19 +000094 SubgraphTraverser main_gt(tsh.GetMainRegion()->GetBlockByName("main"), &tsh, nullptr);
Eric Kunzee5e26762020-10-13 16:11:07 -070095
Tai Ly307392a2023-05-12 21:42:19 +000096 if (main_gt.initializeGraph())
97 {
98 WARNING("Unable to initialize main graph traverser.");
99 goto done;
100 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700101
Tai Ly307392a2023-05-12 21:42:19 +0000102 if (main_gt.linkTensorsAndNodes())
103 {
104 WARNING("Failed to link tensors and nodes");
105 goto done;
106 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700107
Tai Ly307392a2023-05-12 21:42:19 +0000108 if (main_gt.validateGraph())
109 {
110 WARNING("Failed to validate graph. Evaluation aborted.");
111 goto done;
112 }
Kevin Chengcc61be32021-10-14 17:09:57 -0700113
Tai Ly307392a2023-05-12 21:42:19 +0000114 if (main_gt.allocateTensor())
115 {
116 WARNING("Failed to allocate tensor. Evaluation aborted.");
117 goto done;
118 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700119
Tai Ly307392a2023-05-12 21:42:19 +0000120 if (g_func_config.validate_only)
121 {
122 goto done;
123 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700124
Tai Ly307392a2023-05-12 21:42:19 +0000125 if (readInputTensors(main_gt, test_desc))
126 {
127 FATAL_ERROR("Unable to read input tensors");
128 }
129
130 if (!g_func_config.eval)
131 {
132 goto done;
133 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700134
Kevin Chengacb550f2021-06-29 15:32:19 -0700135 // evaluateAll() returns 1 if graph evaluation is forced to be terminated earlier.
Eric Kunzee5e26762020-10-13 16:11:07 -0700136 if (main_gt.evaluateAll())
137 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700138 ASSERT_MSG(main_gt.getGraphStatus() != GraphStatus::TOSA_VALID,
139 "Upon evaluateAll() returning 1, graph can not be VALID.");
140 }
141 else
142 {
143 ASSERT_MSG(main_gt.getGraphStatus() == GraphStatus::TOSA_VALID ||
144 main_gt.getGraphStatus() == GraphStatus::TOSA_UNPREDICTABLE,
145 "Upon evaluateAll() returning 0, graph can only be VALID/UNPREDICTABLE.");
Eric Kunzee5e26762020-10-13 16:11:07 -0700146 }
147
Kevin Chengacb550f2021-06-29 15:32:19 -0700148 // Only generate output tensor if graph is valid.
149 if (main_gt.getGraphStatus() == GraphStatus::TOSA_VALID)
Eric Kunzee5e26762020-10-13 16:11:07 -0700150 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700151 // make sure output tensor is evaluated and show its value
152 int num_output_tensors = main_gt.getNumOutputTensors();
153 bool all_output_valid = true;
154 for (int i = 0; i < num_output_tensors; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700155 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700156 const Tensor* ct = main_gt.getOutputTensor(i);
157 ASSERT_MEM(ct);
158 if (!ct->getIsValid())
Eric Kunzee5e26762020-10-13 16:11:07 -0700159 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700160 ct->dumpTensorParams(g_func_debug.func_debug_file);
161 if (DEBUG_ENABLED(DEBUG_VERB_HIGH, GT))
162 {
163 ct->dumpTensor(g_func_debug.func_debug_file);
164 }
165 all_output_valid = false;
Eric Kunzee5e26762020-10-13 16:11:07 -0700166 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700167 }
Kevin Chengacb550f2021-06-29 15:32:19 -0700168 if (!all_output_valid)
Eric Kunzee5e26762020-10-13 16:11:07 -0700169 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700170 main_gt.dumpGraph(g_func_debug.func_debug_file);
Kevin Cheng903763c2021-09-28 16:14:52 -0700171 FATAL_ERROR(
Kevin Chengacb550f2021-06-29 15:32:19 -0700172 "SubgraphTraverser \"main\" error: Output tensors are not all valid at the end of evaluation.");
173 }
174
175 if (g_func_config.output_tensors)
176 {
Tai Ly307392a2023-05-12 21:42:19 +0000177 if (writeFinalTensors(main_gt, test_desc, getResultFilenamePrefix()))
Kevin Chengacb550f2021-06-29 15:32:19 -0700178 {
179 WARNING("Errors encountered in saving output tensors");
180 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700181 }
182 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700183
Tai Ly307392a2023-05-12 21:42:19 +0000184 done:
185 status = main_gt.getGraphStatus();
186 switch (status)
187 {
188 case GraphStatus::TOSA_VALID:
189 // Result is valid.
190 break;
191 case GraphStatus::TOSA_UNPREDICTABLE:
192 fprintf(stderr, "Graph result: UNPREDICTABLE.\n");
193 break;
194 case GraphStatus::TOSA_ERROR:
195 fprintf(stderr, "Graph result: ERROR.\n");
196 break;
197 default:
198 fprintf(stderr, "Unknown graph status code=%d.\n", (int)main_gt.getGraphStatus());
199 }
200
201 if (status == GraphStatus::TOSA_VALID && g_func_config.eval && g_func_config.precise_mode &&
202 isComplianceModeDotProduct(test_desc))
203 {
204 // first run result is valid, in precise mode and eval is true: turn on abs_mode for second run
205 g_func_config.abs_mode = true;
206 continue;
207 }
208
209 // otherwise, do only one run
210 break;
Kevin Chengacb550f2021-06-29 15:32:19 -0700211 }
212
Eric Kunze286f8342022-06-22 11:30:23 -0700213 g_func_debug.fini_debug();
Tai Ly307392a2023-05-12 21:42:19 +0000214 return (int)status;
Eric Kunzee5e26762020-10-13 16:11:07 -0700215}
216
Tai Ly307392a2023-05-12 21:42:19 +0000217int loadGraph(TosaSerializationHandler& tsh, json& test_desc)
Eric Kunzee5e26762020-10-13 16:11:07 -0700218{
219 char graph_fullname[1024];
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000220 const std::string error_msg1 = "Check \"tosa_file\" in .json specified by --tosa_desc";
221 const std::string error_msg2 = " or via arguments --tosa_file & --flatbuffer_dir";
222
223 if (strlen(test_desc["tosa_file"].get<std::string>().c_str()) <= 0)
224 {
225 FATAL_ERROR("Missing tosa_file.\n%s", error_msg1.c_str());
226 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700227
Eric Kunze286f8342022-06-22 11:30:23 -0700228 snprintf(graph_fullname, sizeof(graph_fullname), "%s/%s", g_func_config.flatbuffer_dir.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700229 test_desc["tosa_file"].get<std::string>().c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700230
Eric Kunzee5e26762020-10-13 16:11:07 -0700231 const char JSON_EXT[] = ".json";
232 int is_json = 0;
233 {
234 // look for JSON file extension
235 size_t suffix_len = strlen(JSON_EXT);
236 size_t str_len = strlen(graph_fullname);
237
238 if (str_len > suffix_len && strncasecmp(graph_fullname + (str_len - suffix_len), JSON_EXT, suffix_len) == 0)
239 {
240 is_json = 1;
241 }
242 }
243
244 if (is_json)
245 {
Eric Kunze286f8342022-06-22 11:30:23 -0700246 if (tsh.LoadFileSchema(g_func_config.operator_fbs.c_str()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700247 {
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000248 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 -0700249 g_func_config.operator_fbs.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700250 }
251
252 if (tsh.LoadFileJson(graph_fullname))
253 {
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000254 FATAL_ERROR("\nError loading JSON graph file: %s\n%s%s\nCheck --operator_fbs is using correct version",
255 graph_fullname, error_msg1.c_str(), error_msg2.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700256 }
257 }
258 else
259 {
260 if (tsh.LoadFileTosaFlatbuffer(graph_fullname))
261 {
Kevin Cheng903763c2021-09-28 16:14:52 -0700262 FATAL_ERROR(
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000263 "\nError loading TOSA flatbuffer file: %s\n%s%s",
264 graph_fullname, error_msg1.c_str(), error_msg2.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700265 }
266 }
267
268 return 0;
269}
270
Tai Ly307392a2023-05-12 21:42:19 +0000271int readInputTensors(SubgraphTraverser& gt, json& test_desc)
Eric Kunzee5e26762020-10-13 16:11:07 -0700272{
273 int tensorCount = gt.getNumInputTensors();
274 Tensor* tensor;
275 char filename[1024];
276
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700277 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700278 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700279 if ((tensorCount != (int)test_desc["ifm_name"].size()) || (tensorCount != (int)test_desc["ifm_file"].size()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700280 {
Eric Kunze286f8342022-06-22 11:30:23 -0700281 WARNING("Number of input tensors(%d) doesn't match name(%ld)/file(%ld) in test descriptor.", tensorCount,
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700282 test_desc["ifm_name"].size(), test_desc["ifm_file"].size());
Eric Kunzee5e26762020-10-13 16:11:07 -0700283 return 1;
284 }
285
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700286 for (int i = 0; i < tensorCount; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700287 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700288 tensor = gt.getInputTensorByName(test_desc["ifm_name"][i].get<std::string>());
289 if (!tensor)
Eric Kunzee5e26762020-10-13 16:11:07 -0700290 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700291 WARNING("Unable to find input tensor %s", test_desc["ifm_name"][i].get<std::string>().c_str());
292 return 1;
293 }
294
Eric Kunze286f8342022-06-22 11:30:23 -0700295 snprintf(filename, sizeof(filename), "%s/%s", g_func_config.flatbuffer_dir.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700296 test_desc["ifm_file"][i].get<std::string>().c_str());
297
298 DEBUG_MED(GT, "Loading input tensor %s from filename: %s", tensor->getName().c_str(), filename);
299
Kevin Chengcc61be32021-10-14 17:09:57 -0700300 if (!tensor->is_allocated())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700301 {
Kevin Chengcc61be32021-10-14 17:09:57 -0700302 WARNING("Tensor %s is not allocated before being initialized", tensor->getName().c_str());
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700303 return 1;
304 }
305
306 if (tensor->readFromNpyFile(filename))
307 {
308 WARNING("Unable to read input tensor %s from filename: %s", tensor->getName().c_str(), filename);
309 tensor->dumpTensorParams(g_func_debug.func_debug_file);
310 return 1;
311 }
312
313 // Push ready consumers to the next node list
314 for (auto gn : tensor->getConsumers())
315 {
316 if (gn->hasAllInputsReady() && !gn->getOnNextNodeList())
317 {
318 gt.addToNextNodeList(gn);
319 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700320 }
321 }
322 }
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700323 catch (nlohmann::json::type_error& e)
324 {
325 WARNING("Fail accessing test descriptor: %s", e.what());
326 return 1;
327 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700328
329 if (DEBUG_ENABLED(DEBUG_VERB_HIGH, GT))
330 {
331 gt.dumpNextNodeList(g_func_debug.func_debug_file);
332 }
333
334 return 0;
335}
336
Tai Ly307392a2023-05-12 21:42:19 +0000337const std::string getResultFilenamePrefix()
338{
339 return g_func_config.abs_mode ? "bounds_" : "";
340}
341
342// returns true iff test_desc contains a dictionay, "compliance",
343// which contains entry "mode" whose value is "dot product"
344bool isComplianceModeDotProduct(json& test_desc)
345{
346 if (test_desc.contains("compliance") && test_desc["compliance"].contains("mode") &&
347 test_desc["compliance"]["mode"] == "dot product")
348 {
349 return true;
350 }
351 return false;
352}
353
354int writeFinalTensors(SubgraphTraverser& gt, json& test_desc, const std::string& filename_prefix)
Eric Kunzee5e26762020-10-13 16:11:07 -0700355{
356 int tensorCount = gt.getNumOutputTensors();
357 const Tensor* tensor;
358 char filename[1024];
359
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700360 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700361 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700362 if ((tensorCount != (int)test_desc["ofm_name"].size()) || (tensorCount != (int)test_desc["ofm_file"].size()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700363 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700364 WARNING("Number of output tensors(%d) doesn't match name(%ld)/file(%ld) in test descriptor.", tensorCount,
365 test_desc["ofm_name"].size(), test_desc["ofm_file"].size());
Eric Kunzee5e26762020-10-13 16:11:07 -0700366 return 1;
367 }
368
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700369 for (int i = 0; i < tensorCount; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700370 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700371 tensor = gt.getOutputTensorByName(test_desc["ofm_name"][i].get<std::string>());
372 if (!tensor)
373 {
374 WARNING("Unable to find output tensor %s", test_desc["ofm_name"][i].get<std::string>().c_str());
375 return 1;
376 }
377
Tai Ly307392a2023-05-12 21:42:19 +0000378 snprintf(filename, sizeof(filename), "%s/%s%s", g_func_config.output_dir.c_str(), filename_prefix.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700379 test_desc["ofm_file"][i].get<std::string>().c_str());
380
381 DEBUG_MED(GT, "Writing output tensor[%d] %s to filename: %s", i, tensor->getName().c_str(), filename);
382
383 if (tensor->writeToNpyFile(filename))
384 {
385 WARNING("Unable to write output tensor[%d] %s to filename: %s", i, tensor->getName().c_str(), filename);
386 return 1;
387 }
388 }
389 }
390 catch (nlohmann::json::type_error& e)
391 {
392 WARNING("Fail accessing test descriptor: %s", e.what());
393 return 1;
394 }
395
396 return 0;
397}
398
399// Read "foo,bar,..." and return std::vector({foo, bar, ...})
400std::vector<std::string> parseFromString(std::string raw_str)
401{
402 bool last_pair = false;
403 std::string::size_type start = 0, end;
404 std::string name;
405
406 std::vector<std::string> result;
407 do
408 {
409 end = raw_str.find(',', start);
410 if (end == std::string::npos)
411 last_pair = true;
412
413 name = raw_str.substr(start, end);
414
415 result.push_back(name);
416
417 start = end + 1; // skip comma
418 } while (!last_pair);
419
420 return result;
421}
422
423int initTestDesc(json& test_desc)
424{
425 std::ifstream ifs(g_func_config.test_desc);
426
427 if (ifs.good())
428 {
429 try
430 {
431 test_desc = nlohmann::json::parse(ifs);
432 }
433 catch (nlohmann::json::parse_error& e)
434 {
435 WARNING("Error parsing test descriptor json: %s", e.what());
Eric Kunzee5e26762020-10-13 16:11:07 -0700436 return 1;
437 }
438 }
Jared Smolens62a7b7f2022-03-19 05:42:27 +0000439 else
440 {
Eric Kunze286f8342022-06-22 11:30:23 -0700441 WARNING("Cannot open input file: %s", g_func_config.test_desc.c_str());
Jared Smolens62a7b7f2022-03-19 05:42:27 +0000442 return 1;
443 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700444
Kevin Chengd5934142021-06-28 16:23:24 -0700445 // Overwrite flatbuffer_dir/output_dir with dirname(g_func_config.test_desc) if it's not specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700446 if (g_func_config.flatbuffer_dir.empty() || g_func_config.output_dir.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700447 {
Eric Kunze286f8342022-06-22 11:30:23 -0700448 std::string test_dir = g_func_config.test_desc.substr(0, g_func_config.test_desc.find_last_of("/\\"));
449 if (g_func_config.flatbuffer_dir.empty())
Kevin Chengd5934142021-06-28 16:23:24 -0700450 {
Eric Kunze286f8342022-06-22 11:30:23 -0700451 g_func_config.flatbuffer_dir = test_dir;
Kevin Chengd5934142021-06-28 16:23:24 -0700452 }
Eric Kunze286f8342022-06-22 11:30:23 -0700453 if (g_func_config.output_dir.empty())
Kevin Chengd5934142021-06-28 16:23:24 -0700454 {
Eric Kunze286f8342022-06-22 11:30:23 -0700455 g_func_config.output_dir = test_dir;
Kevin Chengd5934142021-06-28 16:23:24 -0700456 }
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700457 }
458
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000459 // Overwrite test_desc["tosa_file"] if --tosa_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700460 if (!g_func_config.tosa_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700461 {
Eric Kunze286f8342022-06-22 11:30:23 -0700462 test_desc["tosa_file"] = g_func_config.tosa_file;
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700463 }
464
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000465 // Overwrite test_desc["ifm_name"] if --ifm_name specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700466 if (!g_func_config.ifm_name.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700467 {
Eric Kunze286f8342022-06-22 11:30:23 -0700468 std::vector<std::string> ifm_name_vec = parseFromString(g_func_config.ifm_name);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700469 test_desc["ifm_name"] = ifm_name_vec;
470 }
471
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000472 // Overwrite test_desc["ifm_file"] if --ifm_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700473 if (!g_func_config.ifm_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700474 {
Eric Kunze286f8342022-06-22 11:30:23 -0700475 std::vector<std::string> ifm_file_vec = parseFromString(g_func_config.ifm_file);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700476 test_desc["ifm_file"] = ifm_file_vec;
477 }
478
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000479 // Overwrite test_desc["ofm_name"] if --ofm_name specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700480 if (!g_func_config.ofm_name.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700481 {
Eric Kunze286f8342022-06-22 11:30:23 -0700482 std::vector<std::string> ofm_name_vec = parseFromString(g_func_config.ofm_name);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700483 test_desc["ofm_name"] = ofm_name_vec;
484 }
485
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000486 // Overwrite test_desc["ofm_file"] if --ofm_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700487 if (!g_func_config.ofm_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700488 {
Eric Kunze286f8342022-06-22 11:30:23 -0700489 std::vector<std::string> ofm_file_vec = parseFromString(g_func_config.ofm_file);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700490 test_desc["ofm_file"] = ofm_file_vec;
491 }
492
Eric Kunzee5e26762020-10-13 16:11:07 -0700493 return 0;
494}
Jerry Gea793f462023-04-11 00:05:02 +0000495
496void parse_value(const std::string& text, tosa_level_t& value)
497{
498
499 if (text == "NONE")
500 value = func_config_t::NONE;
501 else if (text == "EIGHTK")
502 value = func_config_t::EIGHTK;
503 else
504 throw cxxopts::argument_incorrect_type("TOSA_LEVEL");
505 return;
506}