-
Notifications
You must be signed in to change notification settings - Fork 410
feat: support configurable constant-fold exclusions #4450
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
Open
fs-eire
wants to merge
1
commit into
pytorch:main
Choose a base branch
from
fs-eire:constant-fold-exclusion-mechanics
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
py/torch_tensorrt/dynamo/lowering/constant_fold_exclusions/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| from ._core import ( | ||
| CONSTANT_FOLD_EXCLUSION_META_KEY, | ||
| ConstantFoldExclusionRule, | ||
| register_constant_fold_exclusion_rule, | ||
| validate_disabled_constant_fold_exclusions, | ||
| ) | ||
|
|
||
| __all__ = [ | ||
| "CONSTANT_FOLD_EXCLUSION_META_KEY", | ||
| "ConstantFoldExclusionRule", | ||
| "register_constant_fold_exclusion_rule", | ||
| "validate_disabled_constant_fold_exclusions", | ||
| ] |
61 changes: 61 additions & 0 deletions
61
py/torch_tensorrt/dynamo/lowering/constant_fold_exclusions/_core.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| from typing import Callable, Collection, Iterable | ||
|
|
||
| import torch | ||
|
|
||
| CONSTANT_FOLD_EXCLUSION_META_KEY = "_torch_tensorrt_constant_fold_exclusions" | ||
|
|
||
| ConstantFoldExclusionRule = Callable[[torch.fx.Node], Iterable[torch.fx.Node]] | ||
| _CONSTANT_FOLD_EXCLUSION_RULES: dict[str, ConstantFoldExclusionRule] = {} | ||
|
|
||
|
|
||
| def _mark_constant_fold_exclusion(nodes: Iterable[torch.fx.Node], rule_id: str) -> None: | ||
| """Record which rule wants ``nodes`` kept out of constant folding. | ||
|
|
||
| The marks carry their rule ID rather than a bare flag so the exclusion pass | ||
| can revoke the ones belonging to disabled rules, whichever marking path | ||
| produced them. | ||
| """ | ||
| for node in nodes: | ||
| node.meta.setdefault(CONSTANT_FOLD_EXCLUSION_META_KEY, set()).add(rule_id) | ||
|
|
||
|
|
||
| def register_constant_fold_exclusion_rule( | ||
| rule_id: str, | ||
| ) -> Callable[[ConstantFoldExclusionRule], ConstantFoldExclusionRule]: | ||
| """Register a named rule that selects FX nodes to exclude from folding.""" | ||
| if not isinstance(rule_id, str) or not rule_id: | ||
| raise ValueError("A constant-fold exclusion rule ID must be a non-empty string") | ||
|
|
||
| def register(rule: ConstantFoldExclusionRule) -> ConstantFoldExclusionRule: | ||
| if rule_id in _CONSTANT_FOLD_EXCLUSION_RULES: | ||
| raise ValueError( | ||
| f"Constant-fold exclusion rule {rule_id!r} is already registered" | ||
| ) | ||
|
|
||
| _CONSTANT_FOLD_EXCLUSION_RULES[rule_id] = rule | ||
| return rule | ||
|
|
||
| return register | ||
|
|
||
|
|
||
| def validate_disabled_constant_fold_exclusions( | ||
| rule_ids: Collection[str], | ||
| ) -> set[str]: | ||
| """Validate disabled rule IDs and return them as a set.""" | ||
| if isinstance(rule_ids, str): | ||
| raise TypeError( | ||
| "disabled_constant_fold_exclusions must be a collection of rule IDs, " | ||
| "not a single string" | ||
| ) | ||
|
|
||
| disabled_rule_ids = set(rule_ids) | ||
| unknown_rule_ids = disabled_rule_ids - _CONSTANT_FOLD_EXCLUSION_RULES.keys() | ||
| if unknown_rule_ids: | ||
| available_rule_ids = ", ".join(sorted(_CONSTANT_FOLD_EXCLUSION_RULES)) | ||
| raise ValueError( | ||
| "Unknown constant-fold exclusion rule IDs: " | ||
| f"{sorted(unknown_rule_ids)}. Available rule IDs: " | ||
| f"[{available_rule_ids}]" | ||
| ) | ||
|
|
||
| return disabled_rule_ids |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
py/torch_tensorrt/dynamo/lowering/passes/mark_constant_fold_exclusions.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| from typing import Any, Optional | ||
|
|
||
| import torch | ||
| from torch_tensorrt.dynamo.lowering.constant_fold_exclusions._core import ( | ||
| CONSTANT_FOLD_EXCLUSION_META_KEY, | ||
| _CONSTANT_FOLD_EXCLUSION_RULES, | ||
| _mark_constant_fold_exclusion, | ||
| validate_disabled_constant_fold_exclusions, | ||
| ) | ||
|
|
||
|
|
||
| def mark_constant_fold_exclusions( | ||
| gm: torch.fx.GraphModule, settings: Optional[Any] = None | ||
| ) -> torch.fx.GraphModule: | ||
| """Apply the registered rules that exclude FX nodes from constant folding. | ||
|
|
||
| This pass is the single authority on which rules are in effect. It runs | ||
| immediately before ``constant_fold`` and is the only marking path that sees | ||
| ``settings``: rules that mark nodes while a decomposition is traced run | ||
| during ``run_decompositions``, long before a settings object is reachable. | ||
| Those marks are therefore revoked here rather than suppressed where they are | ||
| made, so a caller only has to communicate the disabled rules once. | ||
| """ | ||
| disabled_rule_ids = validate_disabled_constant_fold_exclusions( | ||
| settings.disabled_constant_fold_exclusions if settings is not None else () | ||
| ) | ||
|
|
||
| for node in gm.graph.nodes: | ||
| for rule_id, rule in _CONSTANT_FOLD_EXCLUSION_RULES.items(): | ||
| if rule_id in disabled_rule_ids: | ||
| continue | ||
| _mark_constant_fold_exclusion(rule(node), rule_id) | ||
|
|
||
| if disabled_rule_ids: | ||
| for node in gm.graph.nodes: | ||
| marking_rule_ids = node.meta.get(CONSTANT_FOLD_EXCLUSION_META_KEY) | ||
| if marking_rule_ids: | ||
| marking_rule_ids -= disabled_rule_ids | ||
|
|
||
| return gm | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marks can also be set earlier, and this pass is supposed to revoke them when the rule is disabled. Can we add a test that pre-seeds node.meta with a rule ID and asserts it’s cleared after running with that rule disabled?