blob: a10e839203a11ba34d1a1df47bcf4adec1ca5680 [file] [log] [blame]
Jeremy Johnson0ecfa372022-06-30 14:27:56 +01001#!/usr/bin/env python3
Jeremy Johnson35396f22023-01-04 17:05:25 +00002# Copyright (c) 2021-2023, ARM Limited.
Jeremy Johnson0ecfa372022-06-30 14:27:56 +01003# SPDX-License-Identifier: Apache-2.0
4"""Build conformance tests.
5
6Steps:
7- Specific input shapes (or tests) are specified and produced by using the
8 settings in the .json files.
9- Tests are selected to produce a good coverage.
10- Tests are run on the reference model to produce the correct output files.
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +010011- Tests are converted to JSON and/or copied and saved to desired output directory.
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010012"""
13import argparse
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +000014import copy
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010015import json
16import logging
17import multiprocessing as mp
18import os
Jeremy Johnsonfd8c8fe2023-10-23 11:55:38 +010019import re
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010020import shlex
21import shutil
22import subprocess
23from functools import partial
24from itertools import tee
25from pathlib import Path
26
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +010027import conformance.model_files as cmf
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010028from conformance.test_select import Operator
29from convert2conformance.convert2conformance import main as c2c_main
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +010030from convert2conformance.convert2conformance import OUTPUT_TYPE_DEFAULT
31from convert2conformance.convert2conformance import OUTPUT_TYPES
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010032from distutils.dir_util import copy_tree
Jeremy Johnsonfd8c8fe2023-10-23 11:55:38 +010033from serializer.tosa_serializer import TOSA_VERSION
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010034
35logging.basicConfig()
36logger = logging.getLogger("tosa_verif_conformance_generator")
37
38# Configuration for each TOSA profile
39PROFILE_OPS_INFO = {
Jeremy Johnson88588622022-07-12 16:42:29 +010040 "tosa-bi": {
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010041 "operator_test_params": "tosa_base_profile_ops_info.json",
42 "framework_tests": "tosa_base_profile_framework_ops_info.json",
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010043 },
44 "tosa-mi": {
45 # Note: This is just the extra tests not in the base profile!
46 "operator_test_params": "tosa_main_profile_ops_info.json",
47 "framework_tests": "tosa_main_profile_framework_ops_info.json",
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010048 },
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010049}
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +010050PROFILES_ALL = "all"
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010051
Jeremy Johnson93d43902022-09-27 12:26:14 +010052DEFAULT_SEED = 42
53
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +000054# When there is a dictionary of generator argument lists (groups) only the
55# standard group will have negative tests generated for it
56STANDARD_GENERATOR_GROUP = "standard"
57
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +010058TEST_VERSION_LATEST = "latest"
59TEST_VERSION_V0_60_0 = "v0.60.0"
60TEST_VERSIONS = (TEST_VERSION_LATEST, TEST_VERSION_V0_60_0)
Jeremy Johnsonfd8c8fe2023-10-23 11:55:38 +010061REGEX_VERSION = re.compile(r"v([0-9]+)\.([0-9]+)\.([0-9]+)")
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +010062
Jeremy Johnson0ecfa372022-06-30 14:27:56 +010063
64class GenConformanceError(Exception):
65 """Generation error reporting exception."""
66
67 pass
68
69
70def _run_sh_command(args, cwd, full_cmd):
71 """Run an external command and capture stdout/stderr."""
72 # Quote the command line for printing
73 full_cmd_esc = [shlex.quote(x) for x in full_cmd]
74 if args.capture_output:
75 logger.debug(f"Command: {full_cmd_esc}")
76
77 rc = subprocess.run(
78 full_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd
79 )
80
81 if args.capture_output:
82 stdout = rc.stdout.decode("utf-8")
83 logger.debug(f"stdout: \n{stdout}")
84 if rc.returncode != 0:
85
86 raise Exception(
87 "Error running command: {}.\n{}".format(
88 " ".join(full_cmd_esc), rc.stderr.decode("utf-8")
89 )
90 )
91 return (rc.stdout, rc.stderr)
92
93
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +000094def build_op_tests(
Jeremy Johnson1271c442023-09-05 11:39:26 +010095 args,
96 test_type,
97 profile,
98 operator,
99 group,
100 gen_args_list,
101 gen_neg_dim_range,
102 supports=[],
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000103):
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100104 """Build tests for a given operator.
105
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000106 Builds a set of tests based on the given generator arguments list
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100107
108 Returns operator output directory
109 """
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100110 build_tests_cmd = "tosa_verif_build_tests"
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000111 op_build_dir = args.build_dir / profile / group
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100112
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000113 build_cmd_base = [
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100114 build_tests_cmd,
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100115 "--generate-lib-path",
116 str(args.generate_lib_path),
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100117 "--filter",
118 operator,
119 "-o",
120 str(op_build_dir),
121 "--seed",
Jeremy Johnson93d43902022-09-27 12:26:14 +0100122 str(args.random_seed),
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100123 ]
124
Jeremy Johnson1271c442023-09-05 11:39:26 +0100125 if "lazy_data_gen" in supports and args.lazy_data_generation:
126 build_cmd_base.append("--lazy-data-generation")
127
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000128 build_cmds_list = []
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100129
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000130 if test_type in ["positive", "both"]:
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100131 # Append extra parameters and run test generator for each set of parameters.
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000132 for arglist in gen_args_list:
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000133 build_cmd_pos_test = build_cmd_base.copy()
134 build_cmd_pos_test.extend(["--test-type", "positive"])
135 build_cmd_pos_test.extend(arglist)
136 build_cmds_list.append(build_cmd_pos_test)
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100137
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000138 if test_type in ["negative", "both"]:
Jeremy Johnson35396f22023-01-04 17:05:25 +0000139 # Get target-dtypes options and any filter string to limit tests
Jeremy Johnson93d43902022-09-27 12:26:14 +0100140 target_dtypes_args = []
Jeremy Johnson35396f22023-01-04 17:05:25 +0000141 filter_str = None
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000142 for arglist in gen_args_list:
Jeremy Johnson93d43902022-09-27 12:26:14 +0100143 idx = 0
144 while idx < len(arglist):
145 if arglist[idx] == "--target-dtype":
146 if arglist[idx + 1] not in target_dtypes_args:
147 target_dtypes_args.extend(arglist[idx : idx + 2])
148 idx += 1 # skip over option (and then argument below)
Jeremy Johnson35396f22023-01-04 17:05:25 +0000149 elif arglist[idx] == "--filter":
150 filter_str = arglist[idx + 1]
151 idx += 1 # skip over option (and then argument below)
Jeremy Johnson93d43902022-09-27 12:26:14 +0100152 idx += 1
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000153 build_cmd_neg_test = build_cmd_base.copy()
Jeremy Johnson35396f22023-01-04 17:05:25 +0000154 if filter_str:
155 build_cmd_neg_test.extend(["--filter", filter_str])
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000156 build_cmd_neg_test.extend(["--test-type", "negative"])
Jeremy Johnson93d43902022-09-27 12:26:14 +0100157 # Limit sizes of negative tests
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000158 dim_range = gen_neg_dim_range if gen_neg_dim_range is not None else "1,16"
159
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000160 build_cmd_neg_test.extend(["--tensor-dim-range", dim_range])
161 build_cmd_neg_test.extend(target_dtypes_args)
162 build_cmds_list.append(build_cmd_neg_test)
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100163
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000164 logger.debug(f"Creating {operator} tests with {len(build_cmds_list)} parameter(s)")
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100165 error = False
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000166 for i, cmd in enumerate(build_cmds_list):
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100167 try:
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100168 _run_sh_command(args, args.ref_model_path.parent, cmd)
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100169 logger.info(
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000170 f"{operator} test batch {(i+1)}/{len(build_cmds_list)} created successfully"
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100171 )
172 except Exception as e:
173 logger.error(
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000174 f"{operator} test batch {(i+1)}/{len(build_cmds_list)} unsuccessful, skipping"
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100175 )
176 logger.error(f" build_op_tests error: {e} ")
177 error = True
178 if error:
179 raise (GenConformanceError())
180
181 return op_build_dir
182
183
184def _check_to_include_test(profile, test_name, exclude_negative_tests=False):
185 """Check test name for exclusions, return False to indicate excluded."""
186 excludes = ["ERRORIF"] if exclude_negative_tests else []
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100187
188 for exclusion in excludes:
189 if f"_{exclusion}_" in test_name:
190 return False
191 return True
192
193
194def _get_all_tests_list(
195 profile, test_root_dir, operator, exclude_negative_tests=False, include_all=False
196):
197 """Create test list based on tests in the test_dir."""
198 test_dir = test_root_dir / operator
199 if not test_dir.is_dir():
200 # Tests are split into multiple dirs, for example: conv2d_1x1, conv2d_3x3
201 test_dir = test_root_dir
202 directories = [
203 tdir for tdir in test_dir.glob("*") if tdir.name.startswith(operator)
204 ]
205 else:
206 directories = [test_dir]
207
208 tests = []
209 for tdir in directories:
210 tests.extend(
211 [
212 test
213 for test in tdir.glob("*")
214 if include_all
215 or _check_to_include_test(profile, test.name, exclude_negative_tests)
216 ]
217 )
218 return tests
219
220
Jeremy Johnson1271c442023-09-05 11:39:26 +0100221def generate_results(args, profile, operator, op_build_dir, supports=[], tests=None):
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100222 """Run tests on reference model and save result to the test directory."""
Jeremy Johnson1271c442023-09-05 11:39:26 +0100223 if "lazy_data_gen" in supports and args.lazy_data_generation:
224 logger.info("Skipping running tests due to lazy data gen")
225 return
226
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100227 num_cores = args.num_cores
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100228
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +0100229 # Use the test runner
230 ref_cmd_base = [
231 "tosa_verif_run_tests",
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100232 "--ref-model-path",
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100233 str(args.ref_model_path),
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +0100234 "--schema-path",
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100235 str(args.schema_path),
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100236 "-j",
237 str(num_cores),
238 "-v",
239 "-t",
240 ]
241 ref_cmds = []
242
243 if not tests:
244 # Do not need to run ERRORIF tests as they don't have result files
245 tests = _get_all_tests_list(
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100246 profile, op_build_dir, operator, exclude_negative_tests=True
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100247 )
248
249 for test in tests:
Jeremy Johnsone2b5e872023-09-14 17:02:09 +0100250 desc = test / "desc.json"
251 with desc.open("r") as fd:
252 test_desc = json.load(fd)
253 if "meta" in test_desc and "compliance" in test_desc["meta"]:
254 logger.info(
255 f"Skipping generating results for new compliance test - {str(test)}"
256 )
257 continue
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100258 ref_cmd = ref_cmd_base.copy()
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +0100259 ref_cmd.append(str(test.absolute()))
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100260 ref_cmds.append(ref_cmd)
261
262 fail_string = "UNEXPECTED_FAILURE"
263 failed_counter = 0
264
265 job_pool = mp.Pool(args.num_cores)
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100266 sh_partial = partial(_run_sh_command, args, args.ref_model_path.parent)
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100267 pool_results = job_pool.map(sh_partial, ref_cmds)
268 job_pool.close()
269 job_pool.join()
270
271 # Use captured output for run_sh_command to work out if test passed.
272 for i, rc in enumerate(pool_results):
273 if fail_string in str(rc[0]):
274 logger.error(f"Test {i+1}/{len(ref_cmds)}: {ref_cmds[i][-1]} failed.")
275 failed_counter += 1
276 else:
277 logger.info(f"Test {i+1}/{len(ref_cmds)}: {ref_cmds[i][-1]} passed.")
278
279 logger.info(f"{len(ref_cmds)-failed_counter}/{len(ref_cmds)} tests passed")
280 logger.info("Ran tests on model and saved results of passing tests")
281
282
283def convert_tests(
284 args,
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100285 profile,
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100286 operator,
287 op_build_dir,
288 output_dir,
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100289 op_profiles_list,
Jeremy Johnson1271c442023-09-05 11:39:26 +0100290 supports=[],
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100291 tests=None,
292 group=None,
293 trim_op_subdir=False,
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000294 tags=None,
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100295):
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +0100296 """Convert/copy tests to output directory."""
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100297 if group:
298 output_dir = output_dir / group
299
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100300 c2c_args_base = ["--strict"]
301 c2c_args_base.extend(["--schema-path", str(args.schema_path)])
302 c2c_args_base.extend(["--flatc-path", str(args.flatc_path)])
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +0100303 c2c_args_base.extend(["--output-type", args.output_type])
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100304 # This op maybe in more than one profile - e.g. tosa_bi and tosa_mi
305 # even if we are only producing tests for tosa_mi
306 for op_profile in op_profiles_list:
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000307 c2c_args_base.extend(["--profile", op_profile])
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000308 if tags is not None:
309 for tag in tags:
310 c2c_args_base.extend(["--tag", tag])
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100311 if args.framework_schema:
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000312 c2c_args_base.extend(["--framework-schema", str(args.framework_schema)])
Jeremy Johnson1271c442023-09-05 11:39:26 +0100313 if "lazy_data_gen" in supports and args.lazy_data_generation:
314 c2c_args_base.append("--lazy-data-generation")
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000315 c2c_args_base.append("--output-directory")
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100316
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000317 c2c_args_list = []
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100318
319 if not tests:
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100320 tests = _get_all_tests_list(profile, op_build_dir, operator)
321 logger.info(f"Converting all {profile} profile tests")
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100322
323 # Controls if we copy the tests in their operator sub-directory or not
324 output_dir_relative_pos = -1 if trim_op_subdir else -2
325 for test in tests:
326 logger.info(f"Test chosen: {test}")
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000327 c2c_args = c2c_args_base.copy()
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100328 full_output_directory = output_dir / test.relative_to(
329 *test.parts[:output_dir_relative_pos]
330 )
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000331 c2c_args.append(str(full_output_directory))
332 c2c_args.append(str(test))
333 c2c_args_list.append(c2c_args)
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100334
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000335 if len(c2c_args_list) == 0:
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000336 logger.error(
337 f"No tests found for {operator}. Nothing to convert in {op_build_dir}"
338 )
339 raise (GenConformanceError())
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100340
341 job_pool = mp.Pool(args.num_cores)
342
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000343 pool_results = job_pool.map(c2c_main, c2c_args_list)
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100344 job_pool.close()
345 job_pool.join()
346
347 failed_counter = 0
348 for i, result in enumerate(pool_results):
349 if result != 0:
350 logger.error(
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000351 f"test {i+1}/{len(c2c_args_list)}: {c2c_args_list[i][-1]} failed to convert."
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100352 )
353 failed_counter += 1
354 else:
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000355 logger.info(
356 f"test {i+1}/{len(c2c_args_list)}: {c2c_args_list[i][-1]} converted"
357 )
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100358 logger.info(
Jeremy Johnsondd8d9c22022-12-12 14:18:10 +0000359 f"{len(c2c_args_list)-failed_counter}/{len(c2c_args_list)} tests successfully converted"
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100360 )
361
362 if failed_counter > 0:
363 logger.error(f"Stopping due to {failed_counter} test conversion errors")
364 raise (GenConformanceError())
365
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +0100366 logger.info("Converted/copied tests and saved to output directory")
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100367
368 return output_dir
369
370
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100371def get_op_tests_selection(
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000372 args,
373 profile,
374 operator,
375 op_build_dir,
376 selection_config,
377 negative=False,
378 ignore_missing=False,
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100379):
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100380 """Use test picker to get subsection of tests generated."""
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000381 # Need a full copy of the config as the selector updates it
382 config = copy.deepcopy(selection_config)
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100383 logger.info("Choosing {} tests".format(("negative" if negative else "positive")))
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100384 try:
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100385 op = Operator.registry[operator](
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000386 op_build_dir, config, negative=negative, ignore_missing=ignore_missing
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100387 )
388 except KeyError:
389 logger.error(f"{operator} operator is not supported by test_select")
390 raise (GenConformanceError())
391
392 return op.select_tests()
393
394
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100395def check_op_tests(args, profile, operator, output_dir):
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100396 """Move test folders than contain files larger than 30MB to new directory."""
397 destination_dir = str(args.output_dir) + "_large_files"
398
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100399 tests = _get_all_tests_list(profile, output_dir, operator, include_all=True)
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100400 if not tests:
401 logger.error(
402 f"Couldn't find any tests to size check for {operator} in {output_dir}"
403 )
404 raise (GenConformanceError())
405
406 for tdir in tests:
407 move_dir = False
408 test_files = [file for file in tdir.glob("*")]
409 for file in test_files:
410 file_size = os.stat(file).st_size / 1024**2
411 if file_size > 30:
412 move_dir = True
413
414 if move_dir:
415 move_destination = destination_dir / tdir.relative_to(output_dir)
416 logger.warning(
417 f"{tdir.relative_to(output_dir)} contains files that are too large (>30MB), test moved to new folder: {destination_dir}"
418 )
419
420 if move_destination.is_dir():
421 logger.warning(
422 f"{move_destination} directory already exists, deleting existing."
423 )
424 shutil.rmtree(str(move_destination))
425 shutil.move(str(tdir), move_destination)
426
427
428def copy_rename_framework_tests(args, operator, test_picks):
429 """Copy framework tests into new folder and rename them if needed.
430
431 The tests are renamed to match the framework operator names if an
432 alternate name has been used instead.
433 """
434 framework_tests_dir = args.framework_tests_dir
435 new_tests_dir = args.build_dir / "frameworks" / operator
436 os.makedirs(new_tests_dir, exist_ok=True)
437
438 # Get the framework tests operator name
439 if "alternate_names" in test_picks[operator]:
440 alternate_names = test_picks[operator]["alternate_names"]
441 else:
442 alternate_names = [operator]
443
444 # Get the alternate named test directories for the operator
445 for alt_name in alternate_names:
446 test_prefix = f"test_{alt_name}"
447 test_dirs = list(framework_tests_dir.glob(f"{test_prefix}_*"))
448
449 # Copy tests to new directory and rename to match framework operator names
450 # - if there is just 1 alternate name, replace the full test prefix
451 # test_add_... -> add_...
452 # - if there are multiple alternate names, just replace the "test"
453 # test_concatv2_... -> concatenation_concatv2_...
454 old_prefix = test_prefix if len(alternate_names) == 1 else "test"
455
456 for tdir in test_dirs:
457 new_test_name = tdir.name.replace(old_prefix, operator)
458 copy_destination = new_tests_dir / new_test_name
459 logger.debug(f"copying test folder {tdir} to {copy_destination}")
460 copy_tree(str(tdir), str(copy_destination))
461
462 logger.info(f"Copied and renamed {len(test_dirs)} framework test folders")
463 return new_tests_dir.parent
464
465
466def get_framework_tests_selection(args, operator, test_picks, op_build_dir):
467 """Get the list of pre-chosen tests with relative paths."""
468 try:
469 tests = test_picks[operator]["tests"]
470 except KeyError:
471 logger.error(f"Framework test selection not defined for {operator} operator")
472 raise (GenConformanceError())
473
474 test_paths = [op_build_dir / operator / test for test in tests]
475 return test_paths
476
477
478def parse_args(argv=None):
479 """Parse the arguments."""
480 parser = argparse.ArgumentParser()
Jeremy Johnson88588622022-07-12 16:42:29 +0100481 profiles = list(PROFILE_OPS_INFO.keys())
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100482 profiles.append(PROFILES_ALL)
Jeremy Johnson88588622022-07-12 16:42:29 +0100483 parser.add_argument(
484 "--profile",
485 dest="profile",
486 choices=profiles,
487 default=profiles[0],
488 type=str,
489 help=f"TOSA profile (default is {profiles[0]})",
490 )
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100491 parser.add_argument(
492 "--operators",
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100493 "--op",
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100494 type=str,
495 nargs="*",
496 help="The operator(s) to create tests for, if not supplied all tests will be created",
497 )
498 parser.add_argument(
Jeremy Johnson88588622022-07-12 16:42:29 +0100499 "--unit-tests",
500 dest="unit_tests",
501 choices=["operator", "framework", "both"],
502 default="operator",
503 type=str,
504 help="Which unit tests are produced (default is operator)",
505 )
506 parser.add_argument(
507 "--test-type",
508 dest="test_type",
509 choices=["positive", "negative", "both"],
510 default="both",
511 type=str,
512 help="Type of tests produced (default is both)",
513 )
514 parser.add_argument(
Jeremy Johnson1271c442023-09-05 11:39:26 +0100515 "--lazy-data-generation",
516 action="store_true",
517 help="Enable lazy data generation (only for tosa-mi)",
518 )
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100519 rm_group = parser.add_mutually_exclusive_group(required=True)
520 rm_group.add_argument(
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100521 "--ref-model-directory",
522 dest="ref_model_dir",
523 type=Path,
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100524 help="(DEPRECATED - use ref-model-path) Reference Model directory - with build directory",
525 )
526 rm_group.add_argument(
527 "--ref-model-path",
528 dest="ref_model_path",
529 type=Path,
530 help="Path to TOSA reference model executable",
531 )
532 parser.add_argument(
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100533 "--generate-lib-path",
534 dest="generate_lib_path",
535 type=Path,
536 help=(
537 "Path to TOSA generate library. Defaults to "
538 "the library in the directory of `ref-model-path`"
539 ),
540 )
541 parser.add_argument(
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100542 "--schema-path",
543 "--operator-fbs",
544 dest="schema_path",
545 type=Path,
546 help=(
547 "Path to TOSA reference model flat buffer schema. Defaults to "
548 f"`{cmf.DEFAULT_REF_MODEL_SCHEMA_PATH}` in parents parent directory of `ref-model-path`"
549 ),
550 )
551 parser.add_argument(
552 "--flatc-path",
553 dest="flatc_path",
554 type=Path,
555 help=(
556 "Path to flatc executable. Defaults to "
557 f"`{cmf.DEFAULT_REF_MODEL_BUILD_FLATC_PATH}` in parent directory of `ref-model-path`"
558 ),
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100559 )
Jeremy Johnson88588622022-07-12 16:42:29 +0100560 parser.add_argument(
Jeremy Johnson9c2fe6e2023-10-04 16:55:04 +0100561 "--test-version",
562 dest="test_version",
563 choices=TEST_VERSIONS,
564 default=TEST_VERSION_LATEST,
565 help=f"Version of the tests to produce (default is {TEST_VERSION_LATEST})",
566 )
567 parser.add_argument(
568 "--output-type",
569 dest="output_type",
570 choices=OUTPUT_TYPES,
571 default=OUTPUT_TYPE_DEFAULT,
572 help=f"Output file type produced (default is {OUTPUT_TYPE_DEFAULT})",
573 )
574 parser.add_argument(
Jeremy Johnson93d43902022-09-27 12:26:14 +0100575 "--seed",
576 dest="random_seed",
577 default=DEFAULT_SEED,
578 type=int,
579 help="Random test seed",
580 )
581 parser.add_argument(
Jeremy Johnson88588622022-07-12 16:42:29 +0100582 "--framework-tests-directory",
583 dest="framework_tests_dir",
584 type=Path,
585 default=Path.cwd() / "tests",
586 help="The pre-built framework tests directory (default is tests)",
587 )
588 parser.add_argument(
589 "--framework-schema",
590 dest="framework_schema",
591 type=Path,
592 help="Framework flatbuffers schema needed to convert framework models",
593 )
594 parser.add_argument(
595 "--build-directory",
596 dest="build_dir",
597 type=Path,
598 default=Path.cwd() / "conformance_build",
599 help="Temporary build directory for files created during this process (default is conformance_build)",
600 )
601 parser.add_argument(
602 "--output-directory",
603 dest="output_dir",
604 type=Path,
605 default=Path.cwd() / "conformance",
606 help="Output directory (default is conformance)",
607 )
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100608 script_dir = Path(__file__).parent.absolute()
609 parser.add_argument(
610 "--test-param-json-directory",
611 dest="param_json_dir",
612 type=Path,
613 default=script_dir,
Jeremy Johnson88588622022-07-12 16:42:29 +0100614 help=f"Test parameters (ops info) JSON file directory (default is {script_dir})",
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100615 )
616 parser.add_argument(
617 "--convert-all-tests",
618 action="store_true",
619 help="Converts all tests instead of those picked by test_select",
620 )
621 parser.add_argument(
622 "--keep-large-files",
623 action="store_true",
624 help="Keeps tests that contain files larger than 30MB in output directory",
625 )
626 parser.add_argument(
627 "--capture-output",
628 action="store_true",
629 help="Prints output of running sh commands",
630 )
631 parser.add_argument(
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100632 "-j",
633 dest="num_cores",
634 type=int,
635 default=6,
636 help="Number of simultaneous jobs to split the tasks into for multiprocessing",
637 )
638 parser.add_argument(
639 "-v",
640 dest="verbosity",
641 action="count",
642 default=0,
643 help="Verbosity (can be used multiple times for more details)",
644 )
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100645 args = parser.parse_args(argv)
646
647 return args
648
649
Jeremy Johnsonfd8c8fe2023-10-23 11:55:38 +0100650def in_version(test_version, gen_dict):
651 """Check if the selected test_version is compatible with the tests."""
652
653 def version_string_to_numbers(verstr):
654 # Turn the "vM.mm.pp" string into Major, Minor, Patch versions
655 if verstr == TEST_VERSION_LATEST:
656 return (TOSA_VERSION[0], TOSA_VERSION[1], TOSA_VERSION[2])
657 else:
658 match = re.match(REGEX_VERSION, verstr)
659 if match is None:
660 raise KeyError(f"Invalid version string {verstr}")
661 return (int(v) for v in match.groups())
662
663 if "from_version" in gen_dict:
664 selected_version = version_string_to_numbers(test_version)
665 from_version = version_string_to_numbers(gen_dict["from_version"])
666
667 # Check the Major version is compatible, then Minor, and lastly Patch
668 # Unless the versions match, we can exit early due to obvious precedence
669 for sel, fro in zip(selected_version, from_version):
670 if sel < fro:
671 # From version is later than selected version
672 return False
673 elif sel > fro:
674 # From version is earlier than selected version
675 return True
676 # If we get here, the version numbers match exactly
677 return True
678 else:
679 # No specific version info
680 return True
681
682
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100683def main():
684 args = parse_args()
685
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100686 if args.ref_model_dir is not None:
687 # Assume the ref model exe path based on the ref model directory
688 args.ref_model_path = cmf.find_tosa_file(
689 cmf.TosaFileType.REF_MODEL, args.ref_model_dir, False
690 )
691 if not args.ref_model_path.is_file():
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100692 logger.error(
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100693 f"Missing reference model binary (--ref-model-path): {args.ref_model_path}"
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100694 )
695 return 2
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100696 args.ref_model_path = args.ref_model_path.absolute()
697
698 if args.generate_lib_path is None:
699 args.generate_lib_path = cmf.find_tosa_file(
700 cmf.TosaFileType.GENERATE_LIBRARY, args.ref_model_path
701 )
702 if not args.generate_lib_path.is_file():
703 logger.error(
704 f"Missing TOSA generate data library (--generate-lib-path): {args.generate_lib_path}"
705 )
706 return 2
707 args.generate_lib_path = args.generate_lib_path.absolute()
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100708
709 if args.schema_path is None:
710 args.schema_path = cmf.find_tosa_file(
711 cmf.TosaFileType.SCHEMA, args.ref_model_path
712 )
713 if not args.schema_path.is_file():
714 logger.error(
715 f"Missing reference model schema (--schema-path): {args.schema_path}"
716 )
717 return 2
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100718 args.schema_path = args.schema_path.absolute()
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100719
720 if args.flatc_path is None:
721 args.flatc_path = cmf.find_tosa_file(
722 cmf.TosaFileType.FLATC, args.ref_model_path
723 )
724 if not args.flatc_path.is_file():
725 logger.error(f"Missing flatc binary (--flatc-path): {args.flatc_path}")
726 return 2
Jeremy Johnson65ba8092023-10-09 16:31:13 +0100727 args.flatc_path = args.flatc_path.absolute()
Jeremy Johnsonf0348ea2023-09-27 16:10:59 +0100728
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100729 if args.unit_tests in ["framework", "both"]:
Jeremy Johnsonc1d1c632023-08-02 17:21:36 +0100730 logger.warning(
731 "DEPRECATION - Framework tests are not part of TOSA conformance testing"
732 )
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100733 if not args.framework_schema:
734 logger.error(
735 "Need to supply location of Framework flatbuffers schema via --framework-schema"
736 )
737 return 2
738 if not args.framework_tests_dir.is_dir():
739 logger.error(
740 f"Missing or invalid framework tests directory: {args.framework_tests_dir}"
741 )
742 return 2
743
744 loglevels = (logging.WARNING, logging.INFO, logging.DEBUG)
745 loglevel = loglevels[min(args.verbosity, len(loglevels) - 1)]
746 logger.setLevel(loglevel)
747 # Set other loggers the same
748 logging.getLogger("test_select").setLevel(loglevel)
749 logging.getLogger("convert2conformance").setLevel(loglevel)
750
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100751 print(f"Output directory: {args.output_dir}")
752
Jeremy Johnson93d43902022-09-27 12:26:14 +0100753 if args.random_seed != DEFAULT_SEED:
754 logger.warning(
755 "Random test seed changed from default, tests will not match official conformance"
756 )
757
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100758 args.build_dir = args.build_dir.resolve()
759 logger.debug(f"Creating build directory: {args.build_dir}")
760 args.build_dir.mkdir(parents=True, exist_ok=True)
761
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100762 # TODO: For tosa-mi should really generate tosa-bi profile as well
763 # - for now leave it as subset instead of as superset (for testing)
764 if args.profile == PROFILES_ALL:
765 profiles = list(PROFILE_OPS_INFO.keys())
766 else:
767 profiles = [args.profile]
768
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100769 try:
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100770 for profile in profiles:
771 print(f"Creating conformance tests for TOSA {profile} profile")
772 # Framework unit tests
773 if args.unit_tests in ["framework", "both"]:
774 logger.debug("Creating FRAMEWORK unit tests")
775 test_picks_file = (
776 args.param_json_dir / PROFILE_OPS_INFO[profile]["framework_tests"]
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100777 )
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100778 try:
779 with open(test_picks_file, "r") as fd:
780 test_picks = json.load(fd)
781 except Exception as e:
782 logger.error(
783 f"Couldn't load framework tests info - {test_picks_file}: {e}"
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100784 )
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100785 return 1
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100786
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100787 operators = args.operators
788 if not operators:
789 # Create tests for all the operators
790 operators = list(test_picks.keys())
791
792 root_output_dir = (
793 args.output_dir / "frameworks" / "tflite" / "operators"
794 )
795 for op in operators:
796 logger.info(f"FRAMEWORK OP: {op}")
797 if op not in test_picks:
798 logger.warning(
799 f"Framework op {op} not found in {test_picks_file} - skipping"
800 )
801 continue
802
803 op_profiles_list = test_picks[op]["profile"]
804 if (
805 args.profile != PROFILES_ALL
806 and args.profile not in op_profiles_list
807 ):
808 # Skip this operator as not part of the profile chosen
809 logger.debug(f"Skipping {op} as not part of {args.profile}")
810 continue
811
812 logger.debug(f"Copying and renaming {op}")
813 framework_test_dir = copy_rename_framework_tests(
814 args, op, test_picks
815 )
816
817 if args.convert_all_tests:
818 logger.debug("Running and converting all framework tests")
819 framework_tests = None # Don't select any
820 else:
821 logger.debug("Running and converting selected framework tests")
822 framework_tests = get_framework_tests_selection(
823 args, op, test_picks, framework_test_dir
824 )
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100825 convert_tests(
826 args,
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100827 profile,
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100828 op,
829 framework_test_dir,
830 root_output_dir,
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100831 op_profiles_list,
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100832 tests=framework_tests,
833 trim_op_subdir=True,
834 )
835
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100836 # Operator unit tests
837 if args.unit_tests in ["operator", "both"]:
838 logger.debug("Creating OPERATOR unit tests")
839 test_params_file = (
840 args.param_json_dir
841 / PROFILE_OPS_INFO[profile]["operator_test_params"]
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100842 )
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100843 try:
844 with open(test_params_file, "r") as fd:
845 test_params = json.load(fd)
846 except Exception as e:
847 logger.error(
848 f"Couldn't load operator test params - {test_params_file}: {e}"
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100849 )
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100850 return 1
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100851
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100852 operators = args.operators
853 if not operators:
854 # Create tests for all the operators
855 operators = list(test_params.keys())
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100856
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100857 for op in operators:
858 logger.info(f"OPERATOR: {op}")
859 if op not in test_params:
860 logger.warning(
861 f"{op} operator parameters not found in {test_params_file} - skipping"
862 )
863 continue
Jeremy Johnson0ecfa372022-06-30 14:27:56 +0100864
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100865 op_profiles_list = test_params[op]["profile"]
866 if (
867 args.profile != PROFILES_ALL
868 and args.profile not in op_profiles_list
869 ):
870 # Skip this operator as not part of the profile chosen
871 logger.debug(f"Skipping {op} as not part of {args.profile}")
872 continue
873
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100874 operator_group = test_params[op]["group"]
875 root_output_dir = args.output_dir / "operators"
Jeremy Johnson1271c442023-09-05 11:39:26 +0100876 supports = (
877 test_params[op]["support_for"]
878 if "support_for" in test_params[op]
879 else []
880 )
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000881
882 # Iterate through the generation groups selecting tests from each
883 for gen_name, gen_dict in test_params[op]["generation"].items():
Jeremy Johnsonfd8c8fe2023-10-23 11:55:38 +0100884
885 if not in_version(args.test_version, gen_dict):
886 logger.warning(
887 f"{op} [{gen_name}] is not in {args.test_version} - skipping"
888 )
889 continue
890
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000891 no_neg_tests = (
892 "no_negative_tests" in gen_dict
893 and gen_dict["no_negative_tests"] == "true"
894 )
895
896 if no_neg_tests:
897 if args.test_type == "negative":
898 logger.info(
899 f"No negative tests for {op} / generation group {gen_name}"
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100900 )
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000901 continue
902 # Only produce positive tests
903 test_type = "positive"
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100904 else:
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000905 test_type = args.test_type
906
907 gen_neg_dim_range = (
908 gen_dict["negative_dim_range"]
909 if "negative_dim_range" in gen_dict
910 else None
911 )
912
913 ignore_missing = gen_name != STANDARD_GENERATOR_GROUP
914 tags = (
915 [gen_name] if gen_name != STANDARD_GENERATOR_GROUP else None
916 )
917
918 op_build_dir = build_op_tests(
919 args,
920 test_type,
921 profile,
922 op,
923 gen_name,
924 gen_dict["generator_args"],
925 gen_neg_dim_range,
Jeremy Johnson1271c442023-09-05 11:39:26 +0100926 supports=supports,
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000927 )
928
Jeremy Johnson0c716862023-04-13 17:18:19 +0100929 # Work out which selection criteria we are using
930 if "selector" in gen_dict:
931 selector_name = gen_dict["selector"]
932 if selector_name not in test_params[op]["selection"]:
933 logger.warn(
934 f"Could not find {selector_name} in selection dict for {op} - using default"
935 )
936 selector_name = "default"
937 else:
938 selector_name = "default"
939 if selector_name not in test_params[op]["selection"]:
940 logger.error(
941 f"Could not find {selector_name} in selection dict for {op}"
942 )
943 raise (GenConformanceError())
944
945 # Selection criteria
946 selection_config = test_params[op]["selection"][selector_name]
947
Jeremy Johnson76c6a552023-09-11 09:30:02 +0100948 if args.convert_all_tests:
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000949 logger.debug(f"Running and converting all {op} tests")
Jeremy Johnson1271c442023-09-05 11:39:26 +0100950 generate_results(
951 args, profile, op, op_build_dir, supports=supports
952 )
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000953 operator_test_list = None
954 else:
955 logger.debug(
956 f"Running and converting selection of {op} tests"
Jeremy Johnsone4b08ff2022-09-15 10:38:17 +0100957 )
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000958 if test_type in ["positive", "both"]:
Jeremy Johnson76c6a552023-09-11 09:30:02 +0100959 if (
960 "all" in selection_config
961 and selection_config["all"] == "true"
962 ):
963 # Just get all the positive tests
964 tests_gen, tests_gen2 = tee(
965 _get_all_tests_list(
966 profile,
967 op_build_dir,
968 op,
969 exclude_negative_tests=True,
970 )
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000971 )
Jeremy Johnson76c6a552023-09-11 09:30:02 +0100972 else:
973 # Get a selection of positive tests
974 tests_gen, tests_gen2 = tee(
975 get_op_tests_selection(
976 args,
977 profile,
978 op,
979 op_build_dir,
980 selection_config,
981 ignore_missing=ignore_missing,
982 )
983 )
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000984 generate_results(
Jeremy Johnson1271c442023-09-05 11:39:26 +0100985 args,
986 profile,
987 op,
988 op_build_dir,
989 supports=supports,
990 tests=tests_gen,
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +0000991 )
992 operator_test_list = list(tests_gen2)
993 else:
994 operator_test_list = []
995 if test_type in ["negative", "both"]:
996 operator_test_list.extend(
997 get_op_tests_selection(
998 args,
999 profile,
1000 op,
1001 op_build_dir,
1002 selection_config,
1003 negative=True,
1004 )
1005 )
1006 output_dir = convert_tests(
1007 args,
1008 profile,
1009 op,
1010 op_build_dir,
1011 root_output_dir,
1012 op_profiles_list,
Jeremy Johnson1271c442023-09-05 11:39:26 +01001013 supports=supports,
Jeremy Johnsonfd05bb32023-02-07 16:39:24 +00001014 tests=operator_test_list,
1015 group=operator_group,
1016 tags=tags,
1017 )
1018 if not args.keep_large_files:
1019 check_op_tests(args, profile, op, output_dir)
Jeremy Johnson0ecfa372022-06-30 14:27:56 +01001020 except GenConformanceError:
1021 return 1
1022
1023 return 0
1024
1025
1026if __name__ == "__main__":
1027 exit(main())