Model tf.squeeze output shape by dropping singleton axes#379
Open
khatchad wants to merge 3 commits into
Open
Conversation
`tf.squeeze` was a `pass_through` alias, leaking the input shape unchanged. Replace it with a `<new>+<return>` summary paired with a dedicated `Squeeze` generator (the Bucket 2a pattern from wala#513): dtype inherits from `input`; the output shape drops the singleton axes named by `axis`, or every statically size-1 axis when `axis` is absent. Dynamic/symbolic dimensions are never dropped under the axis-absent form (not statically known to be 1), and a named non-singleton axis falls back to ⊤ rather than producing a wrong shape. Closes the last corpus shape residual on the dtype-already-concrete `crf_forward`: `state` (from `tf.squeeze(tf.slice(...), [1])`) now infers as `(2, 4)` instead of the pre-squeeze `(2, 1, 4)`. Adds `tf2_test_squeeze.py` with `testSqueezeAxis` (named axis) and `testSqueezeAll` (all size-1 axes). Full suite green. Progresses wala#513 (the `tf.squeeze` row of the `pass_through` audit). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR improves the TensorFlow modeling in WALA’s Python ML analysis by making tf.squeeze shape-aware instead of treating it as a shape pass-through, enabling tighter inferred tensor shapes in the corpus and in dedicated squeeze tests.
Changes:
- Model
tf.squeezeas a dedicated TensorFlow function (<new> + <return>) and route it to a newSqueezetensor generator. - Implement shape derivation for
tf.squeezeby removing singleton axes (either specified byaxisor all statically-known1dims whenaxisis absent), while preserving dtype viaPassThroughUnaryTensorGenerator. - Add/extend tests to pin inferred shapes for both
tf.squeeze(x, [axis])andtf.squeeze(x)and tighten thecrf_forwardexpectation.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| com.ibm.wala.cast.python.test/data/tf2_test_squeeze.py | New TF2 test program exercising tf.squeeze with and without an axis argument. |
| com.ibm.wala.cast.python.ml/source/com/ibm/wala/cast/python/ml/types/TensorFlowTypes.java | Adds a MethodReference and signature entry for tf.squeeze. |
| com.ibm.wala.cast.python.ml/source/com/ibm/wala/cast/python/ml/client/TensorGeneratorFactory.java | Routes tf.squeeze calls to the new Squeeze generator. |
| com.ibm.wala.cast.python.ml/source/com/ibm/wala/cast/python/ml/client/Squeeze.java | New generator implementing squeeze axis resolution and output-shape derivation. |
| com.ibm.wala.cast.python.ml/data/tensorflow.xml | Replaces squeeze’s prior pass_through alias with a modeled function class and do() method returning a tensor. |
| com.ibm.wala.cast.python.ml.test/source/com/ibm/wala/cast/python/ml/test/TestTensorflow2Model.java | Updates testCrfForward expected shape and adds testSqueezeAxis/testSqueezeAll. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## slice-shape-from-begin-size #379 +/- ##
==============================================================
Coverage 71.68% 71.68%
- Complexity 2744 2767 +23
==============================================================
Files 272 273 +1
Lines 20393 20475 +82
Branches 3298 3322 +24
==============================================================
+ Hits 14618 14677 +59
- Misses 4475 4484 +9
- Partials 1300 1314 +14 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Address review: a named axis out of `[-rank, rank)` now falls back to ⊤ (was silently ignored, leaving the shape unsqueezed), and a named axis is dropped only when it is statically size-1 (a dynamic/symbolic dimension now falls back to ⊤ instead of being assumed squeezable). The corpus and standalone cases are unaffected — their named axes are constant 1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds `testSqueezeSingleAxis` (`tf.squeeze(x, 1)`, exercising the constant-integer axis branch of `resolveAxisInts`) and `testSqueezeMultiAxis` (`tf.squeeze(x, [1, 3])`, exercising multi-element axis normalization), closing the patch-coverage gap on the new generator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Models
tf.squeeze's output shape, thetf.squeezerow of thepass_throughaudit wala#513 (Bucket 2a) — and the last corpus shape residual for the input-signature evaluation. Stacked on #375 (base branchslice-shape-from-begin-size):crf_forward'sstateonly reaches(2, 4)once #375'stf.sliceshape gives(2, 1, 4)to squeeze. Review/merge #375 first; this diff is squeeze-only.Change
tf.squeezewas apass_throughalias, leaking the input shape unchanged. Replace it with a<new>+<return>summary paired with a dedicatedSqueezegenerator:input(viaPassThroughUnaryTensorGenerator).axis(negative axes count from the end), or every statically size-1 axis whenaxisis absent. Dynamic/symbolic dimensions are never dropped under the axis-absent form (not statically known to be 1); a named non-singleton axis falls back to ⊤ rather than producing a wrong shape.Tests
testCrfForward'sstate(fromtf.squeeze(tf.slice(...), [1])) tightens from the pre-squeeze(2, 1, 4)to(2, 4)— the corpuscrf_*family is now fully shape-precise.tf2_test_squeeze.py+testSqueezeAxis(tf.squeeze(x, [1])over(2, 1, 3, 1)→(2, 3, 1)) andtestSqueezeAll(tf.squeeze(x)→(2, 3)).com.ibm.wala.cast.python.jython.testresource bug, fixed in Scopecom.ibm.wala.cast.python.jython.test's resource directory #377).Progresses wala#513.
🤖 Generated with Claude Code