blob: 0375a489712acc86de7a8f2443899c26a80be64b [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);
Eric Kunzee5e26762020-10-13 16:11:07 -070039
Eric Kunze286f8342022-06-22 11:30:23 -070040int main(int argc, char** argv)
Eric Kunzee5e26762020-10-13 16:11:07 -070041{
Matthew Sloyanba5fad32022-09-26 13:31:43 +010042 TosaVersion model_version(TOSA_REFERENCE_MODEL_VERSION_MAJOR,
43 TOSA_REFERENCE_MODEL_VERSION_MINOR,
44 TOSA_REFERENCE_MODEL_VERSION_PATCH,
45 TOSA_REFERENCE_MODEL_VERSION_DRAFT);
Kevin Cheng10096742021-10-20 19:51:41 +000046
Eric Kunzee5e26762020-10-13 16:11:07 -070047 // Initialize configuration and debug subsystems
Eric Kunze286f8342022-06-22 11:30:23 -070048 g_func_debug.init_debug(0);
Eric Kunzee5e26762020-10-13 16:11:07 -070049
Eric Kunze286f8342022-06-22 11:30:23 -070050 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 -070051 {
52 return 1;
53 }
54
Kevin Cheng10096742021-10-20 19:51:41 +000055 TosaSerializationHandler tsh;
56 TosaVersion::compat_t is_compat = model_version.is_compatible(tsh.GetVersion());
57 switch (is_compat)
58 {
59 case TosaVersion::compat_t::COMPLETELY_COMPATIBLE:
60 break;
61 case TosaVersion::compat_t::PARTIALLY_COMPATIBLE:
62 printf("WARNING: Reference model version %s is partially compatible with serializer version %s\n",
63 model_version.to_string().c_str(), tsh.GetVersion().to_string().c_str());
64 break;
65 case TosaVersion::compat_t::NOT_COMPATIBLE:
66 printf("ERROR: Reference model version %s is not compatible with serializer version %s\n",
67 model_version.to_string().c_str(), tsh.GetVersion().to_string().c_str());
68 return TOSA_VERSION_MISMATCH;
69 }
70
James Ward24dbc422022-10-19 12:20:31 +010071 g_func_config.float_is_big_endian = float_is_big_endian();
72
Kevin Chengcd79f0e2021-06-03 15:00:34 -070073 json test_desc;
74
75 // Initialize test descriptor
76 if (initTestDesc(test_desc))
77 {
Kevin Cheng903763c2021-09-28 16:14:52 -070078 FATAL_ERROR("Unable to load test json");
Kevin Chengcd79f0e2021-06-03 15:00:34 -070079 }
80
81 if (loadGraph(tsh, test_desc))
Eric Kunzee5e26762020-10-13 16:11:07 -070082 {
Kevin Cheng903763c2021-09-28 16:14:52 -070083 FATAL_ERROR("Unable to load graph");
Eric Kunzee5e26762020-10-13 16:11:07 -070084 }
85
Jerry Ge9e94af82022-10-27 09:57:00 -070086 SubgraphTraverser main_gt(tsh.GetMainRegion()->GetBlockByName("main"), &tsh, nullptr);
Eric Kunzee5e26762020-10-13 16:11:07 -070087
88 if (main_gt.initializeGraph())
89 {
Kevin Chengacb550f2021-06-29 15:32:19 -070090 WARNING("Unable to initialize main graph traverser.");
91 goto done;
Eric Kunzee5e26762020-10-13 16:11:07 -070092 }
93
94 if (main_gt.linkTensorsAndNodes())
95 {
Kevin Cheng903763c2021-09-28 16:14:52 -070096 WARNING("Failed to link tensors and nodes");
97 goto done;
Eric Kunzee5e26762020-10-13 16:11:07 -070098 }
99
100 if (main_gt.validateGraph())
101 {
Kevin Cheng6097c3d2021-09-23 15:25:24 -0700102 WARNING("Failed to validate graph. Evaluation aborted.");
Kevin Cheng6097c3d2021-09-23 15:25:24 -0700103 goto done;
Eric Kunzee5e26762020-10-13 16:11:07 -0700104 }
105
Kevin Chengcc61be32021-10-14 17:09:57 -0700106 if (main_gt.allocateTensor())
107 {
108 WARNING("Failed to allocate tensor. Evaluation aborted.");
109 goto done;
110 }
111
Eric Kunzee5e26762020-10-13 16:11:07 -0700112 if (g_func_config.validate_only)
113 {
114 goto done;
115 }
116
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700117 if (readInputTensors(main_gt, test_desc))
Eric Kunzee5e26762020-10-13 16:11:07 -0700118 {
Kevin Cheng903763c2021-09-28 16:14:52 -0700119 FATAL_ERROR("Unable to read input tensors");
Eric Kunzee5e26762020-10-13 16:11:07 -0700120 }
121
122 if (g_func_config.eval)
123 {
124
Kevin Chengacb550f2021-06-29 15:32:19 -0700125 // evaluateAll() returns 1 if graph evaluation is forced to be terminated earlier.
Eric Kunzee5e26762020-10-13 16:11:07 -0700126 if (main_gt.evaluateAll())
127 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700128 ASSERT_MSG(main_gt.getGraphStatus() != GraphStatus::TOSA_VALID,
129 "Upon evaluateAll() returning 1, graph can not be VALID.");
130 }
131 else
132 {
133 ASSERT_MSG(main_gt.getGraphStatus() == GraphStatus::TOSA_VALID ||
134 main_gt.getGraphStatus() == GraphStatus::TOSA_UNPREDICTABLE,
135 "Upon evaluateAll() returning 0, graph can only be VALID/UNPREDICTABLE.");
Eric Kunzee5e26762020-10-13 16:11:07 -0700136 }
137
Kevin Chengacb550f2021-06-29 15:32:19 -0700138 // Only generate output tensor if graph is valid.
139 if (main_gt.getGraphStatus() == GraphStatus::TOSA_VALID)
Eric Kunzee5e26762020-10-13 16:11:07 -0700140 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700141 // make sure output tensor is evaluated and show its value
142 int num_output_tensors = main_gt.getNumOutputTensors();
143 bool all_output_valid = true;
144 for (int i = 0; i < num_output_tensors; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700145 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700146 const Tensor* ct = main_gt.getOutputTensor(i);
147 ASSERT_MEM(ct);
148 if (!ct->getIsValid())
Eric Kunzee5e26762020-10-13 16:11:07 -0700149 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700150 ct->dumpTensorParams(g_func_debug.func_debug_file);
151 if (DEBUG_ENABLED(DEBUG_VERB_HIGH, GT))
152 {
153 ct->dumpTensor(g_func_debug.func_debug_file);
154 }
155 all_output_valid = false;
Eric Kunzee5e26762020-10-13 16:11:07 -0700156 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700157 }
Kevin Chengacb550f2021-06-29 15:32:19 -0700158 if (!all_output_valid)
Eric Kunzee5e26762020-10-13 16:11:07 -0700159 {
Kevin Chengacb550f2021-06-29 15:32:19 -0700160 main_gt.dumpGraph(g_func_debug.func_debug_file);
Kevin Cheng903763c2021-09-28 16:14:52 -0700161 FATAL_ERROR(
Kevin Chengacb550f2021-06-29 15:32:19 -0700162 "SubgraphTraverser \"main\" error: Output tensors are not all valid at the end of evaluation.");
163 }
164
165 if (g_func_config.output_tensors)
166 {
167 if (writeFinalTensors(main_gt, test_desc))
168 {
169 WARNING("Errors encountered in saving output tensors");
170 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700171 }
172 }
173 }
174
175done:
Kevin Chengacb550f2021-06-29 15:32:19 -0700176 switch (main_gt.getGraphStatus())
177 {
178 case GraphStatus::TOSA_VALID:
179 // Result is valid.
180 break;
181 case GraphStatus::TOSA_UNPREDICTABLE:
182 fprintf(stderr, "Graph result: UNPREDICTABLE.\n");
183 break;
184 case GraphStatus::TOSA_ERROR:
185 fprintf(stderr, "Graph result: ERROR.\n");
186 break;
187 default:
188 fprintf(stderr, "Unknown graph status code=%d.\n", (int)main_gt.getGraphStatus());
189 }
190
Eric Kunze286f8342022-06-22 11:30:23 -0700191 g_func_debug.fini_debug();
Eric Kunzee5e26762020-10-13 16:11:07 -0700192
Kevin Chengacb550f2021-06-29 15:32:19 -0700193 return (int)main_gt.getGraphStatus();
Eric Kunzee5e26762020-10-13 16:11:07 -0700194}
195
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700196int loadGraph(TosaSerializationHandler& tsh, json test_desc)
Eric Kunzee5e26762020-10-13 16:11:07 -0700197{
198 char graph_fullname[1024];
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000199 const std::string error_msg1 = "Check \"tosa_file\" in .json specified by --tosa_desc";
200 const std::string error_msg2 = " or via arguments --tosa_file & --flatbuffer_dir";
201
202 if (strlen(test_desc["tosa_file"].get<std::string>().c_str()) <= 0)
203 {
204 FATAL_ERROR("Missing tosa_file.\n%s", error_msg1.c_str());
205 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700206
Eric Kunze286f8342022-06-22 11:30:23 -0700207 snprintf(graph_fullname, sizeof(graph_fullname), "%s/%s", g_func_config.flatbuffer_dir.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700208 test_desc["tosa_file"].get<std::string>().c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700209
Eric Kunzee5e26762020-10-13 16:11:07 -0700210 const char JSON_EXT[] = ".json";
211 int is_json = 0;
212 {
213 // look for JSON file extension
214 size_t suffix_len = strlen(JSON_EXT);
215 size_t str_len = strlen(graph_fullname);
216
217 if (str_len > suffix_len && strncasecmp(graph_fullname + (str_len - suffix_len), JSON_EXT, suffix_len) == 0)
218 {
219 is_json = 1;
220 }
221 }
222
223 if (is_json)
224 {
Eric Kunze286f8342022-06-22 11:30:23 -0700225 if (tsh.LoadFileSchema(g_func_config.operator_fbs.c_str()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700226 {
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000227 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 -0700228 g_func_config.operator_fbs.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700229 }
230
231 if (tsh.LoadFileJson(graph_fullname))
232 {
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000233 FATAL_ERROR("\nError loading JSON graph file: %s\n%s%s\nCheck --operator_fbs is using correct version",
234 graph_fullname, error_msg1.c_str(), error_msg2.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700235 }
236 }
237 else
238 {
239 if (tsh.LoadFileTosaFlatbuffer(graph_fullname))
240 {
Kevin Cheng903763c2021-09-28 16:14:52 -0700241 FATAL_ERROR(
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000242 "\nError loading TOSA flatbuffer file: %s\n%s%s",
243 graph_fullname, error_msg1.c_str(), error_msg2.c_str());
Eric Kunzee5e26762020-10-13 16:11:07 -0700244 }
245 }
246
247 return 0;
248}
249
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700250int readInputTensors(SubgraphTraverser& gt, json test_desc)
Eric Kunzee5e26762020-10-13 16:11:07 -0700251{
252 int tensorCount = gt.getNumInputTensors();
253 Tensor* tensor;
254 char filename[1024];
255
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700256 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700257 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700258 if ((tensorCount != (int)test_desc["ifm_name"].size()) || (tensorCount != (int)test_desc["ifm_file"].size()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700259 {
Eric Kunze286f8342022-06-22 11:30:23 -0700260 WARNING("Number of input tensors(%d) doesn't match name(%ld)/file(%ld) in test descriptor.", tensorCount,
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700261 test_desc["ifm_name"].size(), test_desc["ifm_file"].size());
Eric Kunzee5e26762020-10-13 16:11:07 -0700262 return 1;
263 }
264
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700265 for (int i = 0; i < tensorCount; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700266 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700267 tensor = gt.getInputTensorByName(test_desc["ifm_name"][i].get<std::string>());
268 if (!tensor)
Eric Kunzee5e26762020-10-13 16:11:07 -0700269 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700270 WARNING("Unable to find input tensor %s", test_desc["ifm_name"][i].get<std::string>().c_str());
271 return 1;
272 }
273
Eric Kunze286f8342022-06-22 11:30:23 -0700274 snprintf(filename, sizeof(filename), "%s/%s", g_func_config.flatbuffer_dir.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700275 test_desc["ifm_file"][i].get<std::string>().c_str());
276
277 DEBUG_MED(GT, "Loading input tensor %s from filename: %s", tensor->getName().c_str(), filename);
278
Kevin Chengcc61be32021-10-14 17:09:57 -0700279 if (!tensor->is_allocated())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700280 {
Kevin Chengcc61be32021-10-14 17:09:57 -0700281 WARNING("Tensor %s is not allocated before being initialized", tensor->getName().c_str());
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700282 return 1;
283 }
284
285 if (tensor->readFromNpyFile(filename))
286 {
287 WARNING("Unable to read input tensor %s from filename: %s", tensor->getName().c_str(), filename);
288 tensor->dumpTensorParams(g_func_debug.func_debug_file);
289 return 1;
290 }
291
292 // Push ready consumers to the next node list
293 for (auto gn : tensor->getConsumers())
294 {
295 if (gn->hasAllInputsReady() && !gn->getOnNextNodeList())
296 {
297 gt.addToNextNodeList(gn);
298 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700299 }
300 }
301 }
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700302 catch (nlohmann::json::type_error& e)
303 {
304 WARNING("Fail accessing test descriptor: %s", e.what());
305 return 1;
306 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700307
308 if (DEBUG_ENABLED(DEBUG_VERB_HIGH, GT))
309 {
310 gt.dumpNextNodeList(g_func_debug.func_debug_file);
311 }
312
313 return 0;
314}
315
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700316int writeFinalTensors(SubgraphTraverser& gt, json test_desc)
Eric Kunzee5e26762020-10-13 16:11:07 -0700317{
318 int tensorCount = gt.getNumOutputTensors();
319 const Tensor* tensor;
320 char filename[1024];
321
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700322 try
Eric Kunzee5e26762020-10-13 16:11:07 -0700323 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700324 if ((tensorCount != (int)test_desc["ofm_name"].size()) || (tensorCount != (int)test_desc["ofm_file"].size()))
Eric Kunzee5e26762020-10-13 16:11:07 -0700325 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700326 WARNING("Number of output tensors(%d) doesn't match name(%ld)/file(%ld) in test descriptor.", tensorCount,
327 test_desc["ofm_name"].size(), test_desc["ofm_file"].size());
Eric Kunzee5e26762020-10-13 16:11:07 -0700328 return 1;
329 }
330
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700331 for (int i = 0; i < tensorCount; i++)
Eric Kunzee5e26762020-10-13 16:11:07 -0700332 {
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700333 tensor = gt.getOutputTensorByName(test_desc["ofm_name"][i].get<std::string>());
334 if (!tensor)
335 {
336 WARNING("Unable to find output tensor %s", test_desc["ofm_name"][i].get<std::string>().c_str());
337 return 1;
338 }
339
Eric Kunze286f8342022-06-22 11:30:23 -0700340 snprintf(filename, sizeof(filename), "%s/%s", g_func_config.output_dir.c_str(),
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700341 test_desc["ofm_file"][i].get<std::string>().c_str());
342
343 DEBUG_MED(GT, "Writing output tensor[%d] %s to filename: %s", i, tensor->getName().c_str(), filename);
344
345 if (tensor->writeToNpyFile(filename))
346 {
347 WARNING("Unable to write output tensor[%d] %s to filename: %s", i, tensor->getName().c_str(), filename);
348 return 1;
349 }
350 }
351 }
352 catch (nlohmann::json::type_error& e)
353 {
354 WARNING("Fail accessing test descriptor: %s", e.what());
355 return 1;
356 }
357
358 return 0;
359}
360
361// Read "foo,bar,..." and return std::vector({foo, bar, ...})
362std::vector<std::string> parseFromString(std::string raw_str)
363{
364 bool last_pair = false;
365 std::string::size_type start = 0, end;
366 std::string name;
367
368 std::vector<std::string> result;
369 do
370 {
371 end = raw_str.find(',', start);
372 if (end == std::string::npos)
373 last_pair = true;
374
375 name = raw_str.substr(start, end);
376
377 result.push_back(name);
378
379 start = end + 1; // skip comma
380 } while (!last_pair);
381
382 return result;
383}
384
385int initTestDesc(json& test_desc)
386{
387 std::ifstream ifs(g_func_config.test_desc);
388
389 if (ifs.good())
390 {
391 try
392 {
393 test_desc = nlohmann::json::parse(ifs);
394 }
395 catch (nlohmann::json::parse_error& e)
396 {
397 WARNING("Error parsing test descriptor json: %s", e.what());
Eric Kunzee5e26762020-10-13 16:11:07 -0700398 return 1;
399 }
400 }
Jared Smolens62a7b7f2022-03-19 05:42:27 +0000401 else
402 {
Eric Kunze286f8342022-06-22 11:30:23 -0700403 WARNING("Cannot open input file: %s", g_func_config.test_desc.c_str());
Jared Smolens62a7b7f2022-03-19 05:42:27 +0000404 return 1;
405 }
Eric Kunzee5e26762020-10-13 16:11:07 -0700406
Kevin Chengd5934142021-06-28 16:23:24 -0700407 // Overwrite flatbuffer_dir/output_dir with dirname(g_func_config.test_desc) if it's not specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700408 if (g_func_config.flatbuffer_dir.empty() || g_func_config.output_dir.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700409 {
Eric Kunze286f8342022-06-22 11:30:23 -0700410 std::string test_dir = g_func_config.test_desc.substr(0, g_func_config.test_desc.find_last_of("/\\"));
411 if (g_func_config.flatbuffer_dir.empty())
Kevin Chengd5934142021-06-28 16:23:24 -0700412 {
Eric Kunze286f8342022-06-22 11:30:23 -0700413 g_func_config.flatbuffer_dir = test_dir;
Kevin Chengd5934142021-06-28 16:23:24 -0700414 }
Eric Kunze286f8342022-06-22 11:30:23 -0700415 if (g_func_config.output_dir.empty())
Kevin Chengd5934142021-06-28 16:23:24 -0700416 {
Eric Kunze286f8342022-06-22 11:30:23 -0700417 g_func_config.output_dir = test_dir;
Kevin Chengd5934142021-06-28 16:23:24 -0700418 }
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700419 }
420
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000421 // Overwrite test_desc["tosa_file"] if --tosa_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700422 if (!g_func_config.tosa_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700423 {
Eric Kunze286f8342022-06-22 11:30:23 -0700424 test_desc["tosa_file"] = g_func_config.tosa_file;
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700425 }
426
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000427 // Overwrite test_desc["ifm_name"] if --ifm_name specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700428 if (!g_func_config.ifm_name.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700429 {
Eric Kunze286f8342022-06-22 11:30:23 -0700430 std::vector<std::string> ifm_name_vec = parseFromString(g_func_config.ifm_name);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700431 test_desc["ifm_name"] = ifm_name_vec;
432 }
433
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000434 // Overwrite test_desc["ifm_file"] if --ifm_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700435 if (!g_func_config.ifm_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700436 {
Eric Kunze286f8342022-06-22 11:30:23 -0700437 std::vector<std::string> ifm_file_vec = parseFromString(g_func_config.ifm_file);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700438 test_desc["ifm_file"] = ifm_file_vec;
439 }
440
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000441 // Overwrite test_desc["ofm_name"] if --ofm_name specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700442 if (!g_func_config.ofm_name.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700443 {
Eric Kunze286f8342022-06-22 11:30:23 -0700444 std::vector<std::string> ofm_name_vec = parseFromString(g_func_config.ofm_name);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700445 test_desc["ofm_name"] = ofm_name_vec;
446 }
447
Jeremy Johnsonfa888282022-11-16 13:38:55 +0000448 // Overwrite test_desc["ofm_file"] if --ofm_file specified.
Eric Kunze286f8342022-06-22 11:30:23 -0700449 if (!g_func_config.ofm_file.empty())
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700450 {
Eric Kunze286f8342022-06-22 11:30:23 -0700451 std::vector<std::string> ofm_file_vec = parseFromString(g_func_config.ofm_file);
Kevin Chengcd79f0e2021-06-03 15:00:34 -0700452 test_desc["ofm_file"] = ofm_file_vec;
453 }
454
Eric Kunzee5e26762020-10-13 16:11:07 -0700455 return 0;
456}