Skip to content

[IR] Expose the Tape module #2127

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 18 commits into from
Apr 8, 2025
Merged

[IR] Expose the Tape module #2127

merged 18 commits into from
Apr 8, 2025

Conversation

justinchuby
Copy link
Collaborator

@justinchuby justinchuby commented Mar 24, 2025

Expose the Tape class under ir.tape for simplifying graph construction in the IR. This is a secondary API for convenience. I updated onnxscript/ir/passes/common/shape_inference_test.py to demonstrate usage.

I added an optional reference to the graph from Tape. When the graph is specified, the added nodes are appended to the graph. This provides users the ability to examine the graph as they build it up using Tape.

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 exposes the Tape module as part of the public API for simplified graph construction in the IR and updates shape inference tests to demonstrate its usage.

  • Exposes and re-exports the Tape class under onnxscript/ir/tape.py and via onnxscript/ir/init.py.
  • Refactors the Tape class in onnxscript/ir/_tape.py to accept additional parameters for op methods.
  • Updates shape inference tests to use the new Tape API instead of directly instantiating Node objects.

Reviewed Changes

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

File Description
onnxscript/ir/tape.py Introduces the public API for the Tape class and sets its module.
onnxscript/ir/init.py Exports the tape module to be part of the IR package’s public API.
onnxscript/ir/_tape.py Updates the Tape class and op methods with additional parameters.
onnxscript/ir/passes/common/shape_inference_test.py Revises tests to utilize the Tape API for constructing graphs.
Comments suppressed due to low confidence (2)

onnxscript/ir/_tape.py:99

  • In op_multi_output, the 'num_outputs' parameter is now optional and may be None. Ensure that the Node constructor and downstream logic can handle a None value or consider providing a default integer value.
num_outputs: int | None = None,

onnxscript/ir/passes/common/shape_inference_test.py:73

  • [nitpick] Consider using the 'inputs' list directly instead of '[*inputs]' for consistency with other tests and to reduce unnecessary overhead.
val_add = tape.op("Add", inputs=[*inputs])

@justinchuby justinchuby requested a review from Copilot March 24, 2025 20:06
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 exposes the Tape module to simplify IR graph construction by providing a convenient, secondary API. Key changes include:

  • Introducing onnxscript/ir/tape.py to export the Tape class.
  • Updating onnxscript/ir/_tape.py with extended op and op_multi_output signatures.
  • Modifying tests in onnxscript/ir/passes/common/shape_inference_test.py to demonstrate Tape usage.

Reviewed Changes

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

File Description
onnxscript/ir/tape.py Added public API for the Tape module and set the module name.
onnxscript/ir/_tape.py Extended the Tape class with additional parameters in methods.
onnxscript/ir/init.py Updated exports to include the Tape module.
onnxscript/ir/passes/common/shape_inference_test.py Updated tests to use the new Tape API for node operations.

Copy link

codecov bot commented Mar 24, 2025

❌ 5 Tests Failed:

Tests completed Failed Passed Skipped
15603 5 15598 2741
View the top 3 failed test(s) by shortest run time
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.007s 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:1459: in translate_function_def
    fn_ir = self._translate_function_def_common(stmt)
onnxscript/converter.py:1446: in _translate_function_def_common
    self._translate_stmt(s, index_of_stmt=i)
onnxscript/converter.py:968: in _translate_stmt
    return self._translate_assign_stmt(node)
onnxscript/converter.py:1055: in _translate_assign_stmt
    assign(lhs, rhs)
onnxscript/converter.py:999: 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_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:1459: in translate_function_def
    fn_ir = self._translate_function_def_common(stmt)
onnxscript/converter.py:1446: in _translate_function_def_common
    self._translate_stmt(s, index_of_stmt=i)
onnxscript/converter.py:968: in _translate_stmt
    return self._translate_assign_stmt(node)
onnxscript/converter.py:1055: in _translate_assign_stmt
    assign(lhs, rhs)
onnxscript/converter.py:999: 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.048s 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:1459: in translate_function_def
    fn_ir = self._translate_function_def_common(stmt)
onnxscript\converter.py:1446: in _translate_function_def_common
    self._translate_stmt(s, index_of_stmt=i)
onnxscript\converter.py:968: in _translate_stmt
    return self._translate_assign_stmt(node)
onnxscript\converter.py:1055: in _translate_assign_stmt
    assign(lhs, rhs)
onnxscript\converter.py:999: 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.

@justinchuby justinchuby added the module: IR Intermediate representation label Mar 24, 2025
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 exposes the Tape module to simplify graph construction in the IR while updating tests to demonstrate and support the new API.

  • Introduces onnxscript/ir/tape.py exposing the Tape class.
  • Updates shape inference and initializer tests to use Tape operations.
  • Extends the Tape API (and Builder subclass) and updates core type hints to support both Graph and Function types.

Reviewed Changes

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

Show a summary per file
File Description
onnxscript/ir/tape.py Exposes the Tape class with a public API and sets its module.
onnxscript/ir/passes/common/shape_inference_test.py Updates tests to use Tape for creating operations and nodes.
onnxscript/ir/_tape_test.py Adds tests covering tape operations, initializers, and multi-output.
onnxscript/ir/_tape.py Extends the Tape API to include additional parameters and tracks used opsets.
onnxscript/ir/_core.py Adjusts type hints for the graph parameter to accept Function objects.
onnxscript/ir/init.py Includes the tape module in the public IR API exports.

@justinchuby justinchuby requested a review from Copilot March 31, 2025 18:42
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 exposes the Tape module as part of the public IR API for simplified graph construction and improved testing.

  • Introduces onnxscript/ir/tape.py to expose the Tape class.
  • Updates tests in onnxscript/ir/passes/common/shape_inference_test.py and onnxscript/ir/_tape_test.py to demonstrate Tape usage.
  • Enhances the internal Tape implementation and type hints in onnxscript/ir/_tape.py and onnxscript/ir/_core.py to support both Graph and Function types.

Reviewed Changes

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

Show a summary per file
File Description
onnxscript/ir/tape.py Introduces public Tape API by importing from _tape and exposing it under the ir.tape namespace.
onnxscript/ir/passes/common/shape_inference_test.py Updates tests to utilize Tape for node creation and graph construction.
onnxscript/ir/_tape_test.py Adds new tests for Tape functionality including operations and multi-output handling.
onnxscript/ir/_tape.py Extends Tape implementation with additional parameters, type hints, and used_opsets management.
onnxscript/ir/_core.py Updates type hints for the graph parameter to include support for Function objects.
onnxscript/ir/init.py Exports the new tape module as part of the public IR API.

shubhambhokare1
shubhambhokare1 previously approved these changes Apr 7, 2025
Copy link
Contributor

@shubhambhokare1 shubhambhokare1 left a comment

Choose a reason for hiding this comment

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

Thanks, nit: lint and rebase

@justinchuby justinchuby enabled auto-merge (squash) April 8, 2025 16:43
@justinchuby justinchuby merged commit ad64b58 into main Apr 8, 2025
21 of 27 checks passed
@justinchuby justinchuby deleted the justinchu/tape branch April 8, 2025 17:00
@github-project-automation github-project-automation bot moved this from Todo to Done in ONNX Script Review Board Apr 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module: IR Intermediate representation
Projects
Development

Successfully merging this pull request may close these issues.

4 participants