Skip to content

[Passes] Consolidate DCE passes into common passes #2143

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

Merged
merged 15 commits into from
Mar 28, 2025

Conversation

justinchuby
Copy link
Collaborator

Consolidate DCE passes into common passes (unused_removal) for them to be available for pass users. Refactored usage. Added a pass to remove unused opset imports.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR consolidates the dead code elimination passes by moving unused removal logic (nodes, functions, and opsets) into a common pass module, and it updates various parts of the codebase to reference these new passes.

  • Consolidated removal passes into onnxscript.ir.passes.common.unused_removal.
  • Refactored imports and function calls in rewriter, optimizer, and legacy optimizer/test files to use the new common passes.
  • Removed deprecated modules related to unused removal.

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
onnxscript/tools/benchmark/benchmark_helpers.py Updated import for remove_unused_nodes to use the new optimizer API.
onnxscript/rewriter/init.py Refactored removal logic to instantiate and run a PassManager with the consolidated removal passes.
onnxscript/optimizer/_remove_unused_function.py Removed redundant implementation of unused functions removal.
onnxscript/optimizer/_remove_unused.py Removed deprecated module entirely.
onnxscript/optimizer/_optimizer.py Updated unused node removal call to use the consolidated implementation.
onnxscript/optimizer/_legacy/_simple_function_folding_test.py Updated tests to use the new removal functions instead of the old ones.
onnxscript/optimizer/_legacy/_optimizer.py Updated the legacy optimizer to reference the new removal functions.
onnxscript/optimizer/init.py Added new in-place removal functions that wrap the consolidated passes and updated imports accordingly.
onnxscript/ir/passes/common/unused_removal.py Introduced consolidated passes for removing unused nodes, functions, and opset imports.
onnxscript/ir/passes/common/init.py Added licensing headers for consistency.

Copy link

codecov bot commented Mar 28, 2025

❌ 4 Tests Failed:

Tests completed Failed Passed Skipped
14082 4 14078 1719
View the top 3 failed test(s) by shortest run time
onnxscript.backend.onnx_export_test.TestOnnxBackEnd::test_export2python_produces_correct_onnx_script_model_0397_test_ai_onnx_ml_tree_ensemble_set_membership
Stack Traces | 0.01s run time
onnxscript/converter.py:467: in _eval_constant_expr
    return eval(cpl, self.globals, locals)  # pylint: disable=eval-used
E   NameError: name 'nan' is not defined

The above exception was the direct cause of the following exception:
..../test_ort_nightly/lib/python3.11.../site-packages/parameterized/parameterized.py:620: in standalone_func
    return func(*(a + p.args), **p.kwargs, **kw)
onnxscript/backend/onnx_export_test.py:271: in test_export2python_produces_correct_onnx_script_model
    functions = extract_functions(backend_test.name, code, self.test_folder)
onnxscript/backend/onnx_export_test.py:137: in extract_functions
    mod = importlib.import_module(import_name)
.../hostedtoolcache/Python/3.11.11.../x64/lib/python3.11/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1204: in _gcd_import
    ???
<frozen importlib._bootstrap>:1176: in _find_and_load
    ???
<frozen importlib._bootstrap>:1147: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:690: in _load_unlocked
    ???
..../test_ort_nightly/lib/python3.11.../_pytest/assertion/rewrite.py:185: in exec_module
    exec(co, module.__dict__)
tests/onnx_backend_test_code/test_ai_onnx_ml_tree_ensemble_set_membership.py:9: in <module>
    @script()
onnxscript/main.py:91: in transform
    result = script_check(f_ast, opset, env, src, default_opset=default_opset)
onnxscript/main.py:35: in script_check
    return convert.translate_function_def(f)
onnxscript/converter.py:1460: in translate_function_def
    fn_ir = self._translate_function_def_common(stmt)
onnxscript/converter.py:1447: in _translate_function_def_common
    self._translate_stmt(s, index_of_stmt=i)
onnxscript/converter.py:969: in _translate_stmt
    return self._translate_assign_stmt(node)
onnxscript/converter.py:1056: in _translate_assign_stmt
    assign(lhs, rhs)
onnxscript/converter.py:1000: in assign
    t = self._translate_expr(rhs, lhs).name
