Commit 4c43c66
authored
[webgpu] Use multiplication instead of pow if exponent is 2 (#26667)
### Description
More accurately compute Pow(2.0) on WebGPU EP.
Reproduction script:
```py
from onnx import helper, TensorProto
import onnxruntime as ort
import numpy as np
# 1. Create the ONNX model
# Define input and output
input_info = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 1])
output_info = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 1])
# Create a constant tensor for the exponent (2.0)
exponent_tensor = helper.make_tensor('exponent', TensorProto.FLOAT, [], [2.0])
exponent_node = helper.make_node('Constant', [], ['exponent_out'], value=exponent_tensor)
# Create the Pow node
# Pow takes two inputs: Base (X) and Power (exponent_out)
pow_node = helper.make_node(
'Pow',
inputs=['X', 'exponent_out'],
outputs=['Y'],
name='PowNode'
)
# Create the graph
graph_def = helper.make_graph(
[exponent_node, pow_node],
'test-model',
[input_info],
[output_info]
)
# Create the model
model_def = helper.make_model(graph_def, producer_name='onnx-example')
opset = model_def.opset_import[0]
opset.version = 13 # Ensure opset version supports the operations
# 2. Convert model to string (bytes)
model_str = model_def.SerializeToString()
# 3. Prepare input data
np.random.seed(0)
input_data = np.array([[-2e3]], dtype=np.float32)
# 4. Run on CPUExecutionProvider
sess_cpu = ort.InferenceSession(model_str, providers=['CPUExecutionProvider'])
res_cpu = sess_cpu.run(['Y'], {'X': input_data})[0]
print("CPU Result:", res_cpu)
# 5. Run on WebGpuExecutionProvider
sess_webgpu = ort.InferenceSession(model_str, providers=['WebGpuExecutionProvider'])
res_webgpu = sess_webgpu.run(['Y'], {'X': input_data})[0]
print("WebGPU Result:", res_webgpu)
# Compare results
diff = np.abs(res_cpu - res_webgpu)
max_diff = diff.max().item()
assert max_diff < 1e-5, f"Results do not match within tolerance! Max diff: {max_diff}"
print("Results match!")
```
currently produces
```
CPU Result: [[4.e+06]]
WebGPU Result: [[3.999999e+06]]
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Cell In[1], [line 56](vscode-notebook-cell:?execution_count=1&line=56)
54 diff = np.abs(res_cpu - res_webgpu)
55 max_diff = diff.max().item()
---> [56](vscode-notebook-cell:?execution_count=1&line=56) assert max_diff < 1e-5, f"Results do not match within tolerance! Max diff: {max_diff}"
57 print("Results match!")
AssertionError: Results do not match within tolerance! Max diff: 1.0
```
but with this PR:
```
CPU Result: [[4.e+06]]
WebGPU Result: [[4.e+06]]
Results match!
```
### Motivation and Context
Leads to downstream issues/inaccuracies for certain models, especially
those which have larger values to compute pow(x,2) for.
cc @guschmue1 parent f02a640 commit 4c43c66
File tree
1 file changed
+7
-4
lines changed- onnxruntime/core/providers/webgpu/math
1 file changed
+7
-4
lines changedLines changed: 7 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
322 | 322 | | |
323 | 323 | | |
324 | 324 | | |
325 | | - | |
| 325 | + | |
326 | 326 | | |
| 327 | + | |
327 | 328 | | |
328 | | - | |
329 | | - | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
330 | 333 | | |
331 | 334 | | |
332 | 335 | | |
| |||
337 | 340 | | |
338 | 341 | | |
339 | 342 | | |
340 | | - | |
| 343 | + | |
341 | 344 | | |
342 | 345 | | |
343 | 346 | | |
| |||
0 commit comments