Skip to content

Conversation

@BruceDai
Copy link
Contributor

@BruceDai BruceDai commented Dec 10, 2025

This PR is to fix #896.
@huningxin @fdwr @reillyeon PTAL, thanks!


Preview | Diff

@BruceDai BruceDai changed the title add minimum data types and rank range for operations [wip]add minimum data types and rank range for operations Dec 11, 2025
<tr>
<td>{{input}}</td>
<td>specified as part of operation steps</td>
<td></td>
Copy link
Contributor Author

@BruceDai BruceDai Dec 12, 2025

Choose a reason for hiding this comment

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

According to @fdwr's comments on #278 (comment), l2Pool2d is still not implemented in TFLite backend yet, so here I just followed @huningxin's comments on #853.

  "l2Pool2d": {
    "input": {
      "dataTypes": [],
      "rankRange": {}
    },
    "output": {
      "dataTypes": []
    }
  },

Copy link
Collaborator

@fdwr fdwr Dec 16, 2025

Choose a reason for hiding this comment

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

That TFLite l2Pool2d issue has been pending since 2022-06-30 😳. The Chromium backend that calls TFLite could just emulate it for now to unblock us. e.g.:

powResult = pow(input, exponent)
poolSumResult = poolSum(powResult, axes, windowDimensions, padding, strides, dilations)
// where poolSum can be emulated via poolAverage(input * product(windowDimensions)...)
// or by convolution with a filter of 1's.
result = root(poolSumResult, exponent)

(no action expected in this PR - resolve me)

@BruceDai BruceDai changed the title [wip]add minimum data types and rank range for operations add minimum data types and rank range for operations Dec 12, 2025
@fdwr
Copy link
Collaborator

fdwr commented Dec 12, 2025

I checked the unchanged Line 8987, it seems correct by using current 8 indents for to match front

of also 8 indents. Any suggestions? Thanks!

@BruceDai : Remerge with main. My PR adds an extra blank line that pacifies the build error (and yes, that line was already correct, and nothing changed there for months, but bikeshed changed).

Copy link
Member

@reillyeon reillyeon left a comment

Choose a reason for hiding this comment

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

General wording looks good. I have not validated the specific operator limits specified.

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.

👀 Thanks for the updates Bruce - I'm sure they were tedious :b.

<td>[=/any data type|any=]</td>
<td>{{MLOperandDataType/"float32"}}, {{MLOperandDataType/"float16"}}, {{MLOperandDataType/"int32"}}</td>
<td>[=/any rank|N=]</td>
<td>0 to 4</td>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Which ML API is the outlier for pow being 0 to 4 instead of 0 to 5? It will be problematic for callers if mul/div/pow have inconsistent ranks from each other, as certain substitution operations might expect that they can safely chain these or switch from one to another (e.g. mul(a,a) == pow(a,2)) without surprise. I propose the outlier API fix this in their Chromium backend with flanking reshapes (flatten to 1D if > 4D, pow, then back to the original shape). Then pow can be remerged back with the rest above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Which ML API is the outlier for pow being 0 to 4 instead of 0 to 5?

It's limited by TFLite backend.
Please refer to https://source.chromium.org/chromium/chromium/src/+/main:services/webnn/tflite/graph_builder_tflite.cc;l=568

       // Limited to 4D when broadcasting is required:
       // https://source.chromium.org/chromium/chromium/src/+/main:third_party/tflite/src/tensorflow/lite/kernels/pow.cc
       /*pow_input=*/{kFloat16To32AndInt32, SupportedRanks::UpTo(4)},

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we open a TFLite issue? Alternately we open a Chromium issue to {reshape, expand if needed, pow} until TFLite can address it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

<tr>
<td>{{input}}</td>
<td>specified as part of operation steps</td>
<td></td>
Copy link
Collaborator

@fdwr fdwr Dec 16, 2025

Choose a reason for hiding this comment

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

That TFLite l2Pool2d issue has been pending since 2022-06-30 😳. The Chromium backend that calls TFLite could just emulate it for now to unblock us. e.g.:

powResult = pow(input, exponent)
poolSumResult = poolSum(powResult, axes, windowDimensions, padding, strides, dilations)
// where poolSum can be emulated via poolAverage(input * product(windowDimensions)...)
// or by convolution with a filter of 1's.
result = root(poolSumResult, exponent)

(no action expected in this PR - resolve me)

<tr>
<td>{{input}}</td>
<td>[=/any data type|any=]</td>
<td>{{MLOperandDataType/"float32"}}, {{MLOperandDataType/"float16"}}, {{MLOperandDataType/"int32"}}, {{MLOperandDataType/"int8"}}, {{MLOperandDataType/"uint8"}}</td>
Copy link
Collaborator

@fdwr fdwr Dec 16, 2025

Choose a reason for hiding this comment

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

gatherElements includes int8/uint8, but its symmetric counterpart scatterElements does not 😳 I don't know which API has this surprising inconsistency, but I'd rather restrict gatherElements's required data types to exclude int8/uint8 than introduce this asymmetry.

</thead>
<tr>
<td>{{input}}</td>
<td>specified as part of operation steps</td>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we reflect allowed data types in table?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@huningxin In operation steps, the input of averagePool2d supports "float32", "float16" two data types, and the input of maxPool2d supports any data types, so I keep pervious descriptions here.

index.bs Outdated
<tr>
<td>{{input}}</td>
<td>[=/any data type|any=]</td>
<td>{{MLOperandDataType/"float32"}}, {{MLOperandDataType/"float16"}}, {{MLOperandDataType/"int32"}}</td>
Copy link
Contributor

Choose a reason for hiding this comment

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

ORT doesn't support int32

Copy link
Collaborator

@fdwr fdwr Dec 18, 2025

Choose a reason for hiding this comment

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

🤔 An ONNX BitCast operator could help with cases of pure data movement (since no actual math happens) like this one when the operator supports a different data type of the same bit size (sizeof(int32) == sizeof(uint32) == sizeof(float32)). For example, we could call BitCast(int32input, type=float32) -> Triangular -> BitCast(input, type=int32). I'll comment on that ONNX PR.

@BruceDai
Copy link
Contributor Author

Thanks @huningxin and @fdwr for review and identifications. 👍
I submitted a new commit to address your comments. Please take another look, thanks!☕

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.

Add minimum data type set and rank range for input, constant, output and each operator into Spec

4 participants