onnxscript/converter.py:553: in _translate_expr
    r = self._translate_call_expr(node)
onnxscript/converter.py:832: in _translate_call_expr
    attrs = [
onnxscript/converter.py:833: in <listcomp>
    self._translate_attr(x, y, callee.op_schema.attributes[x])
onnxscript/converter.py:517: in _translate_attr
    val = self._eval_constant_expr(expr)
onnxscript/converter.py:469: in _eval_constant_expr
    raise NameError(
E   NameError: ERROR: Missing names, globals contains ['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', '@py_builtins', '@pytest_ar', 'numpy', 'TensorProto', 'make_tensor', 'script', 'external_tensor', 'Opset', 'FLOAT', 'ai_onnx_ml5'], locals [].
E   at: Function 'bck_test_ai_onnx_ml_tree_ensemble_set_membership', line 3
E       Y = ai_onnx_ml5.TreeEnsemble(X, aggregate_function=1, leaf_targetids=[0, 1, 2, 3], leaf_weights=make_tensor("value", 1, dims=[4], vals=[1.0, 10.0, 1000.0, 100.0]), membership_values=make_tensor("value", 1, dims=[8], vals=[1.2000000476837158, 3.700000047683716, 8.0, 9.0, nan, 12.0, 7.0, nan]), n_targets=4, nodes_falseleafs=[1, 0, 1], nodes_falsenodeids=[2, 2, 3], nodes_featureids=[0, 0, 0], nodes_modes=make_tensor("value", 2, dims=[3], vals=[0, 6, 6]), nodes_splits=make_tensor("value", 1, dims=[3], vals=[11.0, 232344.0, nan]), nodes_trueleafs=[0, 1, 1], nodes_truenodeids=[1, 0, 1], post_transform=0, tree_roots=[0])
E                                                                                                                                                                                             ^
onnxscript.backend.onnx_export_test.TestOnnxBackEnd::test_export2python_produces_correct_onnx_script_model_0026_test_ai_onnx_ml_tree_ensemble_set_membership
Stack Traces | 0.046s run time
onnxscript\converter.py:467: in _eval_constant_expr
    return eval(cpl, self.globals, locals)  # pylint: disable=eval-used
E   NameError: name 'nan' is not defined

The above exception was the direct cause of the following exception:
.nox\test_ort_nightly\Lib\site-packages\parameterized\parameterized.py:620: in standalone_func
    return func(*(a + p.args), **p.kwargs, **kw)
onnxscript\backend\onnx_export_test.py:271: in test_export2python_produces_correct_onnx_script_model
    functions = extract_functions(backend_test.name, code, self.test_folder)
onnxscript\backend\onnx_export_test.py:137: in extract_functions
    mod = importlib.import_module(import_name)
C:\hostedtoolcache\windows\Python\3.11.9\x64\Lib\importlib\__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1204: in _gcd_import
    ???
<frozen importlib._bootstrap>:1176: in _find_and_load
    ???
<frozen importlib._bootstrap>:1147: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:690: in _load_unlocked
    ???
.nox\test_ort_nightly\Lib\site-packages\_pytest\assertion\rewrite.py:185: in exec_module
    exec(co, module.__dict__)
tests\onnx_backend_test_code\test_ai_onnx_ml_tree_ensemble_set_membership.py:9: in <module>
    @script()
onnxscript\main.py:91: in transform
    result = script_check(f_ast, opset, env, src, default_opset=default_opset)
onnxscript\main.py:35: in script_check
    return convert.translate_function_def(f)
onnxscript\converter.py:1460: in translate_function_def
    fn_ir = self._translate_function_def_common(stmt)
onnxscript\converter.py:1447: in _translate_function_def_common
    self._translate_stmt(s, index_of_stmt=i)
onnxscript\converter.py:969: in _translate_stmt
    return self._translate_assign_stmt(node)
onnxscript\converter.py:1056: in _translate_assign_stmt
    assign(lhs, rhs)
onnxscript\converter.py:1000: in assign
    t = self._translate_expr(rhs, lhs).name
onnxscript\converter.py:553: in _translate_expr
    r = self._translate_call_expr(node)
onnxscript\converter.py:832: in _translate_call_expr
    attrs = [
onnxscript\converter.py:833: in <listcomp>
    self._translate_attr(x, y, callee.op_schema.attributes[x])
onnxscript\converter.py:517: in _translate_attr
    val = self._eval_constant_expr(expr)
onnxscript\converter.py:469: in _eval_constant_expr
    raise NameError(
E   NameError: ERROR: Missing names, globals contains ['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', '@py_builtins', '@pytest_ar', 'numpy', 'TensorProto', 'make_tensor', 'script', 'external_tensor', 'Opset', 'FLOAT', 'ai_onnx_ml5'], locals [].
E   at: Function 'bck_test_ai_onnx_ml_tree_ensemble_set_membership', line 3
E       Y = ai_onnx_ml5.TreeEnsemble(X, aggregate_function=1, leaf_targetids=[0, 1, 2, 3], leaf_weights=make_tensor("value", 1, dims=[4], vals=[1.0, 10.0, 1000.0, 100.0]), membership_values=make_tensor("value", 1, dims=[8], vals=[1.2000000476837158, 3.700000047683716, 8.0, 9.0, nan, 12.0, 7.0, nan]), n_targets=4, nodes_falseleafs=[1, 0, 1], nodes_falsenodeids=[2, 2, 3], nodes_featureids=[0, 0, 0], nodes_modes=make_tensor("value", 2, dims=[3], vals=[0, 6, 6]), nodes_splits=make_tensor("value", 1, dims=[3], vals=[11.0, 232344.0, nan]), nodes_trueleafs=[0, 1, 1], nodes_truenodeids=[1, 0, 1], post_transform=0, tree_roots=[0])
E                                                                                                                                                                                             ^
onnxscript.backend.onnx_export_test.TestOnnxBackEnd::test_export2python_produces_correct_onnx_script_model_0125_test_ai_onnx_ml_tree_ensemble_set_membership
Stack Traces | 0.109s run time
onnxscript/converter.py:467: in _eval_constant_expr
    return eval(cpl, self.globals, locals)  # pylint: disable=eval-used
E   NameError: name 'nan' is not defined

The above exception was the direct cause of the following exception:
..../test_ort_nightly/lib/python3.11.../site-packages/parameterized/parameterized.py:620: in standalone_func
    return func(*(a + p.args), **p.kwargs, **kw)
onnxscript/backend/onnx_export_test.py:271: in test_export2python_produces_correct_onnx_script_model
    functions = extract_functions(backend_test.name, code, self.test_folder)
onnxscript/backend/onnx_export_test.py:137: in extract_functions
    mod = importlib.import_module(import_name)
.../Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1204: in _gcd_import
    ???
<frozen importlib._bootstrap>:1176: in _find_and_load
    ???
<frozen importlib._bootstrap>:1147: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:690: in _load_unlocked
    ???
..../test_ort_nightly/lib/python3.11.../_pytest/assertion/rewrite.py:185: in exec_module
    exec(co, module.__dict__)
tests/onnx_backend_test_code/test_ai_onnx_ml_tree_ensemble_set_membership.py:9: in <module>
    @script()
onnxscript/main.py:91: in transform
    result = script_check(f_ast, opset, env, src, default_opset=default_opset)
onnxscript/main.py:35: in script_check
    return convert.translate_function_def(f)
onnxscript/converter.py:1460: in translate_function_def
    fn_ir = self._translate_function_def_common(stmt)
onnxscript/converter.py:1447: in _translate_function_def_common
    self._translate_stmt(s, index_of_stmt=i)
onnxscript/converter.py:969: in _translate_stmt
    return self._translate_assign_stmt(node)
onnxscript/converter.py:1056: in _translate_assign_stmt
    assign(lhs, rhs)
onnxscript/converter.py:1000: in assign
    t = self._translate_expr(rhs, lhs).name
onnxscript/converter.py:553: in _translate_expr
    r = self._translate_call_expr(node)
onnxscript/converter.py:832: in _translate_call_expr
    attrs = [
onnxscript/converter.py:833: in <listcomp>
    self._translate_attr(x, y, callee.op_schema.attributes[x])
onnxscript/converter.py:517: in _translate_attr
    val = self._eval_constant_expr(expr)
onnxscript/converter.py:469: in _eval_constant_expr
    raise NameError(
E   NameError: ERROR: Missing names, globals contains ['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', '@py_builtins', '@pytest_ar', 'numpy', 'TensorProto', 'make_tensor', 'script', 'external_tensor', 'Opset', 'FLOAT', 'ai_onnx_ml5'], locals [].
E   at: Function 'bck_test_ai_onnx_ml_tree_ensemble_set_membership', line 3
E       Y = ai_onnx_ml5.TreeEnsemble(X, aggregate_function=1, leaf_targetids=[0, 1, 2, 3], leaf_weights=make_tensor("value", 1, dims=[4], vals=[1.0, 10.0, 1000.0, 100.0]), membership_values=make_tensor("value", 1, dims=[8], vals=[1.2000000476837158, 3.700000047683716, 8.0, 9.0, nan, 12.0, 7.0, nan]), n_targets=4, nodes_falseleafs=[1, 0, 1], nodes_falsenodeids=[2, 2, 3], nodes_featureids=[0, 0, 0], nodes_modes=make_tensor("value", 2, dims=[3], vals=[0, 6, 6]), nodes_splits=make_tensor("value", 1, dims=[3], vals=[11.0, 232344.0, nan]), nodes_trueleafs=[0, 1, 1], nodes_truenodeids=[1, 0, 1], post_transform=0, tree_roots=[0])
E                                                                                                                                                                                             ^

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR consolidates DCE passes into a common “unused_removal” pass to streamline the removal of unused nodes, functions, and opset imports. Key changes include:

  • Updating import paths to use the new common passes.
  • Refactoring the removal functions in optimizer and rewriter modules.
  • Bumping the IR version in tests from 7 to 10.

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
onnxscript/tools/benchmark/benchmark_helpers.py Updated import path for remove_unused_nodes.
onnxscript/rewriter/init.py Replaced direct removal calls with a pass manager implementation.
onnxscript/optimizer/_remove_unused_function.py and _remove_unused.py Removed legacy implementations.
onnxscript/optimizer/_optimizer.py and _legacy/_optimizer.py Updated calls to removal functions with new import paths.
onnxscript/optimizer/init.py Added in-place removal functions that use the new passes.
onnxscript/ir/passes/common/unused_removal_test.py Updated IR versions in test examples.
onnxscript/ir/passes/common/unused_removal.py Added new passes for removing unused nodes, functions, and opsets.
onnxscript/ir/passes/common/init.py Minor update (copyright).
Comments suppressed due to low confidence (1)

onnxscript/ir/passes/common/unused_removal.py:55

  • [nitpick] The condition using 'len([o == 1 for o in optional_info]) == 0' can be less clear than explicitly checking for the presence of any True values (e.g., using 'if not any(optional_info):').
if len([o == 1 for o in optional_info]) == 0:

@justinchuby justinchuby enabled auto-merge (squash) March 28, 2025 20:10
@justinchuby justinchuby disabled auto-merge March 28, 2025 22:10
@justinchuby justinchuby enabled auto-merge (squash) March 28, 2025 22:16
@justinchuby justinchuby disabled auto-merge March 28, 2025 22:31
@justinchuby justinchuby enabled auto-merge (squash) March 28, 2025 22:38
@justinchuby justinchuby merged commit af49eff into main Mar 28, 2025
26 of 29 checks passed
@justinchuby justinchuby deleted the justinchu/dce-passes branch March 28, 2025 22:54
bmehta001 pushed a commit to bmehta001/onnxscript that referenced this pull request Apr 11, 2025
Consolidate DCE passes into common passes (unused_removal) for them to
be available for pass users. Refactored usage. Added a pass to remove
unused opset imports.
bmehta001 pushed a commit to bmehta001/onnxscript that referenced this pull request Apr 11, 2025
Consolidate DCE passes into common passes (unused_removal) for them to
be available for pass users. Refactored usage. Added a pass to remove
unused opset imports.
bmehta001 pushed a commit to bmehta001/onnxscript that referenced this pull request Apr 11, 2025
Consolidate DCE passes into common passes (unused_removal) for them to
be available for pass users. Refactored usage. Added a pass to remove
unused opset imports.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

2 participants