Skip to content

ignore fuse of last dimension in ynn_define_fuse_dims#10544

Closed
aizu-m wants to merge 1 commit into
google:masterfrom
aizu-m:fuse-dims-last-axis-oob
Closed

ignore fuse of last dimension in ynn_define_fuse_dims#10544
aizu-m wants to merge 1 commit into
google:masterfrom
aizu-m:fuse-dims-last-axis-oob

Conversation

@aizu-m

@aizu-m aizu-m commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

ASan, YNNPACK built with -fsanitize=address:

ERROR: AddressSanitizer: heap-buffer-overflow, READ of size 8
  #0 ynn_define_fuse_dims copy.cc:542
0x... located 0 bytes after 24-byte region
  allocated by vector<slinky::expr>::__assign ... copy.cc:539

ynn_define_fuse_dims fuses each axis with the dimension after it: it sets op.axes[axis_to_slinky_dim(rank, axes[i] + 1)], then propagates the shape with output.extents[i] = extent(i) * extent(i + 1) and erase(begin() + i + 1).

For the last dimension (axes[i] == rank-1, or -1) the successor is dimension rank, which is out of bounds, so the loop wrote output.extents[rank] and erased one past the end of the rank-sized extents vector.

The successor of the last dimension is an implicit broadcast dimension, so fusing with it is a no-op. Skip any axis whose successor is out of bounds instead of touching the extents. Out of bounds axes are broadcast dimensions too, so they are now ignored rather than rejected.

@dsharlet

Copy link
Copy Markdown
Collaborator

Most of these and the existing checks in split/fuse should probably be removed, and replaced with code that just ignores them. Splitting or fusing a broadcast dimension (which is what out of bounds dimensions are) is a no-op and should be ignored, not an error.

ynn_define_fuse_dims fuses each axis with the dimension after it. For the
last dimension that successor is an implicit broadcast dimension, so the
shape propagation wrote output.extents[rank] and erased begin()+rank+1,
one past the end of the rank-sized extents vector.

Fusing a broadcast dimension is a no-op, so skip an axis whose successor
is out of bounds instead of touching the extents. Out of bounds axes are
broadcast dimensions too, so they are ignored rather than rejected.
@aizu-m aizu-m force-pushed the fuse-dims-last-axis-oob branch from f589987 to 1c42f21 Compare June 22, 2026 12:44
@aizu-m aizu-m changed the title reject fuse of last dimension in ynn_define_fuse_dims ignore fuse of last dimension in ynn_define_fuse_dims Jun 22, 2026
@aizu-m

aizu-m commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Makes sense. Reworked fuse_dims to skip an axis whose successor is out of bounds rather than error, since fusing with a broadcast dimension is a no-op. Dropped the validate_axis call too, so out of bounds axes are ignored rather than rejected. The test now checks the fuse passes through unchanged for the last axis, the negative index, and an out of range axis.

The sibling split/fuse defines still validate up front. Happy to give them the same pass if you want it, here or as a follow-up.

@dsharlet

Copy link
Copy Markdown
Collaborator

Thanks for this PR, and all of your other PRs, it has been great to have your contributions!

Sorry to collide in this case but I decided to just fix a few of these myself: #10564

@dsharlet

Copy link
Copy Markdown
Collaborator

I'm going to close this one, please feel free to re-open if I missed something after resolving the conflicts.

@dsharlet dsharlet closed this Jun 25, 2026
@aizu-m

aizu-m commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

No worries, #10564 covers it. Pulled the merged diff and traced it: fuse_dims now skips the axis when axis_to_slinky_dim lands at or past the rank, so for the last dim (slot rank) op.axes never gets set and the propagation loop never writes output.extents[rank] or erases past the end. The ASan overflow is gone. Good to see fuse_dim and broadcast got the same pass in one go, that was the follow-up I had in mind. Nothing missed, happy to leave this closed.

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.

2 participants