Skip to content
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

New content: Add definition for shape broadcasting #534

Merged
merged 2 commits into from
Feb 13, 2024

Conversation

inexorabletash
Copy link
Member

@inexorabletash inexorabletash commented Jan 26, 2024

This change introduces a new section for Algorithms, following APIs, to collect algorithms referenced throughout the specification.

A section for Broadcasting is introduced, which defines broadcasting shapes and gives an explicit algorithm matching WebNN implementations of NumPy's General Broadcasting Rules. Definitions for "broadcastable" and "unidirectionally broadcastable" are introduced. The previous definition of "broadcast-shapes" is removed in favor of these new algorithms.

For #324, #462, and potentially #523.


Preview | Diff

@inexorabletash
Copy link
Member Author

I'm still pretty hazy on definitions, so please look at this very skeptically.

Re: introducing a new "Algorithms" section - this is a pattern I've adopted from other specs. I thought I'd give a whirl here and see what everyone thinks. It's easy enough to drop and put these definitions anywhere else to keep the overall spec structure unchanged.

@inexorabletash
Copy link
Member Author

inexorabletash commented Jan 26, 2024

Hold off on reviews, I was confusing unidirectional (mentioned in several places in the spec) and bidirectional (mentioned in the Chromium implementation). Fridays, am I right?

@inexorabletash inexorabletash force-pushed the content-broadcast-shapes branch 2 times, most recently from 8438403 to 74aef99 Compare January 27, 2024 00:09
@inexorabletash
Copy link
Member Author

Okay, this is updated to match the Chromium impl, I think. But... that may not be what's desired @a-sully mentions that unidirectional broadcasting seems specific to ONNX and other frameworks do things to work around this during export.

@a-sully
Copy link
Contributor

a-sully commented Jan 27, 2024

AFAICT ONNX is an outlier in making a distinction between "unidirectional" and "multidirectional" broadcasting. This distinction is not made by:

The "unidirectional broadcastable" constraint of some ONNX ops (e.g. prelu()) requires workarounds when exporting from other formats to ONNX - like in this example of using TVM to export PyTorch to ONNX: pytorch/pytorch#70570 (comment). The folks on that issue discovered that the "unidirectional broadcastable" constraint for prelu() was not documented (which has since been fixed) and that there were inconsistencies between ONNX implementations (which... hopefully has also been fixed ¯\(ツ)/¯ )

Numpy's broadcasting rules are the clear standard across the industry and IMHO is the standard that we should expose to the web. It then becomes up to the user agent to ensure that the constraints of the underlying framework (e.g. unidirectional broadcasting for ONNX, lack of inferred broadcasting specifications for XLA) are satisfied.

@wacky6
Copy link

wacky6 commented Jan 27, 2024

We follow Numpy broadcast rules for ops (in the chromium implementation), I think it's the golden "standard". +1 to adopt this throughout the spec (I didn't realize the spec matmul referred to an implementation defined broadcast 😱).

@a-sully mentions that unidirectional broadcasting seems specific to ONNX and other frameworks do things to work around this during export

Is ONNX unidirectional broadcast issue easy to workaround? The linked prelu() patch seems "easy enough".

Should we (from the spec's perspective) expect implementations (e.g. chromium DML backend)to do asid easy workarounds?

Copy link
Contributor

@huningxin huningxin left a comment

Choose a reason for hiding this comment

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

LGTM with a comment, thanks much!

index.bs Outdated Show resolved Hide resolved
@huningxin
Copy link
Contributor

@fdwr and @wchao1115 , please also take a look. Thanks!

@inexorabletash inexorabletash force-pushed the content-broadcast-shapes branch 3 times, most recently from 1b63ff7 to cf22546 Compare February 7, 2024 17:42
Copy link
Collaborator

@fdwr fdwr left a comment

Choose a reason for hiding this comment

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

Thank you Josh.

index.bs Outdated Show resolved Hide resolved
index.bs Outdated Show resolved Hide resolved
index.bs Show resolved Hide resolved
index.bs Outdated Show resolved Hide resolved
index.bs Outdated Show resolved Hide resolved
index.bs Show resolved Hide resolved
@fdwr
Copy link
Collaborator

fdwr commented Feb 10, 2024

The unidirectional broadcastable constraint of some ONNX ops (e.g. prelu() requires workarounds when exporting from other formats ...

Huh, I would have presumed prelu was bidirectionally broadcastable too (TIL...). For operator behavior changes, I'd like it to be separate from this CR that's just adding definitions.

Is ONNX unidirectional broadcast issue easy to workaround? The linked prelu() patch seems "easy enough".

Yep, easy with a little reshape of leading 1's.

Should we (from the spec's perspective) expect implementations (e.g. chromium DML backend)to do asid easy workarounds?

Whichever broadcasting behavior we have for prelu, unidirectional or bidirectional, it's trivial either way for backends to insert leading 1's as needed (which the Chromium DML backend already does for DML, since DML expects elementwise tensor descriptions of each input to have been massaged to consistent rank first - any higher level concepts like broadcasting already resolved). In the worst case, backends can utilize whatever logic they have for expand to pre-expand tensors before forwarding them along.

@inexorabletash
Copy link
Member Author

History was getting messy - I force-pushed a new squashed commit. It rolls in #564 to get the build working, but I'll rebase once that merges.

This change introduces a new section for Algorithms, following APIs,
to collect algorithms referenced throughout the specification.

A section for Broadcasting is introduced, which defines broadcasting
shapes and gives an explicit algorithm matching WebNN implementations
of NumPy's General Broadcasting Rules. Definitions for "broadcastable"
and "unidirectionally broadcastable" are introduced. The previous
definition of "broadcast-shapes" is removed in favor of these new
algorithms.

Use broadcasting definition in expand(), rather than bespoke steps

For webmachinelearning#324, webmachinelearning#378, webmachinelearning#462, and potentially webmachinelearning#523.

Co-authored-by: Dwayne Robinson <dwayner@microsoft.com>
@fdwr
Copy link
Collaborator

fdwr commented Feb 13, 2024

I force-pushed a new squashed commit.

Josh: 🤔 Shoot, I'm unsure now if I merged your triangular CR via squash commit like I was supposed to. Appears it was a single commit.

Except larger branch integrations where we want to retain history, that's the general policy for cleaner history. Then the CR author doesn't need to ever explicitly squash their changes, because force pushes in GitHub yield this unfortunate result for reviewers to minimize the review delta since last time...

image

Copy link
Collaborator

@fdwr fdwr left a comment

Choose a reason for hiding this comment

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

LGTM. 👞✨

@inexorabletash
Copy link
Member Author

No worries... I tend to squash locally, force-push, and always review the full diff anyway to see what the actual change is going to be. I'll try to refrain from squashing/force-pushing here though, going forward!

Copy link
Collaborator

@fdwr fdwr left a comment

Choose a reason for hiding this comment

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

One more tiny fix after re-review, which I'll just (per your earlier permission) submit and complete this. Thanks Josh.

index.bs Outdated Show resolved Hide resolved
@fdwr fdwr merged commit a26b587 into webmachinelearning:main Feb 13, 2024
2 checks passed
github-actions bot added a commit that referenced this pull request Feb 13, 2024
SHA: a26b587
Reason: push, by fdwr

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@inexorabletash inexorabletash deleted the content-broadcast-shapes branch February 13, 2024 06:09
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.

5 participants