-
Notifications
You must be signed in to change notification settings - Fork 73
[RFC,TESTING] Add filecheck test infrastructure #342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
b010e86
4e122a7
130d01d
398233c
c45924d
df00dc7
0552773
c4f2d5b
8d6dcb8
314002e
8fb7920
dd6eb32
5332139
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,16 +5,114 @@ | |
| from numba.tests.support import SerialMixin | ||
| from numba.cuda.cuda_paths import get_conda_ctk | ||
| from numba.cuda.cudadrv import driver, devices, libs | ||
| from numba.cuda.dispatcher import CUDADispatcher | ||
|
ashermancinelli marked this conversation as resolved.
|
||
| from numba.core import config | ||
| from numba.tests.support import TestCase | ||
| from pathlib import Path | ||
| from filecheck.matcher import Matcher, Options | ||
| from filecheck.parser import Parser, pattern_for_opts | ||
| from filecheck.finput import FInput | ||
| from io import StringIO | ||
| import unittest | ||
|
|
||
| numba_cuda_dir = Path(__file__).parent | ||
| test_data_dir = numba_cuda_dir / "tests" / "data" | ||
|
|
||
|
|
||
| class CUDATestCase(SerialMixin, TestCase): | ||
| class FileCheckTestCaseMixin: | ||
| """ | ||
| Mixin for tests that use FileCheck. | ||
|
|
||
| Methods assertFileCheckAsm and assertFileCheckLLVM will inspect a | ||
| CUDADispatcher and assert that the compilation artifacts match the | ||
| FileCheck checks given in the kernel's docstring. | ||
|
|
||
| Method assertFileCheckMatches can be used to assert that a given string | ||
| matches FileCheck checks, and is not specific to CUDADispatcher. | ||
| """ | ||
|
|
||
| def assertFileCheckAsm( | ||
| self, | ||
| ir_producer: CUDADispatcher, | ||
| signature: tuple[type, ...] | None = None, | ||
| check_prefixes: list[str] = ["ASM"], | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This use of a list as a default argument is probably safe as it's not mutated, but it always sets off alarm bells to see a mutable default in a Python function definition. I think you could either use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A tuple or frozenset would be okay with me, let me try that out. Thanks! |
||
| **extra_filecheck_options: dict[str, str | int], | ||
| ) -> None: | ||
| """ | ||
| Assert that the assembly output of the given CUDADispatcher matches | ||
| the FileCheck checks given in the kernel's docstring. | ||
| """ | ||
| ir_content = ir_producer.inspect_asm() | ||
| if signature: | ||
| ir_content = ir_content[signature] | ||
| check_patterns = ir_producer.__doc__ | ||
| self.assertFileCheckMatches( | ||
| ir_content, | ||
| check_patterns=check_patterns, | ||
| check_prefixes=check_prefixes, | ||
| **extra_filecheck_options, | ||
| ) | ||
|
|
||
| def assertFileCheckLLVM( | ||
| self, | ||
| ir_producer: CUDADispatcher, | ||
| signature: tuple[type, ...] | None = None, | ||
| check_prefixes: list[str] = ["LLVM"], | ||
| **extra_filecheck_options: dict[str, str | int], | ||
| ) -> None: | ||
| """ | ||
| Assert that the LLVM IR output of the given CUDADispatcher matches | ||
| the FileCheck checks given in the kernel's docstring. | ||
| """ | ||
| ir_content = ir_producer.inspect_llvm() | ||
| if signature: | ||
| ir_content = ir_content[signature] | ||
| check_patterns = ir_producer.__doc__ | ||
| self.assertFileCheckMatches( | ||
| ir_content, | ||
| check_patterns=check_patterns, | ||
| check_prefixes=check_prefixes, | ||
| **extra_filecheck_options, | ||
| ) | ||
|
|
||
| def assertFileCheckMatches( | ||
| self, | ||
| ir_content: str, | ||
| check_patterns: str, | ||
| check_prefixes: list[str] = ["CHECK"], | ||
| **extra_filecheck_options: dict[str, str | int], | ||
| ) -> None: | ||
| """ | ||
| Assert that the given string matches the passed FileCheck checks. | ||
|
|
||
| Args: | ||
| ir_content: The string to check against. | ||
| check_patterns: The FileCheck checks to use. | ||
| check_prefixes: The prefixes to use for the FileCheck checks. | ||
| extra_filecheck_options: Extra options to pass to FileCheck. | ||
| """ | ||
| opts = Options( | ||
| match_filename="-", | ||
| check_prefixes=check_prefixes, | ||
| **extra_filecheck_options, | ||
| ) | ||
| input_file = FInput(fname="-", content=ir_content) | ||
| parser = Parser(opts, StringIO(check_patterns), *pattern_for_opts(opts)) | ||
| matcher = Matcher(opts, input_file, parser) | ||
| matcher.stderr = StringIO() | ||
| result = matcher.run() | ||
| if result != 0: | ||
| raise AssertionError( | ||
|
ashermancinelli marked this conversation as resolved.
Outdated
|
||
| ( | ||
| f"FileCheck failed:\n{matcher.stderr.getvalue()}\n\n" | ||
| f"Check prefixes:\n{check_prefixes}\n\n" | ||
| f"Check patterns:\n{check_patterns}\n" | ||
| f"IR:\n{ir_content}\n\n" | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| class CUDATestCase(SerialMixin, FileCheckTestCaseMixin, TestCase): | ||
| """ | ||
| For tests that use a CUDA device. Test methods in a CUDATestCase must not | ||
| be run out of module order, because the ContextResettingTestCase may reset | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.