webmachinelearning / webnn

šŸ§  Web Neural Network API
https://www.w3.org/TR/webnn/
Other
397 stars 48 forks source link

Behavior for numeric overflows/underflows/etc in algorithms #636

Open inexorabletash opened 8 months ago

inexorabletash commented 8 months ago

Some spec algorithms steps perform math that could overflow/underflow in implementations that do the arithmetic using particular types, such as uint32_t. This has been raised in https://github.com/webmachinelearning/webnn/issues/610#issue-2196705182 and https://github.com/webmachinelearning/webnn/pull/582#discussion_r1503641101 and probably elsewhere.

There are a handful of nuances here:

https://source.chromium.org/chromium/chromium/src/+/main:components/ml/webnn/graph_validation_utils.cc;l=36 is an implementation example where a filter size is constrained to be a uint32 even though larger values could be supported (I think?)

I checked with some other spec experts. Approaches really vary depending on the spec's domain.

Most specs implicitly follow the guidance from Infra which says this on algorithm limits:

A document using the Infra Standard generally should not enforce specific limits on algorithm inputs with regards to their size, resource usage, or equivalent. This allows for competition among user agents and avoids constraining the potential computing needs of the future.

This seems like good practice to follow. On the other hand, some of the more fundamental specs (e.g. ECMA-262 - the JavaScript definition) need to specify in great detail how calculations are performed and deal with all of the fun edge cases. This is done with incredibly detailed algorithms and the use of helpers such as ā„() (for converting to reals) and š”½() (for converting to doubles), along with consistent spec notation like ! (asserting that an expression will not throw) and ? (signaling that an expression may throw, and exceptions should propagate)

I think that for WebNN we have a range of options, and we may change our approach over time - e.g. start off without trying to capture this fine level of detail, but then introduce more rigor over time. Some options:

I'd lean towards the lightweight former options, for now at least, but with these notes:

inexorabletash commented 8 months ago

Process-wise, I'd propose that we hear from the editors and WG here, pick an approach we're happy with for now, then close this issue knowing that we might revisit later.

CC: @fdwr @huningxin @zolkis

zolkis commented 8 months ago

Add a generic statement to the spec referencing the Infra note.

This certainly makes sense.

Introduce helpers and/or shorthand like ECMA-262's but for checked math, e.g. š•Œ32(...) meaning "if the result of this calculation doesn't fit into a uint32, then throw an exception. Bikeshed supports text macros to make authoring this easier.

Not yet sure about this. But interop is a primary concern, so all means helping (but not overspecifying) it should be considered.

I'd lean towards the lightweight former options, for now at least, but with these notes:

Agreed with the notes, except I'd think more about the third note (and how to make those detectable with interop tests).

inexorabletash commented 7 months ago

Some examples of intermediate values that might overflow:

inexorabletash commented 2 months ago

Quick update here - @huningxin put together a spreadsheet enumerating places where the Chromium prototype does "checked math" to catch overflows (etc) and generates exceptions which aren't captured in the spec. The plan was to propose spec changes to capture those; once complete this issue can be closed.