Skip to content

Follow the shape-vector provenance walk through user-function returns (wala/ML#706)#554

Merged
khatchad merged 3 commits into
masterfrom
706-interprocedural-shape-walk
Jul 10, 2026
Merged

Follow the shape-vector provenance walk through user-function returns (wala/ML#706)#554
khatchad merged 3 commits into
masterfrom
706-interprocedural-shape-walk

Conversation

@khatchad

@khatchad khatchad commented Jul 9, 2026

Copy link
Copy Markdown
Member

Closes wala#706.

The shape-vector provenance walk (wala#703, #552) was intraprocedural, so a shape list produced by a user helper (the BERT/ALBERT get_shape_list pattern) stopped it at the helper's invoke and reported ⊤; one context additionally leaked the input tensor's shape through Reshape's fallback because the chain check didn't recognize the helper form.

What Changed

  • getShapesOfShapeVector resolves a helper invoke's call-graph targets and walks every callee's returned value through the same chain recognition, unioning across callees and returns and falling back to ⊤ when any return doesn't resolve. No explicit parameter-to-argument mapping is needed: the callee parameter's interprocedural points-to set already holds the caller's allocation, so the .shape base case resolves across the boundary. A visited set threaded through the recursion guards recursive helpers.
  • isShapeVectorChain mirrors the interprocedural case (and now takes the builder), so the legacy pin's skip case and Reshape's ⊤-guard recognize the helper form.

Coverage

testShapeHelperSlice pins the precise (5, 6) for get_shape(t)[-2:]. testShapeHelperSliceVar combines the hop with the negated variable bound from #553 (get_shape(t)[-k:]), which is structurally NLPGNN's einsum_via_matmul shape read (get_shape_list(input_tensor)[-num_inner_dims:]).

🤖 Generated with Claude Code

…wala#706).

The walk added for wala#703 was intraprocedural, so a shape list
produced by a user helper (the BERT/ALBERT `get_shape_list` pattern)
stopped it at the helper's invoke. `getShapesOfShapeVector` now resolves
the invoke's call-graph targets and walks every callee's returned value
through the same chain recognition, unioning across callees and returns
and falling back to ⊤ when any return doesn't resolve. No explicit
parameter-to-argument mapping is needed: the callee parameter's
interprocedural points-to set already holds the caller's allocation, so
the `.shape` base case resolves across the boundary. A visited set
threaded through the recursion guards recursive helpers.

`isShapeVectorChain` mirrors the interprocedural case (and now takes the
builder), so the legacy pin's skip case and `Reshape`'s ⊤-guard recognize
the helper form; without it, the pin unioned ⊤ into the precise result and
one context leaked the input tensor's shape.

`testShapeHelperSlice` pins the precise `(5, 6)` for `get_shape(t)[-2:]`;
`testShapeHelperSliceVar` combines the hop with wala#704's negated
variable bound (`get_shape(t)[-k:]`), structurally NLPGNN's
`einsum_via_matmul` shape read.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019qw3CqL43aLvPaj1xkWQ2m
Copilot AI review requested due to automatic review settings July 9, 2026 22:46
@khatchad khatchad enabled auto-merge July 9, 2026 22:46

Copilot AI left a comment

Copy link
Copy Markdown

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 extends TensorFlow shape-vector provenance in the Python tensor analysis so that shape lists produced by user helper functions (e.g., get_shape_list-style helpers) are followed interprocedurally through callee returns, preventing premature ⊤ results and avoiding reshape fallback leaks when the helper form is involved.

Changes:

  • Add interprocedural handling to TensorGenerator.getShapesOfShapeVector by walking call-graph targets and analyzing each callee’s returned value(s), with recursion guarding via a visited set.
  • Extend TensorGenerator.isShapeVectorChain to mirror the interprocedural helper-return case (now requiring the call-graph builder).
  • Add two new Python fixtures and corresponding JUnit tests to cover helper-return slicing with both literal and negated-variable slice bounds.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
com.ibm.wala.cast.python.ml/source/com/ibm/wala/cast/python/ml/client/TensorGenerator.java Implements interprocedural shape-vector provenance via callee-return walking and updates shape-vector structural recognition accordingly.
com.ibm.wala.cast.python.ml/source/com/ibm/wala/cast/python/ml/client/PythonTensorAnalysisEngine.java Updates the shape-vector structural check call site to pass the builder after the signature change.
com.ibm.wala.cast.python.test/data/tf2_test_shape_helper_slice.py Adds a fixture covering helper-return [-2:] slicing feeding tf.reshape.
com.ibm.wala.cast.python.test/data/tf2_test_shape_helper_slice_var.py Adds a fixture combining helper-return provenance with [-k:] (negated variable bound) slicing.
com.ibm.wala.cast.python.ml.test/source/com/ibm/wala/cast/python/ml/test/TestTensorflow2Model.java Adds tests validating precise (5, 6) inference for both new helper fixtures.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.18644% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.32%. Comparing base (2fa3f54) to head (a7b1459).

Files with missing lines Patch % Lines
...bm/wala/cast/python/ml/client/TensorGenerator.java 68.51% 1 Missing and 16 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #554      +/-   ##
============================================
+ Coverage     74.31%   74.32%   +0.01%     
- Complexity     3591     3601      +10     
============================================
  Files           304      304              
  Lines         23341    23391      +50     
  Branches       3966     3985      +19     
============================================
+ Hits          17346    17386      +40     
+ Misses         4388     4385       -3     
- Partials       1607     1620      +13     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Address review feedback: a helper mixing value-returns with a bare
`return` can produce no value (None) on some path, so both the shape walk
and the structural chain check now treat the call as unresolvable rather
than skipping the bare return. Also document the chain check's `builder`
parameter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019qw3CqL43aLvPaj1xkWQ2m
Copilot AI review requested due to automatic review settings July 9, 2026 23:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

The previous commit claimed this fix but carried only the Javadoc change:
the edit script aborted on a failed anchor before writing the code. A
helper mixing value-returns with a bare `return` can produce no value
(None) on some path, so the shape walk now returns ⊤ and the structural
chain check returns false on a bare return instead of skipping it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019qw3CqL43aLvPaj1xkWQ2m
Copilot AI review requested due to automatic review settings July 9, 2026 23:40
@khatchad

khatchad commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

❌ Patch coverage check failed.

The uncovered lines are the interprocedural walk's sound-fallback guards: the bare-return and recursive-helper rejections, the callee-without-IR and no-return degradations, and their mirrors in the structural chain check. Forcing them requires helpers whose degenerate form (return without a value feeding a shape position, self-recursive shape helpers) makes the fixture's own runtime assertions unreachable or invalid. The behavioral paths are covered by testShapeHelperSlice and testShapeHelperSliceVar.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

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

@khatchad khatchad added this pull request to the merge queue Jul 9, 2026
Merged via the queue into master with commit c014dae Jul 10, 2026
12 of 13 checks passed
@khatchad khatchad deleted the 706-interprocedural-shape-walk branch July 10, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Follow the shape-vector provenance walk through user-function returns (get_shape_list)

2 participants