Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 1 | """Template test runner class for running TOSA tests.""" |
Jeremy Johnson | f0348ea | 2023-09-27 16:10:59 +0100 | [diff] [blame] | 2 | # Copyright (c) 2020-2023, ARM Limited. |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 3 | # SPDX-License-Identifier: Apache-2.0 |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 4 | import json |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 5 | from enum import IntEnum |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 6 | |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 7 | import schemavalidation.schemavalidation as sch |
| 8 | from checker.color_print import LogColors |
| 9 | from checker.color_print import print_color |
| 10 | from checker.color_print import set_print_in_color |
| 11 | from checker.tosa_result_checker import set_print_result |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 12 | from checker.tosa_result_checker import test_check |
Jeremy Johnson | 65ba809 | 2023-10-09 16:31:13 +0100 | [diff] [blame] | 13 | from generator.datagenerator import GenerateLibrary |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 14 | from json2fbbin import json2fbbin |
Jeremy Johnson | 65ba809 | 2023-10-09 16:31:13 +0100 | [diff] [blame] | 15 | from json2numpy import json2numpy |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 16 | from runner.tosa_test_presets import TOSA_REFCOMPLIANCE_RUNNER |
| 17 | |
| 18 | |
| 19 | def isComplianceModeDotProduct(testDesc): |
| 20 | """Checks the test descriptor for DOT_PRODUCT compliance mode.""" |
| 21 | if ( |
| 22 | "meta" in testDesc |
| 23 | and "compliance" in testDesc["meta"] |
| 24 | and "tensors" in testDesc["meta"]["compliance"] |
| 25 | ): |
| 26 | for _, t in testDesc["meta"]["compliance"]["tensors"].items(): |
| 27 | if "mode" in t and t["mode"] == "DOT_PRODUCT": |
| 28 | return True |
| 29 | return False |
| 30 | |
| 31 | |
| 32 | def getRunnerResultFilePath(resultFilePath, sutModule): |
| 33 | """Return the result file path with the runner specific naming.""" |
| 34 | return resultFilePath.with_suffix(f".{sutModule}{resultFilePath.suffix}") |
| 35 | |
| 36 | |
| 37 | def getBoundsResultFilePath(resultFilePath, sutModule=None): |
| 38 | """Return the bounds result file with/without runner specific naming.""" |
| 39 | boundsFilePath = resultFilePath.parent / f"bounds_{resultFilePath.name}" |
| 40 | if sutModule is not None: |
| 41 | boundsFilePath = boundsFilePath.with_suffix( |
| 42 | f".{sutModule}{boundsFilePath.suffix}" |
| 43 | ) |
| 44 | return boundsFilePath |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 45 | |
Kevin Cheng | 550ccc5 | 2021-03-03 11:21:43 -0800 | [diff] [blame] | 46 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 47 | class TosaTestInvalid(Exception): |
| 48 | """Exception raised for errors loading test description. |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 49 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 50 | Attributes: |
| 51 | path - full path to missing test description file |
| 52 | exception = underlying exception |
| 53 | """ |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 54 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 55 | def __init__(self, path, exception): |
| 56 | """Initialize test not found error.""" |
| 57 | self.path = path |
| 58 | self.exception = exception |
| 59 | self.message = "Invalid test, could not read test description {}: {}".format( |
| 60 | self.path, str(self.exception) |
| 61 | ) |
| 62 | super().__init__(self.message) |
Kevin Cheng | 550ccc5 | 2021-03-03 11:21:43 -0800 | [diff] [blame] | 63 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 64 | |
| 65 | class TosaTestRunner: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 66 | """TOSA Test Runner template class for systems under test.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 67 | |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 68 | def __init__(self, args, runnerArgs, testDirPath): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 69 | """Initialize and load JSON meta data file.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 70 | self.args = args |
| 71 | self.runnerArgs = runnerArgs |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 72 | self.testDir = str(testDirPath) |
| 73 | self.testDirPath = testDirPath |
| 74 | self.testName = self.testDirPath.name |
Jeremy Johnson | 9c2fe6e | 2023-10-04 16:55:04 +0100 | [diff] [blame] | 75 | self.verify_lib_path = args.verify_lib_path |
Jeremy Johnson | 65ba809 | 2023-10-09 16:31:13 +0100 | [diff] [blame] | 76 | self.generate_lib_path = args.generate_lib_path |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 77 | |
Jeremy Johnson | 015c355 | 2022-02-23 12:15:03 +0000 | [diff] [blame] | 78 | set_print_in_color(not args.no_color) |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 79 | # Stop the result checker printing anything - we will do it |
| 80 | set_print_result(False) |
Jeremy Johnson | 015c355 | 2022-02-23 12:15:03 +0000 | [diff] [blame] | 81 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 82 | # Check if we want to run binary and if its already converted |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 83 | descFilePath = testDirPath / "desc.json" |
| 84 | descBinFilePath = testDirPath / "desc_binary.json" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 85 | if args.binary: |
| 86 | if descBinFilePath.is_file(): |
| 87 | descFilePath = descBinFilePath |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 88 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 89 | try: |
| 90 | # Load the json test file |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 91 | with descFilePath.open("r") as fd: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 92 | self.testDesc = json.load(fd) |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 93 | # Validate the json with the schema |
| 94 | sch.TestDescSchemaValidator().validate_config(self.testDesc) |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 95 | except Exception as e: |
| 96 | raise TosaTestInvalid(str(descFilePath), e) |
| 97 | |
| 98 | # Convert to binary if needed |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 99 | tosaFilePath = testDirPath / self.testDesc["tosa_file"] |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 100 | if args.binary and tosaFilePath.suffix == ".json": |
| 101 | # Convert tosa JSON to binary |
| 102 | json2fbbin.json_to_fbbin( |
Jeremy Johnson | f0348ea | 2023-09-27 16:10:59 +0100 | [diff] [blame] | 103 | args.flatc_path, |
| 104 | args.schema_path, |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 105 | tosaFilePath, |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 106 | testDirPath, |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 107 | ) |
| 108 | # Write new desc_binary file |
| 109 | self.testDesc["tosa_file"] = tosaFilePath.stem + ".tosa" |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 110 | with descBinFilePath.open("w") as fd: |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 111 | json.dump(self.testDesc, fd, indent=2) |
| 112 | descFilePath = descBinFilePath |
| 113 | |
| 114 | # Set location of desc.json (or desc_binary.json) file in use |
| 115 | self.descFile = str(descFilePath) |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 116 | self.descFilePath = descFilePath |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 117 | |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 118 | # Check for compliance mode - need to run refmodel to get results |
| 119 | if "meta" in self.testDesc and "compliance" in self.testDesc["meta"]: |
| 120 | self.complianceMode = True |
| 121 | if "expected_result" in self.testDesc: |
| 122 | if self.args.verbose: |
| 123 | print("Warning: fixing conflicting compliance mode in test.desc") |
| 124 | self.testDesc.pop("expected_result") |
| 125 | else: |
| 126 | self.complianceMode = False |
| 127 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 128 | def skipTest(self): |
Jeremy Johnson | 8858862 | 2022-07-12 16:42:29 +0100 | [diff] [blame] | 129 | """Check if the test is skipped due to test type or profile selection.""" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 130 | expectedFailure = self.testDesc["expected_failure"] |
| 131 | if self.args.test_type == "negative" and not expectedFailure: |
Jeremy Johnson | 8858862 | 2022-07-12 16:42:29 +0100 | [diff] [blame] | 132 | return True, "non-negative type" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 133 | elif self.args.test_type == "positive" and expectedFailure: |
Jeremy Johnson | 8858862 | 2022-07-12 16:42:29 +0100 | [diff] [blame] | 134 | return True, "non-positive type" |
| 135 | if self.args.profile: |
| 136 | profile = self.testDesc["profile"] if "profile" in self.testDesc else [] |
| 137 | if self.args.profile not in profile: |
| 138 | return True, "non-{} profile".format(self.args.profile) |
| 139 | return False, "" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 140 | |
Jeremy Johnson | 65ba809 | 2023-10-09 16:31:13 +0100 | [diff] [blame] | 141 | def _ready_file(self, dataFile, jsonOnly=False): |
| 142 | """Convert/create any data file that is missing.""" |
| 143 | dataPath = self.testDirPath / dataFile |
| 144 | if not dataPath.is_file(): |
| 145 | jsonPath = dataPath.with_suffix(".json") |
| 146 | if jsonPath.is_file(): |
| 147 | # Data files stored as JSON |
| 148 | if self.args.verbose: |
| 149 | print(f"Readying data file: {dataPath}") |
| 150 | json2numpy.json_to_npy(jsonPath) |
| 151 | elif not jsonOnly: |
| 152 | # Use data generator for all data files |
| 153 | if self.args.verbose: |
| 154 | print("Readying all data input files") |
| 155 | dgl = GenerateLibrary(self.generate_lib_path) |
| 156 | dgl.set_config(self.testDesc) |
| 157 | dgl.write_numpy_files(self.testDirPath) |
| 158 | |
| 159 | def readyDataFiles(self): |
| 160 | """Check that the data files have been created/converted.""" |
| 161 | for dataFile in self.testDesc["ifm_file"]: |
| 162 | self._ready_file(dataFile) |
| 163 | # Convert expected result if any |
| 164 | if "expected_result_file" in self.testDesc: |
| 165 | for dataFile in self.testDesc["expected_result_file"]: |
| 166 | self._ready_file(dataFile, jsonOnly=True) |
| 167 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 168 | def runTestGraph(self): |
| 169 | """Override with function that calls system under test.""" |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 170 | pass |
| 171 | |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 172 | def testResult(self, tosaGraphResult, graphMessage=None): |
| 173 | """Work out test result based on graph result and output files.""" |
| 174 | expectedFailure = self.testDesc["expected_failure"] |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 175 | print_check_result = False |
| 176 | |
| 177 | sutModule = self.__module__ |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 178 | |
| 179 | if tosaGraphResult == TosaTestRunner.TosaGraphResult.TOSA_VALID: |
| 180 | if expectedFailure: |
| 181 | result = TosaTestRunner.Result.UNEXPECTED_PASS |
| 182 | resultMessage = "Expected failure test incorrectly passed" |
| 183 | else: |
| 184 | # Work through all the results produced by the testing, assuming success |
| 185 | # but overriding this with any failures found |
| 186 | result = TosaTestRunner.Result.EXPECTED_PASS |
| 187 | messages = [] |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 188 | |
| 189 | # Go through each output result checking it |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 190 | for resultNum, resultFileName in enumerate(self.testDesc["ofm_file"]): |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 191 | resultFilePath = self.testDirPath / resultFileName |
| 192 | |
| 193 | # Work out the file to check against (if any) |
| 194 | if self.complianceMode and sutModule != TOSA_REFCOMPLIANCE_RUNNER: |
| 195 | conformanceFilePath = getRunnerResultFilePath( |
| 196 | resultFilePath, TOSA_REFCOMPLIANCE_RUNNER |
| 197 | ) |
| 198 | if isComplianceModeDotProduct(self.testDesc): |
| 199 | conformanceBoundsPath = getBoundsResultFilePath( |
| 200 | resultFilePath, TOSA_REFCOMPLIANCE_RUNNER |
| 201 | ) |
| 202 | else: |
| 203 | # Not expecting a bounds file for this test |
| 204 | conformanceBoundsPath = None |
| 205 | elif "expected_result_file" in self.testDesc: |
| 206 | conformanceBoundsPath = None |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 207 | try: |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 208 | conformanceFilePath = ( |
| 209 | self.testDirPath |
| 210 | / self.testDesc["expected_result_file"][resultNum] |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 211 | ) |
| 212 | except IndexError: |
| 213 | result = TosaTestRunner.Result.INTERNAL_ERROR |
| 214 | msg = "Internal error: Missing expected_result_file {} in {}".format( |
| 215 | resultNum, self.descFile |
| 216 | ) |
| 217 | messages.append(msg) |
| 218 | print(msg) |
| 219 | break |
| 220 | else: |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 221 | # Nothing to check against |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 222 | conformanceFilePath = None |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 223 | conformanceBoundsPath = None |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 224 | |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 225 | if conformanceFilePath: |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 226 | print_check_result = True # Result from checker |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 227 | chkResult, tolerance, msg = test_check( |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 228 | conformanceFilePath, |
| 229 | resultFilePath, |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 230 | test_name=self.testName, |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 231 | test_desc=self.testDesc, |
| 232 | bnd_result_path=conformanceBoundsPath, |
| 233 | ofm_name=self.testDesc["ofm_name"][resultNum], |
| 234 | verify_lib_path=self.verify_lib_path, |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 235 | ) |
| 236 | # Change EXPECTED_PASS assumption if we have any failures |
| 237 | if chkResult != 0: |
| 238 | result = TosaTestRunner.Result.UNEXPECTED_FAILURE |
| 239 | messages.append(msg) |
| 240 | if self.args.verbose: |
| 241 | print(msg) |
| 242 | else: |
| 243 | # No conformance file to verify, just check results file exists |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 244 | if not resultFilePath.is_file(): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 245 | result = TosaTestRunner.Result.UNEXPECTED_FAILURE |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 246 | msg = f"Results file is missing: {resultFilePath}" |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 247 | messages.append(msg) |
| 248 | print(msg) |
| 249 | |
Jeremy Johnson | e4b08ff | 2022-09-15 10:38:17 +0100 | [diff] [blame] | 250 | if resultFilePath.is_file(): |
| 251 | # Move the resultFilePath to allow subsequent system under |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 252 | # tests to create them and to test they have been created |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 253 | # and to enable compliance testing against refmodel results |
| 254 | resultFilePath.rename( |
| 255 | getRunnerResultFilePath(resultFilePath, sutModule) |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 256 | ) |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 257 | if ( |
| 258 | isComplianceModeDotProduct(self.testDesc) |
| 259 | and sutModule == TOSA_REFCOMPLIANCE_RUNNER |
| 260 | ): |
| 261 | boundsFilePath = getBoundsResultFilePath(resultFilePath) |
| 262 | if boundsFilePath.is_file(): |
| 263 | boundsFilePath = boundsFilePath.rename( |
| 264 | getBoundsResultFilePath(resultFilePath, sutModule) |
| 265 | ) |
| 266 | else: |
| 267 | result = TosaTestRunner.Result.INTERNAL_ERROR |
| 268 | msg = f"Internal error: Missing expected dot product compliance bounds file {boundsFilePath}" |
| 269 | messages.append(msg) |
| 270 | print(msg) |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 271 | |
| 272 | resultMessage = "\n".join(messages) if len(messages) > 0 else None |
| 273 | else: |
| 274 | if ( |
| 275 | expectedFailure |
| 276 | and tosaGraphResult == TosaTestRunner.TosaGraphResult.TOSA_ERROR |
| 277 | ): |
| 278 | result = TosaTestRunner.Result.EXPECTED_FAILURE |
| 279 | resultMessage = None |
| 280 | else: |
| 281 | result = TosaTestRunner.Result.UNEXPECTED_FAILURE |
| 282 | resultMessage = graphMessage |
| 283 | |
Jeremy Johnson | e2b5e87 | 2023-09-14 17:02:09 +0100 | [diff] [blame] | 284 | status = "Result" if print_check_result else "Result code" |
| 285 | if ( |
| 286 | result == TosaTestRunner.Result.EXPECTED_FAILURE |
| 287 | or result == TosaTestRunner.Result.EXPECTED_PASS |
| 288 | ): |
| 289 | print_color(LogColors.GREEN, f"{sutModule}: {status} PASS {self.testName}") |
| 290 | else: |
| 291 | print_color(LogColors.RED, f"{sutModule}: {status} FAIL {self.testName}") |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 292 | |
| 293 | return result, resultMessage |
| 294 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 295 | class Result(IntEnum): |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 296 | """Test result codes.""" |
| 297 | |
Eric Kunze | e5e2676 | 2020-10-13 16:11:07 -0700 | [diff] [blame] | 298 | EXPECTED_PASS = 0 |
| 299 | EXPECTED_FAILURE = 1 |
| 300 | UNEXPECTED_PASS = 2 |
| 301 | UNEXPECTED_FAILURE = 3 |
| 302 | INTERNAL_ERROR = 4 |
Jeremy Johnson | be1a940 | 2021-12-15 17:14:56 +0000 | [diff] [blame] | 303 | SKIPPED = 5 |
| 304 | |
| 305 | class TosaGraphResult(IntEnum): |
| 306 | """The tosa_graph_result codes.""" |
| 307 | |
| 308 | TOSA_VALID = 0 |
| 309 | TOSA_UNPREDICTABLE = 1 |
| 310 | TOSA_ERROR = 2 |
| 311 | OTHER_ERROR = 3 |