8000 Support per-parameter test decoration by jbschlosser · Pull Request #79979 · pytorch/pytorch · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Support per-parameter test decoration #79979

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

Closed
wants to merge 8 commits into from

Conversation

jbschlosser
Copy link
Contributor
@jbschlosser jbschlosser commented Jun 21, 2022

Stack from ghstack:

Fixes #79161

This PR does the following:

  • Expands the parametrize_fn() signature from returning a 3-tuple of (test, test_name, param_kwargs) to returning a 4-tuple of (test, test_name, param_kwargs, decorator_fn). Expected signature for the addition is decorator_fn(param_kwargs) -> List[decorator] i.e. given the full set of test params, return a list of decorators to apply.
    • @modules, @ops, and @parametrize now fit the new signature, returning decorator_fns instead of applying decorators themselves.
    • instantiate_parametrized_tests() and instantiate_device_type_tests() now call the returned decorator_fn, passing in the full set of param_kwargs (after composition + device / dtype additions) and applying the returned decorators.
    • Composing multiple parametrize_fns also composes the corresponding decorator_fns; the composed decorator_fn simply concatenates the decorator lists returned by the constituents.
  • Expands DecorateInfo.is_active to support callables:
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
  • Adds several tests to test/test_testing.py ensuring proper decoration using @parametrize and @modules.
  • (minor) Refactors ModuleInfo slightly to better match OpInfo; replace should_skip() with get_decorators() and merge skips and decorators.
  • (minor) Fixes a couple ModuleInfo naming oddities uncovered during testing.

@jbschlosser jbschlosser requested review from mruberry, ngimel and a team as code owners June 21, 2022 21:35
jbschlosser added a commit that referenced this pull request Jun 21, 2022
ghstack-source-id: 0ed81f8
Pull Request resolved: #79979
@facebook-github-bot
Copy link
Contributor
facebook-github-bot commented Jun 21, 2022

🔗 Helpful links

✅ No Failures (0 Pending)

As of commit d6add3c (more details on the Dr. CI page):

Expand to see more

💚 💚 Looks good so far! There are no failures yet. 💚 💚


This comment was automatically generated by Dr. CI (expand for details).

Please report bugs/suggestions to the (internal) Dr. CI Users group.

Click here to manually regenerate this comment.

@jbschlosser jbschlosser changed the title Support per-param test decoration Support per-parameter test decoration Jun 21, 2022
Comment on lines 367 to 374
# Add the device param kwarg if the test needs device or devices.
param_kwargs = {} if param_kwargs is None else param_kwargs
test_sig_params = inspect.signature(test).parameters
if 'device' in test_sig_params or 'devices' in test_sig_params:
device_arg: str = cls.get_primary_device()
if hasattr(test, 'num_required_devices'):
device_arg = cls.get_all_devices()
_update_param_kwargs(param_kwargs, 'device', device_arg)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was moved here from below so that the device kwarg is present in param_kwargs when passed to the decorator_fn().

Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize` and `modules`.
* (minor) Refactors `ModuleInfo` slightly to better match `OpInfo`; replace `should_skip()` with `get_decorators()` and merge `skips` and `decorators`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
jbschlosser added a commit that referenced this pull request Jun 21, 2022
ghstack-source-id: 4a48f0e
Pull Request resolved: #79979
@jbschlosser jbschlosser requested a review from anjali411 June 24, 2022 17:40
Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize` and `modules`.
* (minor) Refactors `ModuleInfo` slightly to better match `OpInfo`; replace `should_skip()` with `get_decorators()` and merge `skips` and `decorators`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize` and `modules`.
* (minor) Refactors `ModuleInfo` slightly to better match `OpInfo`; replace `should_skip()` with `get_decorators()` and merge `skips` and `decorators`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
jbschlosser added a commit that referenced this pull request Jun 24, 2022
ghstack-source-id: 84c4beb
Pull Request resolved: #79979
Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize` and `modules`.
* (minor) Refactors `ModuleInfo` slightly to better match `OpInfo`; replace `should_skip()` with `get_decorators()` and merge `skips` and `decorators`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize` and `modules`.
* (minor) Refactors `ModuleInfo` slightly to better match `OpInfo`; replace `should_skip()` with `get_decorators()` and merge `skips` and `decorators`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
jbschlosser added a commit that referenced this pull request Jun 28, 2022
ghstack-source-id: f712e2c
Pull Request resolved: #79979
Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize` and `modules`.
* (minor) Refactors `ModuleInfo` slightly to better match `OpInfo`; replace `should_skip()` with `get_decorators()` and merge `skips` and `decorators`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
jbschlosser added a commit that referenced this pull request Jun 29, 2022
ghstack-source-id: 1bb39f3
Pull Request resolved: #79979
Comment on lines +323 to +332
@classmethod
def _init_and_get_primary_device(cls):
try:
return cls.get_primary_device()
except Exception:
# For CUDATestBase, XLATestBase, and possibly others, the primary device won't be available
# until setUpClass() sets it. Call that manually here if needed.
if hasattr(cls, 'setUpClass'):
cls.setUpClass()
return cls.get_primary_device()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit messy. The device specific test class for CUDA, XLA, and maybe others (?) define setupUpClass() method that populates the primary device. In the past, this has been run by unittest just before the first test invocation. Unfortunately, that's too late if we want the per-param decoration mechanism to have access to it during test generation time.

The hacky approach here calls setUpClass() if trying to get the primary device fails. Open to better suggestions! Note that I have been operating under the assumption that there may be other device-specific test classes out there we don't know about or can't easily change. If we aren't restricted by this, other options involving changing CUDATestBase / XLATestBase open up.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also can't immediately think of a better way to do this; I found the comment very helpful

@@ -1494,6 +1500,48 @@ def test_two_things_custom_names(self, x, y):
test_names = _get_test_names_for_test_class(TestParametrized)
self.assertEqual(expected_test_names, test_names)

def test_apply_param_specific_decorators(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice tests and comments

@@ -1506,7 +1554,7 @@ def test_modules(self, module_info):
instantiate_parametrized_tests(TestParametrized)

def test_ops_decorator_misuse_error(self):
# Test that @modules errors out when used with instantiate_parametrized_tests().
# Test that @ops errors out when used with instantiate_parametrized_tests().
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix

@@ -1685,6 +1733,81 @@ def test_op_parametrized(self, device, dtype, op, flag):
test_names = _get_test_names_for_test_class(device_cls)
self.assertEqual(sorted(expected_test_names), sorted(test_names))

def test_modules_composition_names(self, device):
device = self.device_type
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment here, too, please

@mruberry mruberry added the ciflow/trunk Trigger trunk jobs on your pull request label Jul 7, 2022
Copy link
Collaborator
@mruberry mruberry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stamped!

I triggered some additional jobs, too

@mruberry
Copy link
Collaborator
mruberry commented Jul 7, 2022

Is there some documentation this should update? Maybe a comment like the one describing the OpInfos or the device-generic test framework?

Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize` and `modules`.
* (minor) Refactors `ModuleInfo` slightly to better match `OpInfo`; replace `should_skip()` with `get_decorators()` and merge `skips` and `decorators`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
jbschlosser added a commit that referenced this pull request Jul 8, 2022
ghstack-source-id: 1176de8
Pull Request resolved: #79979
@github-actions
Copy link
Contributor
github-actions bot commented Sep 6, 2022

Looks like this PR hasn't been updated in a while so we're going to go ahead and mark this as Stale.
Feel free to remove the Stale label if you feel this was a mistake.
If you are unable to remove the Stale label please contact a maintainer in order to do so.
If you want the bot to never mark this PR stale again, add the no-stale label.
Stale pull requests will automatically be closed after 30 days of inactivity.

@github-actions github-actions bot added the Stale label Sep 6, 2022
@facebook-github-bot
Copy link
Contributor

/easycla

As part of the transition to the PyTorch Foundation, this project now requires contributions be covered under the new CLA. See #85559 for additional details.

This comment will trigger a new check of this PR. If you are already covered, you will simply see a new "EasyCLA" check that passes. If you are not covered, a bot will leave a new comment with a link to sign.

@linux-foundation-easycla
Copy link

CLA Missing ID CLA Not Signed

@github-actions github-actions bot closed this Nov 3, 2022
jbschlosser added a commit that referenced this pull request Jan 4, 2023
Continuation of #79979.

Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize`, `modules`, and `ops`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
jbschlosser added a commit that referenced this pull request Jan 4, 2023
Continuation of #79979.

Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `parametrize`, `modules`, and `ops`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.

[ghstack-poisoned]
pytorchmergebot pushed a commit that referenced this pull request Jan 4, 2023
Continuation of #79979.

Fixes #79161

This PR does the following:
* Expands the `parametrize_fn()` signature from returning a 3-tuple of `(test, test_name, param_kwargs)` to returning a 4-tuple of `(test, test_name, param_kwargs, decorator_fn)`. Expected signature for the addition is `decorator_fn(param_kwargs) -> List[decorator]` i.e. given the full set of test params, return a list of decorators to apply.
    * `modules`, `ops`, and `parametrize` now fit the new signature, returning `decorator_fn`s instead of applying decorators themselves.
    * `instantiate_parametrized_tests()` and `instantiate_device_type_tests()` now call the returned `decorator_fn`, passing in the full set of `param_kwargs` (after composition + `device` / `dtype` additions) and applying the returned decorators.
    * Composing multiple `parametrize_fn`s also composes the corresponding `decorator_fn`s; the composed `decorator_fn` simply concatenates the decorator lists returned by the constituents.
* Expands `DecorateInfo.is_active` to support callables:
```python
DecorateInfo(
    unittest.expectedFailure, "TestOps", "test_python_ref_executor",
    device_type='cuda', active_if=lambda params: params['executor'] == 'nvfuser'
),
```
* Adds several tests to `test/test_testing.py` ensuring proper decoration using `@parametrize`, `@modules`, and `@ops`.
* (minor) Fixes a couple `ModuleInfo` naming oddities uncovered during testing.
Pull Request resolved: #91658
Approved by: https://github.com/malfet
@facebook-github-bot facebook-github-bot deleted the gh/jbschlosser/42/head branch June 8, 2023 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ciflow/trunk Trigger trunk jobs on your pull request cla signed Stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0